mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
refactor: split oversized catalog and protocol helpers (#106476)
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
export const CLAUDE_LOCAL_SESSION_HOST_ID = "gateway:local";
|
||||
const CLAUDE_ADOPTED_SESSION_KEY_PREFIX = "plugin:anthropic:catalog-adopt:claude:";
|
||||
|
||||
export function adoptedSourceKey(hostId: string, threadId: string): string {
|
||||
return `${hostId}\0${threadId}`;
|
||||
}
|
||||
|
||||
export function adoptedSessionKey(hostId: string, threadId: string): string {
|
||||
// Local rows hash threadId alone: adopted keys minted before node support
|
||||
// must stay stable, or existing adopted sessions would orphan/duplicate.
|
||||
const source =
|
||||
hostId === CLAUDE_LOCAL_SESSION_HOST_ID ? threadId : adoptedSourceKey(hostId, threadId);
|
||||
return `${CLAUDE_ADOPTED_SESSION_KEY_PREFIX}${createHash("sha256").update(source).digest("hex")}`;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
@@ -19,6 +18,11 @@ export const CLAUDE_SESSIONS_LIST_COMMAND = "anthropic.claude.sessions.list.v1";
|
||||
export const CLAUDE_SESSION_READ_COMMAND = "anthropic.claude.sessions.read.v1";
|
||||
export const CLAUDE_CLI_NODE_RUN_COMMAND = "agent.cli.claude.run.v1";
|
||||
import { CLAUDE_CLI_BACKEND_ID, CLAUDE_CLI_DEFAULT_MODEL_REF } from "./cli-constants.js";
|
||||
import {
|
||||
adoptedSessionKey,
|
||||
adoptedSourceKey,
|
||||
CLAUDE_LOCAL_SESSION_HOST_ID,
|
||||
} from "./session-catalog-adoption.js";
|
||||
import {
|
||||
collectTranscriptText,
|
||||
parseTranscriptLine,
|
||||
@@ -27,7 +31,6 @@ import {
|
||||
|
||||
export type { ClaudeTranscriptItem } from "./session-catalog-transcript.js";
|
||||
|
||||
const CLAUDE_LOCAL_SESSION_HOST_ID = "gateway:local";
|
||||
const DEFAULT_PAGE_LIMIT = 50;
|
||||
const MAX_PAGE_LIMIT = 100;
|
||||
const DEFAULT_TRANSCRIPT_LIMIT = 20;
|
||||
@@ -46,8 +49,6 @@ const MAX_TRANSCRIPT_SCAN_BYTES = 64 * 1024 * 1024;
|
||||
const MAX_TRANSCRIPT_PAGE_BYTES = 20 * 1024 * 1024;
|
||||
|
||||
const NODE_INVOKE_TIMEOUT_MS = 30_000;
|
||||
const CLAUDE_ADOPTED_SESSION_KEY_PREFIX = "plugin:anthropic:catalog-adopt:claude:";
|
||||
|
||||
const CLAUDE_HISTORY_IMPORT_MAX_ITEMS = 200;
|
||||
const CLAUDE_HISTORY_IMPORT_MAX_BYTES = 512 * 1024;
|
||||
|
||||
@@ -1063,18 +1064,6 @@ async function readClaudeSessionTranscript(params: {
|
||||
};
|
||||
}
|
||||
|
||||
function adoptedSourceKey(hostId: string, threadId: string): string {
|
||||
return `${hostId}\0${threadId}`;
|
||||
}
|
||||
|
||||
function adoptedSessionKey(hostId: string, threadId: string): string {
|
||||
// Local rows hash threadId alone: adopted keys minted before node support
|
||||
// must stay stable, or existing adopted sessions would orphan/duplicate.
|
||||
const source =
|
||||
hostId === CLAUDE_LOCAL_SESSION_HOST_ID ? threadId : adoptedSourceKey(hostId, threadId);
|
||||
return `${CLAUDE_ADOPTED_SESSION_KEY_PREFIX}${createHash("sha256").update(source).digest("hex")}`;
|
||||
}
|
||||
|
||||
function currentConfig(api: OpenClawPluginApi): OpenClawConfig {
|
||||
return (api.runtime.config?.current?.() as OpenClawConfig | undefined) ?? api.config;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ export {
|
||||
type ClawHubTrustErrorCode,
|
||||
type ClawHubTrustErrorDetails,
|
||||
} from "./clawhub-trust-error-details.js";
|
||||
import type { Static, TSchema } from "typebox";
|
||||
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
|
||||
import type { ValidationError } from "./validation-errors.js";
|
||||
export { formatValidationErrors, type ValidationError } from "./validation-errors.js";
|
||||
import { lazyCompile } from "./protocol-validator.js";
|
||||
export type { ProtocolValidator } from "./protocol-validator.js";
|
||||
export * from "./schema/worker-inference.js";
|
||||
export type {
|
||||
SessionCatalog,
|
||||
@@ -492,67 +492,6 @@ import {
|
||||
FsListDirResultSchema,
|
||||
} from "./schema.js";
|
||||
|
||||
/** Runtime validator shape shared by gateway clients and server handlers. */
|
||||
export type ProtocolValidator<T = unknown> = ((data: unknown) => data is T) & {
|
||||
errors: ValidationError[] | null; // Ajv-style last validation errors.
|
||||
/** Original schema used by the validator, exposed for diagnostics/tests. */
|
||||
schema: unknown;
|
||||
};
|
||||
|
||||
// Defer TypeBox compilation because this module is common on startup paths.
|
||||
function lazyCompile<const Schema extends TSchema>(
|
||||
schema: Schema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<Static<Schema>>;
|
||||
// Keep compact hand-authored public types where schema-derived declarations are intentionally avoided.
|
||||
function lazyCompile<T>(
|
||||
schema: TSchema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<T>;
|
||||
function lazyCompile<T = unknown>(
|
||||
schema: TSchema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<T> {
|
||||
let compiled: TypeBoxValidator | undefined;
|
||||
let errors: ValidationError[] | null = null;
|
||||
|
||||
const getCompiled = () => {
|
||||
compiled ??= Compile(schema as never);
|
||||
return compiled;
|
||||
};
|
||||
|
||||
const validate = ((data: unknown): data is T => {
|
||||
const precheckError = precheck?.(data);
|
||||
if (precheckError) {
|
||||
errors = [precheckError];
|
||||
return false;
|
||||
}
|
||||
const current = getCompiled();
|
||||
const valid = current.Check(data);
|
||||
errors = valid ? null : ([...current.Errors(data)] as ValidationError[]);
|
||||
return valid;
|
||||
}) as ProtocolValidator<T>;
|
||||
|
||||
Object.defineProperties(validate, {
|
||||
errors: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => errors,
|
||||
set: (nextErrors: ValidationError[] | null | undefined) => {
|
||||
// Preserve Ajv-compatible mutability for callers/tests that clear errors.
|
||||
errors = nextErrors ?? null;
|
||||
},
|
||||
},
|
||||
schema: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => schema,
|
||||
},
|
||||
});
|
||||
|
||||
return validate;
|
||||
}
|
||||
|
||||
// Validator names mirror schemas so callers can pair them with wire contracts.
|
||||
export const validateCommandsListParams = lazyCompile(CommandsListParamsSchema);
|
||||
export const validateConnectParams = lazyCompile(ConnectParamsSchema);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import type { Static, TSchema } from "typebox";
|
||||
import { Compile, type Validator as TypeBoxValidator } from "typebox/compile";
|
||||
import type { ValidationError } from "./validation-errors.js";
|
||||
|
||||
/** Runtime validator shape shared by gateway clients and server handlers. */
|
||||
export type ProtocolValidator<T = unknown> = ((data: unknown) => data is T) & {
|
||||
errors: ValidationError[] | null; // Ajv-style last validation errors.
|
||||
/** Original schema used by the validator, exposed for diagnostics/tests. */
|
||||
schema: unknown;
|
||||
};
|
||||
|
||||
// Defer TypeBox compilation because the protocol entrypoint is common on startup paths.
|
||||
export function lazyCompile<const Schema extends TSchema>(
|
||||
schema: Schema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<Static<Schema>>;
|
||||
// Keep compact hand-authored public types where schema-derived declarations are intentionally avoided.
|
||||
export function lazyCompile<T>(
|
||||
schema: TSchema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<T>;
|
||||
export function lazyCompile<T = unknown>(
|
||||
schema: TSchema,
|
||||
precheck?: (data: unknown) => ValidationError | undefined,
|
||||
): ProtocolValidator<T> {
|
||||
let compiled: TypeBoxValidator | undefined;
|
||||
let errors: ValidationError[] | null = null;
|
||||
|
||||
const getCompiled = () => {
|
||||
compiled ??= Compile(schema as never);
|
||||
return compiled;
|
||||
};
|
||||
|
||||
const validate = ((data: unknown): data is T => {
|
||||
const precheckError = precheck?.(data);
|
||||
if (precheckError) {
|
||||
errors = [precheckError];
|
||||
return false;
|
||||
}
|
||||
const current = getCompiled();
|
||||
const valid = current.Check(data);
|
||||
errors = valid ? null : ([...current.Errors(data)] as ValidationError[]);
|
||||
return valid;
|
||||
}) as ProtocolValidator<T>;
|
||||
|
||||
Object.defineProperties(validate, {
|
||||
errors: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => errors,
|
||||
set: (nextErrors: ValidationError[] | null | undefined) => {
|
||||
// Preserve Ajv-compatible mutability for callers/tests that clear errors.
|
||||
errors = nextErrors ?? null;
|
||||
},
|
||||
},
|
||||
schema: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => schema,
|
||||
},
|
||||
});
|
||||
|
||||
return validate;
|
||||
}
|
||||
Reference in New Issue
Block a user