mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers * fix: remove duplicate coercion imports * fix: preserve serialized coercion guard * chore: ratchet coercion helper carve-outs * fix(test): keep gauntlet subprocess startup lean * fix: preserve imported session timestamp semantics * fix: preserve catalog timestamp string semantics * chore: align plugin SDK surface ratchet * fix: preserve trajectory and SDK string contracts * fix(test): preserve QA record assertion semantics * fix: complete standalone record guard rename * refactor(cron): use canonical string coercion * fix(acpx): preserve Pi timestamp parsing * test(channels): adapt custody test harnesses * test(telegram): classify media harness as test support * test(acpx): split timestamp contract coverage * test(channels): support generated custody contracts * chore: ban the full coercion helper name set Extends the declaration guard to all eleven consolidated helper names and renames the cron schedule-identity readNumber wrapper to readScheduleInteger so the banned generic name cannot regrow. * fix(scripts): repair release-validation guard drift and lint cause Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after main added isRecord call sites in parallel, and attaches the caught YAML error as the thrown error cause (preserve-caught-error was red on main). * fix: preserve Claude timestamp string semantics * fix: preserve persisted timestamp string semantics * fix: preserve date-first timestamp contracts * fix(openai): harden delegation failure formatting * chore: close coercion helper guard gaps * test(openai): model non-error delegation rejection * chore: refresh plugin SDK API contract * fix(tasks): use canonical string field reader * fix(ai): use canonical provider error field coercion * fix(browser): migrate native bootstrap coercion * docs(plugin-sdk): clarify text record export compatibility * fix(gateway): normalize approval execution identity * test(outbound): isolate message action poll harness
This commit is contained in:
committed by
GitHub
parent
f788af0238
commit
fa03d9b913
@@ -2348,6 +2348,14 @@ jobs:
|
||||
pnpm tool-display:check
|
||||
pnpm check:host-env-policy:swift
|
||||
pnpm dup:check:coverage
|
||||
if has_package_script "check:coercion-helpers"; then
|
||||
pnpm check:coercion-helpers
|
||||
elif [[ "$HISTORICAL_TARGET" == "true" ]]; then
|
||||
echo "[skip] historical target predates the coercion-helper declaration guard"
|
||||
else
|
||||
echo "Current CI targets must provide the check:coercion-helpers package script." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "$PR_BASE_SHA" ]; then
|
||||
timeout --signal=TERM --kill-after=10s 120s git fetch --no-tags --depth=1 origin "+${PR_BASE_SHA}:refs/remotes/origin/ci-base"
|
||||
node scripts/report-test-temp-creations.mjs --base refs/remotes/origin/ci-base --head HEAD --no-merge-base
|
||||
|
||||
+69
-66
@@ -53,17 +53,17 @@
|
||||
{"closureHash":"ff3c4616cd6212a6d698831a8b287ad87e3968c8663f4090d095bb30ec40fc1c","declaration":"export function abortAndDrainAgentHarnessRun(params: { sessionId: string; sessionKey?: string; settleMs?: number; forceClear?: boolean; reason?: string; }): Promise<AbortAndDrainEmbeddedAgentRunResult>;","entrypoint":"agent-harness","exportName":"abortAndDrainAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise<OpenClawAgentToolResult>; };","entrypoint":"agent-harness","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise<AgentToolResult<unknown>>; };","entrypoint":"agent-harness","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1115e6754f66da077a1d2f349cf2bfd26382b0978b4efcf131d8d5e8a219e485","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"2624f0c11a7852cedded8f42322cb6e6a6c719d6be2ec4571e8d1fb252c6eaaf","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise<void>;","entrypoint":"agent-harness","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"27d9f61df9ccf68615cb2002a6da891e36ab0c07623bc37c4d07aa980b446881","declaration":"export function resolveWebSearchToolPolicy(params: WebSearchToolPolicyParams): WebSearchToolPolicyResolution;","entrypoint":"agent-harness","exportName":"resolveWebSearchToolPolicy","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
|
||||
{"closureHash":"7dcb6a9a37ace260567e3b46fc8d051aa124df2edfb093dfb56f082da56eaafb","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"65b516857f90d0029866f6b3179cac436dd6d5c85bd83d440fbcdbe297b70bf6","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"beb6715ad81487caa2cc2ed8444d6ac2dcf83c9e71fc42d5db9214f2eb12b946","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ca20bb488d357785086f04e71b0fbb300a27325217bdbfdcaa1e422eca2fe255","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"008b6c78d5e44a9d1df1d7e32e6015382ee9ba1cb9b10bd4c2b467619d1c89d4","declaration":"export type AgentToolResultMiddlewareEvent = AgentToolResultMiddlewareEvent;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddlewareEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7414a2a79c2d78c1d52538250c827305bba1a2bb25010448837c8524a9f95b3c","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"agent-harness","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f6d52c26f4fa2377f384935aa8e0c990e8634bc56ddc35dc00f4e00d5dfd16c4","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b96b39b906aac64a2ce1037ad8f6f811f832b5189f53c0c966cba9dedca50615","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b0d89fe509b6812c24b0a46cbc7d7ce20af0009a415c4e50e20c41af02975b11","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"67dd9a76536fb9f41ae19a380dd71bf10682ff80c63f363b5f8511948dcd1aab","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult<TResult = unknown> = OpenClawAgentToolResult<TResult>;","entrypoint":"agent-harness","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
|
||||
{"category":"runtime","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","recordType":"module"}
|
||||
{"closureHash":"fab99dfcb01d475a1bfdbe7a8fac9be10a93dac5f12ac78c2dea673c8ab86abf","declaration":"export function abortAgentHarnessRun(sessionId: string): boolean;\nexport function abortAgentHarnessRun(sessionId: undefined, opts: { mode: \"all\" | \"compacting\"; reason?: \"restart\"; }): boolean;","entrypoint":"agent-harness-runtime","exportName":"abortAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
@@ -82,8 +82,8 @@
|
||||
{"closureHash":"f8ad3d762c9753fdc36b2b9af0980167fdc54090c7bcca2f3dbe7c8951e86821","declaration":"export function buildAgentRuntimePlan(params: BuildAgentRuntimePlanParams): AgentRuntimePlan;","entrypoint":"agent-harness-runtime","exportName":"buildAgentRuntimePlan","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"528d11abf061b0b303722737de5a6406e7e55bffa38c45144c77d896ae1b3b0a","declaration":"export function buildBootstrapContextForFiles(bootstrapFiles: WorkspaceBootstrapFile[], params: { config?: OpenClawConfig; agentId?: string | null; warn?: (message: string) => void; }): EmbeddedContextFile[];","entrypoint":"agent-harness-runtime","exportName":"buildBootstrapContextForFiles","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"44d5a4667d2f3dc3a28e5c9d7b46765b1fb3c62820288e40251f5174911c8a6a","declaration":"export function buildEmbeddedAttemptToolRunContext(params: { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; toolsAllow?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; }): { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; runtimeToolAllowlist?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; };","entrypoint":"agent-harness-runtime","exportName":"buildEmbeddedAttemptToolRunContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"faa83a109c85aaabd294ba35f76000b22901b5d6cc33a57f9cfbb7e3792c6506","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters<typeof buildAfterTurnRuntimeContext>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e10f6ebee88eb98a88ea66a8d1dfff03f7ce1b82c50dc3b5d130652b450e9ccc","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters<typeof buildAfterTurnRuntimeContextFromUsage>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e194f5cdcc6a602b877027a0c105c9e850c02f81439eb655d3e9d56febc28a22","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters<typeof buildAfterTurnRuntimeContext>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"74b53fe40a520f5dffa1593ed0bfea15ac8b08cc74428d03375e47e9bed0adc1","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters<typeof buildAfterTurnRuntimeContextFromUsage>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"33a7cd8d63d4ef045ee3a42f806026a8b621e7dd32d8d6fbf4e7b44452d5e0ce","declaration":"export function buildNativeHookRelayCommand(params: { provider: NativeHookRelayProvider; relayId: string; generation?: string; event: NativeHookRelayEvent; preToolUseUnavailable?: \"noop\"; timeoutMs?: number; executable?: string; nice?: number | false; nodeExecutable?: string; }): string;","entrypoint":"agent-harness-runtime","exportName":"buildNativeHookRelayCommand","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3846647c3c2fb0242f70591cf95c2e02f2a5a3c44447efb4cf7a31b2dc2122fd","declaration":"export function buildSkillWorkshopPromptSection(): string[];","entrypoint":"agent-harness-runtime","exportName":"buildSkillWorkshopPromptSection","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"32e977ece65144a83ae1b0a3c8d1b9b00a2a2506ad9ef1db3b2b9770ce762dbe","declaration":"export function buildWatchedSessionsHarnessContext(params: { config?: OpenClawConfig; sessionKey?: string; sandboxed?: boolean; toolNames: Iterable<string>; capabilityToolNames?: Iterable<string>; }): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"buildWatchedSessionsHarnessContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
@@ -100,7 +100,7 @@
|
||||
{"closureHash":"51f76e9e37b65b358f0313e10152d950b003bc3e50f4bb26fe29a988237772e2","declaration":"export function consumePreExecutionBlockedToolCall(toolCallId: string, runId?: string): boolean;","entrypoint":"agent-harness-runtime","exportName":"consumePreExecutionBlockedToolCall","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise<OpenClawAgentToolResult>; };","entrypoint":"agent-harness-runtime","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise<AgentToolResult<unknown>>; };","entrypoint":"agent-harness-runtime","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b7399f160a14a25556f800de6cede4d57349dd45aa90f59a8fae5aaf19c01913","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b63d7e807de37989954018686a2c3ddaa30f4bb71d610221b178495f978ef9bb","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"6f436485257f69fa07a18203b91d4341690522f12aff4f25805c7a1e21326ee3","declaration":"export function detectAndLoadAgentHarnessPromptImages(params: { prompt: string; workspaceDir: string; model: { input?: string[]; }; existingImages?: ImageContent[]; imageOrder?: PromptImageOrderEntry[]; media?: MediaFact[]; config?: OpenClawConfig; workspaceOnly?: boolean; localRoots?: readonly string[]; sandbox?: { root: string; bridge: SandboxFsBridge; }; }): Promise<{ images: ImageContent[]; detectedRefs: Array<{ raw: string; resolved: string; type: \"path\" | \"media-uri\"; }>; loadedCount: number; skippedCount: number; }>;","entrypoint":"agent-harness-runtime","exportName":"detectAndLoadAgentHarnessPromptImages","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c38cd390190bb07ddcd247420d6e0b489a0229bd402ddca0440417217a57251a","declaration":"export function emitAgentEvent(event: Omit<AgentEventPayload, \"seq\" | \"ts\">): void;","entrypoint":"agent-harness-runtime","exportName":"emitAgentEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
@@ -162,7 +162,7 @@
|
||||
{"closureHash":"40154c3b7b2a7179df33f4a3fbef5e56078be2759d5aab29f39eb0f3c92fc631","declaration":"export function projectRuntimeToolInputSchema(schema: unknown, path?: string): RuntimeToolInputSchemaProjection;","entrypoint":"agent-harness-runtime","exportName":"projectRuntimeToolInputSchema","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e42e3dc63e8545bb9a6056336fbd6c1dc8f356dce4f0f1c6d9765254c974390e","declaration":"export function projectSettledTurnFinalizationAttemptResult(result: AgentHarnessAttemptResult): AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"projectSettledTurnFinalizationAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3fbe470f065d2c2f16de538d8347934ec2daee2081d8903db1777b0afd2a8043","declaration":"export function queueAgentHarnessMessage(sessionId: string, text: string, options?: EmbeddedAgentQueueMessageOptions): boolean;","entrypoint":"agent-harness-runtime","exportName":"queueAgentHarnessMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"acb8a5ff66840716e1996e6e1ffa633baa50cf4fd79a1eb203f45c09f62ee2ac","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"ed44ea59be68bee94ef22b61cd88171c361275dcc72e786f13155e997c803b28","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b7cc6c35506dc6955e0359aa5c53c15a4d0db23639da8c1717f8fefda953c119","declaration":"export function requestDeferredPluginToolApproval(params: { deferredApproval: DeferredPluginToolApproval; signal?: AbortSignal; }): Promise<HookOutcome>;","entrypoint":"agent-harness-runtime","exportName":"requestDeferredPluginToolApproval","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"a2306cba08cb05ff8430c8362c0cc3c821706da5a4e65a06849ad0d0fb007ae3","declaration":"export function resetAgentEventsForTest(options?: { preserveListeners?: boolean; }): void;","entrypoint":"agent-harness-runtime","exportName":"resetAgentEventsForTest","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
@@ -197,7 +197,7 @@
|
||||
{"closureHash":"e4784aeda4c24b60cd49b7f5983e70a380a4759d5176c74d30f2900952ba848f","declaration":"export function runAgentHarnessBeforeAgentFinalizeHook(params: { event: PluginHookBeforeAgentFinalizeEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): Promise<AgentHarnessBeforeAgentFinalizeOutcome>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeAgentFinalizeHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8fec73ee8c7c9be3335bd6dc1bac9278f0be5beef22a5975eb06e56f504f4bd6","declaration":"export function runAgentHarnessBeforeCompactionHook(params: { sessionFile: string; messages?: AgentMessage[]; ctx: AgentHarnessHookContext; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeCompactionHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"021b81820bef2e8d54c50a5fc159d6665b23b50a1f5c40dae76a4833839d89c9","declaration":"export function runAgentHarnessBeforeMessageWriteHook(params: { message: AgentMessage; agentId?: string; sessionKey?: string; }): AgentMessage | null;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeMessageWriteHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e0214147021b247e720c4a4ae1fc8597c082c2c4286ac131b6f981f0895b8b0f","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise<QuestionWaitAnswerResult>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d40db54ef0fcc481063d718dea2ed1bdbe64b75aee82cd0efcf02ba86039765d","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise<QuestionWaitAnswerResult>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"50a4d7cb20dd8f884abbcb62d77b5b2df183fbfcd058cc7aa76edacd1f7b90d8","declaration":"export function runAgentHarnessLlmInputHook(params: { event: PluginHookLlmInputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmInputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1bd55c141c249b1c04470cafe0cd4d41dce334ea2883ce83235af56d24a15cca","declaration":"export function runAgentHarnessLlmOutputHook(params: { event: PluginHookLlmOutputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmOutputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c4c5131ab7065decd8d8e935ac3779e3baa2c52fbbbd95a6ccb624377db09ca1","declaration":"export function runBeforeToolCallHook(args: { toolName: string; params: unknown; toolKind?: PluginHookToolKind; toolInputKind?: PluginHookToolInputKind; toolCallId?: string; ctx?: HookContext; signal?: AbortSignal; approvalMode?: \"request\" | \"report\" | \"deny\" | \"defer\"; }): Promise<HookOutcome>;","entrypoint":"agent-harness-runtime","exportName":"runBeforeToolCallHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
|
||||
@@ -219,13 +219,13 @@
|
||||
{"closureHash":"0701a22057edc3b733da7e05948db94aa98b337b224a5718efdd85212a8602bf","declaration":"export const TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT: string;","entrypoint":"agent-harness-runtime","exportName":"TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
|
||||
{"closureHash":"b5845c99df6c2a834a16678c320e0111bad96a3a7ac245d379aa5e6d2555d29b","declaration":"export const agentHarnessAttemptTerminal: { merge: (current: AgentRunAttemptTerminal, incoming: AgentRunAttemptTerminal) => AgentRunAttemptTerminal; normalize: (input: { aborted?: boolean; externalAbort?: boolean; idleTimedOut?: boolean; promptError?: unknown; promptErrorSource?: AgentRunAttemptFailureSource | null; timedOut?: boolean; timedOutByRunBudget?: boolean; timedOutDuringCompaction?: boolean; timedOutDuringToolExecution?: boolean; }) => AgentRunAttemptTerminal; project: (terminal: AgentRunAttemptTerminal) => { aborted: boolean; cleanupYieldAborted: boolean; externalAbort: boolean; failed: boolean; idleTimedOut: boolean; interrupted: boolean; promptError: unknown; promptErrorSource: AgentRunAttemptFailureSource | null; timedOut: boolean; timedOutByRunBudget: boolean; timedOutDuringCompaction: boolean; timedOutDuringToolExecution: boolean; }; setFailure: (terminal: AgentRunAttemptTerminal, failure: { source: AgentRunAttemptFailureSource; error: unknown; } | null) => AgentRunAttemptTerminal;};","entrypoint":"agent-harness-runtime","exportName":"agentHarnessAttemptTerminal","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
|
||||
{"closureHash":"22bcf962aa76c76074c4ed4ad7d6558edbc3588e239263e09af74c1000bbe012","declaration":"export const embeddedAgentLog: SubsystemLogger;","entrypoint":"agent-harness-runtime","exportName":"embeddedAgentLog","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
|
||||
{"closureHash":"6e65a3ec38a9eef02bee0ae22b71a7008ffe3253d15f7cf9f5c0a9d2bf1729e0","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record<string, unknown> | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record<string, unknown>) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
|
||||
{"closureHash":"3bf4f5b98fbf675ac0208efd9de33e62abb30a5a8063e99a661f097d0dee7b84","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record<string, unknown> | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record<string, unknown>) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
|
||||
{"closureHash":"f237bbc11e1d389679cd4e2ad7aa9055951b3029348e3374b81f769786a51d55","declaration":"export type AbortAndDrainAgentHarnessRunResult = AbortAndDrainEmbeddedAgentRunResult;","entrypoint":"agent-harness-runtime","exportName":"AbortAndDrainAgentHarnessRunResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6f802f46717d28d260bbcb2cf4790dfed4e9ab28c4fe822d259228189cca4665","declaration":"export type AgentApprovalEventData = AgentApprovalEventData;","entrypoint":"agent-harness-runtime","exportName":"AgentApprovalEventData","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"12aac3a57ce200b0f082002be237625729f84ed7c337f1bac90bcd0688a53319","declaration":"export type AgentEventPayload = AgentEventPayload;","entrypoint":"agent-harness-runtime","exportName":"AgentEventPayload","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7dcb6a9a37ace260567e3b46fc8d051aa124df2edfb093dfb56f082da56eaafb","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7dcb6a9a37ace260567e3b46fc8d051aa124df2edfb093dfb56f082da56eaafb","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4759104bcc383686c88c8abe83e69cf8ea009becfc6321e2924f447eab73ea04","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"beb6715ad81487caa2cc2ed8444d6ac2dcf83c9e71fc42d5db9214f2eb12b946","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"beb6715ad81487caa2cc2ed8444d6ac2dcf83c9e71fc42d5db9214f2eb12b946","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f6c32237f90d7fe6a024b516a1dd2e6e395c42c66db291649dab441fc1a84ebc","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2dc2a62deea63b316142cc28d40afb88fb0d1e5ce3e048f141420726cda38248","declaration":"export type AgentHarnessAttemptResult = AgentHarnessAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"c7e642234081160830fd9e18a301900f8ee1ea8c88382e5a286f0102de65b714","declaration":"export type AgentHarnessAuthBindingFingerprintParams = AgentHarnessAuthBindingFingerprintParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAuthBindingFingerprintParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"8f496ce75f294f2aa440a49c3c5b065ddff3a4714df775116af5e53f7fd14fe5","declaration":"export type AgentHarnessCompactParams = CompactEmbeddedAgentSessionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessCompactParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
@@ -239,8 +239,8 @@
|
||||
{"closureHash":"95741b872a194687696eba4a96d6e887ec6e81922695fa0282cb2f0a46ff9f97","declaration":"export type AgentHarnessSessionForkParams = AgentHarnessSessionForkParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f3c46fef2a6c3393b0b6ad09915abcd6f57bb58ddddde1d60ebd113c7a1c5fa6","declaration":"export type AgentHarnessSessionForkResult = AgentHarnessSessionForkResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4b5a59730309e446f59a8ec1c554c3193aca1959916594cc657347098bd67a35","declaration":"export type AgentHarnessSettledTurnFinalizationResult = AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSettledTurnFinalizationResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2b1360e9069d9dd3d4f620b5dd962312128d71e0ce2c91d28b521dc97a8f5785","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"468d17121be5df45a4f9af2a72586e03deccdee7c56c43577bbd209541498ab7","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"cf635da6cc7587a76acf23e9b488e32f10eac93aa77df664c79f8e9d9e7117be","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"9cccf03a0d94f0917acf7759c8438a447288490f2fa616890e342faa501f84ac","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"e84173055503c40dd0ef1cb67c6d333e9257fcf995252b27c1d58f5c904e8de9","declaration":"export type AgentHarnessSideQuestionResult = AgentHarnessSideQuestionResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"50214d08dac98e3c1031ac7bc733b85cb2247d2eef3b6b2045758ae403af7647","declaration":"export type AgentHarnessSupport = AgentHarnessSupport;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupport","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"50ce26ea22bc225e6064d2e5f37356b6f4ce4a57f8b9fa42baa4c421da48aad5","declaration":"export type AgentHarnessSupportContext = AgentHarnessSupportContext;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupportContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
@@ -250,7 +250,7 @@
|
||||
{"closureHash":"20a8a7c9d5ebf425c30d04eea3856c6c889a210f1fa53c99299df24882afbf92","declaration":"export type AgentHarnessUserInputOption = AgentHarnessUserInputOption;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputOption","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6224f51b4189f10a642ad7a8f50a902ec9c6a6a4f8dac0c0de5f7bc0271a27e5","declaration":"export type AgentHarnessUserInputPromptOptions = AgentHarnessUserInputPromptOptions;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputPromptOptions","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"d8f1d0d118e1536d1f442d11aeae5334a1ed7949a6c61824f547e12931278e1d","declaration":"export type AgentHarnessUserInputQuestion = AgentHarnessUserInputQuestion;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"65b516857f90d0029866f6b3179cac436dd6d5c85bd83d440fbcdbe297b70bf6","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ca20bb488d357785086f04e71b0fbb300a27325217bdbfdcaa1e422eca2fe255","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6f2af683e6a31cde5a473c77e4f03b8f0ec0351a43ea6c0af979d5b394a33f95","declaration":"export type AgentMessage = AgentMessage;","entrypoint":"agent-harness-runtime","exportName":"AgentMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"185abd2870d4df65e9f94623061a30167d17ef1279a395201fe429398bf23500","declaration":"export type AgentToolResultMiddlewareContext = AgentToolResultMiddlewareContext;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddlewareContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
@@ -276,8 +276,8 @@
|
||||
{"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedAgentCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedAgentCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"1bbefad0193436f7340f9d0dec50be5d482973325c3c65170b1053dd05566f0a","declaration":"export type EmbeddedContextFile = EmbeddedContextFile;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedContextFile","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedPiCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedPiCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f6d52c26f4fa2377f384935aa8e0c990e8634bc56ddc35dc00f4e00d5dfd16c4","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b96b39b906aac64a2ce1037ad8f6f811f832b5189f53c0c966cba9dedca50615","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b0d89fe509b6812c24b0a46cbc7d7ce20af0009a415c4e50e20c41af02975b11","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"67dd9a76536fb9f41ae19a380dd71bf10682ff80c63f363b5f8511948dcd1aab","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"a6cd2eebe0d06e6578ec8438a207c5acda10ddf01041102d84e4c576a0b6a42f","declaration":"export type EmbeddedRunAttemptResult = EmbeddedRunAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f6cb2d6411db22cb04220777720d97bcca977351de1cb344ce2ff6ab126a3a08","declaration":"export type ExecApprovalDecision = ExecApprovalDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecApprovalDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7acb0dffc7bcda6c727e4afc49c955fa8e14f4f8b7b45d197ed794dfa0d73b8e","declaration":"export type ExecAutoReviewDecision = ExecAutoReviewDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecAutoReviewDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
@@ -293,7 +293,7 @@
|
||||
{"closureHash":"d8a720bf250da8daf4dc6a52087aa8728ec33b650b3ad3906fcb40e184de66a0","declaration":"export type NativeHookRelayEvent = \"pre_tool_use\" | \"post_tool_use\" | \"permission_request\" | \"before_agent_finalize\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"cb72ca18e056e52e779d0bf5b67606e1dc160f225225b55937304541105027f4","declaration":"export type NativeHookRelayProcessResponse = NativeHookRelayProcessResponse;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProcessResponse","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6ee390ae4784b987e22255c16884fb4171033bbfaefaef655e3dd2a2513814a5","declaration":"export type NativeHookRelayProvider = \"codex\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProvider","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"41d1cdaabc26115ac40b9eed172da5f18884e89ac8e198e1b63f48a685f66d62","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b8476f913ffe1828ec5a260a90635d3766d93e772f6a34f804e45ba287c863c5","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"90fea3155b5d32c22da90460fdaea94e4fd6895d1ca18613d5036ba9835153f9","declaration":"export type NodeListNode = NodeListNode;","entrypoint":"agent-harness-runtime","exportName":"NodeListNode","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"cefe1325c866f0cf7edbec5dcca2fe420237eedc0da172e54094e365894d205d","declaration":"export type NormalizedUsage = NormalizedUsage;","entrypoint":"agent-harness-runtime","exportName":"NormalizedUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult<TResult = unknown> = OpenClawAgentToolResult<TResult>;","entrypoint":"agent-harness-runtime","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
|
||||
@@ -762,7 +762,7 @@
|
||||
{"closureHash":"9fc7e45343d7bfbc6ed56d05c9f824e2f9cf6dafc3ca4b25437d1f65c2200727","declaration":"export function clearAccountEntryFields<TAccountEntry extends object>(params: { accounts?: Record<string, TAccountEntry>; accountId: string; fields: string[]; isValueSet?: (value: unknown) => boolean; markClearedOnFieldPresence?: boolean; }): { nextAccounts?: Record<string, TAccountEntry>; changed: boolean; cleared: boolean; };","entrypoint":"channel-core","exportName":"clearAccountEntryFields","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f4e084b64b5376268885a73fe507aa5d72bee17a88ec2d7ae1d19b36ea5f1ccb","declaration":"export function createChannelConfigUiHints(params: { channelLabel: string; dmPolicy?: { channelKey: string; includeLegacyNestedPolicy?: boolean; legacyNestedPolicyOrder?: \"before\" | \"after\"; }; configWrites?: boolean; mentionPatterns?: { targetDescription: string; policyTargetDescription?: string; policyNote?: string; denyNote?: string; }; nativeCommands?: boolean; implicitMentions?: boolean; progress?: { includeCommentary?: boolean; commentaryOrder?: \"before-command\" | \"after-command\"; labels?: \"openclaw\"; titleWording?: boolean; }; streaming?: Partial<Record<StreamingHintKey, StreamingHintValue>>; retry?: boolean; }): HintMap;","entrypoint":"channel-core","exportName":"createChannelConfigUiHints","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"ed8c322fac76968f7f059b65eaa881098ed918b22705b27101166b052213a9d9","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"20eebe7796477e813273c70382bb74de3f830573f2a84500e969305ad6f7d251","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"19ee364314ffd766b8f15835014206753bc1f96af4d7084b97a0a1cc2774d4df","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry<TPlugin>(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"channel-core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8895f7af11b994dcd383ebc45d8cfb3c3b1e6d88a64a001b04f604a83f77e517","declaration":"export function parseOptionalDelimitedEntries(value?: string): string[] | undefined;","entrypoint":"channel-core","exportName":"parseOptionalDelimitedEntries","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3f97534b10d08eda6a556044eaba623b3744b200a2033877e48d2f2ca924d298","declaration":"export function recoverCurrentThreadSessionId(params: { route: ChannelOutboundSessionRoute; currentSessionKey?: string | null; canRecover?: (context: ThreadAwareOutboundSessionRouteRecoveryContext) => boolean; }): string | undefined;","entrypoint":"channel-core","exportName":"recoverCurrentThreadSessionId","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
|
||||
@@ -774,24 +774,24 @@
|
||||
{"closureHash":"8126b651a679d5435eaa5d346916792c3600e5f0f75d8492b077dd361854f7dd","declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; currentSessionKey?: string; resolvedTarget?: { to: string; kind: ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"channel-core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"37b373e93fe7f86fdbce119947c9e49b17e71ce50fe47e118c4d078c5cea20ec","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"channel-core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"86553d1dbbbe0b04d6a233ab33dee847c2cf5f9809032d41c5bff6bec06b78da","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4180509522e17f8afdf5014bc51f5601952dfa403503e66f8f53e92b0c6ddd45","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
|
||||
{"category":"channel","entrypoint":"channel-dm-policy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","recordType":"module"}
|
||||
{"closureHash":"821fe6ccd0d9323322bf70c4d1ca5697071a0e32032f44c1e14157162c2c729d","declaration":"export function createChannelDmPolicy<TConfig extends DmPolicyAccountConfig>(params: CreateChannelDmPolicyParams<TConfig>): ChannelSetupDmPolicy & { promptAllowFrom: NonNullable<ChannelSetupDmPolicy[\"promptAllowFrom\"]>; };","entrypoint":"channel-dm-policy","exportName":"createChannelDmPolicy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","kind":"function","recordType":"export"}
|
||||
{"category":null,"entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","recordType":"module"}
|
||||
{"closureHash":"69a48a0339b8298cbf357f4b03fd5d0bdd64dd0900b1c9aa0eec9ea1d967f9ed","declaration":"export function defineBundledChannelEntry<TPlugin = ChannelPlugin>({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions<TPlugin>): BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
|
||||
{"closureHash":"a9d4fe591235caf5ebf66ed031d29a7b23bfe4b83fe3506ee97f61f02ce31165","declaration":"export function defineBundledChannelSetupEntry<TPlugin = ChannelPlugin>({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
|
||||
{"closureHash":"449cfd12281e321f062ab0decf424e0dcdc9c4542aaed374c1d513c2e520a0fb","declaration":"export function defineBundledChannelEntry<TPlugin = ChannelPlugin>({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions<TPlugin>): BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
|
||||
{"closureHash":"73376c2d9f2518d075102db21266e4ed390cff19ee17167d8d6dcaa90391aca4","declaration":"export function defineBundledChannelSetupEntry<TPlugin = ChannelPlugin>({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
|
||||
{"closureHash":"cd150287d7e286e7a0d7d6caeb05d0a1efa63b5f351f75f69ba932510a108afd","declaration":"export function loadBundledEntryExportSync<T>(importMetaUrl: string, reference: BundledEntryModuleRef, options?: BundledEntryModuleLoadOptions): T;","entrypoint":"channel-entry-contract","exportName":"loadBundledEntryExportSync","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
|
||||
{"closureHash":"7781a3d570d08929af5b3b6cffbb9ef4b9c8e8f1bed55234e0015a681868c812","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"channel-entry-contract","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"fa5a588c0ce180e7a20042afea7ea0159187359a8642759d7009f3debdca5ae0","declaration":"export type BundledChannelEntryContract<TPlugin = ChannelPlugin> = BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"685f95aaa394a91f73185ac30346f2046707aa09c77e4cfc27a100bc3ec23f15","declaration":"export type BundledChannelEntryContract<TPlugin = ChannelPlugin> = BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f4b82dfd995bd6f08b232984743389d1c854866cb845a8dbb3605acb28818688","declaration":"export type BundledChannelEntryFeatures = BundledChannelEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"960693591b9bdc974bf3f0097076d90490078db3dceb35349a4f851736cde4fc","declaration":"export type BundledChannelLegacySessionSurface = BundledChannelLegacySessionSurface;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacySessionSurface","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"edf79e6a736e5c4977e3b86ef21e7fdf0c0b2bc7deacd8edbee2ca76cb8cef43","declaration":"export type BundledChannelLegacyStateMigrationDetector = BundledChannelLegacyStateMigrationDetector;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacyStateMigrationDetector","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"8bf37d6eeb66e312f279aa9230c6f35058758d2748e0e336bc43265d961cfce2","declaration":"export type BundledChannelSetupEntryContract<TPlugin = ChannelPlugin> = BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f95a404850bcbf1c6ec8227f92ecdf94e65f96de06f63f2f993a5d838b831f62","declaration":"export type BundledChannelSetupEntryContract<TPlugin = ChannelPlugin> = BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"24679ecdf2ff34157b6345a37b58ec1363ec8cb1969b522599d0d92bb7a113b7","declaration":"export type BundledChannelSetupEntryFeatures = BundledChannelSetupEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"367219c821915e5be4d1ba3a86754475a5f8a4194512f0401de3be11cc649c60","declaration":"export type BundledEntryModuleLoadOptions = BundledEntryModuleLoadOptions;","entrypoint":"channel-entry-contract","exportName":"BundledEntryModuleLoadOptions","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"83a2ebce6f822a66006deff2ec1d23f7fde3e1da68e23d5c3d57d152f857726a","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"fcee79acac847664aaaa8af8392ae3797cd55ac1e38dfbb622fafa5b7d3cb0bf","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"e54f9b270df967e0f857de804dbe989f2c55b637c449c9948c4baae8eee18c7b","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"closureHash":"568b5ab033b4970cedd3916d948d31bcdd3c19ea8928c7cd7dc7abf7623b8af8","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-entry-contract","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
|
||||
{"category":null,"entrypoint":"channel-feedback","importSpecifier":"openclaw/plugin-sdk/channel-feedback","recordType":"module"}
|
||||
@@ -1103,7 +1103,7 @@
|
||||
{"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
|
||||
{"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
|
||||
{"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-message","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
|
||||
{"closureHash":"50a03b18eb2b53c0e4f3aea18130b93e600214baf98686ce749addf6f8004a66","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
|
||||
{"closureHash":"49e98f675c3f385cf2acea1d1b7480f1a510449c1a04bf3d65475b9a7492d2dd","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
|
||||
{"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-message","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
|
||||
{"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-message","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-message","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
|
||||
@@ -1232,7 +1232,7 @@
|
||||
{"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
|
||||
{"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
|
||||
{"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-outbound","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
|
||||
{"closureHash":"50a03b18eb2b53c0e4f3aea18130b93e600214baf98686ce749addf6f8004a66","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
|
||||
{"closureHash":"49e98f675c3f385cf2acea1d1b7480f1a510449c1a04bf3d65475b9a7492d2dd","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
|
||||
{"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-outbound","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
|
||||
{"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-outbound","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-outbound","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
|
||||
@@ -1298,7 +1298,7 @@
|
||||
{"closureHash":"cd6b0d3f962c8cb40d405e92bb06bb8e9285b386200897f550d21036022262c1","declaration":"export const PAIRING_APPROVED_MESSAGE: \"✅ OpenClaw access approved. Send a message to start chatting.\";","entrypoint":"channel-plugin-common","exportName":"PAIRING_APPROVED_MESSAGE","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"const","recordType":"export"}
|
||||
{"closureHash":"712435252d2fe5135542ca6b5a4375a6edea24e83829338011dc6ae7e9802fbb","declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-plugin-common","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
|
||||
{"closureHash":"37b373e93fe7f86fdbce119947c9e49b17e71ce50fe47e118c4d078c5cea20ec","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-plugin-common","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4180509522e17f8afdf5014bc51f5601952dfa403503e66f8f53e92b0c6ddd45","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-plugin-common","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
|
||||
{"category":null,"entrypoint":"channel-policy","importSpecifier":"openclaw/plugin-sdk/channel-policy","recordType":"module"}
|
||||
{"closureHash":"017ab29d16d0f3d02d60f3513e65a373868d26496bc93d020d8fc8c17fd875f4","declaration":"export function buildAccountScopedDmSecurityPolicy(params: { cfg: OpenClawConfig; channelKey: string; accountId?: string | null; fallbackAccountId?: string | null; policy?: string | null; allowFrom?: Array<string | number> | null; defaultPolicy?: string; allowFromPathSuffix?: string; policyPathSuffix?: string; approveChannelId?: string; approveHint?: string; normalizeEntry?: (raw: string) => string; inheritSharedDefaultsFromDefaultAccount?: boolean; }): ChannelSecurityDmPolicy;","entrypoint":"channel-policy","exportName":"buildAccountScopedDmSecurityPolicy","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
|
||||
@@ -1897,8 +1897,8 @@
|
||||
{"closureHash":"ed8c322fac76968f7f059b65eaa881098ed918b22705b27101166b052213a9d9","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"785b0f750c5bd20f9f3ca081886a5af79ee0e4d2c38f78f769bf994b234f5076","declaration":"export function createDedupeCache(options: DedupeCacheOptions): DedupeCache;","entrypoint":"core","exportName":"createDedupeCache","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"core","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"20eebe7796477e813273c70382bb74de3f830573f2a84500e969305ad6f7d251","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"60eaea4ee788df80eb81ba87d49e396cb9ffb40eb7d6bfd74fbcd817a34f3dcc","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"19ee364314ffd766b8f15835014206753bc1f96af4d7084b97a0a1cc2774d4df","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"ea866f93256b2e5f8da5bad7c96511f00f9b42fa85f6689cc70ab26bde2dd0cb","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry<TPlugin>(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3c5ce0c3733cbb038aeb914af1df5d701f362f0521921b8abd0c9214db9cc4b8","declaration":"export function delegateCompactionToRuntime(params: Parameters<ContextEngine[\"compact\"]>[0]): Promise<CompactResult>;","entrypoint":"core","exportName":"delegateCompactionToRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"2c282e0e308f9442bca7cdeb8e89a097531b1d54a692c9d86e5f39a8db1c2537","declaration":"export function deleteAccountFromConfigSection(params: { cfg: OpenClawConfig; sectionKey: string; accountId: string; clearBaseFields?: string[]; }): OpenClawConfig;","entrypoint":"core","exportName":"deleteAccountFromConfigSection","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
@@ -1945,7 +1945,7 @@
|
||||
{"closureHash":"2e6ce1f4c1692270a00dc0cf08e2752a26739c3143f8091cb270063c6034605d","declaration":"export function tryReadSecretFileSync(filePath: string | undefined, label: string, options: CredentialFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options?: FsSafeSecretFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): ConfiguredCredentialResult<string>;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): CredentialResult<string>;","entrypoint":"core","exportName":"tryReadSecretFileSync","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b40933a11984425d14a7a479bda0d2cd14cbfa9371164774f39bebbf12861df7","declaration":"export const DEFAULT_ACCOUNT_ID: \"default\";","entrypoint":"core","exportName":"DEFAULT_ACCOUNT_ID","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"}
|
||||
{"closureHash":null,"declaration":"export const DEFAULT_SECRET_FILE_MAX_BYTES: number;","entrypoint":"core","exportName":"DEFAULT_SECRET_FILE_MAX_BYTES","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"}
|
||||
{"closureHash":"7dcb6a9a37ace260567e3b46fc8d051aa124df2edfb093dfb56f082da56eaafb","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"beb6715ad81487caa2cc2ed8444d6ac2dcf83c9e71fc42d5db9214f2eb12b946","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"core","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"core","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"core","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
@@ -1977,10 +1977,10 @@
|
||||
{"closureHash":"54ea426dde51859b572b4c1079d2b70b412096f73da2b8c265f2749d9f01cbb5","declaration":"export type NormalizedLocation = NormalizedLocation;","entrypoint":"core","exportName":"NormalizedLocation","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"5189698d102b8b064eefe1442b008312973c3994fd6b203d2205725d7ee9d118","declaration":"export type OpenClawPluginActiveModelContext = OpenClawPluginActiveModelContext;","entrypoint":"core","exportName":"OpenClawPluginActiveModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"c968e96cdb5c97e92d26b7b15fb5255531b45a12e7c5c0a2e7e456d31cc6e358","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"0fd3922f47a01a793d0b383cf6744734aae5c4fc2990344c2ed7b0969ae1d309","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"05cefddc1e544e0efd37301f07a5adae39f6cc580239b314c1959b8887a23ce9","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"core","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"core","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ddc2738dd0ece94ddde9a7c655f92c15ec6416645ecf932d4aa404c7b7761159","declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"core","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
|
||||
@@ -2215,7 +2215,7 @@
|
||||
{"closureHash":"0db968dad99d84ecef5202167daadd092e3b4f456270283d3fd61585ac2bbd5a","declaration":"export type DiscordComponentSendResult = DiscordComponentSendResult;","entrypoint":"discord","exportName":"DiscordComponentSendResult","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"084b46d7dd510eb182a4705559251e824220b57dbfa6dc54392507b72ba1815e","declaration":"export type DiscordOutboundTargetResolution = DiscordOutboundTargetResolution;","entrypoint":"discord","exportName":"DiscordOutboundTargetResolution","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"discord","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4180509522e17f8afdf5014bc51f5601952dfa403503e66f8f53e92b0c6ddd45","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"discord","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6b9967e919c1cd420c8356b4f9d40dbc81932b4b15a733eecdcfb2ad84f8e5d8","declaration":"export type ResolvedDiscordAccount = ResolvedDiscordAccount;","entrypoint":"discord","exportName":"ResolvedDiscordAccount","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6bed5ca896b7034117e4757e2c6b4111dd5293dbad9416e3828dd6afa4e858ce","declaration":"export type ThreadBindingRecord = ThreadBindingRecord;","entrypoint":"discord","exportName":"ThreadBindingRecord","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
|
||||
@@ -2360,7 +2360,7 @@
|
||||
{"closureHash":"98e0cc16352b7dfcceb4957f8cd2acfe3c2b3acb223c42a5cfb885e088fcb04c","declaration":"export function resolveInboundReplyDispatchCounts(result: ChannelTurnDispatchResultLike): Record<ReplyDispatchKind, number>;","entrypoint":"inbound-reply-dispatch","exportName":"resolveInboundReplyDispatchCounts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
|
||||
{"closureHash":"4cd63266d379acc2cdf9aba02f50b8ceb55500cf820787c370fc98d173fb1950","declaration":"export function runChannelInboundEvent<TRaw, TDispatchResult = DispatchFromConfigResult>(params: RunChannelTurnParams<TRaw, TDispatchResult, ChannelProviderOwnedMessageSendingDeliveryAdapter>): Promise<ChannelTurnResult<TDispatchResult>>;\nexport function runChannelInboundEvent<TRaw, TDispatchResult = DispatchFromConfigResult>(params: ChannelInboundEventRunnerParams<TRaw, TDispatchResult>): Promise<ChannelTurnResult<TDispatchResult>>;","entrypoint":"inbound-reply-dispatch","exportName":"runChannelInboundEvent","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
|
||||
{"closureHash":"2c68496a174872b31aaf1ac8fad2789deb79d490c5ffbcb157325f1c95d1b51f","declaration":"export function runPreparedInboundReply<TDispatchResult>(params: PreparedChannelTurn<TDispatchResult>): Promise<ChannelTurnResult<TDispatchResult>>;","entrypoint":"inbound-reply-dispatch","exportName":"runPreparedInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
|
||||
{"closureHash":"50a03b18eb2b53c0e4f3aea18130b93e600214baf98686ce749addf6f8004a66","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"}
|
||||
{"closureHash":"49e98f675c3f385cf2acea1d1b7480f1a510449c1a04bf3d65475b9a7492d2dd","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"}
|
||||
{"closureHash":"ab30d0470348e3af7c18a273afc0d169d91f204fba557c75c4694e8a0ea6c936","declaration":"export type AssembledInboundReply = AssembledChannelTurn;","entrypoint":"inbound-reply-dispatch","exportName":"AssembledInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
|
||||
{"closureHash":"3de0d6d1bb8f9a83bd1c6e57aa8618e3fea71054236cd530c555e348bd0b7702","declaration":"export type ChannelBotLoopProtectionFacts = ChannelBotLoopProtectionFacts;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelBotLoopProtectionFacts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f0da845bbdf49b30f6718a4b7ff012a0536deb98f65418583555dc90825797ca","declaration":"export type ChannelInboundDroppedHistoryOptions = ChannelTurnDroppedHistoryOptions;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelInboundDroppedHistoryOptions","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
|
||||
@@ -3195,19 +3195,19 @@
|
||||
{"closureHash":"3362ea0b650933db6db467ef8ae1c82e682e946761647c8dfae401eec1237bd6","declaration":"export function callMeetingBrowserProxyOnNode(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; } & MeetingBrowserRequestParams): Promise<unknown>;","entrypoint":"meeting-runtime","exportName":"callMeetingBrowserProxyOnNode","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c5fcd1d157edcb4773235adfaf8051e3ec7ca428cb7916b6d55f2511affab56c","declaration":"export function convertMeetingBridgeAudioForStt(audio: Buffer, audioFormat: MeetingRealtimeAudioFormat): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingBridgeAudioForStt","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"aa9063c27c5ff714d3653571c4a2a71e9d2eea5609b161f03e4738e15411358b","declaration":"export function convertMeetingTtsAudioForBridge(audio: Buffer, sampleRate: number, audioFormat: MeetingRealtimeAudioFormat, outputFormat?: string, platformName?: string): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingTtsAudioForBridge","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"100fe96a062f631b3d357570ee03626683a69465aeb2afee265a31e7153a31d9","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"41a29ffc111d6672c56e82aa27884261d3d23aded7b02186e1acd9817f450fa1","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0f81bc377d2158b9c8adb6878e454f34c2e57d53bdef9aa34d567d279800c240","declaration":"export function createMeetingBrowserNodeCaller(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; }): MeetingBrowserRequestCaller;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeCaller","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f244ca8c47f556c9f388953cf9a7581c7d4d413af93e0dfa1462779e6a687a7c","declaration":"export function createMeetingBrowserNodeInvokePolicy(options: MeetingBrowserNodePolicyOptions): OpenClawPluginNodeInvokePolicy;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeInvokePolicy","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1aa4e3ff39a2cbe162421c62b1fa4a362973381d4d9ff15c671249b1ebd566bc","declaration":"export function createMeetingNodeHost(options: MeetingNodeHostOptions): { handleCommand(paramsJSON?: string | null): Promise<string>; };","entrypoint":"meeting-runtime","exportName":"createMeetingNodeHost","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"909a4ea24585b49a91095ada5ab95e0aa7d741a4554f757ddab8ef45385af1ee","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise<void>; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"7bbd4d7df1e47521e1c2a00bb1f228a7aebc93ae0a9b5fa5ed66c9c24c8a4166","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise<void>; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"9124db05923060c467edb149bd8abdc8be1d00d00f867cf84600972923a58489","declaration":"export function createMeetingSession<TTransport extends string, TMode extends string, TToolPolicy extends string>(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { provider?: string; voiceProvider?: string; transcriptionProvider?: string; model?: string; toolPolicy: TToolPolicy; }; }; resolved: MeetingResolvedJoin<TTransport, TMode>; createdAt: string; }): MeetingSessionRecord<TTransport, TMode, { enabled: boolean; strategy: string; provider: string | undefined; model: string | undefined; transcriptionProvider: string | undefined; toolPolicy: TToolPolicy; }>;","entrypoint":"meeting-runtime","exportName":"createMeetingSession","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"fb276e07e395ab19177b3d7967fd0a8fcda79130883f15092a4a306b826481b9","declaration":"export function createMeetingSetupStatus(checks: MeetingSetupCheck[]): MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"createMeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0457ac9dc4b0b2d11cdbe2070d75ae2e5c2fe5cee69017e92f849849cd06b0f3","declaration":"export function createMeetingVoiceCallGateway(params: { config: MeetingVoiceCallConfig; runtime: PluginRuntime; surface: MeetingVoiceCallSurface; connectClient: (params: { config: MeetingVoiceCallConfig; surface: MeetingVoiceCallSurface; }) => Promise<MeetingVoiceCallGatewayClient>; }): MeetingVoiceCallGateway;","entrypoint":"meeting-runtime","exportName":"createMeetingVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"34fdb56d1bcb289d35cdde3b9818a22020cec7a9de7de6e4a2ce028769650e1a","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"153b475879020471ce39741d83aacf36f31aed63a58897eae9f8ae902a67814c","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c0987b15a391a92d53d3e4e12b61eb122f9547fcf4f45478cdd3c5a8973a3e52","declaration":"export function endMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise<void>;","entrypoint":"meeting-runtime","exportName":"endMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b3ebc10fe7ab372e1317eaa8f78621cf277bba1e33fda57acf2254f6759d1e9d","declaration":"export function getMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise<MeetingVoiceCallStatusResult>;","entrypoint":"meeting-runtime","exportName":"getMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"aac088df8e80d9ce89c45feccdb04ace3ae4417b3fcdd0f058410ddf25c96b46","declaration":"export function isMeetingVoiceCallMissingError(error: unknown): boolean;","entrypoint":"meeting-runtime","exportName":"isMeetingVoiceCallMissingError","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d24f2c4fbb2bf5bf5d36afb40e95ec5930ac1f1c71ccd6458193ddd11c1466bd","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise<MeetingVoiceCallJoinResult>;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"2ddcdaee317e00718d3061c832e4fb4a6d1a43b43e926c6136ecd553d2989167","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise<MeetingVoiceCallJoinResult>;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"bac9621cd025754fbcd4c21409b06eb0503405db81f35cac993aaf0b881ab3e1","declaration":"export function leaveMeetingWithBrowser<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; callBrowser: MeetingBrowserRequestCaller; launch: boolean; meetingSessionId?: string; meetingUrl: string; tab: MeetingBrowserTab; timeoutMs: number; }): Promise<{ left: boolean; note: string; }>;","entrypoint":"meeting-runtime","exportName":"leaveMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c7b1aeac134b2070d053adf33026d876998b852ccd65cd2c9667119b1a1abee2","declaration":"export function openMeetingWithBrowser<Session extends MeetingBrowserJoinSession<Mode>, Mode extends string, Health extends MeetingBrowserHealth & { browserTitle?: string; browserUrl?: string; notes?: string[]; }, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; callBrowser: MeetingBrowserRequestCaller; config: MeetingBrowserControllerConfig; session: Session; }): Promise<{ launched: boolean; browser?: Health; tab?: MeetingBrowserTab; }>;","entrypoint":"meeting-runtime","exportName":"openMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"34858979bd248799c2215d9c7bdd5d4a6b27660c9173bfca2e50dd4373ac27db","declaration":"export function readMeetingBrowserTab(result: unknown): MeetingBrowserCandidateTab | undefined;","entrypoint":"meeting-runtime","exportName":"readMeetingBrowserTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
@@ -3218,8 +3218,8 @@
|
||||
{"closureHash":"a1c367ec2dd927543d490a1393128d475e10c7bd131ffd789c80d88a2d2d0cb2","declaration":"export function resolveMeetingBrowserNodeInfo(params: { runtime: PluginRuntime; adapter: NodeAdapter; requestedNode?: string; }): Promise<MeetingBrowserNodeInfo>;","entrypoint":"meeting-runtime","exportName":"resolveMeetingBrowserNodeInfo","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f21196c9ea8ab90248ffdcdef3e942f1247ee2b9064ddb9757fffe352362c779","declaration":"export function resolveMeetingRealtimeAudioFormat(audioFormat: MeetingRealtimeAudioFormat): RealtimeVoiceAudioFormat;","entrypoint":"meeting-runtime","exportName":"resolveMeetingRealtimeAudioFormat","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"521dc5c262524a709cdd27cdc88e95004073da8223537bcbc73d5d423172dc2b","declaration":"export function speakMeetingViaVoiceCallGateway(params: { gateway: MeetingVoiceCallGateway; callId: string; message: string; }): Promise<void>;","entrypoint":"meeting-runtime","exportName":"speakMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"afc66af1fb900349a8f9d8bad16b33fdd83ee3fa460a966af8eb028f43148620","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"07c791b011bbbe133c0180c2c2c9975369282e0897f295be5a04beb30c2d9c16","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise<void>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d30a62bb6292da6e0da6cbd96032084122428ec76c16fb0b711813a1cd7d386e","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0e6b815a67f214774c65fff9589717c3f0a3e6327a1c0ecce7c405a9bb627b64","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise<void>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"663b9c77231b21af697efd5042e22d1c33e9ee972adeb312ad86d81a2b2e36f7","declaration":"export type MeetingAgentConsultParams = MeetingAgentConsultParams;","entrypoint":"meeting-runtime","exportName":"MeetingAgentConsultParams","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"adf0745c611bf737fc28978d766fc2a25b7104e71b6b2fed4e9b95e519c7b115","declaration":"export type MeetingBrowserCandidateTab = MeetingBrowserCandidateTab;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserCandidateTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"59b1526172b7491b85f14f13c1ee26d8d6726f33093770748580c767b1689a17","declaration":"export type MeetingBrowserControllerConfig = MeetingBrowserControllerConfig;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserControllerConfig","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
@@ -3251,7 +3251,7 @@
|
||||
{"closureHash":"8244b408803f57cf2004157e96f2ce11bb036cdf864123b15ba2fac7f03b5d43","declaration":"export type MeetingSessionRuntimeHandles<THealth extends MeetingBrowserHealth> = MeetingSessionRuntimeHandles<THealth>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeHandles","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"aa8054fc2c442891197e89bdad61e79999ea15d813c4b127fb6150607b9e67e7","declaration":"export type MeetingSessionRuntimeJoinContext<TSession extends MeetingSessionRecord<TTransport, TMode>, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab> = MeetingSessionRuntimeJoinContext<TSession, TTransport, TMode, THealth, TTab>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeJoinContext","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"325241724edd38da439c5df03d225e2a7cb8e56d817e98ed7c37850656d3744b","declaration":"export type MeetingSessionRuntimeMessages<TSpeechBlockedReason extends string> = MeetingSessionRuntimeMessages<TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeMessages","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b0575ac4d37523c2a2a427931c64c2f8b89fcd2a779eedad66f43efe77b6b1ac","declaration":"export type MeetingSessionRuntimeOptions<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"9140b7d74ad1d6db84343684461ee4328a4f977b1e071843a5fcc6fe4a0593c7","declaration":"export type MeetingSessionRuntimeOptions<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"d3c730cba02d30512c4cdae6e2367c662982e2c25671833ecd8701283924c642","declaration":"export type MeetingSessionState = MeetingSessionState;","entrypoint":"meeting-runtime","exportName":"MeetingSessionState","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2496931157bf64fdb16013172ab9c023e60c5f85b98f46a3ee9532ce58d636d6","declaration":"export type MeetingSetupCheck = MeetingSetupCheck;","entrypoint":"meeting-runtime","exportName":"MeetingSetupCheck","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f0aed6f7955a43fc387d8bbc072cb6276b0f2d18e7f829441a2ad45974bb3831","declaration":"export type MeetingSetupStatus = MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"MeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
@@ -3265,9 +3265,9 @@
|
||||
{"closureHash":"20c70a94483aeddda4d1500cfcc5e71fab844b474ba4061c55d6c8693d40821b","declaration":"export type MeetingVoiceCallJoinResult = MeetingVoiceCallJoinResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallJoinResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"4fb2c5928aa6f809dd4c604d71c5c99cdfe3e98b6e9c1662601c9b4ad9738162","declaration":"export type MeetingVoiceCallStatusResult = MeetingVoiceCallStatusResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallStatusResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"5ef812397b6409a4ca228943dd1080661365959477b42e705a9aaa219757d14f","declaration":"export type MeetingVoiceCallSurface = MeetingVoiceCallSurface;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallSurface","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"dd91b64c44f2f66a2b3a36610e50ba1b10638db372bfbd17eb30be636f704da6","declaration":"export interface MeetingPlatformAdapter<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot, CreateParams = never, CreateResult = never, DialInParams = never, DialInPlan = never> extends MeetingPlatformAdapterContract<Session, Mode, Health, Transcript, CreateParams, CreateResult, DialInParams, DialInPlan> {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
|
||||
{"closureHash":"0f7612ffa6432932130e8e6f83d267c98466eb46a91d43fc8c037c2303e63e05","declaration":"export interface MeetingPlatformAdapter<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot, CreateParams = never, CreateResult = never, DialInParams = never, DialInPlan = never> extends MeetingPlatformAdapterContract<Session, Mode, Health, Transcript, CreateParams, CreateResult, DialInParams, DialInPlan> {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
|
||||
{"closureHash":"79884bd1df1ea0d07d5ceb4c62d93c1ee744b75d31c94c988845869c0f3cbd2d","declaration":"export interface MeetingRealtimeAudioTransport {\n onFatal(handler: () => void): void;\n startInput(onAudio: (audio: Buffer) => void): void;\n beginOutput?(): void;\n stop(): Promise<void>;\n writeOutput(audio: Buffer): Promise<void>;\n clearOutput(): Promise<void>;\n dispose(): Promise<void>;\n getHealth?(): MeetingRealtimeAudioTransportHealth;\n startBargeInMonitor?(onBargeIn: (audio: Buffer) => boolean): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
|
||||
{"closureHash":"bcc4e7d34932202ad3805c54ac67cb466924d2c0374a33e6a2a02ffa518ce3ca","declaration":"export class MeetingSessionRuntime<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map<string, TSession>;\n readonly #sessionLeaves: Map<string, Promise<MeetingSessionLeaveResult<TSession>>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map<string, () => Promise<void>>;\n readonly #sessionSpeakers: Map<string, (instructions?: string) => void>;\n readonly #sessionHealth: Map<string, () => Partial<THealth>>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts<TSession>;\n readonly #transcriptStore: MeetingSessionTranscriptStore<TSession>;\n constructor(private readonly options: MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise<TranscriptsStartResult>;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise<TranscriptsStopResult>;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin<TTransport, TMode>): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise<boolean>;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise<void>;\n async refreshCaptionHealth(session: TSession): Promise<void>;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin<TTransport, TMode>): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise<boolean>;\n async #rollbackFailedJoinSession(session: TSession): Promise<void>;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise<void>;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles<THealth>): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"}
|
||||
{"closureHash":"9e91eff317b13d93107e856c077bd51db614f2aa65d3c7d4c60e86ae09f489b6","declaration":"export class MeetingSessionRuntime<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map<string, TSession>;\n readonly #sessionLeaves: Map<string, Promise<MeetingSessionLeaveResult<TSession>>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map<string, () => Promise<void>>;\n readonly #sessionSpeakers: Map<string, (instructions?: string) => void>;\n readonly #sessionHealth: Map<string, () => Partial<THealth>>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts<TSession>;\n readonly #transcriptStore: MeetingSessionTranscriptStore<TSession>;\n constructor(private readonly options: MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise<TranscriptsStartResult>;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise<TranscriptsStopResult>;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin<TTransport, TMode>): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise<boolean>;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise<void>;\n async refreshCaptionHealth(session: TSession): Promise<void>;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin<TTransport, TMode>): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise<boolean>;\n async #rollbackFailedJoinSession(session: TSession): Promise<void>;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise<void>;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles<THealth>): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"}
|
||||
{"category":null,"entrypoint":"memory-core-host-engine-foundation","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","recordType":"module"}
|
||||
{"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"memory-core-host-engine-foundation","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"}
|
||||
{"closureHash":null,"declaration":"export function isPathInside(root: string, target: string): boolean;","entrypoint":"memory-core-host-engine-foundation","exportName":"isPathInside","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"}
|
||||
@@ -3403,9 +3403,9 @@
|
||||
{"category":"core","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","recordType":"module"}
|
||||
{"closureHash":"3d27406644141af2733cfca6e8c1240fc62327910109f585ce9073cafd7fd89c","declaration":"export function buildJsonPluginConfigSchema(schema: JsonSchemaObject, options?: BuildJsonPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildJsonPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
|
||||
{"closureHash":"aff66c792d532642afb9c6e5a03c8d220f219250c3a8b49733f32058f22f98ca","declaration":"export function buildPluginConfigSchema(schema: ZodTypeAny, options?: BuildPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
|
||||
{"closureHash":"60eaea4ee788df80eb81ba87d49e396cb9ffb40eb7d6bfd74fbcd817a34f3dcc","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
|
||||
{"closureHash":"ea866f93256b2e5f8da5bad7c96511f00f9b42fa85f6689cc70ab26bde2dd0cb","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0ef1dfa3b5deeb456480e292c0e835c3cd6d13e7bb7059fc735546507da51594","declaration":"export function emptyPluginConfigSchema(): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"emptyPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
|
||||
{"closureHash":"7dcb6a9a37ace260567e3b46fc8d051aa124df2edfb093dfb56f082da56eaafb","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"beb6715ad81487caa2cc2ed8444d6ac2dcf83c9e71fc42d5db9214f2eb12b946","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"plugin-entry","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
@@ -3421,10 +3421,10 @@
|
||||
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"plugin-entry","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"2f6e368fff73e942044cdf95c7c751b46c741e22ac0d2d4d97f45a3158f758ae","declaration":"export type OpenClawGatewayDiscoveryAdvertiseContext = OpenClawGatewayDiscoveryAdvertiseContext;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryAdvertiseContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b198058e0065e5c60b729a5bdf568f7e2436a006d8c4a7c63de764c7283f96ba","declaration":"export type OpenClawGatewayDiscoveryService = OpenClawGatewayDiscoveryService;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"c968e96cdb5c97e92d26b7b15fb5255531b45a12e7c5c0a2e7e456d31cc6e358","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"0fd3922f47a01a793d0b383cf6744734aae5c4fc2990344c2ed7b0969ae1d309","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"05cefddc1e544e0efd37301f07a5adae39f6cc580239b314c1959b8887a23ce9","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7470b211ac4d3449cd0fc353ee2eb48e9fbc2dbc9259d21c680d0203577aa94f","declaration":"export type OpenClawPluginHttpRouteHandler = OpenClawPluginHttpRouteHandler;","entrypoint":"plugin-entry","exportName":"OpenClawPluginHttpRouteHandler","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
|
||||
@@ -3574,14 +3574,14 @@
|
||||
{"closureHash":"ad45bb1eb13e99e3217eb7e7e2d29fa456bc1930059dd5e94d7500e05e54c6bc","declaration":"export function executePluginCommand(params: { command: RegisteredPluginCommand; args?: string; senderId?: string; channel: string; channelId?: PluginCommandContext[\"channelId\"]; isAuthorizedSender: boolean; senderIsOwner?: boolean; gatewayClientScopes?: PluginCommandContext[\"gatewayClientScopes\"]; agentId?: string; sessionKey?: PluginCommandContext[\"sessionKey\"]; sessionId?: PluginCommandContext[\"sessionId\"]; sessionTarget?: PluginCommandContext[\"sessionTarget\"]; sessionFile?: PluginCommandContext[\"sessionFile\"]; authProfileId?: string; commandBody: string; config: OpenClawConfig; from?: PluginCommandContext[\"from\"]; to?: PluginCommandContext[\"to\"]; originatingTo?: string; accountId?: PluginCommandContext[\"accountId\"]; messageThreadId?: PluginCommandContext[\"messageThreadId\"]; threadParentId?: PluginCommandContext[\"threadParentId\"]; diagnosticsSessions?: PluginCommandContext[\"diagnosticsSessions\"]; diagnosticsUploadApproved?: PluginCommandContext[\"diagnosticsUploadApproved\"]; diagnosticsPreviewOnly?: PluginCommandContext[\"diagnosticsPreviewOnly\"]; diagnosticsPrivateRouted?: PluginCommandContext[\"diagnosticsPrivateRouted\"]; }): Promise<PluginCommandResult>;","entrypoint":"plugin-runtime","exportName":"executePluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"7e75fc04d621dc8d12f459d5b5b0c039a39b77c30c2b51af481e123c352f57b8","declaration":"export function getGlobalHookRunner(): HookRunner | null;","entrypoint":"plugin-runtime","exportName":"getGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"db6583607237e4081814e2c5d4f8fb6f216ad3bbfe623bf16fc1a9c09c15f64b","declaration":"export function getPluginCommandSpecs(provider?: string, options?: PluginCommandSpecOptions): Array<{ name: string; description: string; descriptionLocalizations?: Record<string, string>; acceptsArgs: boolean; }>;","entrypoint":"plugin-runtime","exportName":"getPluginCommandSpecs","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"501447aa669a7dd46a644791d7374819a7e1d5b3cfffac3251a8d5a3efb9d1b5","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"dbfeaea0c67177141cc6e662d6df7d97cac656a9079377c514bffb89073f3c8e","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"cfe277ce6de0c6ed50f1f54b66c889f6c95e91b058e8bcdc27aa37317a93a447","declaration":"export function listRegisteredPluginAgentPromptGuidance(params?: { surface?: AgentPromptSurfaceKind; includeLegacyGlobalGuidance?: boolean; }): string[];","entrypoint":"plugin-runtime","exportName":"listRegisteredPluginAgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"693462c2a5c07646277169ede37b71ed12dc8d56c648b7fed73712900be34dcf","declaration":"export function matchPluginCommand(commandBody: string, options?: { channel?: string; }): { command: RegisteredPluginCommand; args?: string; } | null;","entrypoint":"plugin-runtime","exportName":"matchPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8d575a525d165780642e70ff1385311c3422429c2e26c479a85baae491d62efe","declaration":"export function registerPluginCommand(pluginId: string, command: OpenClawPluginCommandDefinition, opts?: { pluginName?: string; pluginRoot?: string; allowReservedCommandNames?: boolean; allowOwnerStatusExposure?: boolean; }): CommandRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"16986e5d431f584c2d5053289eca3d2225bbe47a92cdfbbc2af91b264a165846","declaration":"export function registerPluginInteractiveHandler(pluginId: string, registration: PluginInteractiveHandlerRegistration, opts?: { pluginName?: string; pluginRoot?: string; }): InteractiveRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginInteractiveHandler","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"f20c07a48e2c949fbc889e7a32760f4e52339d9f6d3eab49e00ff249266e2396","declaration":"export function startLazyPluginServiceModule(params: { skipEnvVar?: string; overrideEnvVar?: string; validateOverrideSpecifier?: (specifier: string) => string; loadDefaultModule: () => Promise<LazyServiceModule>; loadOverrideModule?: (specifier: string) => Promise<LazyServiceModule>; startExportNames: string[]; stopExportNames?: string[]; }): Promise<LazyPluginServiceHandle | null>;","entrypoint":"plugin-runtime","exportName":"startLazyPluginServiceModule","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"bad43ffe69d1d9d6c92c79df4c388b3dda685013a92392daef456f1622ade659","declaration":"export type LazyPluginServiceHandle = LazyPluginServiceHandle;","entrypoint":"plugin-runtime","exportName":"LazyPluginServiceHandle","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"6545dfa8438683bf5ab321b0fe5cca9e47fc91686fe2166f8abc9084ce170aac","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"ff621688b7b58ebfa7157b153d83921a47158e43ac312ff61df85d437216ae10","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f06379ada10ce0eca4e66bdf978db2c0035e054a135dc044c6d831ac7797c08f","declaration":"export type PluginConversationBinding = PluginConversationBinding;","entrypoint":"plugin-runtime","exportName":"PluginConversationBinding","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"a1223d674b2b66918a576ae05b04318d7b8cbe9b1d3bc6dd7a08d1a4fa79b291","declaration":"export type PluginConversationBindingRequestParams = PluginConversationBindingRequestParams;","entrypoint":"plugin-runtime","exportName":"PluginConversationBindingRequestParams","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
|
||||
@@ -3671,10 +3671,10 @@
|
||||
{"closureHash":"e66adcb55dec79be73a52bc76594b7e9210fd93c69a85b56098fbb58cecbb354","declaration":"export type WriteOAuthCredentialsOptions = WriteOAuthCredentialsOptions;","entrypoint":"provider-auth","exportName":"WriteOAuthCredentialsOptions","importSpecifier":"openclaw/plugin-sdk/provider-auth","kind":"type","recordType":"export"}
|
||||
{"category":null,"entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","recordType":"module"}
|
||||
{"closureHash":"b5665596a3f011454a5614681513516acd50b6c749536c43842d811980cf7ad3","declaration":"export function augmentModelCatalogWithProviderPlugins(params: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; metadataSnapshot?: PluginMetadataSnapshot; context: ProviderAugmentModelCatalogContext; }): Promise<ModelCatalogEntry[]>;","entrypoint":"provider-catalog-runtime","exportName":"augmentModelCatalogWithProviderPlugins","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d3d9275ea2612b0f8837fe12d4b14cd3e3d06e3aed4c3417754a3b1c95e39e25","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters<typeof resolvePluginProviders>[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"5d83dd4ba5e9f0b8c1d9ffaf583f5312c88e21d5cb90637ac0f260133265f738","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"4c281c99ff58abf4ab164909c5528ec9c7d33b10fd660bf340b028111b616c6f","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick<PluginMetadataSnapshot, \"owners\" | \"manifestRegistry\" | \"byPluginId\">; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"048abfae415819c157f5a6f7fbdab5f0a17f48863f973a7ac361c7a645e6ec5b","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"a360cb1f899330116af2fd6f2370cc53c0ff5083bd27a4d5e5977c05fa4627a6","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters<typeof resolvePluginProviders>[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"a8a3abd31253da5e27e43db29968d818f98a55a6f08e0be1e7e94265c634f7fa","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0d463b51098a4f8bb1ca72db875efc938f64978bbf498632bdc7fb8b61648f4a","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick<PluginMetadataSnapshot, \"owners\" | \"manifestRegistry\" | \"byPluginId\">; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"4e83218d414f08a78be577d566d883f6147e50776a128e6c3e9c49057ab93cdc","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
|
||||
{"category":null,"entrypoint":"proxy-capture","importSpecifier":"openclaw/plugin-sdk/proxy-capture","recordType":"module"}
|
||||
{"closureHash":"d0e4e026d736bc00b1758d1089c44c3c5f3a09c7254291584de8cb297365804c","declaration":"export function acquireDebugProxyCaptureStore(dbPath: string, blobDir: string): { store: LegacyDebugProxyCaptureStore; release: () => void; };\nexport function acquireDebugProxyCaptureStore(options?: DebugProxyCaptureStoreOptions): { store: SharedDebugProxyCaptureStore; release: () => void; };","entrypoint":"proxy-capture","exportName":"acquireDebugProxyCaptureStore","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d41cbb9de51b7aee1c6cf8c713b0bc44f27ac926fbb6422c05726f196d11964e","declaration":"export function captureHttpExchange(params: { url: string; method: string; requestHeaders?: Headers | Record<string, string> | undefined; requestBody?: BodyInit | Buffer | string | null; response: Response; transport?: \"http\" | \"sse\"; flowId?: string; meta?: Record<string, unknown>; }, resolved?: DebugProxySettings, deps?: DebugProxyCaptureRuntimeDeps): void;","entrypoint":"proxy-capture","exportName":"captureHttpExchange","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"}
|
||||
@@ -4303,7 +4303,7 @@
|
||||
{"closureHash":"eb612aa7bb0e0ac71925a219bb93f04867caec9eafa8c46e118433b7fc7651e6","declaration":"export let STATE_DIR: string;","entrypoint":"state-paths","exportName":"STATE_DIR","importSpecifier":"openclaw/plugin-sdk/state-paths","kind":"variable","recordType":"export"}
|
||||
{"category":null,"entrypoint":"status-helpers","importSpecifier":"openclaw/plugin-sdk/status-helpers","recordType":"module"}
|
||||
{"closureHash":"da271ab51c875f3b557969c3fed4b62459b26cf511fff81be0f37be71a7dc1db","declaration":"export function appendMatchMetadata(message: string, params: { matchKey?: unknown; matchSource?: unknown; }): string;","entrypoint":"status-helpers","exportName":"appendMatchMetadata","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
{"closureHash":"feb6b6cc6719326e5f09c3ed6c38083e178f7ca9fb5dae74e90ab0f50811bcf6","declaration":"export function asString(value: unknown): string | undefined;","entrypoint":"status-helpers","exportName":"asString","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
{"closureHash":"c0c92d709ca55c2e9c2d579eed61ce2203c9046bcbf6699a0d0bb3a72287d477","declaration":"export function asString(value: unknown): string | undefined;","entrypoint":"status-helpers","exportName":"asString","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
{"closureHash":"36929d73a3e6a600c84a9f80a68403194e0669e4ffa146306f9b9627253c2e47","declaration":"export function buildBaseAccountStatusSnapshot<TExtra extends StatusSnapshotExtra>(params: { account: { accountId: string; name?: string; enabled?: boolean; configured?: boolean; }; runtime?: RuntimeLifecycleSnapshot | null; probe?: unknown; }, extra?: TExtra): { lastInboundAt: number | null; lastOutboundAt: number | null; activeRunStartedAt?: number | undefined; lastRunActivityAt?: number | undefined; activeRuns?: number | undefined; busy?: boolean | undefined; terminalDisconnect?: true | undefined; ingressUnavailable?: true | undefined; lifecycle?: \"blocked\" | \"starting\" | \"ready\" | \"recovering\" | \"stopped\" | undefined; healthState?: string | undefined; lastTransportActivityAt?: number | undefined; lastEventAt?: number | undefined; lastDisconnect?: string | { at: number; status?: number; error?: string; loggedOut?: boolean; } | undefined; lastConnectedAt?: number | undefined; reconnectAttempts?: number | undefined; restartPending?: boolean | undefined; connected?: boolean | undefined; linked?: boolean | undefined; running: boolean; lastStartAt: number | null; lastStopAt: number | null; lastError: string | null; probe: unknown; accountId: string; name: string | undefined; enabled: boolean | undefined; configured: boolean | undefined; } & TExtra;","entrypoint":"status-helpers","exportName":"buildBaseAccountStatusSnapshot","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0bf8ae29b2d9d8623e8a34f219f4e078c8f6e1c01cfd9fae07176500563e803b","declaration":"export function buildBaseChannelStatusSummary<TExtra extends StatusSnapshotExtra>(snapshot: { configured?: boolean | null; running?: boolean | null; lastStartAt?: number | null; lastStopAt?: number | null; lastError?: string | null; }, extra?: TExtra): { configured: boolean; } & TExtra & { running: boolean; lastStartAt: number | null; lastStopAt: number | null; lastError: string | null; };","entrypoint":"status-helpers","exportName":"buildBaseChannelStatusSummary","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
{"closureHash":"091884288f381f9d44c4f98f991990eedf0ca4b62af623b97beb0c17fe9ec6a6","declaration":"export function buildComputedAccountStatusSnapshot<TExtra extends StatusSnapshotExtra>(params: { accountId: string; name?: string; enabled?: boolean; configured?: boolean; runtime?: RuntimeLifecycleSnapshot | null; probe?: unknown; }, extra?: TExtra): { lastInboundAt: number | null; lastOutboundAt: number | null; activeRunStartedAt?: number | undefined; lastRunActivityAt?: number | undefined; activeRuns?: number | undefined; busy?: boolean | undefined; terminalDisconnect?: true | undefined; ingressUnavailable?: true | undefined; lifecycle?: \"blocked\" | \"starting\" | \"ready\" | \"recovering\" | \"stopped\" | undefined; healthState?: string | undefined; lastTransportActivityAt?: number | undefined; lastEventAt?: number | undefined; lastDisconnect?: string | { at: number; status?: number; error?: string; loggedOut?: boolean; } | undefined; lastConnectedAt?: number | undefined; reconnectAttempts?: number | undefined; restartPending?: boolean | undefined; connected?: boolean | undefined; linked?: boolean | undefined; running: boolean; lastStartAt: number | null; lastStopAt: number | null; lastError: string | null; probe: unknown; accountId: string; name: string | undefined; enabled: boolean | undefined; configured: boolean | undefined; } & TExtra;","entrypoint":"status-helpers","exportName":"buildComputedAccountStatusSnapshot","importSpecifier":"openclaw/plugin-sdk/status-helpers","kind":"function","recordType":"export"}
|
||||
@@ -4333,7 +4333,9 @@
|
||||
{"closureHash":"c4a67c4e399ef77063c033fa6408ab52201677b3e91d18cbf72c2b0ef3b04868","declaration":"export function asBoolean(value: unknown): boolean | undefined;","entrypoint":"string-coerce-runtime","exportName":"asBoolean","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8cc60d63f99d6ed490bb90c379e40689b7a7360b5731c47622dbca57646867c7","declaration":"export function asFiniteNumber(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"asFiniteNumber","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"91afebd87438e96391af3fe271f3c0297be88678420987a648e0ab2073fec8cb","declaration":"export function asFiniteNumberInRange(value: unknown, range: { min?: number; max?: number; minExclusive?: boolean; maxExclusive?: boolean; }): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"asFiniteNumberInRange","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8f5f89cd550e17fde19f6229edd7502cd473384edc289f448032a066f27d8139","declaration":"export function asNullableObjectRecord(value: unknown): Record<string, unknown> | null;","entrypoint":"string-coerce-runtime","exportName":"asNullableObjectRecord","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"4c772989882503a1861c55c9ebac600ceaf218d44147d87da0628eba845bff15","declaration":"export function asNullableRecord(value: unknown): Record<string, unknown> | null;","entrypoint":"string-coerce-runtime","exportName":"asNullableRecord","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3ce3856918e2e7e45071d174e5948657ba2cf18bfedc6fe1ac9d7d859012f6b2","declaration":"export function asOptionalObjectRecord(value: unknown): Record<string, unknown> | undefined;","entrypoint":"string-coerce-runtime","exportName":"asOptionalObjectRecord","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1627961066a987bec6f21c1cebccf61ded3c26ae834f5819e1909632a5586834","declaration":"export function asOptionalRecord(value: unknown): Record<string, unknown> | undefined;","entrypoint":"string-coerce-runtime","exportName":"asOptionalRecord","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"41c29f2f42fa1a43f9f4a56dbe9ccd3c87232ffc4b7046bb15848f0150e5a1a4","declaration":"export function asPositiveSafeInteger(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"asPositiveSafeInteger","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"28f70710cc0d9006bc47149d51fc65a6c990f1c2f7c9a16f96d94fa593041bcb","declaration":"export function asRecord(value: unknown): Record<string, unknown>;","entrypoint":"string-coerce-runtime","exportName":"asRecord","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
@@ -4361,6 +4363,7 @@
|
||||
{"closureHash":"37287f8f868dd5f82766f20dd47e2c83aea94022461d2b27ad1fbe97a5c7cca8","declaration":"export function normalizeUniqueStringEntries(values?: Iterable<unknown>): string[];","entrypoint":"string-coerce-runtime","exportName":"normalizeUniqueStringEntries","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"70c7cea3e68443c494677f7012c4aae2d3be3a4b586d777e299273230fa3a460","declaration":"export function normalizeUniqueTrimmedStringList(value: unknown): string[];","entrypoint":"string-coerce-runtime","exportName":"normalizeUniqueTrimmedStringList","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b4468874f0640fe53b525195faa47195b7946cb28e2edbee566dc00d53d81ed5","declaration":"export function parseBooleanValue(value: unknown, options?: BooleanParseOptions): boolean | undefined;","entrypoint":"string-coerce-runtime","exportName":"parseBooleanValue","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"8e6357d6b3d286570af672d24cc93cbe84875a4c49c4142b6ba283687015799a","declaration":"export function parseDateTimestampMs(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"parseDateTimestampMs","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1b4c281d27d98dd358c598879e048447d3be1855a4e7f27dc769e20cdef38a10","declaration":"export function parseFiniteNumber(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"parseFiniteNumber","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"35e6fd636ae00132a4b61439bd6932cd2f2f7b3d3870f239f7d3935babcce365","declaration":"export function parseStrictFiniteNumber(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"parseStrictFiniteNumber","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0eecec70484482da2e1775cd09bd90c1a1b7a5541b6fe77ea28ce355c475becd","declaration":"export function parseStrictInteger(value: unknown): number | undefined;","entrypoint":"string-coerce-runtime","exportName":"parseStrictInteger","importSpecifier":"openclaw/plugin-sdk/string-coerce-runtime","kind":"function","recordType":"export"}
|
||||
@@ -4636,16 +4639,16 @@
|
||||
{"closureHash":"e365d7ad911453b5139ba700931b061e560cff80b50d4cbe5e9615b5d7e13a52","declaration":"export type ScopedExpiringIdCache<TScope extends string | number, TId extends string | number> = ScopedExpiringIdCache<TScope, TId>;","entrypoint":"text-runtime","exportName":"ScopedExpiringIdCache","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"type","recordType":"export"}
|
||||
{"closureHash":"af5502c92594c2e9049a4b4994e17c00d3adee3f6d1e68edd818a539c74c8787","declaration":"export interface CodeRegion {\n start: number;\n end: number;\n}","entrypoint":"text-runtime","exportName":"CodeRegion","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"interface","recordType":"export"}
|
||||
{"category":null,"entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","recordType":"module"}
|
||||
{"closureHash":"1b4fb3ffd40b901d362f1e8e4824a82cf8526ef00ef846974f13254e1c0dffa5","declaration":"export function defineToolPlugin<TConfigSchema extends TSchema | undefined = undefined>(definition: DefineToolPluginOptions<TConfigSchema>): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
|
||||
{"closureHash":"0a3affca237e0370b796f418bfbe87212c7f1dc7d8066586a113c8d3f1c9c183","declaration":"export function defineToolPlugin<TConfigSchema extends TSchema | undefined = undefined>(definition: DefineToolPluginOptions<TConfigSchema>): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
|
||||
{"closureHash":"36ef907ce20f885b5f3068cbf0475dc442a68da9652579bb5bf8fb83ad34c38b","declaration":"export function getToolPluginMetadata(entry: unknown): ToolPluginMetadata | undefined;","entrypoint":"tool-plugin","exportName":"getToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
|
||||
{"closureHash":"bdc58154e36b2625fb3daccca3eab248d981077d04d747f0ad507cb2ff565198","declaration":"export const toolPluginMetadataSymbol: typeof toolPluginMetadataSymbol;","entrypoint":"tool-plugin","exportName":"toolPluginMetadataSymbol","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"const","recordType":"export"}
|
||||
{"closureHash":"bb1c06399667b2257908a8f507e882da468aa6c3ff6fd6b038e8a4338b594441","declaration":"export type DefineToolPluginOptions<TConfigSchema extends TSchema | undefined = undefined> = DefineToolPluginOptions<TConfigSchema>;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"c4eec6214d34f00b92ad6e3c995f2bafe2ecc652ee616b98ba38fb870f9d81ea","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"870ea60b2645fb6af508f6a2a588fd6e53836bc187b3aa6cb519bb1553d20e82","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"dff06f936a371772c6fe219d33fd974f8bb778b5e96f9d92de14dc2f57886e94","declaration":"export type ToolPluginFactoryContext<TConfig> = ToolPluginFactoryContext<TConfig>;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"11aa5fbcec024a768b7af0c54f8fc899c202ff892edf481ba1476ff895345abb","declaration":"export type DefineToolPluginOptions<TConfigSchema extends TSchema | undefined = undefined> = DefineToolPluginOptions<TConfigSchema>;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"7daed12952abd818d864a6e96c60c90bb79ddb73a94f50f3e21c676dbdb3dbd7","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"15bac4724ce2f1cfb2aebdc5f66cd10de56c84f916bf65169ce1bfed39866e2d","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"84872c7903f1cb60ab330047241d2bca21e43ee84f2e1073fd78cf3aa6b56dcb","declaration":"export type ToolPluginFactoryContext<TConfig> = ToolPluginFactoryContext<TConfig>;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"f774bd092f51a31fbb34847213f9583234f585f66918d0af55e81bbbae40463b","declaration":"export type ToolPluginMetadata = ToolPluginMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"414a89d0c80eaaf682dc25d306e7223c981c6fd25366adb973a106f4268a6a54","declaration":"export type ToolPluginStaticToolMetadata = ToolPluginStaticToolMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginStaticToolMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"372dc6fb47a6060961e287821d9e87b59359ace16d0b9fb38347205a9f9ab5d6","declaration":"export type ToolPluginToolDefinition<TConfig, TParamsSchema extends TSchema> = ToolPluginToolDefinition<TConfig, TParamsSchema>;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"closureHash":"11e44768d91eaaa804d40fd52e29e5a93d24698515dcd50bb22f48c542b92f9a","declaration":"export type ToolPluginToolDefinition<TConfig, TParamsSchema extends TSchema> = ToolPluginToolDefinition<TConfig, TParamsSchema>;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
|
||||
{"category":null,"entrypoint":"tool-results","importSpecifier":"openclaw/plugin-sdk/tool-results","recordType":"module"}
|
||||
{"closureHash":"c5b0951c3629834dff78f92317cf1421a6bbc0faf9307be1cabb915055665280","declaration":"export function jsonResult<TDetails>(payload: TDetails): AgentToolResult<TDetails>;","entrypoint":"tool-results","exportName":"jsonResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"}
|
||||
{"closureHash":"b9aefc637a694c74e028e92006004bef18185ed569af48ac43d36b646b0af2f3","declaration":"export function textResult<TDetails>(text: string, details: TDetails): AgentToolResult<TDetails>;","entrypoint":"tool-results","exportName":"textResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"}
|
||||
@@ -4679,9 +4682,9 @@
|
||||
{"closureHash":"9f9174f1023a8a451232f5d97d1e922b7faa88b76b58cffbfbe246a1488e0ddd","declaration":"export function readJsonWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; emptyObjectOnEmpty?: boolean; invalidJsonMessage?: string; }): Promise<{ ok: true; value: unknown; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readJsonWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"1bbddd5d1c8297e315275db4d5e1c8748ff09c0be7c37b0cf456db4fc69f8909","declaration":"export function readRequestBodyWithLimit(req: IncomingMessage, options: ReadRequestBodyOptions): Promise<string>;","entrypoint":"webhook-ingress","exportName":"readRequestBodyWithLimit","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"e8a1174cac83ce346a231fd25e82bb5f7618ffb57cdd9af6eaa208411f70646d","declaration":"export function readWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; invalidBodyMessage?: string; }): Promise<{ ok: true; value: string; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"d958ba4df86fc65fd5fdbabd463e4b6ab5a572f28c350dffa1f987f64c8280bd","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"16a1cd83bd12e1f265a4b2e2fabe6c4d108e9570ee88c7daaf020608a5007f25","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"05835f2f66f906f736b82b332a84a9714bc3a6b211890a62d8fc4dbf9258a7d4","declaration":"export function registerWebhookTarget<T extends { path: string; }>(targetsByPath: Map<string, T[]>, target: T, opts?: RegisterWebhookTargetOptions<T>): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"2dd6ae1adcd4f011a2969c4a990622dc764078e775304eac40c9991864091a86","declaration":"export function registerWebhookTargetWithPluginRoute<T extends { path: string; }>(params: { targetsByPath: Map<string, T[]>; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions<T>[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"3a78257a9745ef83d912a6d4659ff16a67d2eab326098f6084119ef510f915a7","declaration":"export function registerWebhookTargetWithPluginRoute<T extends { path: string; }>(params: { targetsByPath: Map<string, T[]>; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions<T>[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"ec2f47e9bd7a075a3dd4302ac9e4c0bfe20630445db6735cf803f2d354275841","declaration":"export function requestBodyErrorToText(code: RequestBodyLimitErrorCode): string;","entrypoint":"webhook-ingress","exportName":"requestBodyErrorToText","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"5e1f3b468d56eb0f82104184077fdf4b6bd0c1444aa10b71a65fcaa2ec0298a2","declaration":"export function resolveRequestClientIp(req?: IncomingMessage, trustedProxies?: string[], allowRealIpFallback?: boolean): string | undefined;","entrypoint":"webhook-ingress","exportName":"resolveRequestClientIp","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
{"closureHash":"56c3e9868dfa6ee2a7a128eb02039a16b52696759adadbd3fe0a3bd7a6a07eeb","declaration":"export function resolveSingleWebhookTarget<T>(targets: readonly T[], isMatch: (target: T) => boolean): WebhookTargetMatchResult<T>;","entrypoint":"webhook-ingress","exportName":"resolveSingleWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
|
||||
@@ -4699,7 +4702,7 @@
|
||||
{"closureHash":"efb74e84339c15d6f607b38d1d477b0504d47d04ae78e77083a1893c756a0b54","declaration":"export const WEBHOOK_RATE_LIMIT_DEFAULTS: Readonly<{ windowMs: 60000; maxRequests: 120; maxTrackedKeys: 4096;}>;","entrypoint":"webhook-ingress","exportName":"WEBHOOK_RATE_LIMIT_DEFAULTS","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"const","recordType":"export"}
|
||||
{"closureHash":"13b28ec9acae43c3bdcd683b9831154f88118dee8142e42b7eebfd59f08c602c","declaration":"export type BoundedCounter = BoundedCounter;","entrypoint":"webhook-ingress","exportName":"BoundedCounter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"9e737ae8c17038ef7becbd2bf1b756cfeaed571e2ded368c0fe3a446ebd1f666","declaration":"export type FixedWindowRateLimiter = FixedWindowRateLimiter;","entrypoint":"webhook-ingress","exportName":"FixedWindowRateLimiter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"c78ccdc3cb8e45f5da08133b6cb7beef96a37484c85f2eb9d018b5e78aa6d1d7","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"75b1673b974b3866ffe5ad188f96f05a191310fcd95ff97efbcac5829e9eafdc","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"b3e98619854462acfac6538ac9a2d0cefb88704a0eac712563f0996b07364152","declaration":"export type RegisterWebhookTargetOptions<T extends {\n path: string;\n}> = RegisterWebhookTargetOptions<T>;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookTargetOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"964c2bfd8f268c411ee7b982c9de02c207f4bec402dd62c9f998a59752bb9d1f","declaration":"export type RegisteredWebhookTarget<T> = RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"RegisteredWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
{"closureHash":"aa552e5bdaefc9eb94d3b5a5cdf8c413fad555d9f452c6a2a6af5a3ce695c9d1","declaration":"export type WebhookAnomalyTracker = WebhookAnomalyTracker;","entrypoint":"webhook-ingress","exportName":"WebhookAnomalyTracker","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
import { listPiSummaryPage, readPiSessionById } from "./pi-session-store.js";
|
||||
import { parsePiSessionTimestampMs } from "./pi-session-timestamp.js";
|
||||
|
||||
const LOCAL_HOST_ID = "gateway";
|
||||
const DEFAULT_PAGE_LIMIT = 20;
|
||||
@@ -161,17 +162,6 @@ function textFromContent(content: unknown): string {
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function timestampMs(value: unknown): number | undefined {
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const parsed = Date.parse(value);
|
||||
return Number.isNaN(parsed) ? undefined : parsed;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseListParams(value: unknown): { searchTerm?: string; limit: number; cursor?: string } {
|
||||
if (value === undefined || value === null) {
|
||||
return { limit: DEFAULT_PAGE_LIMIT };
|
||||
@@ -236,7 +226,8 @@ function isoTimestamp(
|
||||
message: Record<string, unknown>,
|
||||
entry: Record<string, unknown>,
|
||||
): string | undefined {
|
||||
const value = timestampMs(message.timestamp) ?? timestampMs(entry.timestamp);
|
||||
const value =
|
||||
parsePiSessionTimestampMs(message.timestamp) ?? parsePiSessionTimestampMs(entry.timestamp);
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
function optionalString(value: unknown, maxLength: number): string | undefined {
|
||||
function readBoundedString(value: unknown, maxLength: number): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ function resolveConfiguredPath(
|
||||
function settingsSessionDir(file: string): string | undefined {
|
||||
try {
|
||||
const value = JSON.parse(readFileSync(file, "utf8")) as unknown;
|
||||
return isRecord(value) ? optionalString(value.sessionDir, 4_096) : undefined;
|
||||
return isRecord(value) ? readBoundedString(value.sessionDir, 4_096) : undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import type { SessionCatalogSession } from "openclaw/plugin-sdk/session-catalog";
|
||||
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { piAcpSessionStoreRoot, piSessionStore } from "./pi-session-paths.js";
|
||||
import { parsePiSessionTimestampMs } from "./pi-session-timestamp.js";
|
||||
|
||||
const MAX_DISCOVERY_FILES = 10_000;
|
||||
const SUMMARY_SCAN_BATCH_SIZE = 100;
|
||||
@@ -84,7 +85,7 @@ function cacheSummary(file: string, value: CachedSummary): void {
|
||||
}
|
||||
}
|
||||
|
||||
function optionalString(value: unknown, maxLength: number): string | undefined {
|
||||
function readBoundedString(value: unknown, maxLength: number): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -258,17 +259,6 @@ function textFromContent(content: unknown): string {
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function timestampMs(value: unknown): number | undefined {
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const parsed = Date.parse(value);
|
||||
return Number.isNaN(parsed) ? undefined : parsed;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function processSummaryLine(state: PiSummaryScanState, line: Buffer): void {
|
||||
const content = line.at(-1) === 0x0d ? line.subarray(0, -1) : line;
|
||||
const entry = parsePiJsonLines(content.toString("utf8"))[0];
|
||||
@@ -285,14 +275,14 @@ function processSummaryLine(state: PiSummaryScanState, line: Buffer): void {
|
||||
}
|
||||
if (entry.type === "session_info") {
|
||||
// Latest metadata wins, including an explicit empty-name clear.
|
||||
state.name = optionalString(entry.name, 1_000);
|
||||
state.name = readBoundedString(entry.name, 1_000);
|
||||
} else if (
|
||||
!state.firstMessage &&
|
||||
entry.type === "message" &&
|
||||
isRecord(entry.message) &&
|
||||
entry.message.role === "user"
|
||||
) {
|
||||
state.firstMessage = optionalString(textFromContent(entry.message.content), 1_000);
|
||||
state.firstMessage = readBoundedString(textFromContent(entry.message.content), 1_000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,10 +409,10 @@ async function readPiSessionSummary(
|
||||
const { header, name, firstMessage } = projectedState;
|
||||
const version =
|
||||
header?.type === "session" && typeof header.version === "number" ? header.version : 1;
|
||||
const threadId = header?.type === "session" ? optionalString(header.id, 256) : undefined;
|
||||
const threadId = header?.type === "session" ? readBoundedString(header.id, 256) : undefined;
|
||||
if (header && threadId && SESSION_ID_PATTERN.test(threadId)) {
|
||||
const cwd = optionalString(header.cwd, 4_096);
|
||||
const createdAt = timestampMs(header.timestamp);
|
||||
const cwd = readBoundedString(header.cwd, 4_096);
|
||||
const createdAt = parsePiSessionTimestampMs(header.timestamp);
|
||||
summary = {
|
||||
file: candidate.file,
|
||||
version,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { listLocalPiSessionPage, readLocalPiTranscriptPage } from "./pi-session-catalog.js";
|
||||
import { createPiStoreFixture } from "./pi-session-catalog.test-support.js";
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
const originalSessionDir = process.env.PI_CODING_AGENT_SESSION_DIR;
|
||||
const originalAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
|
||||
afterEach(async () => {
|
||||
if (originalSessionDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_SESSION_DIR;
|
||||
} else {
|
||||
process.env.PI_CODING_AGENT_SESSION_DIR = originalSessionDir;
|
||||
}
|
||||
if (originalAgentDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
} else {
|
||||
process.env.PI_CODING_AGENT_DIR = originalAgentDir;
|
||||
}
|
||||
await Promise.all(
|
||||
temporaryDirectories.splice(0).map(async (directory) => {
|
||||
await fs.rm(directory, { recursive: true, force: true });
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
describe("Pi session timestamp contract", () => {
|
||||
it("preserves date parsing for numeric-looking timestamp strings", async () => {
|
||||
const directory = await createPiStoreFixture(temporaryDirectories);
|
||||
const entries = [
|
||||
{
|
||||
type: "session",
|
||||
version: 3,
|
||||
id: "pi-session",
|
||||
timestamp: "2026",
|
||||
cwd: "/workspace",
|
||||
},
|
||||
{
|
||||
type: "message",
|
||||
id: "user-1",
|
||||
parentId: null,
|
||||
timestamp: "2026",
|
||||
message: { role: "user", content: "hello", timestamp: "0" },
|
||||
},
|
||||
];
|
||||
await fs.writeFile(
|
||||
path.join(directory, "session.jsonl"),
|
||||
`${entries.map((entry) => JSON.stringify(entry)).join("\n")}\n`,
|
||||
);
|
||||
|
||||
const listed = await listLocalPiSessionPage({ limit: 20 });
|
||||
expect(listed.sessions[0]?.createdAt).toBe(Date.parse("2026"));
|
||||
expect(listed.sessions[0]?.createdAt).not.toBe(2_026);
|
||||
|
||||
const transcript = await readLocalPiTranscriptPage({ threadId: "pi-session", limit: 20 });
|
||||
expect(transcript.items[0]?.timestamp).toBe(new Date(Date.parse("0")).toISOString());
|
||||
expect(transcript.items[0]?.timestamp).not.toBe(new Date(0).toISOString());
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { asFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
/** Preserve Pi JSONL's date-first string contract while accepting numeric millisecond values. */
|
||||
export function parsePiSessionTimestampMs(value: unknown): number | undefined {
|
||||
if (typeof value === "string") {
|
||||
const parsed = Date.parse(value);
|
||||
return Number.isFinite(parsed) ? parsed : undefined;
|
||||
}
|
||||
return asFiniteNumber(value);
|
||||
}
|
||||
@@ -192,6 +192,66 @@ describe("Pi session upstream activity", () => {
|
||||
).resolves.toEqual([]);
|
||||
});
|
||||
|
||||
it("preserves Pi date parsing for numeric-looking activity timestamps", async () => {
|
||||
const sessionDirectory = await createPiStoreFixture(
|
||||
temporaryDirectories,
|
||||
"hi",
|
||||
"Pi catalog session",
|
||||
{ command: "pwd" },
|
||||
true,
|
||||
);
|
||||
const continued = await linkContinuedPiSession("agent:main:pi", "pi-session");
|
||||
const file = path.join(sessionDirectory, "session.jsonl");
|
||||
const probe = {
|
||||
sessionKey: continued.sessionKey,
|
||||
agentId: "main",
|
||||
threadId: "pi-session",
|
||||
hostId: "gateway",
|
||||
upstreamKind: continued.upstream!.kind,
|
||||
upstreamRef: continued.upstream!.ref,
|
||||
marker: continued.upstream!.marker,
|
||||
ownRecentUserTexts: [],
|
||||
};
|
||||
|
||||
await fs.appendFile(
|
||||
file,
|
||||
`${JSON.stringify({
|
||||
type: "message",
|
||||
timestamp: "0",
|
||||
message: { role: "user", content: "first external Pi turn" },
|
||||
})}\n`,
|
||||
);
|
||||
const first = await checkPiUpstreamActivity([probe]);
|
||||
expect(first).toEqual([
|
||||
expect.objectContaining({
|
||||
kind: "activity",
|
||||
humanTurns: 1,
|
||||
occurredAt: Date.parse("0"),
|
||||
}),
|
||||
]);
|
||||
expect(first[0]?.kind === "activity" ? first[0].occurredAt : undefined).not.toBe(0);
|
||||
|
||||
await fs.appendFile(
|
||||
file,
|
||||
`${JSON.stringify({
|
||||
type: "message",
|
||||
timestamp: "2026",
|
||||
message: { role: "user", content: "second external Pi turn" },
|
||||
})}\n`,
|
||||
);
|
||||
await expect(
|
||||
checkPiUpstreamActivity([
|
||||
{ ...probe, marker: first[0]!.kind === "activity" ? first[0]!.nextMarker : null },
|
||||
]),
|
||||
).resolves.toEqual([
|
||||
expect.objectContaining({
|
||||
kind: "activity",
|
||||
humanTurns: 1,
|
||||
occurredAt: Date.parse("2026"),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("stops the cursor before the first unclassifiable complete row", async () => {
|
||||
const sessionDirectory = await createPiStoreFixture(
|
||||
temporaryDirectories,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/session-catalog";
|
||||
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { readPiSessionFileBaseline } from "./pi-session-store.js";
|
||||
import { parsePiSessionTimestampMs } from "./pi-session-timestamp.js";
|
||||
|
||||
const MAX_PI_UPSTREAM_SCAN_BYTES = 1024 * 1024;
|
||||
|
||||
@@ -72,17 +73,6 @@ function textFromContent(content: unknown): string | undefined {
|
||||
return text || undefined;
|
||||
}
|
||||
|
||||
function timestampMs(value: unknown): number | undefined {
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const parsed = Date.parse(value);
|
||||
return Number.isNaN(parsed) ? undefined : parsed;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function readFilePath(probe: SessionUpstreamProbe): string | undefined {
|
||||
return isRecord(probe.upstreamRef) && typeof probe.upstreamRef.filePath === "string"
|
||||
? probe.upstreamRef.filePath
|
||||
@@ -168,7 +158,9 @@ async function checkPiSessionUpstreamActivity(
|
||||
humanTurns += 1;
|
||||
occurredAt = Math.max(
|
||||
occurredAt ?? 0,
|
||||
timestampMs(entry.message.timestamp) ?? timestampMs(entry.timestamp) ?? stat.mtimeMs,
|
||||
parsePiSessionTimestampMs(entry.message.timestamp) ??
|
||||
parsePiSessionTimestampMs(entry.timestamp) ??
|
||||
stat.mtimeMs,
|
||||
);
|
||||
}
|
||||
const nextOffset = markerOffset + classifiedBytes;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { isPathInside } from "openclaw/plugin-sdk/security-runtime";
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeStringEntries,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -138,7 +138,7 @@ function normalizePromptConfigText(value: unknown): string | undefined {
|
||||
}
|
||||
|
||||
function hasDeprecatedModelFallbackPolicy(pluginConfig: unknown): boolean {
|
||||
const raw = asRecord(pluginConfig);
|
||||
const raw = asOptionalRecord(pluginConfig);
|
||||
return raw ? Object.hasOwn(raw, "modelFallbackPolicy") : false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
@@ -179,7 +179,7 @@ function readExplicitMemoryEvidence(source: Record<string, unknown>): boolean |
|
||||
}
|
||||
|
||||
function readStructuredMemoryFailure(source: unknown): boolean | undefined {
|
||||
const record = asRecord(source);
|
||||
const record = asOptionalRecord(source);
|
||||
if (!record) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -206,7 +206,7 @@ function readStructuredMemoryEvidence(source: unknown): boolean | undefined {
|
||||
if (Array.isArray(source)) {
|
||||
return source.length > 0;
|
||||
}
|
||||
const record = asRecord(source);
|
||||
const record = asOptionalRecord(source);
|
||||
return record ? readExplicitMemoryEvidence(record) : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/plugin-config-runtime";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { parseAgentSessionKey, parseThreadSessionSuffix } from "openclaw/plugin-sdk/routing";
|
||||
import { asOptionalRecord as asRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveCanonicalSessionKeyFromSessionId } from "./session.js";
|
||||
import {
|
||||
DEFAULT_AGENT_ID,
|
||||
@@ -108,7 +108,7 @@ function formatActiveMemoryCommandHelp(): string {
|
||||
}
|
||||
|
||||
function isActiveMemoryGloballyEnabled(cfg: OpenClawConfig): boolean {
|
||||
const entry = asRecord(cfg.plugins?.entries?.["active-memory"]);
|
||||
const entry = asOptionalRecord(cfg.plugins?.entries?.["active-memory"]);
|
||||
if (entry?.enabled === false) {
|
||||
return false;
|
||||
}
|
||||
@@ -142,8 +142,8 @@ function updateActiveMemoryGlobalEnabledInConfig(
|
||||
enabled: boolean,
|
||||
): OpenClawConfig {
|
||||
const entries = { ...cfg.plugins?.entries };
|
||||
const existingEntry = asRecord(entries["active-memory"]) ?? {};
|
||||
const existingConfig = asRecord(existingEntry.config) ?? {};
|
||||
const existingEntry = asOptionalRecord(entries["active-memory"]) ?? {};
|
||||
const existingConfig = asOptionalRecord(existingEntry.config) ?? {};
|
||||
entries["active-memory"] = {
|
||||
...existingEntry,
|
||||
enabled: true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
@@ -35,7 +35,7 @@ function readMemoryToolResultEvidence(params: {
|
||||
hasUsableMemoryResult: boolean;
|
||||
hasUnavailableMemorySearchResult: boolean;
|
||||
} {
|
||||
const result = asRecord(params.result);
|
||||
const result = asOptionalRecord(params.result);
|
||||
const rawContent = result?.content;
|
||||
const textContent =
|
||||
normalizeOptionalString(result?.detailedContent) ??
|
||||
@@ -63,11 +63,11 @@ function readMemoryToolResultEvidence(params: {
|
||||
}
|
||||
|
||||
function extractAssistantTextFromSessionRecord(value: unknown): string {
|
||||
const record = asRecord(value);
|
||||
const record = asOptionalRecord(value);
|
||||
if (!record) {
|
||||
return "";
|
||||
}
|
||||
const nestedMessage = asRecord(record.message);
|
||||
const nestedMessage = asOptionalRecord(record.message);
|
||||
const topLevelMessage = normalizeOptionalString(record.role) === "assistant" ? record : undefined;
|
||||
const message = nestedMessage ?? topLevelMessage;
|
||||
if (!message || normalizeOptionalString(message.role) !== "assistant") {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -221,7 +221,7 @@ function watchTerminalMemorySearchResult(params: {
|
||||
}
|
||||
|
||||
function normalizeSearchDebug(value: unknown): ActiveMemorySearchDebug | undefined {
|
||||
const debug = asRecord(value);
|
||||
const debug = asOptionalRecord(value);
|
||||
if (!debug) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -255,8 +255,8 @@ function normalizeSearchDebug(value: unknown): ActiveMemorySearchDebug | undefin
|
||||
function readActiveMemorySearchDebugFromRunResult(
|
||||
result: unknown,
|
||||
): ActiveMemorySearchDebug | undefined {
|
||||
const record = asRecord(result);
|
||||
const meta = asRecord(record?.meta);
|
||||
const record = asOptionalRecord(result);
|
||||
const meta = asOptionalRecord(record?.meta);
|
||||
return (
|
||||
normalizeSearchDebug(meta?.activeMemorySearchDebug) ??
|
||||
normalizeSearchDebug(meta?.memorySearchDebug) ??
|
||||
@@ -266,9 +266,9 @@ function readActiveMemorySearchDebugFromRunResult(
|
||||
}
|
||||
|
||||
function readActiveMemorySessionFileFromRunResult(result: unknown): string | undefined {
|
||||
const record = asRecord(result);
|
||||
const meta = asRecord(record?.meta);
|
||||
const agentMeta = asRecord(meta?.agentMeta);
|
||||
const record = asOptionalRecord(result);
|
||||
const meta = asOptionalRecord(record?.meta);
|
||||
const agentMeta = asOptionalRecord(meta?.agentMeta);
|
||||
return (
|
||||
normalizeOptionalString(agentMeta?.sessionFile) ?? normalizeOptionalString(meta?.sessionFile)
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
type SessionTranscriptTargetParams,
|
||||
} from "openclaw/plugin-sdk/session-transcript-runtime";
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -176,8 +176,9 @@ async function streamActiveMemoryTranscriptRecords(params: {
|
||||
}
|
||||
|
||||
function resolveToolResultMessage(value: unknown): Record<string, unknown> | undefined {
|
||||
const record = asRecord(value);
|
||||
const message = asRecord(record?.message) ?? (record?.role === "toolResult" ? record : undefined);
|
||||
const record = asOptionalRecord(value);
|
||||
const message =
|
||||
asOptionalRecord(record?.message) ?? (record?.role === "toolResult" ? record : undefined);
|
||||
return message && normalizeOptionalString(message.role) === "toolResult" ? message : undefined;
|
||||
}
|
||||
|
||||
@@ -192,8 +193,8 @@ function extractActiveMemorySearchDebugFromSessionRecord(
|
||||
if (toolName !== "memory_search" && toolName !== "memory_recall") {
|
||||
return undefined;
|
||||
}
|
||||
const details = asRecord(message.details);
|
||||
const debug = asRecord(details?.debug);
|
||||
const details = asOptionalRecord(message.details);
|
||||
const debug = asOptionalRecord(details?.debug);
|
||||
const warning = normalizeOptionalString(details?.warning);
|
||||
const action = normalizeOptionalString(details?.action);
|
||||
const error = normalizeOptionalString(details?.error);
|
||||
@@ -240,7 +241,7 @@ function hasUnavailableMemoryResultInSessionRecord(
|
||||
if (!toolName || !toolsAllow.includes(toolName)) {
|
||||
return false;
|
||||
}
|
||||
const details = asRecord(message.details);
|
||||
const details = asOptionalRecord(message.details);
|
||||
const unavailable = message.isError === true || readStructuredMemoryFailure(details) === true;
|
||||
if (unavailable) {
|
||||
return true;
|
||||
@@ -260,7 +261,7 @@ function hasTerminalUnavailableMemoryResultInSessionRecord(
|
||||
if (!toolName || !toolsAllow.includes(toolName)) {
|
||||
return false;
|
||||
}
|
||||
const details = asRecord(message.details);
|
||||
const details = asOptionalRecord(message.details);
|
||||
if (details?.disabled === true || details?.unavailable === true) {
|
||||
return true;
|
||||
}
|
||||
@@ -325,7 +326,7 @@ function hasUsableMemoryResultInSessionRecord(
|
||||
if (hasUnavailableMemoryResultInSessionRecord(value, toolsAllow)) {
|
||||
return false;
|
||||
}
|
||||
const details = asRecord(message.details);
|
||||
const details = asOptionalRecord(message.details);
|
||||
const content = extractTextContent(message.content);
|
||||
if (toolName === "memory_search") {
|
||||
if (Array.isArray(details?.results)) {
|
||||
@@ -372,7 +373,7 @@ function hasUsableMemoryResultInSessionRecord(
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
const parsed = asRecord(JSON.parse(content));
|
||||
const parsed = asOptionalRecord(JSON.parse(content));
|
||||
return (
|
||||
typeof parsed?.expandedSummaryCount === "number" &&
|
||||
Number.isFinite(parsed.expandedSummaryCount) &&
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
type MemoryEmbeddingProviderCreateOptions,
|
||||
} from "openclaw/plugin-sdk/memory-core-host-engine-embeddings";
|
||||
import {
|
||||
asOptionalRecord as asRecord,
|
||||
asOptionalRecord,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -263,9 +263,9 @@ function parseSingle(family: Family, raw: string): number[] {
|
||||
return asNumberArray(Array.isArray(data.embeddings) ? data.embeddings[0]?.embedding : null);
|
||||
case "twelvelabs": {
|
||||
if (Array.isArray(data.data)) {
|
||||
return asNumberArray(asRecord(data.data[0])?.embedding);
|
||||
return asNumberArray(asOptionalRecord(data.data[0])?.embedding);
|
||||
}
|
||||
const dataRecord = asRecord(data.data);
|
||||
const dataRecord = asOptionalRecord(data.data);
|
||||
if (dataRecord) {
|
||||
return asNumberArray(dataRecord.embedding);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ function parseCohereBatch(family: Family, raw: string): number[][] {
|
||||
throw malformedBedrockEmbeddingResponse();
|
||||
}
|
||||
if (family === "cohere-v4" && !Array.isArray(embeddings)) {
|
||||
const embeddingRecord = asRecord(embeddings);
|
||||
const embeddingRecord = asOptionalRecord(embeddings);
|
||||
if (!embeddingRecord) {
|
||||
throw malformedBedrockEmbeddingResponse();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ vi.mock("openclaw/plugin-sdk/session-transcript-runtime", () => ({
|
||||
}));
|
||||
|
||||
describe("importClaudeHistory", () => {
|
||||
it("falls back for invalid timestamps while preserving valid pre-epoch dates", async () => {
|
||||
it("preserves Date.parse semantics for valid strings and falls back for invalid values", async () => {
|
||||
appended.length = 0;
|
||||
const fallbackTimestamp = new Date("2026-07-18T12:00:00.000Z").getTime();
|
||||
vi.useFakeTimers();
|
||||
@@ -29,11 +29,13 @@ describe("importClaudeHistory", () => {
|
||||
await importClaudeHistory({
|
||||
items: [
|
||||
{ type: "userMessage", text: "invalid", timestamp: "not-a-date", uuid: "u-1" },
|
||||
{ type: "userMessage", text: "numeric year", timestamp: "2026", uuid: "u-2" },
|
||||
{ type: "userMessage", text: "numeric zero", timestamp: "0", uuid: "u-3" },
|
||||
{
|
||||
type: "userMessage",
|
||||
text: "pre-epoch",
|
||||
timestamp: "1969-12-31T23:59:59.000Z",
|
||||
uuid: "u-2",
|
||||
uuid: "u-4",
|
||||
},
|
||||
],
|
||||
threadId: "thread-1",
|
||||
@@ -47,8 +49,13 @@ describe("importClaudeHistory", () => {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
|
||||
expect(appended).toHaveLength(2);
|
||||
expect(appended.map((message) => message.timestamp)).toEqual([-1_000, fallbackTimestamp + 1]);
|
||||
expect(appended).toHaveLength(4);
|
||||
expect(appended.map((message) => message.timestamp)).toEqual([
|
||||
-1_000,
|
||||
Date.parse("0"),
|
||||
Date.parse("2026"),
|
||||
fallbackTimestamp + 3,
|
||||
]);
|
||||
expect(JSON.stringify(appended)).not.toContain('"timestamp":null');
|
||||
});
|
||||
|
||||
|
||||
@@ -544,6 +544,34 @@ describe("Claude session catalog", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves date-first parsing for numeric-looking index timestamps", async () => {
|
||||
const home = await createHome();
|
||||
const sessionId = "numeric-looking-timestamps";
|
||||
await writeProject({
|
||||
home,
|
||||
entries: [
|
||||
{
|
||||
sessionId,
|
||||
created: "0",
|
||||
modified: "2026",
|
||||
isSidechain: false,
|
||||
},
|
||||
],
|
||||
transcripts: { [sessionId]: [message(sessionId, "user", "timestamp contract", 1)] },
|
||||
});
|
||||
|
||||
await expect(listLocalClaudeSessionPage({}, home)).resolves.toMatchObject({
|
||||
sessions: [
|
||||
{
|
||||
threadId: sessionId,
|
||||
createdAt: Date.parse("0"),
|
||||
updatedAt: Date.parse("2026"),
|
||||
recencyAt: Date.parse("2026"),
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("adopts a local CLI row with a locked one-shot fork binding", async () => {
|
||||
const home = await createHome();
|
||||
process.env.HOME = home;
|
||||
|
||||
@@ -12,7 +12,7 @@ import type {
|
||||
SessionCatalogPullRequestSummary,
|
||||
SessionCatalogTranscriptItem,
|
||||
} from "openclaw/plugin-sdk/session-catalog";
|
||||
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { readClaudeDesktopCustomGroups } from "./claude-desktop-groups.js";
|
||||
import { CLAUDE_CLI_BACKEND_ID, CLAUDE_CLI_DEFAULT_MODEL_REF } from "./cli-constants.js";
|
||||
import {
|
||||
@@ -222,7 +222,7 @@ function cacheCatalogDiscovery(filePath: string, entry: CatalogDiscoveryCacheEnt
|
||||
setBoundedCache(catalogDiscoveryCache, filePath, entry, MAX_CATALOG_DISCOVERY_CACHE_ENTRIES);
|
||||
}
|
||||
|
||||
function optionalString(value: unknown, maxLength = MAX_STRING_LENGTH): string | undefined {
|
||||
function readBoundedString(value: unknown, maxLength = MAX_STRING_LENGTH): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -323,15 +323,10 @@ function isCliEntrypoint(value: unknown): value is string {
|
||||
return typeof value === "string" && CLI_ENTRYPOINTS.has(value);
|
||||
}
|
||||
|
||||
function timestampMs(value: unknown): number | undefined {
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Date.parse(value);
|
||||
return Number.isFinite(parsed) ? parsed : undefined;
|
||||
// Claude's persisted string timestamps are date expressions, including numeric-looking years.
|
||||
// Numeric fields are already millisecond values, so preserve that distinct mixed-input contract.
|
||||
function parseClaudeCatalogTimestampMs(value: unknown): number | undefined {
|
||||
return typeof value === "string" ? asFiniteNumber(Date.parse(value)) : asFiniteNumber(value);
|
||||
}
|
||||
|
||||
function isWithin(root: string, candidate: string): boolean {
|
||||
@@ -550,7 +545,7 @@ async function readDesktopMetadata(homeDir: string): Promise<{
|
||||
continue;
|
||||
}
|
||||
const metadata = raw as DesktopSessionMetadata;
|
||||
const cliSessionId = optionalString(metadata.cliSessionId, 256);
|
||||
const cliSessionId = readBoundedString(metadata.cliSessionId, 256);
|
||||
if (!cliSessionId) {
|
||||
continue;
|
||||
}
|
||||
@@ -560,7 +555,7 @@ async function readDesktopMetadata(homeDir: string): Promise<{
|
||||
continue;
|
||||
}
|
||||
if (!archived.has(cliSessionId)) {
|
||||
const localSessionId = optionalString(metadata.sessionId, 256);
|
||||
const localSessionId = readBoundedString(metadata.sessionId, 256);
|
||||
const customGroup = localSessionId ? customGroups.get(localSessionId) : undefined;
|
||||
active.set(cliSessionId, customGroup ? { ...metadata, customGroup } : metadata);
|
||||
}
|
||||
@@ -607,7 +602,7 @@ async function readIndexRecords(context: ClaudeSessionScanContext): Promise<{
|
||||
continue;
|
||||
}
|
||||
const entry = candidate as SessionIndexEntry;
|
||||
const sessionId = optionalString(entry.sessionId, 256);
|
||||
const sessionId = readBoundedString(entry.sessionId, 256);
|
||||
if (!sessionId) {
|
||||
continue;
|
||||
}
|
||||
@@ -621,7 +616,7 @@ async function readIndexRecords(context: ClaudeSessionScanContext): Promise<{
|
||||
if (entry.isSidechain === true) {
|
||||
return undefined;
|
||||
}
|
||||
const indexedPath = optionalString(entry.fullPath, MAX_STRING_LENGTH);
|
||||
const indexedPath = readBoundedString(entry.fullPath, MAX_STRING_LENGTH);
|
||||
return await safeSessionFileForScan(
|
||||
context,
|
||||
indexedPath ?? path.join(directory, `${sessionId}.jsonl`),
|
||||
@@ -640,21 +635,23 @@ async function readIndexRecords(context: ClaudeSessionScanContext): Promise<{
|
||||
if (!safeFile) {
|
||||
continue;
|
||||
}
|
||||
const createdAt = timestampMs(entry.created);
|
||||
const updatedAt = timestampMs(entry.modified) ?? timestampMs(entry.fileMtime);
|
||||
const summary = optionalString(entry.summary, 500);
|
||||
const firstPrompt = optionalString(entry.firstPrompt, 500);
|
||||
const createdAt = parseClaudeCatalogTimestampMs(entry.created);
|
||||
const updatedAt =
|
||||
parseClaudeCatalogTimestampMs(entry.modified) ??
|
||||
parseClaudeCatalogTimestampMs(entry.fileMtime);
|
||||
const summary = readBoundedString(entry.summary, 500);
|
||||
const firstPrompt = readBoundedString(entry.firstPrompt, 500);
|
||||
records.set(sessionId, {
|
||||
threadId: sessionId,
|
||||
name: summary ?? firstPrompt ?? null,
|
||||
cwd: optionalString(entry.projectPath),
|
||||
cwd: readBoundedString(entry.projectPath),
|
||||
status: "stored",
|
||||
...(createdAt !== undefined ? { createdAt } : {}),
|
||||
...(updatedAt !== undefined ? { updatedAt, recencyAt: updatedAt } : {}),
|
||||
source: "claude-cli",
|
||||
modelProvider: "anthropic",
|
||||
...(optionalString(entry.gitBranch, 500)
|
||||
? { gitBranch: optionalString(entry.gitBranch, 500) }
|
||||
...(readBoundedString(entry.gitBranch, 500)
|
||||
? { gitBranch: readBoundedString(entry.gitBranch, 500) }
|
||||
: {}),
|
||||
archived: false,
|
||||
filePath: safeFile.filePath,
|
||||
@@ -800,7 +797,7 @@ async function discoverCliRecords(
|
||||
return false;
|
||||
}
|
||||
if (raw.type === "ai-title") {
|
||||
aiTitle = optionalString(raw.aiTitle, 500) ?? aiTitle;
|
||||
aiTitle = readBoundedString(raw.aiTitle, 500) ?? aiTitle;
|
||||
return false;
|
||||
}
|
||||
if (typeof raw.entrypoint === "string" && !isCliEntrypoint(raw.entrypoint)) {
|
||||
@@ -820,23 +817,23 @@ async function discoverCliRecords(
|
||||
}
|
||||
const fragments: string[] = [];
|
||||
collectTranscriptText(raw.message.content, fragments);
|
||||
const firstPrompt = optionalString(fragments[0], 500);
|
||||
const createdAt = timestampMs(raw.timestamp);
|
||||
const firstPrompt = readBoundedString(fragments[0], 500);
|
||||
const createdAt = parseClaudeCatalogTimestampMs(raw.timestamp);
|
||||
records.set(sessionId, {
|
||||
threadId: sessionId,
|
||||
name: aiTitle ?? firstPrompt ?? null,
|
||||
cwd: optionalString(raw.cwd),
|
||||
cwd: readBoundedString(raw.cwd),
|
||||
status: "stored",
|
||||
...(createdAt !== undefined ? { createdAt } : {}),
|
||||
updatedAt: stat.mtimeMs,
|
||||
recencyAt: stat.mtimeMs,
|
||||
source: "claude-cli",
|
||||
modelProvider: "anthropic",
|
||||
...(optionalString(raw.version, 256)
|
||||
? { cliVersion: optionalString(raw.version, 256) }
|
||||
...(readBoundedString(raw.version, 256)
|
||||
? { cliVersion: readBoundedString(raw.version, 256) }
|
||||
: {}),
|
||||
...(optionalString(raw.gitBranch, 500)
|
||||
? { gitBranch: optionalString(raw.gitBranch, 500) }
|
||||
...(readBoundedString(raw.gitBranch, 500)
|
||||
? { gitBranch: readBoundedString(raw.gitBranch, 500) }
|
||||
: {}),
|
||||
archived: false,
|
||||
filePath,
|
||||
@@ -937,9 +934,9 @@ async function scanClaudeSessions(
|
||||
if (!filePath) {
|
||||
continue;
|
||||
}
|
||||
const createdAt = timestampMs(metadata.createdAt) ?? existing?.createdAt;
|
||||
const updatedAt = timestampMs(metadata.lastActivityAt) ?? existing?.updatedAt;
|
||||
const customGroup = optionalString(metadata.customGroup, 500);
|
||||
const createdAt = parseClaudeCatalogTimestampMs(metadata.createdAt) ?? existing?.createdAt;
|
||||
const updatedAt = parseClaudeCatalogTimestampMs(metadata.lastActivityAt) ?? existing?.updatedAt;
|
||||
const customGroup = readBoundedString(metadata.customGroup, 500);
|
||||
const pullRequest = desktopPullRequestSummary(metadata);
|
||||
records.set(sessionId, {
|
||||
...(existing ?? {
|
||||
@@ -948,8 +945,9 @@ async function scanClaudeSessions(
|
||||
modelProvider: "anthropic" as const,
|
||||
archived: false as const,
|
||||
}),
|
||||
name: optionalString(metadata.title, 500) ?? existing?.name ?? null,
|
||||
cwd: optionalString(metadata.cwd) ?? optionalString(metadata.originCwd) ?? existing?.cwd,
|
||||
name: readBoundedString(metadata.title, 500) ?? existing?.name ?? null,
|
||||
cwd:
|
||||
readBoundedString(metadata.cwd) ?? readBoundedString(metadata.originCwd) ?? existing?.cwd,
|
||||
...(createdAt !== undefined ? { createdAt } : {}),
|
||||
...(updatedAt !== undefined ? { updatedAt, recencyAt: updatedAt } : {}),
|
||||
...(customGroup ? { customGroup } : {}),
|
||||
@@ -1090,7 +1088,7 @@ function readListParams(value: unknown): {
|
||||
throw new ClaudeCatalogParamsError(`unknown Claude session catalog parameter: ${unknown}`);
|
||||
}
|
||||
const cursor = readOptionalCursor(value.cursor, "catalog");
|
||||
const searchTerm = optionalString(value.searchTerm, MAX_SEARCH_LENGTH);
|
||||
const searchTerm = readBoundedString(value.searchTerm, MAX_SEARCH_LENGTH);
|
||||
return {
|
||||
limit: readLimit(value.limit, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT),
|
||||
...(cursor ? { cursor } : {}),
|
||||
@@ -1140,7 +1138,7 @@ function readTranscriptParams(
|
||||
if (unknown) {
|
||||
throw new ClaudeCatalogParamsError(`unknown Claude session read parameter: ${unknown}`);
|
||||
}
|
||||
const threadId = optionalString(value.threadId, 256);
|
||||
const threadId = readBoundedString(value.threadId, 256);
|
||||
if (!threadId || !/^[A-Za-z0-9._:-]+$/.test(threadId)) {
|
||||
throw new ClaudeCatalogParamsError("threadId is invalid");
|
||||
}
|
||||
@@ -1208,7 +1206,7 @@ export async function readLocalClaudeTranscriptPage(
|
||||
const segment = chunk.subarray(index + 1, right);
|
||||
if (segment.length > 0 || fragments.length > 0) {
|
||||
const line = Buffer.concat([segment, ...fragments.toReversed()]);
|
||||
const item = parseTranscriptLine(line, optionalString);
|
||||
const item = parseTranscriptLine(line, readBoundedString);
|
||||
fragments = [];
|
||||
if (item) {
|
||||
found.push({ item, start: position + index + 1 });
|
||||
@@ -1226,7 +1224,7 @@ export async function readLocalClaudeTranscriptPage(
|
||||
if (position === 0) {
|
||||
if (prefix.length > 0 || fragments.length > 0) {
|
||||
const line = Buffer.concat([prefix, ...fragments.toReversed()]);
|
||||
const item = parseTranscriptLine(line, optionalString);
|
||||
const item = parseTranscriptLine(line, readBoundedString);
|
||||
if (item) {
|
||||
found.push({ item, start: 0 });
|
||||
}
|
||||
@@ -1294,7 +1292,7 @@ function parseCatalogPage(value: unknown): ClaudeSessionCatalogPage {
|
||||
if (!isRecord(candidate)) {
|
||||
throw new Error("Claude node returned an invalid session");
|
||||
}
|
||||
const threadId = optionalString(candidate.threadId, 256);
|
||||
const threadId = readBoundedString(candidate.threadId, 256);
|
||||
const source = candidate.source;
|
||||
if (
|
||||
!threadId ||
|
||||
@@ -1309,7 +1307,7 @@ function parseCatalogPage(value: unknown): ClaudeSessionCatalogPage {
|
||||
if (!(key in candidate)) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = optionalString(candidate[key], maxLength);
|
||||
const parsed = readBoundedString(candidate[key], maxLength);
|
||||
if (!parsed) {
|
||||
throw new Error("Claude node returned an invalid session");
|
||||
}
|
||||
@@ -1385,7 +1383,7 @@ function parseGatewayQuery(value: unknown): {
|
||||
if (unknown) {
|
||||
throw new ClaudeCatalogParamsError(`unknown Claude session catalog parameter: ${unknown}`);
|
||||
}
|
||||
const search = optionalString(value.search, MAX_SEARCH_LENGTH);
|
||||
const search = readBoundedString(value.search, MAX_SEARCH_LENGTH);
|
||||
let hostIds: string[] | undefined;
|
||||
if (value.hostIds !== undefined) {
|
||||
if (!Array.isArray(value.hostIds) || value.hostIds.length > MAX_HOSTS) {
|
||||
@@ -1394,7 +1392,7 @@ function parseGatewayQuery(value: unknown): {
|
||||
hostIds = [
|
||||
...new Set(
|
||||
value.hostIds.map((hostId) => {
|
||||
const normalized = optionalString(hostId, 256);
|
||||
const normalized = readBoundedString(hostId, 256);
|
||||
if (
|
||||
!normalized ||
|
||||
(normalized !== CLAUDE_LOCAL_SESSION_HOST_ID && !normalized.startsWith("node:"))
|
||||
|
||||
@@ -12,10 +12,10 @@ import type {
|
||||
} from "openclaw/plugin-sdk/speech-core";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
asObject,
|
||||
resolveSpeechProviderApiKey,
|
||||
trimToUndefined,
|
||||
} from "openclaw/plugin-sdk/speech-core";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
azureSpeechTTS,
|
||||
DEFAULT_AZURE_SPEECH_AUDIO_FORMAT,
|
||||
@@ -68,12 +68,12 @@ function readAzureSpeechEnvEndpoint(): string | undefined {
|
||||
function resolveAzureSpeechConfigRecord(
|
||||
rawConfig: Record<string, unknown>,
|
||||
): Record<string, unknown> | undefined {
|
||||
const providers = asObject(rawConfig.providers);
|
||||
const providers = asOptionalRecord(rawConfig.providers);
|
||||
return (
|
||||
asObject(providers?.["azure-speech"]) ??
|
||||
asObject(providers?.azure) ??
|
||||
asObject(rawConfig["azure-speech"]) ??
|
||||
asObject(rawConfig.azure)
|
||||
asOptionalRecord(providers?.["azure-speech"]) ??
|
||||
asOptionalRecord(providers?.azure) ??
|
||||
asOptionalRecord(rawConfig["azure-speech"]) ??
|
||||
asOptionalRecord(rawConfig.azure)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,12 @@ import {
|
||||
readProviderJsonResponse,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import type { SpeechVoiceOption } from "openclaw/plugin-sdk/speech-core";
|
||||
import { asObject, trimToUndefined } from "openclaw/plugin-sdk/speech-core";
|
||||
import { trimToUndefined } from "openclaw/plugin-sdk/speech-core";
|
||||
import {
|
||||
fetchWithSsrFGuard,
|
||||
ssrfPolicyFromHttpBaseUrlAllowedHostname,
|
||||
} from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
/** Default Azure Speech neural voice. */
|
||||
export const DEFAULT_AZURE_SPEECH_VOICE = "en-US-JennyNeural";
|
||||
@@ -157,12 +158,12 @@ export async function listAzureSpeechVoices(params: {
|
||||
const voices = await readProviderJsonResponse<unknown>(response, "azure-speech.voices");
|
||||
return Array.isArray(voices)
|
||||
? voices.flatMap((value) => {
|
||||
const voice = asObject(value);
|
||||
const voice = asOptionalRecord(value);
|
||||
const id = trimToUndefined(voice?.ShortName);
|
||||
if (!voice || !id || isDeprecatedVoice(voice)) {
|
||||
return [];
|
||||
}
|
||||
const voiceTag = asObject(voice.VoiceTag);
|
||||
const voiceTag = asOptionalRecord(voice.VoiceTag);
|
||||
const tailoredScenarios = readAzureVoiceTagStrings(voiceTag?.TailoredScenarios);
|
||||
const personalities = readAzureVoiceTagStrings(voiceTag?.VoicePersonalities);
|
||||
return [
|
||||
|
||||
@@ -47,7 +47,7 @@ function hasOnlyKeys(value: Record<string, unknown>, allowed: Set<string>): bool
|
||||
return Object.keys(value).every((key) => allowed.has(key));
|
||||
}
|
||||
|
||||
function optionalString(value: unknown, maxLength: number): string | undefined {
|
||||
function readBoundedString(value: unknown, maxLength: number): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -96,19 +96,19 @@ export function parseBeamUpload(
|
||||
if (value.version !== 1) {
|
||||
return { ok: false, error: "version must be 1" };
|
||||
}
|
||||
const beamId = optionalString(value.beamId, 64);
|
||||
const beamId = readBoundedString(value.beamId, 64);
|
||||
if (!beamId || !/^[a-f0-9]{32}$/i.test(beamId)) {
|
||||
return { ok: false, error: "beamId must be a 32-character hex id" };
|
||||
}
|
||||
const source = optionalString(value.source, 32);
|
||||
const source = readBoundedString(value.source, 32);
|
||||
if (!source || !/^[a-z0-9._-]+$/i.test(source)) {
|
||||
return { ok: false, error: "source must be a short identifier" };
|
||||
}
|
||||
const title = optionalString(value.title, 160);
|
||||
const title = readBoundedString(value.title, 160);
|
||||
if (!title) {
|
||||
return { ok: false, error: "title must be a non-empty string" };
|
||||
}
|
||||
const updatedAt = optionalString(value.updatedAt, 64);
|
||||
const updatedAt = readBoundedString(value.updatedAt, 64);
|
||||
if (!updatedAt || !isIsoTimestamp(updatedAt)) {
|
||||
return { ok: false, error: "updatedAt must be an ISO timestamp" };
|
||||
}
|
||||
@@ -118,7 +118,8 @@ export function parseBeamUpload(
|
||||
if (value.truncated !== undefined && typeof value.truncated !== "boolean") {
|
||||
return { ok: false, error: "truncated must be a boolean" };
|
||||
}
|
||||
const hookEvent = value.hookEvent === undefined ? undefined : optionalString(value.hookEvent, 64);
|
||||
const hookEvent =
|
||||
value.hookEvent === undefined ? undefined : readBoundedString(value.hookEvent, 64);
|
||||
if (value.hookEvent !== undefined && !hookEvent) {
|
||||
return { ok: false, error: "hookEvent must be a short string" };
|
||||
}
|
||||
@@ -140,7 +141,7 @@ export function parseBeamUpload(
|
||||
) {
|
||||
return { ok: false, error: "transcript item type is invalid" };
|
||||
}
|
||||
const text = optionalString(rawItem.text, BEAM_MAX_ITEM_CHARS);
|
||||
const text = readBoundedString(rawItem.text, BEAM_MAX_ITEM_CHARS);
|
||||
if (!text) {
|
||||
return {
|
||||
ok: false,
|
||||
|
||||
@@ -25,7 +25,7 @@ const {
|
||||
} = mocks;
|
||||
const dnsLabelEncoder = new TextEncoder();
|
||||
|
||||
const asString = (value: unknown, fallback: string) =>
|
||||
const stringOrFallback = (value: unknown, fallback: string) =>
|
||||
typeof value === "string" && value.trim() ? value : fallback;
|
||||
|
||||
function expectDnsLabelByteLength(value: string, expected: number) {
|
||||
@@ -81,8 +81,9 @@ function mockCiaoService(params?: {
|
||||
advertise,
|
||||
destroy,
|
||||
on,
|
||||
getFQDN: () => `${asString(options.type, "service")}.${asString(options.domain, "local")}.`,
|
||||
getHostname: () => asString(options.hostname, "unknown"),
|
||||
getFQDN: () =>
|
||||
`${stringOrFallback(options.type, "service")}.${stringOrFallback(options.domain, "local")}.`,
|
||||
getHostname: () => stringOrFallback(options.hostname, "unknown"),
|
||||
getPort: () => Number(options.port ?? -1),
|
||||
};
|
||||
Object.defineProperty(service, "serviceState", {
|
||||
@@ -173,7 +174,7 @@ describe("gateway bonjour advertiser", () => {
|
||||
expect(createService).toHaveBeenCalledTimes(1);
|
||||
const [gatewayCall] = createService.mock.calls as Array<[Record<string, unknown>]>;
|
||||
expect(gatewayCall?.[0]?.type).toBe("openclaw-gw");
|
||||
const gatewayType = asString(gatewayCall?.[0]?.type, "");
|
||||
const gatewayType = stringOrFallback(gatewayCall?.[0]?.type, "");
|
||||
expect(gatewayType.length).toBeLessThanOrEqual(15);
|
||||
expect(gatewayCall?.[0]?.port).toBe(18789);
|
||||
expect(gatewayCall?.[0]?.domain).toBe("local");
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
*/
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { isRecord } from "./src/record-shared.js";
|
||||
import {
|
||||
isRecord,
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
function listContainsBrowser(value: unknown): boolean {
|
||||
return (
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { asNullableRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
assertBrowserProxyFileBytesWithinLimits,
|
||||
assertBrowserProxyFileCountWithinLimit,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
type BrowserProxyUploadV1,
|
||||
} from "./browser-proxy-envelope.js";
|
||||
import { DEFAULT_UPLOAD_DIR, resolveExistingUploadPaths } from "./browser/paths.js";
|
||||
import { asRecord } from "./record-shared.js";
|
||||
|
||||
const logger = createSubsystemLogger("browser");
|
||||
const BROWSER_PROXY_UPLOAD_ROOT_NAME = ".proxy-uploads";
|
||||
@@ -73,7 +73,7 @@ export function isBrowserProxyUploadRequest(params: {
|
||||
if (!isFileChooserRequest(params.method, params.path)) {
|
||||
return false;
|
||||
}
|
||||
const body = asRecord(params.body);
|
||||
const body = asNullableRecord(params.body);
|
||||
return Boolean(body && Array.isArray(body.paths) && body.paths.length > 0);
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ export async function prepareBrowserProxyUploadRequest(params: {
|
||||
if (!isFileChooserRequest(params.method, params.path)) {
|
||||
return { body: params.body };
|
||||
}
|
||||
const body = asRecord(params.body);
|
||||
const body = asNullableRecord(params.body);
|
||||
if (!body) {
|
||||
return { body: params.body };
|
||||
}
|
||||
@@ -497,7 +497,7 @@ export async function stageBrowserProxyUploadRequest(params: {
|
||||
if (!isFileChooserRequest(params.method, params.path)) {
|
||||
throw new Error("INVALID_REQUEST: browser proxy upload requires the file chooser route");
|
||||
}
|
||||
const body = asRecord(params.body);
|
||||
const body = asNullableRecord(params.body);
|
||||
if (!body || Object.hasOwn(body, "paths")) {
|
||||
throw new Error("INVALID_REQUEST: browser proxy upload body must omit paths");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* Session tracking for tabs created through the browser tool.
|
||||
*/
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { BrowserTabOwnership } from "./browser/client.types.js";
|
||||
|
||||
type SessionTabParams = {
|
||||
@@ -19,10 +20,6 @@ type SessionTabRegistry = {
|
||||
untrackSessionBrowserTab: (params: SessionTabParams) => void;
|
||||
};
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readOpenedTab(result: unknown): {
|
||||
targetId?: string;
|
||||
aliases: string[];
|
||||
@@ -33,14 +30,14 @@ function readOpenedTab(result: unknown): {
|
||||
return { aliases: [] };
|
||||
}
|
||||
const opened = result as Record<string, unknown>;
|
||||
const targetId = readString(opened.targetId);
|
||||
const targetId = normalizeOptionalString(opened.targetId);
|
||||
const aliases = [
|
||||
targetId,
|
||||
readString(opened.tabId),
|
||||
readString(opened.label),
|
||||
readString(opened.suggestedTargetId),
|
||||
normalizeOptionalString(opened.tabId),
|
||||
normalizeOptionalString(opened.label),
|
||||
normalizeOptionalString(opened.suggestedTargetId),
|
||||
].filter((alias): alias is string => Boolean(alias));
|
||||
const profile = readString(opened.resolvedProfile);
|
||||
const profile = normalizeOptionalString(opened.resolvedProfile);
|
||||
const rawOwnership =
|
||||
opened.ownership && typeof opened.ownership === "object"
|
||||
? (opened.ownership as BrowserTabOwnership)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Parses Chrome MCP tool results and formats redacted tool failures.
|
||||
import path from "node:path";
|
||||
import {
|
||||
asNullableRecord,
|
||||
normalizeOptionalString,
|
||||
readStringValue,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { toErrorObject } from "../infra/errors.js";
|
||||
import { redactToolPayloadText } from "../logging/redact.js";
|
||||
import { asRecord } from "../record-shared.js";
|
||||
import { redactCdpUrl } from "./cdp.helpers.js";
|
||||
import {
|
||||
CHROME_CONNECTION_TOOL_ERROR_RE,
|
||||
@@ -28,7 +28,7 @@ function asPages(value: unknown): ChromeMcpStructuredPage[] {
|
||||
}
|
||||
const out: ChromeMcpStructuredPage[] = [];
|
||||
for (const entry of value) {
|
||||
const record = asRecord(entry);
|
||||
const record = asNullableRecord(entry);
|
||||
if (!record || typeof record.id !== "number") {
|
||||
continue;
|
||||
}
|
||||
@@ -42,14 +42,14 @@ function asPages(value: unknown): ChromeMcpStructuredPage[] {
|
||||
}
|
||||
|
||||
function extractStructuredContent(result: ChromeMcpToolResult): Record<string, unknown> {
|
||||
return asRecord(result.structuredContent) ?? {};
|
||||
return asNullableRecord(result.structuredContent) ?? {};
|
||||
}
|
||||
|
||||
function extractTextContent(result: ChromeMcpToolResult): string[] {
|
||||
const content = Array.isArray(result.content) ? result.content : [];
|
||||
return content
|
||||
.map((entry) => {
|
||||
const record = asRecord(entry);
|
||||
const record = asNullableRecord(entry);
|
||||
return record && typeof record.text === "string" ? record.text : "";
|
||||
})
|
||||
.filter(Boolean);
|
||||
@@ -80,7 +80,7 @@ export function extractStructuredPages(result: ChromeMcpToolResult): ChromeMcpSt
|
||||
|
||||
export function extractSnapshot(result: ChromeMcpToolResult): ChromeMcpSnapshotNode {
|
||||
const structured = extractStructuredContent(result);
|
||||
const snapshot = asRecord(structured.snapshot);
|
||||
const snapshot = asNullableRecord(structured.snapshot);
|
||||
if (!snapshot) {
|
||||
throw new Error("Chrome MCP snapshot response was missing structured snapshot data.");
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* and compact AI snapshots with stable refs and duplicate tracking.
|
||||
*/
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { normalizeString } from "../record-shared.js";
|
||||
import type { SnapshotAriaNode } from "./client.types.js";
|
||||
import type { RoleRefMap, RoleSnapshotOptions } from "./pw-role-snapshot.js";
|
||||
import { CONTENT_ROLES, INTERACTIVE_ROLES, STRUCTURAL_ROLES } from "./snapshot-roles.js";
|
||||
@@ -20,6 +19,13 @@ export type ChromeMcpSnapshotNode = {
|
||||
children?: ChromeMcpSnapshotNode[];
|
||||
};
|
||||
|
||||
function normalizeSnapshotString(value: unknown): string | undefined {
|
||||
if (typeof value === "string") {
|
||||
return value.trim() || undefined;
|
||||
}
|
||||
return typeof value === "number" || typeof value === "boolean" ? String(value) : undefined;
|
||||
}
|
||||
|
||||
function normalizeRole(node: ChromeMcpSnapshotNode): string {
|
||||
const role = normalizeLowercaseStringOrEmpty(node.role);
|
||||
return role || "generic";
|
||||
@@ -94,14 +100,14 @@ export function flattenChromeMcpSnapshotToAriaNodes(
|
||||
if (out.length >= boundedLimit) {
|
||||
return;
|
||||
}
|
||||
const ref = normalizeString(node.id);
|
||||
const ref = normalizeSnapshotString(node.id);
|
||||
if (ref) {
|
||||
out.push({
|
||||
ref,
|
||||
role: normalizeRole(node),
|
||||
name: normalizeString(node.name) ?? "",
|
||||
value: normalizeString(node.value),
|
||||
description: normalizeString(node.description),
|
||||
name: normalizeSnapshotString(node.name) ?? "",
|
||||
value: normalizeSnapshotString(node.value),
|
||||
description: normalizeSnapshotString(node.description),
|
||||
depth,
|
||||
});
|
||||
}
|
||||
@@ -131,9 +137,9 @@ export function buildAiSnapshotFromChromeMcpSnapshot(params: {
|
||||
|
||||
const visit = (node: ChromeMcpSnapshotNode, depth: number) => {
|
||||
const role = normalizeRole(node);
|
||||
const name = normalizeString(node.name);
|
||||
const value = normalizeString(node.value);
|
||||
const description = normalizeString(node.description);
|
||||
const name = normalizeSnapshotString(node.name);
|
||||
const value = normalizeSnapshotString(node.value);
|
||||
const description = normalizeSnapshotString(node.description);
|
||||
const maxDepth = params.options?.maxDepth;
|
||||
if (maxDepth !== undefined && depth > maxDepth) {
|
||||
return;
|
||||
@@ -145,7 +151,7 @@ export function buildAiSnapshotFromChromeMcpSnapshot(params: {
|
||||
if (name) {
|
||||
line += ` "${escapeQuoted(name)}"`;
|
||||
}
|
||||
const ref = normalizeString(node.id);
|
||||
const ref = normalizeSnapshotString(node.id);
|
||||
if (ref && shouldCreateRef(role, name)) {
|
||||
const nth = registerRef(tracker, ref, role, name);
|
||||
refs[ref] = nth === undefined ? { role, name } : { role, name, nth };
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { asNullableRecord, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
/**
|
||||
* Managed Chrome graphics diagnostics.
|
||||
*
|
||||
@@ -5,7 +6,6 @@
|
||||
* exact RunningChrome instance that owns the process.
|
||||
*/
|
||||
import type { SsrFPolicy } from "../infra/net/ssrf.js";
|
||||
import { asRecord, isRecord } from "../record-shared.js";
|
||||
import { redactCdpErrorText, withCdpSocket } from "./cdp.helpers.js";
|
||||
import { getChromeWebSocketUrl, type RunningChrome } from "./chrome.js";
|
||||
import type {
|
||||
@@ -23,16 +23,16 @@ type ChromeGraphicsProbeOptions = {
|
||||
ssrfPolicy?: SsrFPolicy;
|
||||
};
|
||||
|
||||
function readString(value: unknown): string {
|
||||
function readChromeString(value: unknown): string {
|
||||
return typeof value === "string" ? value.trim() : "";
|
||||
}
|
||||
|
||||
function readNumber(value: unknown): number {
|
||||
function readChromeNumber(value: unknown): number {
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
||||
}
|
||||
|
||||
function readStringRecord(value: unknown): Record<string, string> {
|
||||
const record = asRecord(value);
|
||||
const record = asNullableRecord(value);
|
||||
if (!record) {
|
||||
return {};
|
||||
}
|
||||
@@ -49,10 +49,10 @@ function readStringArray(value: unknown): string[] {
|
||||
}
|
||||
|
||||
function readSize(value: unknown): { width: number; height: number } {
|
||||
const size = asRecord(value);
|
||||
const size = asNullableRecord(value);
|
||||
return {
|
||||
width: readNumber(size?.width),
|
||||
height: readNumber(size?.height),
|
||||
width: readChromeNumber(size?.width),
|
||||
height: readChromeNumber(size?.height),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,18 +62,18 @@ function readRecordArray(value: unknown): Record<string, unknown>[] {
|
||||
|
||||
function readDevices(value: unknown): BrowserGraphicsDevice[] {
|
||||
return readRecordArray(value).map((device) => ({
|
||||
vendorId: readNumber(device.vendorId),
|
||||
deviceId: readNumber(device.deviceId),
|
||||
vendor: readString(device.vendorString),
|
||||
device: readString(device.deviceString),
|
||||
driverVendor: readString(device.driverVendor),
|
||||
driverVersion: readString(device.driverVersion),
|
||||
vendorId: readChromeNumber(device.vendorId),
|
||||
deviceId: readChromeNumber(device.deviceId),
|
||||
vendor: readChromeString(device.vendorString),
|
||||
device: readChromeString(device.deviceString),
|
||||
driverVendor: readChromeString(device.driverVendor),
|
||||
driverVersion: readChromeString(device.driverVersion),
|
||||
}));
|
||||
}
|
||||
|
||||
function readVideoDecoding(value: unknown): BrowserVideoDecodeCapability[] {
|
||||
return readRecordArray(value).map((capability) => ({
|
||||
profile: readString(capability.profile),
|
||||
profile: readChromeString(capability.profile),
|
||||
minResolution: readSize(capability.minResolution),
|
||||
maxResolution: readSize(capability.maxResolution),
|
||||
}));
|
||||
@@ -81,10 +81,10 @@ function readVideoDecoding(value: unknown): BrowserVideoDecodeCapability[] {
|
||||
|
||||
function readVideoEncoding(value: unknown): BrowserVideoEncodeCapability[] {
|
||||
return readRecordArray(value).map((capability) => ({
|
||||
profile: readString(capability.profile),
|
||||
profile: readChromeString(capability.profile),
|
||||
maxResolution: readSize(capability.maxResolution),
|
||||
maxFramerateNumerator: readNumber(capability.maxFramerateNumerator),
|
||||
maxFramerateDenominator: readNumber(capability.maxFramerateDenominator),
|
||||
maxFramerateNumerator: readChromeNumber(capability.maxFramerateNumerator),
|
||||
maxFramerateDenominator: readChromeNumber(capability.maxFramerateDenominator),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ function firstAttribute(
|
||||
names: readonly string[],
|
||||
): string | null {
|
||||
for (const name of names) {
|
||||
const value = readString(attributes[name]);
|
||||
const value = readChromeString(attributes[name]);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
@@ -133,8 +133,8 @@ function normalizeChromeGraphicsInfo(
|
||||
value: unknown,
|
||||
observedAt = Date.now(),
|
||||
): BrowserGraphicsDiagnostics {
|
||||
const result = asRecord(value);
|
||||
const gpu = asRecord(result?.gpu);
|
||||
const result = asNullableRecord(value);
|
||||
const gpu = asNullableRecord(result?.gpu);
|
||||
if (!gpu) {
|
||||
return {
|
||||
status: "unavailable",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { loadJsonFile, saveJsonFile } from "openclaw/plugin-sdk/json-store";
|
||||
import { asRecord } from "../record-shared.js";
|
||||
import { asNullableRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
DEFAULT_OPENCLAW_BROWSER_COLOR,
|
||||
DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
|
||||
@@ -20,7 +20,7 @@ function decoratedMarkerPath(userDataDir: string) {
|
||||
}
|
||||
|
||||
function safeReadJson(filePath: string): Record<string, unknown> | null {
|
||||
return asRecord(loadJsonFile(filePath));
|
||||
return asNullableRecord(loadJsonFile(filePath));
|
||||
}
|
||||
|
||||
function safeWriteJson(filePath: string, data: Record<string, unknown>) {
|
||||
@@ -28,11 +28,14 @@ function safeWriteJson(filePath: string, data: Record<string, unknown>) {
|
||||
}
|
||||
|
||||
function readNestedRecord(root: unknown, key: string): Record<string, unknown> | null {
|
||||
return asRecord(asRecord(root)?.[key]);
|
||||
return asNullableRecord(asNullableRecord(root)?.[key]);
|
||||
}
|
||||
|
||||
function readDefaultProfileInfo(localState: unknown): Record<string, unknown> | null {
|
||||
return readNestedRecord(readNestedRecord(asRecord(localState)?.profile, "info_cache"), "Default");
|
||||
return readNestedRecord(
|
||||
readNestedRecord(asNullableRecord(localState)?.profile, "info_cache"),
|
||||
"Default",
|
||||
);
|
||||
}
|
||||
|
||||
function setDeep(obj: Record<string, unknown>, keys: string[], value: unknown) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
||||
import { asRecord } from "../record-shared.js";
|
||||
import { asNullableRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
type BrowserNativeBootstrapResponse,
|
||||
decodeBrowserNativeFrame,
|
||||
@@ -103,10 +103,11 @@ async function validateNativeManifest(params: {
|
||||
throw new Error("launcher is outside the managed root");
|
||||
}
|
||||
const parsed: unknown = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
||||
if (!asRecord(parsed)) {
|
||||
const manifestRecord = asNullableRecord(parsed);
|
||||
if (!manifestRecord) {
|
||||
throw new Error("invalid manifest");
|
||||
}
|
||||
const manifest = parsed as NativeHostManifest;
|
||||
const manifest = manifestRecord as NativeHostManifest;
|
||||
const expectedOrigins = validateExpectedOrigins(params.expectedOrigins);
|
||||
const keys = ["name", "description", "path", "type", "allowed_origins"];
|
||||
if (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os from "node:os";
|
||||
import { asRecord } from "../record-shared.js";
|
||||
import { asNullableRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
const BROWSER_NATIVE_REQUEST_MAX_BYTES = 4 * 1024;
|
||||
const BROWSER_NATIVE_RESPONSE_MAX_BYTES = 1024 * 1024;
|
||||
@@ -38,7 +38,7 @@ function rootJsonKeys(raw: string): string[] | null {
|
||||
index += 1;
|
||||
}
|
||||
};
|
||||
const readString = (): string | null => {
|
||||
const readJsonString = (): string | null => {
|
||||
if (raw[index] !== '"') {
|
||||
return null;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ function rootJsonKeys(raw: string): string[] | null {
|
||||
if (raw[index] === "}") {
|
||||
return keys;
|
||||
}
|
||||
const key = readString();
|
||||
const key = readJsonString();
|
||||
if (key === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -149,7 +149,7 @@ function parseBrowserNativeRequest(raw: string): BrowserNativeBootstrapRequest |
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
const record = asRecord(parsed);
|
||||
const record = asNullableRecord(parsed);
|
||||
return record?.v === 1 && record.op === "bootstrap" && isCanonicalNonce(record.nonce)
|
||||
? { v: 1, op: "bootstrap", nonce: record.nonce }
|
||||
: null;
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asNullableRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
parseBrowserMajorVersion,
|
||||
readBrowserVersion,
|
||||
@@ -20,7 +23,6 @@ import {
|
||||
import { listSystemProfiles } from "./browser/system-profiles.js";
|
||||
import { movePathToTrash } from "./browser/trash.js";
|
||||
import type { OpenClawConfig } from "./config/config.js";
|
||||
import { asRecord } from "./record-shared.js";
|
||||
import { formatCliCommand, note } from "./sdk-setup-tools.js";
|
||||
import { CONFIG_DIR, resolveUserPath } from "./utils.js";
|
||||
|
||||
@@ -57,7 +59,7 @@ type BrowserDoctorFilesystemDeps = {
|
||||
};
|
||||
|
||||
function collectChromeMcpProfiles(cfg: OpenClawConfig): ExistingSessionProfile[] {
|
||||
const browser = asRecord(cfg.browser);
|
||||
const browser = asNullableRecord(cfg.browser);
|
||||
if (!browser) {
|
||||
return [];
|
||||
}
|
||||
@@ -68,13 +70,13 @@ function collectChromeMcpProfiles(cfg: OpenClawConfig): ExistingSessionProfile[]
|
||||
profiles.set("user", { name: "user" });
|
||||
}
|
||||
|
||||
const configuredProfiles = asRecord(browser.profiles);
|
||||
const configuredProfiles = asNullableRecord(browser.profiles);
|
||||
if (!configuredProfiles) {
|
||||
return [...profiles.values()].toSorted((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
for (const [profileName, rawProfile] of Object.entries(configuredProfiles)) {
|
||||
const profile = asRecord(rawProfile);
|
||||
const profile = asNullableRecord(rawProfile);
|
||||
const driver = normalizeOptionalString(profile?.driver) ?? "";
|
||||
if (driver === "existing-session") {
|
||||
profiles.set(profileName, {
|
||||
@@ -88,7 +90,7 @@ function collectChromeMcpProfiles(cfg: OpenClawConfig): ExistingSessionProfile[]
|
||||
}
|
||||
|
||||
function collectManagedProfiles(cfg: OpenClawConfig): ManagedProfile[] {
|
||||
const browser = asRecord(cfg.browser);
|
||||
const browser = asNullableRecord(cfg.browser);
|
||||
if (!browser) {
|
||||
return [];
|
||||
}
|
||||
@@ -99,13 +101,13 @@ function collectManagedProfiles(cfg: OpenClawConfig): ManagedProfile[] {
|
||||
profiles.set(defaultProfile, { name: defaultProfile });
|
||||
}
|
||||
|
||||
const configuredProfiles = asRecord(browser.profiles);
|
||||
const configuredProfiles = asNullableRecord(browser.profiles);
|
||||
if (!configuredProfiles) {
|
||||
return [...profiles.values()].toSorted((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
for (const [profileName, rawProfile] of Object.entries(configuredProfiles)) {
|
||||
const profile = asRecord(rawProfile);
|
||||
const profile = asNullableRecord(rawProfile);
|
||||
const driver = normalizeOptionalString(profile?.driver) ?? "openclaw";
|
||||
if (driver !== "existing-session") {
|
||||
profiles.set(profileName, { name: profileName });
|
||||
@@ -134,7 +136,7 @@ function isSameOrChildPath(candidatePath: string, parentPath: string): boolean {
|
||||
}
|
||||
|
||||
function isLegacyClawdProfileConfigured(cfg: OpenClawConfig, legacyProfileDir: string): boolean {
|
||||
const browser = asRecord(cfg.browser);
|
||||
const browser = asNullableRecord(cfg.browser);
|
||||
if (!browser) {
|
||||
return false;
|
||||
}
|
||||
@@ -142,7 +144,7 @@ function isLegacyClawdProfileConfigured(cfg: OpenClawConfig, legacyProfileDir: s
|
||||
return true;
|
||||
}
|
||||
|
||||
const configuredProfiles = asRecord(browser.profiles);
|
||||
const configuredProfiles = asNullableRecord(browser.profiles);
|
||||
if (!configuredProfiles) {
|
||||
return false;
|
||||
}
|
||||
@@ -151,7 +153,7 @@ function isLegacyClawdProfileConfigured(cfg: OpenClawConfig, legacyProfileDir: s
|
||||
}
|
||||
|
||||
for (const rawProfile of Object.values(configuredProfiles)) {
|
||||
const profile = asRecord(rawProfile);
|
||||
const profile = asNullableRecord(rawProfile);
|
||||
const userDataDir = normalizeOptionalString(profile?.userDataDir);
|
||||
if (userDataDir && isSameOrChildPath(resolveUserPath(userDataDir), legacyProfileDir)) {
|
||||
return true;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Small record/string coercion helpers shared by Browser setup and audits.
|
||||
*/
|
||||
import {
|
||||
asNullableRecord,
|
||||
hasNonEmptyString as sharedHasNonEmptyString,
|
||||
isRecord,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
/** Re-export record guards under Browser-local names. */
|
||||
export { asNullableRecord as asRecord, isRecord };
|
||||
|
||||
/** Re-export shared non-empty string predicate. */
|
||||
export const hasNonEmptyString = sharedHasNonEmptyString;
|
||||
|
||||
/** Normalizes primitive string/number/boolean values to non-empty strings. */
|
||||
export function normalizeString(value: unknown): string | undefined {
|
||||
if (typeof value === "string") {
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
}
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -5,10 +5,12 @@ import type { OpenClawPluginSecurityAuditContext } from "openclaw/plugin-sdk/plu
|
||||
import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
|
||||
import { formatCliCommand } from "openclaw/plugin-sdk/setup-tools";
|
||||
import { isPrivateNetworkOptInEnabled, isPrivateIpAddress } from "openclaw/plugin-sdk/ssrf-policy";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
hasNonEmptyString,
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { redactCdpUrl, resolveBrowserConfig, resolveProfile } from "./browser/config.js";
|
||||
import { resolveBrowserControlAuth } from "./browser/control-auth.js";
|
||||
import { hasNonEmptyString } from "./record-shared.js";
|
||||
|
||||
const BLOCKED_HOSTNAMES = new Set([
|
||||
"localhost",
|
||||
|
||||
@@ -8,6 +8,12 @@ import type {
|
||||
ModelDefinitionConfig,
|
||||
ModelProviderConfig,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
asFiniteNumberInRange,
|
||||
asOptionalRecord,
|
||||
asPositiveSafeInteger,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
const CLAWROUTER_DEFAULT_BASE_URL = "https://clawrouter.openclaw.ai";
|
||||
|
||||
@@ -73,19 +79,9 @@ type RouteMetadata = {
|
||||
upstreamModel?: string;
|
||||
};
|
||||
|
||||
function readRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readStringArray(value: unknown): string[] {
|
||||
return Array.isArray(value)
|
||||
? value.map(readString).filter((entry): entry is string => Boolean(entry))
|
||||
? value.map(normalizeOptionalString).filter((entry): entry is string => Boolean(entry))
|
||||
: [];
|
||||
}
|
||||
|
||||
@@ -102,16 +98,8 @@ export function normalizeClawRouterReasoningEfforts(
|
||||
return efforts.length > 0 ? efforts : undefined;
|
||||
}
|
||||
|
||||
function readNonNegativeNumber(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
|
||||
}
|
||||
|
||||
function readPositiveSafeInteger(value: unknown): number | undefined {
|
||||
return Number.isSafeInteger(value) && Number(value) > 0 ? Number(value) : undefined;
|
||||
}
|
||||
|
||||
function readCatalogRows(body: unknown): readonly unknown[] {
|
||||
const providers = readRecord(body)?.providers;
|
||||
const providers = asOptionalRecord(body)?.providers;
|
||||
if (!Array.isArray(providers)) {
|
||||
throw new Error("ClawRouter catalog response must contain providers[]");
|
||||
}
|
||||
@@ -119,9 +107,9 @@ function readCatalogRows(body: unknown): readonly unknown[] {
|
||||
}
|
||||
|
||||
function parseCatalogRoute(value: unknown): CatalogRoute | undefined {
|
||||
const row = readRecord(value);
|
||||
const path = readString(row?.path);
|
||||
const requestFormat = readString(row?.requestFormat);
|
||||
const row = asOptionalRecord(value);
|
||||
const path = normalizeOptionalString(row?.path);
|
||||
const requestFormat = normalizeOptionalString(row?.requestFormat);
|
||||
if (!path || !requestFormat) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -133,25 +121,35 @@ function parseCatalogRoute(value: unknown): CatalogRoute | undefined {
|
||||
}
|
||||
|
||||
function parseCatalogPricing(value: unknown): CatalogPricing | undefined {
|
||||
const row = readRecord(value);
|
||||
const row = asOptionalRecord(value);
|
||||
if (!row) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
inputMicrosPerMillion: readNonNegativeNumber(row.inputMicrosPerMillion),
|
||||
outputMicrosPerMillion: readNonNegativeNumber(row.outputMicrosPerMillion),
|
||||
cachedInputMicrosPerMillion: readNonNegativeNumber(row.cachedInputMicrosPerMillion),
|
||||
cacheWrite5mInputMicrosPerMillion: readNonNegativeNumber(row.cacheWrite5mInputMicrosPerMillion),
|
||||
cacheWrite1hInputMicrosPerMillion: readNonNegativeNumber(row.cacheWrite1hInputMicrosPerMillion),
|
||||
maxInputTokens: readPositiveSafeInteger(row.maxInputTokens),
|
||||
defaultMaxOutputTokens: readPositiveSafeInteger(row.defaultMaxOutputTokens),
|
||||
inputMicrosPerMillion: asFiniteNumberInRange(row.inputMicrosPerMillion, { min: 0 }),
|
||||
outputMicrosPerMillion: asFiniteNumberInRange(row.outputMicrosPerMillion, { min: 0 }),
|
||||
cachedInputMicrosPerMillion: asFiniteNumberInRange(row.cachedInputMicrosPerMillion, { min: 0 }),
|
||||
cacheWrite5mInputMicrosPerMillion: asFiniteNumberInRange(
|
||||
row.cacheWrite5mInputMicrosPerMillion,
|
||||
{
|
||||
min: 0,
|
||||
},
|
||||
),
|
||||
cacheWrite1hInputMicrosPerMillion: asFiniteNumberInRange(
|
||||
row.cacheWrite1hInputMicrosPerMillion,
|
||||
{
|
||||
min: 0,
|
||||
},
|
||||
),
|
||||
maxInputTokens: asPositiveSafeInteger(row.maxInputTokens),
|
||||
defaultMaxOutputTokens: asPositiveSafeInteger(row.defaultMaxOutputTokens),
|
||||
};
|
||||
}
|
||||
|
||||
function parseCatalogModel(value: unknown): CatalogModel | undefined {
|
||||
const row = readRecord(value);
|
||||
const id = readString(row?.id);
|
||||
const upstream = readString(row?.upstream);
|
||||
const row = asOptionalRecord(value);
|
||||
const id = normalizeOptionalString(row?.id);
|
||||
const upstream = normalizeOptionalString(row?.upstream);
|
||||
if (!id || !upstream) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -165,15 +163,15 @@ function parseCatalogModel(value: unknown): CatalogModel | undefined {
|
||||
}
|
||||
|
||||
function parseCatalogProvider(value: unknown): CatalogProvider | undefined {
|
||||
const row = readRecord(value);
|
||||
const id = readString(row?.id);
|
||||
const nativeBaseUrl = readString(row?.nativeBaseUrl);
|
||||
const row = asOptionalRecord(value);
|
||||
const id = normalizeOptionalString(row?.id);
|
||||
const nativeBaseUrl = normalizeOptionalString(row?.nativeBaseUrl);
|
||||
if (!id || !nativeBaseUrl || !nativeBaseUrl.startsWith("/v1/native/")) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
id,
|
||||
displayName: readString(row?.displayName) ?? id,
|
||||
displayName: normalizeOptionalString(row?.displayName) ?? id,
|
||||
openaiCompatible: row?.openaiCompatible === true,
|
||||
nativeBaseUrl,
|
||||
routes: Array.isArray(row?.routes)
|
||||
@@ -377,9 +375,9 @@ export async function buildClawRouterProviderConfig(params: {
|
||||
}
|
||||
|
||||
function readRouteMetadata(params: ProviderRuntimeModel["params"]): RouteMetadata | undefined {
|
||||
const row = readRecord(params?.[ROUTE_METADATA_KEY]);
|
||||
const baseUrl = readString(row?.baseUrl);
|
||||
const api = readString(row?.api);
|
||||
const row = asOptionalRecord(params?.[ROUTE_METADATA_KEY]);
|
||||
const baseUrl = normalizeOptionalString(row?.baseUrl);
|
||||
const api = normalizeOptionalString(row?.api);
|
||||
if (
|
||||
!baseUrl ||
|
||||
(api !== "openai-responses" &&
|
||||
@@ -389,7 +387,7 @@ function readRouteMetadata(params: ProviderRuntimeModel["params"]): RouteMetadat
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
const upstreamModel = readString(row?.upstreamModel);
|
||||
const upstreamModel = normalizeOptionalString(row?.upstreamModel);
|
||||
return {
|
||||
api,
|
||||
baseUrl,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Doctor contract hooks for Codex plugin config and state migrations.
|
||||
*/
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { asNullableRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
type LegacyConfigRule = {
|
||||
path: string[];
|
||||
@@ -9,32 +10,26 @@ type LegacyConfigRule = {
|
||||
match: (value: unknown) => boolean;
|
||||
};
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | null {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: null;
|
||||
}
|
||||
|
||||
function hasRetiredDynamicToolsProfile(value: unknown): boolean {
|
||||
return Object.hasOwn(asRecord(value) ?? {}, "codexDynamicToolsProfile");
|
||||
return Object.hasOwn(asNullableRecord(value) ?? {}, "codexDynamicToolsProfile");
|
||||
}
|
||||
|
||||
function hasLegacyPluginDestructivePolicy(value: unknown): boolean {
|
||||
const codexPlugins = asRecord(value);
|
||||
const codexPlugins = asNullableRecord(value);
|
||||
if (!codexPlugins) {
|
||||
return false;
|
||||
}
|
||||
if (codexPlugins.allow_destructive_actions === "on-request") {
|
||||
return true;
|
||||
}
|
||||
const plugins = asRecord(codexPlugins.plugins);
|
||||
const plugins = asNullableRecord(codexPlugins.plugins);
|
||||
return Object.values(plugins ?? {}).some(
|
||||
(plugin) => asRecord(plugin)?.allow_destructive_actions === "on-request",
|
||||
(plugin) => asNullableRecord(plugin)?.allow_destructive_actions === "on-request",
|
||||
);
|
||||
}
|
||||
|
||||
function hasRetiredOnFailureApprovalPolicy(value: unknown): boolean {
|
||||
return asRecord(value)?.approvalPolicy === "on-failure";
|
||||
return asNullableRecord(value)?.approvalPolicy === "on-failure";
|
||||
}
|
||||
|
||||
/** Legacy Codex config keys that doctor should report or repair. */
|
||||
@@ -66,10 +61,10 @@ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }):
|
||||
config: OpenClawConfig;
|
||||
changes: string[];
|
||||
} {
|
||||
const rawEntry = asRecord(cfg.plugins?.entries?.codex);
|
||||
const rawPluginConfig = asRecord(rawEntry?.config);
|
||||
const rawCodexPlugins = asRecord(rawPluginConfig?.codexPlugins);
|
||||
const rawAppServer = asRecord(rawPluginConfig?.appServer);
|
||||
const rawEntry = asNullableRecord(cfg.plugins?.entries?.codex);
|
||||
const rawPluginConfig = asNullableRecord(rawEntry?.config);
|
||||
const rawCodexPlugins = asNullableRecord(rawPluginConfig?.codexPlugins);
|
||||
const rawAppServer = asNullableRecord(rawPluginConfig?.appServer);
|
||||
const shouldRemoveDynamicToolsProfile =
|
||||
rawPluginConfig !== null && hasRetiredDynamicToolsProfile(rawPluginConfig);
|
||||
const shouldRewriteDestructivePolicy = hasLegacyPluginDestructivePolicy(rawCodexPlugins);
|
||||
@@ -86,10 +81,10 @@ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }):
|
||||
const nextConfig = structuredClone(cfg) as OpenClawConfig & {
|
||||
plugins?: Record<string, unknown>;
|
||||
};
|
||||
const nextPlugins = asRecord(nextConfig.plugins);
|
||||
const nextEntries = asRecord(nextPlugins?.entries);
|
||||
const nextEntry = asRecord(nextEntries?.codex);
|
||||
const nextPluginConfig = asRecord(nextEntry?.config);
|
||||
const nextPlugins = asNullableRecord(nextConfig.plugins);
|
||||
const nextEntries = asNullableRecord(nextPlugins?.entries);
|
||||
const nextEntry = asNullableRecord(nextEntries?.codex);
|
||||
const nextPluginConfig = asNullableRecord(nextEntry?.config);
|
||||
if (!nextPluginConfig) {
|
||||
return { config: cfg, changes: [] };
|
||||
}
|
||||
@@ -103,13 +98,13 @@ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }):
|
||||
}
|
||||
|
||||
if (shouldRewriteDestructivePolicy) {
|
||||
const nextCodexPlugins = asRecord(nextPluginConfig.codexPlugins);
|
||||
const nextCodexPlugins = asNullableRecord(nextPluginConfig.codexPlugins);
|
||||
if (nextCodexPlugins?.allow_destructive_actions === "on-request") {
|
||||
nextCodexPlugins.allow_destructive_actions = "auto";
|
||||
}
|
||||
const nextPluginPolicies = asRecord(nextCodexPlugins?.plugins);
|
||||
const nextPluginPolicies = asNullableRecord(nextCodexPlugins?.plugins);
|
||||
for (const plugin of Object.values(nextPluginPolicies ?? {})) {
|
||||
const nextPlugin = asRecord(plugin);
|
||||
const nextPlugin = asNullableRecord(plugin);
|
||||
if (nextPlugin?.allow_destructive_actions === "on-request") {
|
||||
nextPlugin.allow_destructive_actions = "auto";
|
||||
}
|
||||
@@ -120,7 +115,7 @@ export function normalizeCompatibilityConfig({ cfg }: { cfg: OpenClawConfig }):
|
||||
}
|
||||
|
||||
if (shouldRewriteApprovalPolicy) {
|
||||
const nextAppServer = asRecord(nextPluginConfig.appServer);
|
||||
const nextAppServer = asNullableRecord(nextPluginConfig.appServer);
|
||||
if (nextAppServer?.approvalPolicy === "on-failure") {
|
||||
nextAppServer.approvalPolicy = "on-request";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ import {
|
||||
type NativeHookRelayProcessResponse,
|
||||
type NativeHookRelayRegistrationHandle,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
normalizeTrimmedStringList,
|
||||
readStringField as readString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
import { formatCodexDisplayText } from "../command-formatters.js";
|
||||
import { resolveCodexToolAbortTerminalReason } from "./dynamic-tool-execution.js";
|
||||
@@ -1271,11 +1274,6 @@ function readStringPreview(
|
||||
return value === undefined ? undefined : previewSource(value);
|
||||
}
|
||||
|
||||
function readString(record: JsonObject | undefined, key: string): string | undefined {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function previewSource(value: string): ApprovalPreviewSource {
|
||||
return {
|
||||
value: sliceUtf16Safe(value, 0, APPROVAL_PREVIEW_SCAN_MAX_LENGTH),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
/**
|
||||
* Predicates and readers for Codex app-server notification envelopes.
|
||||
*/
|
||||
@@ -390,11 +391,6 @@ function extractRawResponseItemText(item: JsonObject): string {
|
||||
.join("");
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
/** Reads a typed Codex item from notification params when id/type are present. */
|
||||
export function readCodexNotificationItem(
|
||||
params: JsonValue | undefined,
|
||||
|
||||
@@ -3,6 +3,7 @@ import path from "node:path";
|
||||
import type { AuthProfileStore } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
|
||||
import {
|
||||
CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS,
|
||||
@@ -671,8 +672,3 @@ function collectAssistantTextFromItems(items: CodexThreadItem[] | undefined): st
|
||||
.join("\n\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ import {
|
||||
assignMcpCatalogSafeServerNames,
|
||||
type McpToolCatalog,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
asOptionalRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { CodexAppServerClient } from "./client.js";
|
||||
import type { CodexMcpServerStatus } from "./protocol.js";
|
||||
import { sessionBindingIdentity, type CodexAppServerBindingStore } from "./session-binding.js";
|
||||
@@ -12,16 +16,6 @@ const MCP_STATUS_PAGE_SIZE = 100;
|
||||
const MCP_STATUS_MAX_PAGES = 100;
|
||||
type AgentHarnessMcpCatalogParams = Parameters<NonNullable<AgentHarness["loadMcpToolCatalog"]>>[0];
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function catalogTool(params: {
|
||||
serverName: string;
|
||||
safeServerName: string;
|
||||
@@ -29,15 +23,16 @@ function catalogTool(params: {
|
||||
raw?: unknown;
|
||||
deniedBySession?: true;
|
||||
}): McpToolCatalog["tools"][number] {
|
||||
const raw = asRecord(params.raw);
|
||||
const description = readString(raw?.description);
|
||||
const raw = asOptionalRecord(params.raw);
|
||||
const description = normalizeOptionalString(raw?.description);
|
||||
const title = normalizeOptionalString(raw?.title);
|
||||
return {
|
||||
serverName: params.serverName,
|
||||
safeServerName: params.safeServerName,
|
||||
toolName: params.toolName,
|
||||
...(readString(raw?.title) ? { title: readString(raw?.title) } : {}),
|
||||
...(title ? { title } : {}),
|
||||
...(description ? { description } : {}),
|
||||
inputSchema: (asRecord(raw?.inputSchema) ?? { type: "object" }) as never,
|
||||
inputSchema: (asOptionalRecord(raw?.inputSchema) ?? { type: "object" }) as never,
|
||||
fallbackDescription: description ?? params.toolName,
|
||||
...(params.deniedBySession ? { deniedBySession: true } : {}),
|
||||
};
|
||||
|
||||
@@ -80,7 +80,7 @@ export async function handleCodexAppServerElicitationRequest(params: {
|
||||
signal?: AbortSignal;
|
||||
}): Promise<JsonValue | undefined> {
|
||||
const requestParams = isJsonObject(params.requestParams) ? params.requestParams : undefined;
|
||||
if (!requestParams || readString(requestParams, "threadId") !== params.threadId) {
|
||||
if (!requestParams || readNonBlankStringField(requestParams, "threadId") !== params.threadId) {
|
||||
return undefined;
|
||||
}
|
||||
const requestTurnId = requestParams.turnId;
|
||||
@@ -161,7 +161,7 @@ function resolvePluginElicitation(params: {
|
||||
return uniquePluginMatch(entry ? [entry] : [], "connector_id");
|
||||
}
|
||||
|
||||
const serverName = readString(requestParams, "serverName");
|
||||
const serverName = readNonBlankStringField(requestParams, "serverName");
|
||||
if (serverName && context) {
|
||||
const matches = entries.filter((entry) => entry.mcpServerNames.includes(serverName));
|
||||
if (matches.length > 0) {
|
||||
@@ -188,9 +188,10 @@ function resolvePluginElicitation(params: {
|
||||
|
||||
function isCodexConnectorApprovalElicitation(requestParams: JsonObject, meta: JsonObject): boolean {
|
||||
return (
|
||||
readString(requestParams, "serverName") === CODEX_APPS_SERVER_NAME &&
|
||||
readString(meta, MCP_TOOL_APPROVAL_KIND_KEY) === MCP_TOOL_APPROVAL_KIND &&
|
||||
readString(meta, MCP_TOOL_APPROVAL_SOURCE_KEY) === MCP_TOOL_APPROVAL_CONNECTOR_SOURCE
|
||||
readNonBlankStringField(requestParams, "serverName") === CODEX_APPS_SERVER_NAME &&
|
||||
readNonBlankStringField(meta, MCP_TOOL_APPROVAL_KIND_KEY) === MCP_TOOL_APPROVAL_KIND &&
|
||||
readNonBlankStringField(meta, MCP_TOOL_APPROVAL_SOURCE_KEY) ===
|
||||
MCP_TOOL_APPROVAL_CONNECTOR_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ function hasDisplayNameOnlyPluginMatch(
|
||||
meta: JsonObject,
|
||||
entries: CodexAppPolicyContextEntry[],
|
||||
): boolean {
|
||||
const connectorName = readString(meta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY);
|
||||
const connectorName = readNonBlankStringField(meta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY);
|
||||
if (!connectorName) {
|
||||
return false;
|
||||
}
|
||||
@@ -340,14 +341,14 @@ function readPluginApprovalElicitation(
|
||||
requestParams: JsonObject,
|
||||
): BridgeableApprovalElicitation | undefined {
|
||||
if (
|
||||
readString(requestParams, "mode") !== "form" ||
|
||||
readNonBlankStringField(requestParams, "mode") !== "form" ||
|
||||
!isJsonObject(requestParams.requestedSchema)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
const requestedSchema = requestParams.requestedSchema;
|
||||
if (
|
||||
readString(requestedSchema, "type") !== "object" ||
|
||||
readNonBlankStringField(requestedSchema, "type") !== "object" ||
|
||||
!isJsonObject(requestedSchema.properties)
|
||||
) {
|
||||
return undefined;
|
||||
@@ -355,9 +356,10 @@ function readPluginApprovalElicitation(
|
||||
|
||||
const meta = isJsonObject(requestParams["_meta"]) ? requestParams["_meta"] : {};
|
||||
const title =
|
||||
sanitizeDisplayText(readString(requestParams, "message") ?? "") || "Codex plugin approval";
|
||||
sanitizeDisplayText(readNonBlankStringField(requestParams, "message") ?? "") ||
|
||||
"Codex plugin approval";
|
||||
const descriptionMeta: JsonObject = { ...meta };
|
||||
if (!readString(descriptionMeta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY)) {
|
||||
if (!readNonBlankStringField(descriptionMeta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY)) {
|
||||
descriptionMeta[MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY] = appPolicyDisplayName(entry);
|
||||
}
|
||||
return {
|
||||
@@ -366,7 +368,7 @@ function readPluginApprovalElicitation(
|
||||
title,
|
||||
meta: descriptionMeta,
|
||||
requestedSchema,
|
||||
serverName: sanitizeOptionalDisplayText(readString(requestParams, "serverName")),
|
||||
serverName: sanitizeOptionalDisplayText(readNonBlankStringField(requestParams, "serverName")),
|
||||
}),
|
||||
requestedSchema,
|
||||
meta,
|
||||
@@ -409,8 +411,8 @@ function declineElicitationResponse(): JsonValue {
|
||||
function logPluginElicitationDecline(reason: string, requestParams: JsonObject | undefined): void {
|
||||
embeddedAgentLog.debug("codex plugin elicitation declined", {
|
||||
reason,
|
||||
serverName: readString(requestParams, "serverName"),
|
||||
mode: readString(requestParams, "mode"),
|
||||
serverName: readNonBlankStringField(requestParams, "serverName"),
|
||||
mode: readNonBlankStringField(requestParams, "mode"),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -419,7 +421,7 @@ function readBridgeableApprovalElicitation(
|
||||
): BridgeableApprovalElicitation | undefined {
|
||||
if (
|
||||
!requestParams ||
|
||||
readString(requestParams, "mode") !== "form" ||
|
||||
readNonBlankStringField(requestParams, "mode") !== "form" ||
|
||||
!isJsonObject(requestParams["_meta"]) ||
|
||||
requestParams["_meta"][MCP_TOOL_APPROVAL_KIND_KEY] !== MCP_TOOL_APPROVAL_KIND ||
|
||||
!isJsonObject(requestParams.requestedSchema)
|
||||
@@ -429,21 +431,22 @@ function readBridgeableApprovalElicitation(
|
||||
|
||||
const requestedSchema = requestParams.requestedSchema;
|
||||
if (
|
||||
readString(requestedSchema, "type") !== "object" ||
|
||||
readNonBlankStringField(requestedSchema, "type") !== "object" ||
|
||||
!isJsonObject(requestedSchema.properties)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const title =
|
||||
sanitizeDisplayText(readString(requestParams, "message") ?? "") || "Codex MCP tool approval";
|
||||
sanitizeDisplayText(readNonBlankStringField(requestParams, "message") ?? "") ||
|
||||
"Codex MCP tool approval";
|
||||
return {
|
||||
title,
|
||||
description: buildApprovalDescription({
|
||||
title,
|
||||
meta: requestParams["_meta"],
|
||||
requestedSchema,
|
||||
serverName: sanitizeOptionalDisplayText(readString(requestParams, "serverName")),
|
||||
serverName: sanitizeOptionalDisplayText(readNonBlankStringField(requestParams, "serverName")),
|
||||
}),
|
||||
requestedSchema,
|
||||
meta: requestParams["_meta"],
|
||||
@@ -454,12 +457,12 @@ function readComputerUseApprovalElicitation(
|
||||
requestParams: JsonObject | undefined,
|
||||
expectedServerName: string | undefined,
|
||||
): BridgeableApprovalElicitation | undefined {
|
||||
const serverName = readString(requestParams, "serverName");
|
||||
const serverName = readNonBlankStringField(requestParams, "serverName");
|
||||
if (
|
||||
!serverName ||
|
||||
!expectedServerName ||
|
||||
serverName !== expectedServerName ||
|
||||
readString(requestParams, "mode") !== "form"
|
||||
readNonBlankStringField(requestParams, "mode") !== "form"
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -468,7 +471,7 @@ function readComputerUseApprovalElicitation(
|
||||
? requestParams.requestedSchema
|
||||
: EMPTY_OBJECT_SCHEMA;
|
||||
if (
|
||||
readString(requestedSchema, "type") !== "object" ||
|
||||
readNonBlankStringField(requestedSchema, "type") !== "object" ||
|
||||
!isJsonObject(requestedSchema.properties)
|
||||
) {
|
||||
return undefined;
|
||||
@@ -476,7 +479,8 @@ function readComputerUseApprovalElicitation(
|
||||
|
||||
const meta = isJsonObject(requestParams?.["_meta"]) ? requestParams["_meta"] : {};
|
||||
const title =
|
||||
sanitizeDisplayText(readString(requestParams, "message") ?? "") || COMPUTER_USE_APPROVAL_TITLE;
|
||||
sanitizeDisplayText(readNonBlankStringField(requestParams, "message") ?? "") ||
|
||||
COMPUTER_USE_APPROVAL_TITLE;
|
||||
return {
|
||||
title,
|
||||
description: buildApprovalDescription({
|
||||
@@ -497,13 +501,13 @@ function buildApprovalDescription(params: {
|
||||
serverName: string | undefined;
|
||||
}): string {
|
||||
const connectorName = sanitizeOptionalDisplayText(
|
||||
readString(params.meta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY),
|
||||
readNonBlankStringField(params.meta, MCP_TOOL_APPROVAL_CONNECTOR_NAME_KEY),
|
||||
);
|
||||
const toolTitle = sanitizeOptionalDisplayText(
|
||||
readString(params.meta, MCP_TOOL_APPROVAL_TOOL_TITLE_KEY),
|
||||
readNonBlankStringField(params.meta, MCP_TOOL_APPROVAL_TOOL_TITLE_KEY),
|
||||
);
|
||||
const toolDescription = sanitizeOptionalDisplayText(
|
||||
readString(params.meta, MCP_TOOL_APPROVAL_TOOL_DESCRIPTION_KEY),
|
||||
readNonBlankStringField(params.meta, MCP_TOOL_APPROVAL_TOOL_DESCRIPTION_KEY),
|
||||
);
|
||||
const summaryLines = [
|
||||
connectorName && `App: ${connectorName}`,
|
||||
@@ -532,10 +536,12 @@ function readPropertyDescriptionLines(requestedSchema: JsonObject): string[] {
|
||||
return undefined;
|
||||
}
|
||||
const propTitle =
|
||||
sanitizeDisplayText(readString(schema, "title") ?? "") ||
|
||||
sanitizeDisplayText(readNonBlankStringField(schema, "title") ?? "") ||
|
||||
sanitizeDisplayText(name) ||
|
||||
"field";
|
||||
const description = sanitizeOptionalDisplayText(readString(schema, "description"));
|
||||
const description = sanitizeOptionalDisplayText(
|
||||
readNonBlankStringField(schema, "description"),
|
||||
);
|
||||
return description ? `- ${propTitle}: ${description}` : `- ${propTitle}`;
|
||||
})
|
||||
.filter((line): line is string => Boolean(line));
|
||||
@@ -554,8 +560,8 @@ function readDisplayParamLines(meta: JsonObject): string[] {
|
||||
return undefined;
|
||||
}
|
||||
const name =
|
||||
sanitizeOptionalDisplayText(readString(param, "display_name")) ??
|
||||
sanitizeOptionalDisplayText(readString(param, "name"));
|
||||
sanitizeOptionalDisplayText(readNonBlankStringField(param, "display_name")) ??
|
||||
sanitizeOptionalDisplayText(readNonBlankStringField(param, "name"));
|
||||
if (!name) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -764,7 +770,7 @@ function readApprovalFieldValue(
|
||||
if (!isApprovalField(property)) {
|
||||
return undefined;
|
||||
}
|
||||
const type = readString(property.schema, "type");
|
||||
const type = readNonBlankStringField(property.schema, "type");
|
||||
if (type === "boolean") {
|
||||
return true;
|
||||
}
|
||||
@@ -831,8 +837,8 @@ function isPersistField(property: ApprovalPropertyContext): boolean {
|
||||
function propertyText(property: ApprovalPropertyContext): string {
|
||||
return [
|
||||
property.name,
|
||||
readString(property.schema, "title"),
|
||||
readString(property.schema, "description"),
|
||||
readNonBlankStringField(property.schema, "title"),
|
||||
readNonBlankStringField(property.schema, "description"),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
@@ -902,11 +908,11 @@ function readEnumOptions(schema: JsonObject): Array<{ value: string; label: stri
|
||||
return schema.oneOf
|
||||
.map((entry) => {
|
||||
const option = isJsonObject(entry) ? entry : undefined;
|
||||
const value = readString(option, "const");
|
||||
const value = readNonBlankStringField(option, "const");
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
return { value, label: readString(option, "title") ?? value };
|
||||
return { value, label: readNonBlankStringField(option, "title") ?? value };
|
||||
})
|
||||
.filter((entry): entry is { value: string; label: string } => Boolean(entry));
|
||||
}
|
||||
@@ -925,14 +931,14 @@ function isSessionApprovalOption(option: { value: string; label: string }): bool
|
||||
);
|
||||
}
|
||||
|
||||
function readString(record: JsonObject | undefined, key: string): string | undefined {
|
||||
function readNonBlankStringField(record: JsonObject | undefined, key: string): string | undefined {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" && value.trim() ? value : undefined;
|
||||
}
|
||||
|
||||
function readFirstString(record: JsonObject | undefined, keys: string[]): string | undefined {
|
||||
for (const key of keys) {
|
||||
const value = readString(record, key);
|
||||
const value = readNonBlankStringField(record, key);
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import type { AssistantMessage } from "openclaw/plugin-sdk/llm";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
createAssistantCommentaryMessage as buildAssistantCommentaryMessage,
|
||||
createAssistantMessage as buildAssistantMessage,
|
||||
@@ -7,7 +8,7 @@ import {
|
||||
type AssistantMessageOptions,
|
||||
} from "./event-projector-assistant-message.js";
|
||||
import { shouldClearTerminalPresentationForNativeItem } from "./event-projector-items.js";
|
||||
import { extractRawAssistantText, readItemString, readString } from "./event-projector-values.js";
|
||||
import { extractRawAssistantText, readItemString } from "./event-projector-values.js";
|
||||
import type { CodexThreadItem, JsonObject } from "./protocol.js";
|
||||
|
||||
type AgentEvent = Parameters<NonNullable<EmbeddedRunAttemptParams["onAgentEvent"]>>[0];
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
readStringField as readString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
isNonSuccessItemStatus,
|
||||
itemKind,
|
||||
@@ -19,12 +23,7 @@ import {
|
||||
shouldEmitTranscriptToolProgress,
|
||||
} from "./event-projector-tool-progress.js";
|
||||
import { CodexToolTranscriptProjection } from "./event-projector-tool-transcript.js";
|
||||
import {
|
||||
readHookOutputEntries,
|
||||
readNullableString,
|
||||
readNumber,
|
||||
readString,
|
||||
} from "./event-projector-values.js";
|
||||
import { readHookOutputEntries, readNullableString } from "./event-projector-values.js";
|
||||
import { isJsonObject, type CodexThreadItem, type JsonObject } from "./protocol.js";
|
||||
|
||||
type AgentEvent = Parameters<NonNullable<EmbeddedRunAttemptParams["onAgentEvent"]>>[0];
|
||||
@@ -78,7 +77,7 @@ export class CodexEventProjection {
|
||||
if (!run) {
|
||||
return;
|
||||
}
|
||||
const durationMs = readNumber(run, "durationMs");
|
||||
const durationMs = asFiniteNumber(run.durationMs);
|
||||
const entries = readHookOutputEntries(run.entries);
|
||||
const hookTurnId = readNullableString(params, "turnId");
|
||||
this.emitAgentEvent({
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
|
||||
import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
|
||||
import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
|
||||
import { readItemString, readString } from "./event-projector-values.js";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { readItemString } from "./event-projector-values.js";
|
||||
import type { CodexThreadItem, JsonObject } from "./protocol.js";
|
||||
import type { CodexRemoteWorkspaceFileReader } from "./remote-workspace-media.js";
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
||||
import { asDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveCodexToolAbortTerminalReason } from "./dynamic-tool-execution.js";
|
||||
import {
|
||||
auditNativeToolName,
|
||||
@@ -13,7 +14,7 @@ import {
|
||||
type CodexNativeToolAuditStatus,
|
||||
type CodexNativeToolUnfinishedStatus,
|
||||
} from "./event-projector-items.js";
|
||||
import { readItem, readString } from "./event-projector-values.js";
|
||||
import { readItem } from "./event-projector-values.js";
|
||||
import {
|
||||
emitCodexNativePreToolUseFailureDiagnostic,
|
||||
type CodexNativePreToolUseFailure,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import type { AgentPlanStep, AgentPlanStepStatus } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
readNonNegativeInteger,
|
||||
readNullableString,
|
||||
readString,
|
||||
splitPlanText,
|
||||
} from "./event-projector-values.js";
|
||||
import type { CodexThreadItem, JsonObject } from "./protocol.js";
|
||||
|
||||
@@ -2,8 +2,8 @@ import {
|
||||
formatToolAggregate,
|
||||
formatToolProgressOutput,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
import { readString } from "./event-projector-values.js";
|
||||
import { isJsonObject, type CodexThreadItem } from "./protocol.js";
|
||||
|
||||
export const MAX_TOOL_OUTPUT_DELTA_MESSAGES_PER_ITEM = 20;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
type EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams,
|
||||
type ToolProgressDetailMode,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
||||
import type { EmbeddedRunAttemptResult } from "./attempt-terminal.js";
|
||||
import {
|
||||
@@ -35,7 +36,6 @@ import {
|
||||
toolOutputRawEchoSignature,
|
||||
truncateToolTranscriptText,
|
||||
} from "./event-projector-tool-output.js";
|
||||
import { readString } from "./event-projector-values.js";
|
||||
import type {
|
||||
CodexDynamicToolCallOutputContentItem,
|
||||
CodexThreadItem,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readNonNegativeInteger, readNumber, readString } from "./event-projector-values.js";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
readStringField as readString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { readNonNegativeInteger } from "./event-projector-values.js";
|
||||
import { isJsonObject, type JsonObject } from "./protocol.js";
|
||||
|
||||
function readTokenCount(record: JsonObject, key: string): number | undefined {
|
||||
@@ -80,7 +84,10 @@ function normalizeCodexTokenUsageBreakdown(
|
||||
): ReturnType<typeof normalizeUsage> {
|
||||
// v2 TokenUsageBreakdown. inputTokens includes cached input; OpenClaw usage
|
||||
// tracks uncached input, cache reads, and cache writes separately.
|
||||
const readCount = source === "response" ? readTokenCount : readNumber;
|
||||
const readCount =
|
||||
source === "response"
|
||||
? readTokenCount
|
||||
: (value: JsonObject, key: string) => asFiniteNumber(value[key]);
|
||||
const totalTokens = readCount(record, "totalTokens");
|
||||
const inputTokens = readCount(record, "inputTokens");
|
||||
const cacheRead = readCount(record, "cachedInputTokens");
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { asFiniteNumber, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { isJsonObject, type CodexThreadItem, type JsonObject, type JsonValue } from "./protocol.js";
|
||||
|
||||
export function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
export function normalizeNonEmptyString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
@@ -39,19 +35,14 @@ export function readNullableString(record: JsonObject, key: string): string | nu
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
export function readNumber(record: JsonObject, key: string): number | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
|
||||
export function readNonNegativeInteger(record: JsonObject, key: string): number | undefined {
|
||||
const value = readNumber(record, key);
|
||||
const value = asFiniteNumber(record[key]);
|
||||
return value !== undefined && Number.isInteger(value) && value >= 0 ? value : undefined;
|
||||
}
|
||||
|
||||
export function readCodexErrorNotificationMessage(record: JsonObject): string | undefined {
|
||||
const error = record.error;
|
||||
return isJsonObject(error) ? readString(error, "message") : undefined;
|
||||
return isJsonObject(error) ? readStringField(error, "message") : undefined;
|
||||
}
|
||||
|
||||
export function readHookOutputEntries(
|
||||
@@ -64,11 +55,11 @@ export function readHookOutputEntries(
|
||||
if (!isJsonObject(entry)) {
|
||||
return [];
|
||||
}
|
||||
const text = readString(entry, "text");
|
||||
const text = readStringField(entry, "text");
|
||||
if (!text) {
|
||||
return [];
|
||||
}
|
||||
const kind = readString(entry, "kind");
|
||||
const kind = readStringField(entry, "kind");
|
||||
return [{ ...(kind ? { kind } : {}), text }];
|
||||
});
|
||||
}
|
||||
@@ -86,11 +77,11 @@ export function extractRawAssistantText(item: JsonObject): string | undefined {
|
||||
if (!isJsonObject(entry)) {
|
||||
return [];
|
||||
}
|
||||
const type = readString(entry, "type");
|
||||
const type = readStringField(entry, "type");
|
||||
if (type !== "output_text" && type !== "text") {
|
||||
return [];
|
||||
}
|
||||
const value = readString(entry, "text");
|
||||
const value = readStringField(entry, "text");
|
||||
return value === undefined ? [] : [value];
|
||||
});
|
||||
return parts.length > 0 ? parts.join("").trim() : undefined;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
type BeforeToolCallFailureDisposition,
|
||||
type EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { AttemptFailureSource } from "./attempt-terminal.js";
|
||||
import type { EmbeddedRunAttemptResult } from "./attempt-terminal.js";
|
||||
import { CodexAssistantProjection } from "./event-projector-assistant.js";
|
||||
@@ -37,7 +38,6 @@ import {
|
||||
readCodexErrorNotificationMessage,
|
||||
readItem,
|
||||
readItemString,
|
||||
readString,
|
||||
} from "./event-projector-values.js";
|
||||
import type { CodexNativePreToolUseFailure } from "./native-hook-relay.js";
|
||||
import {
|
||||
|
||||
@@ -299,11 +299,15 @@ function resolveManagedCodexPackageBinCandidate(root: string): string | null {
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as {
|
||||
bin?: unknown;
|
||||
};
|
||||
const packageBin =
|
||||
packageJson.bin && typeof packageJson.bin === "object"
|
||||
? (packageJson.bin as Record<string, unknown>)
|
||||
: undefined;
|
||||
const binPath =
|
||||
typeof packageJson.bin === "string"
|
||||
? packageJson.bin
|
||||
: isRecord(packageJson.bin) && typeof packageJson.bin.codex === "string"
|
||||
? packageJson.bin.codex
|
||||
: typeof packageBin?.codex === "string"
|
||||
? packageBin.codex
|
||||
: null;
|
||||
return binPath ? path.resolve(packageRoot, binPath) : null;
|
||||
} catch {
|
||||
@@ -311,10 +315,6 @@ function resolveManagedCodexPackageBinCandidate(root: string): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
|
||||
function isDistExtensionRoot(pluginRoot: string, platform: NodeJS.Platform): boolean {
|
||||
const pathApi = pathForPlatform(platform);
|
||||
const extensionsDir = pathApi.dirname(pluginRoot);
|
||||
|
||||
@@ -4,6 +4,10 @@ import {
|
||||
type McpToolCatalog,
|
||||
type SessionMcpRuntime,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
asOptionalRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { getCodexAppServerClientInstanceId, type CodexAppServerClient } from "./client.js";
|
||||
import type { CodexMcpServerStatus, CodexThreadItem, JsonObject, JsonValue } from "./protocol.js";
|
||||
import { retainSharedCodexAppServerClientIfCurrent } from "./shared-client.js";
|
||||
@@ -15,28 +19,20 @@ type NativeMcpCallToolResult = {
|
||||
_meta?: JsonValue;
|
||||
};
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readMcpAppResourceUri(item: CodexThreadItem): string | undefined {
|
||||
const appContext = asRecord(item.appContext);
|
||||
const uri = readString(appContext?.resourceUri) ?? readString(item.mcpAppResourceUri);
|
||||
const appContext = asOptionalRecord(item.appContext);
|
||||
const uri =
|
||||
normalizeOptionalString(appContext?.resourceUri) ??
|
||||
normalizeOptionalString(item.mcpAppResourceUri);
|
||||
return uri?.startsWith("ui://") ? uri : undefined;
|
||||
}
|
||||
|
||||
function readMcpToolResult(item: CodexThreadItem): NativeMcpCallToolResult | undefined {
|
||||
const result = asRecord(item.result);
|
||||
const result = asOptionalRecord(item.result);
|
||||
if (!result || !Array.isArray(result.content)) {
|
||||
return undefined;
|
||||
}
|
||||
const resultMeta = asRecord(result["_meta"]);
|
||||
const resultMeta = asOptionalRecord(result["_meta"]);
|
||||
return {
|
||||
content: result.content as JsonValue[],
|
||||
...(result.structuredContent !== undefined
|
||||
@@ -52,7 +48,7 @@ function readMcpToolResult(item: CodexThreadItem): NativeMcpCallToolResult | und
|
||||
|
||||
function statusTools(status: CodexMcpServerStatus): Array<Record<string, unknown>> {
|
||||
return Object.entries(status.tools).map(([name, value]) =>
|
||||
Object.assign({}, asRecord(value), { name }),
|
||||
Object.assign({}, asOptionalRecord(value) ?? {}, { name }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,8 +96,8 @@ function createNativeMcpRuntime(params: {
|
||||
serverName: status.name,
|
||||
safeServerName: status.name,
|
||||
toolName: String(tool.name),
|
||||
inputSchema: (asRecord(tool.inputSchema) ?? { type: "object" }) as never,
|
||||
fallbackDescription: readString(tool.description) ?? String(tool.name),
|
||||
inputSchema: (asOptionalRecord(tool.inputSchema) ?? { type: "object" }) as never,
|
||||
fallbackDescription: normalizeOptionalString(tool.description) ?? String(tool.name),
|
||||
})),
|
||||
),
|
||||
};
|
||||
@@ -128,7 +124,7 @@ function createNativeMcpRuntime(params: {
|
||||
threadId: params.threadId,
|
||||
server: serverName,
|
||||
tool: toolName,
|
||||
arguments: (asRecord(input) ?? {}) as JsonObject,
|
||||
arguments: (asOptionalRecord(input) ?? {}) as JsonObject,
|
||||
})) as never,
|
||||
listTools: async (serverName) => {
|
||||
const status = (await loadStatuses()).find((entry) => entry.name === serverName);
|
||||
@@ -163,8 +159,8 @@ export function createCodexNativeMcpAppResultDetailsPreparer(params: {
|
||||
}
|
||||
const runtime = createNativeMcpRuntime(params);
|
||||
return async (item) => {
|
||||
const serverName = readString(item.server);
|
||||
const toolName = readString(item.tool);
|
||||
const serverName = normalizeOptionalString(item.server);
|
||||
const toolName = normalizeOptionalString(item.tool);
|
||||
const uiResourceUri = readMcpAppResourceUri(item);
|
||||
const toolResult = readMcpToolResult(item);
|
||||
if (!serverName || !toolName || !uiResourceUri || !toolResult) {
|
||||
|
||||
@@ -12,7 +12,11 @@ import {
|
||||
type AgentHarnessTaskRuntimeScope,
|
||||
} from "openclaw/plugin-sdk/agent-harness-task-runtime";
|
||||
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
||||
import { asFiniteNumber, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
normalizeOptionalString,
|
||||
readStringField as readString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
claimCodexAppServerLiveThread,
|
||||
releaseCodexAppServerLiveThread,
|
||||
@@ -1835,11 +1839,6 @@ function readThreadSpawnSource(thread: JsonObject | undefined): JsonObject | und
|
||||
return isJsonObject(subAgent?.thread_spawn) ? subAgent.thread_spawn : undefined;
|
||||
}
|
||||
|
||||
function readString(record: JsonObject | undefined, key: string): string | undefined {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function readStringArray(value: unknown): string[] {
|
||||
if (!Array.isArray(value)) {
|
||||
return [];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Extracts native Codex subagent completion notifications from trusted
|
||||
* inter-agent commentary messages emitted by the app-server.
|
||||
*/
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { CodexServerNotification, JsonObject, JsonValue } from "./protocol.js";
|
||||
import { isJsonObject } from "./protocol.js";
|
||||
|
||||
@@ -253,11 +254,6 @@ function extractSingleTextPart(item: JsonObject): string | undefined {
|
||||
return readString(entry, "text")?.trim();
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function normalizeStatusKey(value: string): string {
|
||||
return value.replace(/[^a-z0-9]/giu, "").toLowerCase();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* runtime rows so parent sessions can observe child progress.
|
||||
*/
|
||||
import type { AgentHarnessTaskRuntime } from "openclaw/plugin-sdk/agent-harness-task-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX } from "./native-subagent-task-ids.js";
|
||||
import type {
|
||||
CodexServerNotification,
|
||||
@@ -502,11 +503,6 @@ function readStringArray(value: JsonValue | undefined): string[] {
|
||||
return value.filter((entry): entry is string => typeof entry === "string" && entry.trim() !== "");
|
||||
}
|
||||
|
||||
function readString(value: JsonObject, key: string): string | undefined {
|
||||
const entry = value[key];
|
||||
return typeof entry === "string" ? entry : undefined;
|
||||
}
|
||||
|
||||
function readNullableString(value: JsonObject, key: string): string | null | undefined {
|
||||
const entry = value[key];
|
||||
return typeof entry === "string" || entry === null ? entry : undefined;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Correlates Codex app-server notifications with the active thread/turn so
|
||||
* projectors can ignore global or stale events without losing diagnostics.
|
||||
*/
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { isJsonObject, type JsonObject, type JsonValue } from "./protocol.js";
|
||||
|
||||
/** Returns true when a notification payload belongs to the exact active thread and turn. */
|
||||
@@ -27,20 +28,18 @@ export function isCodexNotificationForTurn(
|
||||
*/
|
||||
export function readCodexNotificationThreadId(record: JsonObject): string | undefined {
|
||||
const thread = isJsonObject(record.thread) ? record.thread : undefined;
|
||||
return readString(record, "threadId") ?? (thread ? readString(thread, "id") : undefined);
|
||||
return (
|
||||
normalizeOptionalString(record.threadId) ??
|
||||
(thread ? normalizeOptionalString(thread.id) : undefined)
|
||||
);
|
||||
}
|
||||
|
||||
/** Reads a turn id from either top-level notification params or nested turn payloads. */
|
||||
export function readCodexNotificationTurnId(record: JsonObject): string | undefined {
|
||||
return readNestedTurnId(record) ?? readString(record, "turnId");
|
||||
return readNestedTurnId(record) ?? normalizeOptionalString(record.turnId);
|
||||
}
|
||||
|
||||
function readNestedTurnId(record: JsonObject): string | undefined {
|
||||
const turn = record.turn;
|
||||
return isJsonObject(turn) ? readString(turn, "id") : undefined;
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
return isJsonObject(turn) ? normalizeOptionalString(turn.id) : undefined;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,12 @@ import {
|
||||
type ProviderUsageSnapshot,
|
||||
type UsageWindow,
|
||||
} from "openclaw/plugin-sdk/provider-usage";
|
||||
import { asFiniteNumber, parseStrictFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asBoolean,
|
||||
asFiniteNumber,
|
||||
normalizeOptionalString,
|
||||
parseStrictFiniteNumber,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { isJsonObject, type JsonObject, type JsonValue } from "./protocol.js";
|
||||
|
||||
const CODEX_LIMIT_ID = "codex";
|
||||
@@ -61,7 +66,7 @@ export function formatCodexUsageLimitErrorMessage(params: {
|
||||
rateLimitsAuthoritative?: boolean;
|
||||
nowMs?: number;
|
||||
}): string | undefined {
|
||||
const message = normalizeText(params.message);
|
||||
const message = normalizeOptionalString(params.message);
|
||||
if (!isCodexUsageLimitError(params.codexErrorInfo)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -108,7 +113,7 @@ export function formatCodexUsageLimitErrorMessage(params: {
|
||||
export function shouldRefreshCodexRateLimitsForUsageLimitMessage(
|
||||
message: string | null | undefined,
|
||||
): boolean {
|
||||
const text = normalizeText(message);
|
||||
const text = normalizeOptionalString(message);
|
||||
// Only our formatted prefix is a refresh contract. Provider prose alone is
|
||||
// not structural evidence of a Codex usage-limit failure.
|
||||
return Boolean(
|
||||
@@ -274,7 +279,8 @@ function summarizeRateLimitSnapshot(snapshot: JsonObject, nowMs: number): string
|
||||
return window ? [formatRateLimitWindow(key, window, nowMs)] : [];
|
||||
});
|
||||
const reachedType =
|
||||
readString(snapshot, "rateLimitReachedType") ?? readString(snapshot, "rate_limit_reached_type");
|
||||
normalizeOptionalString(snapshot.rateLimitReachedType) ??
|
||||
normalizeOptionalString(snapshot.rate_limit_reached_type);
|
||||
const suffix = reachedType ? ` (${formatReachedType(reachedType)})` : "";
|
||||
if (windows.length > 0) {
|
||||
return `${label}: ${windows.join(" · ")}${suffix}`;
|
||||
@@ -346,8 +352,10 @@ function addRateLimitSnapshot(
|
||||
seen: Set<string>,
|
||||
): void {
|
||||
const signature = [
|
||||
readNullableString(snapshot, "limitId") ?? readNullableString(snapshot, "limit_id") ?? "",
|
||||
readNullableString(snapshot, "limitName") ?? readNullableString(snapshot, "limit_name") ?? "",
|
||||
normalizeOptionalString(snapshot.limitId) ?? normalizeOptionalString(snapshot.limit_id) ?? "",
|
||||
normalizeOptionalString(snapshot.limitName) ??
|
||||
normalizeOptionalString(snapshot.limit_name) ??
|
||||
"",
|
||||
formatWindowSignature(snapshot.primary),
|
||||
formatWindowSignature(snapshot.secondary),
|
||||
].join("|");
|
||||
@@ -379,7 +387,7 @@ function readRateLimitWindow(
|
||||
if (!isJsonObject(window)) {
|
||||
return undefined;
|
||||
}
|
||||
const resetsAt = readNumber(window, "resetsAt") ?? readNumber(window, "resets_at");
|
||||
const resetsAt = asFiniteNumber(window.resetsAt) ?? asFiniteNumber(window.resets_at);
|
||||
const resetsAtMs =
|
||||
resolveExpiresAtMsFromEpochSeconds(resetsAt, { maxMs: MAX_DATE_TIMESTAMP_MS }) ?? 0;
|
||||
return {
|
||||
@@ -397,8 +405,8 @@ function readRateLimitWindow(
|
||||
|
||||
function snapshotHasDisplayableData(snapshot: JsonObject): boolean {
|
||||
if (
|
||||
readString(snapshot, "rateLimitReachedType") ??
|
||||
readString(snapshot, "rate_limit_reached_type")
|
||||
normalizeOptionalString(snapshot.rateLimitReachedType) ??
|
||||
normalizeOptionalString(snapshot.rate_limit_reached_type)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -411,7 +419,7 @@ function readOptionalNumberField(
|
||||
record: JsonObject,
|
||||
...keys: string[]
|
||||
): { usedPercent?: number; windowDurationMins?: number } {
|
||||
const value = keys.map((key) => readNumber(record, key)).find((entry) => entry !== undefined);
|
||||
const value = keys.map((key) => asFiniteNumber(record[key])).find((entry) => entry !== undefined);
|
||||
if (value === undefined) {
|
||||
return {};
|
||||
}
|
||||
@@ -436,10 +444,10 @@ function formatRateLimitWindowDetails(window: RateLimitReset, nowMs: number): st
|
||||
|
||||
function formatLimitLabel(snapshot: JsonObject): string {
|
||||
const label =
|
||||
readNullableString(snapshot, "limitName") ??
|
||||
readNullableString(snapshot, "limit_name") ??
|
||||
readNullableString(snapshot, "limitId") ??
|
||||
readNullableString(snapshot, "limit_id");
|
||||
normalizeOptionalString(snapshot.limitName) ??
|
||||
normalizeOptionalString(snapshot.limit_name) ??
|
||||
normalizeOptionalString(snapshot.limitId) ??
|
||||
normalizeOptionalString(snapshot.limit_id);
|
||||
if (!label || label === CODEX_LIMIT_ID) {
|
||||
return "Codex";
|
||||
}
|
||||
@@ -465,8 +473,8 @@ function formatAccountResetTime(resetsAtMs: number, nowMs: number): string {
|
||||
|
||||
function snapshotHasLimitBlock(snapshot: JsonObject): boolean {
|
||||
return Boolean(
|
||||
readString(snapshot, "rateLimitReachedType") ??
|
||||
readString(snapshot, "rate_limit_reached_type") ??
|
||||
normalizeOptionalString(snapshot.rateLimitReachedType) ??
|
||||
normalizeOptionalString(snapshot.rate_limit_reached_type) ??
|
||||
readWindowEntries(snapshot).some(
|
||||
(entry) => entry.window.usedPercent !== undefined && entry.window.usedPercent >= 100,
|
||||
),
|
||||
@@ -474,7 +482,8 @@ function snapshotHasLimitBlock(snapshot: JsonObject): boolean {
|
||||
}
|
||||
|
||||
function isCodexLimitSnapshot(snapshot: JsonObject): boolean {
|
||||
const id = readNullableString(snapshot, "limitId") ?? readNullableString(snapshot, "limit_id");
|
||||
const id =
|
||||
normalizeOptionalString(snapshot.limitId) ?? normalizeOptionalString(snapshot.limit_id);
|
||||
return !id || id === CODEX_LIMIT_ID;
|
||||
}
|
||||
|
||||
@@ -522,7 +531,8 @@ function formatProviderUsageWindowLabel(
|
||||
}
|
||||
|
||||
function resolveCodexProviderUsagePlan(snapshot: JsonObject): string | undefined {
|
||||
const plan = readString(snapshot, "planType") ?? readString(snapshot, "plan_type");
|
||||
const plan =
|
||||
normalizeOptionalString(snapshot.planType) ?? normalizeOptionalString(snapshot.plan_type);
|
||||
const credits = isJsonObject(snapshot.credits) ? snapshot.credits : undefined;
|
||||
const creditSummary = formatCodexCreditSummary(credits);
|
||||
if (!creditSummary) {
|
||||
@@ -535,11 +545,11 @@ function formatCodexCreditSummary(credits: JsonObject | undefined): string | und
|
||||
if (!credits) {
|
||||
return undefined;
|
||||
}
|
||||
const hasCredits = readBoolean(credits, "hasCredits") ?? readBoolean(credits, "has_credits");
|
||||
const hasCredits = asBoolean(credits.hasCredits) ?? asBoolean(credits.has_credits);
|
||||
if (hasCredits === false) {
|
||||
return undefined;
|
||||
}
|
||||
if (readBoolean(credits, "unlimited")) {
|
||||
if (asBoolean(credits.unlimited)) {
|
||||
return "Unlimited credits";
|
||||
}
|
||||
const balance =
|
||||
@@ -745,8 +755,8 @@ function formatWindowSignature(value: JsonValue | undefined): string {
|
||||
if (!isJsonObject(value)) {
|
||||
return "";
|
||||
}
|
||||
return `${readNumber(value, "usedPercent") ?? readNumber(value, "used_percent") ?? ""}:${
|
||||
readNumber(value, "resetsAt") ?? readNumber(value, "resets_at") ?? ""
|
||||
return `${asFiniteNumber(value.usedPercent) ?? asFiniteNumber(value.used_percent) ?? ""}:${
|
||||
asFiniteNumber(value.resetsAt) ?? asFiniteNumber(value.resets_at) ?? ""
|
||||
}`;
|
||||
}
|
||||
|
||||
@@ -764,26 +774,4 @@ function extractCodexRetryHint(message: string | undefined): string | undefined
|
||||
return tryAgainRelative?.[1]?.trim();
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readNullableString(record: JsonObject, key: string): string | undefined {
|
||||
return readString(record, key) ?? undefined;
|
||||
}
|
||||
|
||||
function readNumber(record: JsonObject, key: string): number | undefined {
|
||||
return asFiniteNumber(record[key]);
|
||||
}
|
||||
|
||||
function readBoolean(record: JsonObject, key: string): boolean | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "boolean" ? value : undefined;
|
||||
}
|
||||
|
||||
function normalizeText(value: string | null | undefined): string | undefined {
|
||||
const text = value?.trim();
|
||||
return text ? text : undefined;
|
||||
}
|
||||
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
|
||||
|
||||
@@ -3,6 +3,11 @@ import {
|
||||
formatErrorMessage,
|
||||
type EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
asBoolean,
|
||||
asFiniteNumber,
|
||||
hasNonEmptyString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { EmbeddedRunAttemptResult } from "./attempt-terminal.js";
|
||||
import { CodexAppServerRpcError } from "./client.js";
|
||||
import { isJsonObject, type CodexServerNotification } from "./protocol.js";
|
||||
@@ -147,54 +152,44 @@ export function buildCodexAppServerTimeoutDiagnostics(params: {
|
||||
lastActivityReason?: string;
|
||||
details?: Record<string, unknown>;
|
||||
}): NonNullable<EmbeddedRunAttemptResult["codexAppServerFailure"]>["diagnostics"] {
|
||||
const readString = (key: string) => {
|
||||
const readNonBlankDetailString = (key: string) => {
|
||||
const value = params.details?.[key];
|
||||
return typeof value === "string" && value.trim() ? value : undefined;
|
||||
};
|
||||
const readNumber = (key: string) => {
|
||||
const value = params.details?.[key];
|
||||
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
||||
};
|
||||
const readBoolean = (key: string) => {
|
||||
const value = params.details?.[key];
|
||||
return typeof value === "boolean" ? value : undefined;
|
||||
return hasNonEmptyString(value) ? value : undefined;
|
||||
};
|
||||
const activeAppServerTurnRequests = asFiniteNumber(params.details?.activeAppServerTurnRequests);
|
||||
const activeTurnItemCount = asFiniteNumber(params.details?.activeTurnItemCount);
|
||||
const terminalTurnNotificationQueued = asBoolean(params.details?.terminalTurnNotificationQueued);
|
||||
const completionIdleWatchArmed = asBoolean(params.details?.completionIdleWatchArmed);
|
||||
const assistantCompletionIdleWatchArmed = asBoolean(
|
||||
params.details?.assistantCompletionIdleWatchArmed,
|
||||
);
|
||||
const terminalIdleWatchArmed = asBoolean(params.details?.terminalIdleWatchArmed);
|
||||
return {
|
||||
...(params.idleMs !== undefined ? { idleMs: params.idleMs } : {}),
|
||||
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),
|
||||
...(params.lastActivityReason ? { lastActivityReason: params.lastActivityReason } : {}),
|
||||
...(readString("lastNotificationMethod")
|
||||
? { lastNotificationMethod: readString("lastNotificationMethod") }
|
||||
...(readNonBlankDetailString("lastNotificationMethod")
|
||||
? { lastNotificationMethod: readNonBlankDetailString("lastNotificationMethod") }
|
||||
: {}),
|
||||
...(readString("lastNotificationItemId")
|
||||
? { lastNotificationItemId: readString("lastNotificationItemId") }
|
||||
...(readNonBlankDetailString("lastNotificationItemId")
|
||||
? { lastNotificationItemId: readNonBlankDetailString("lastNotificationItemId") }
|
||||
: {}),
|
||||
...(readString("lastNotificationItemType")
|
||||
? { lastNotificationItemType: readString("lastNotificationItemType") }
|
||||
...(readNonBlankDetailString("lastNotificationItemType")
|
||||
? { lastNotificationItemType: readNonBlankDetailString("lastNotificationItemType") }
|
||||
: {}),
|
||||
...(readString("lastNotificationItemRole")
|
||||
? { lastNotificationItemRole: readString("lastNotificationItemRole") }
|
||||
...(readNonBlankDetailString("lastNotificationItemRole")
|
||||
? { lastNotificationItemRole: readNonBlankDetailString("lastNotificationItemRole") }
|
||||
: {}),
|
||||
...(readString("lastAssistantTextPreview")
|
||||
? { lastAssistantTextPreview: readString("lastAssistantTextPreview") }
|
||||
...(readNonBlankDetailString("lastAssistantTextPreview")
|
||||
? { lastAssistantTextPreview: readNonBlankDetailString("lastAssistantTextPreview") }
|
||||
: {}),
|
||||
...(readNumber("activeAppServerTurnRequests") !== undefined
|
||||
? { activeAppServerTurnRequests: readNumber("activeAppServerTurnRequests") }
|
||||
: {}),
|
||||
...(readNumber("activeTurnItemCount") !== undefined
|
||||
? { activeTurnItemCount: readNumber("activeTurnItemCount") }
|
||||
: {}),
|
||||
...(readBoolean("terminalTurnNotificationQueued") !== undefined
|
||||
? { terminalTurnNotificationQueued: readBoolean("terminalTurnNotificationQueued") }
|
||||
: {}),
|
||||
...(readBoolean("completionIdleWatchArmed") !== undefined
|
||||
? { completionIdleWatchArmed: readBoolean("completionIdleWatchArmed") }
|
||||
: {}),
|
||||
...(readBoolean("assistantCompletionIdleWatchArmed") !== undefined
|
||||
? { assistantCompletionIdleWatchArmed: readBoolean("assistantCompletionIdleWatchArmed") }
|
||||
: {}),
|
||||
...(readBoolean("terminalIdleWatchArmed") !== undefined
|
||||
? { terminalIdleWatchArmed: readBoolean("terminalIdleWatchArmed") }
|
||||
...(activeAppServerTurnRequests !== undefined ? { activeAppServerTurnRequests } : {}),
|
||||
...(activeTurnItemCount !== undefined ? { activeTurnItemCount } : {}),
|
||||
...(terminalTurnNotificationQueued !== undefined ? { terminalTurnNotificationQueued } : {}),
|
||||
...(completionIdleWatchArmed !== undefined ? { completionIdleWatchArmed } : {}),
|
||||
...(assistantCompletionIdleWatchArmed !== undefined
|
||||
? { assistantCompletionIdleWatchArmed }
|
||||
: {}),
|
||||
...(terminalIdleWatchArmed !== undefined ? { terminalIdleWatchArmed } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { createMockPluginRegistry } from "openclaw/plugin-sdk/plugin-test-runtim
|
||||
import { registerSandboxBackend } from "openclaw/plugin-sdk/sandbox";
|
||||
import { upsertSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import { formatSqliteSessionFileMarker } from "openclaw/plugin-sdk/sqlite-runtime-testing";
|
||||
import { readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
// Codex tests cover run attempt.context engine plugin behavior.
|
||||
import { createRequireRecord } from "openclaw/plugin-sdk/test-fixtures";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
@@ -208,10 +209,6 @@ type MockCallReader = { mock: { calls: unknown[][] } };
|
||||
|
||||
const requireRecord = createRequireRecord("record", "expected-label-object");
|
||||
|
||||
function optionalString(value: unknown): string {
|
||||
return typeof value === "string" ? value : "";
|
||||
}
|
||||
|
||||
function requireFirstCallArg(mock: unknown, label: string): unknown {
|
||||
const call = (mock as MockCallReader).mock.calls[0];
|
||||
if (!call) {
|
||||
@@ -256,7 +253,7 @@ function getRequestInputTextAt(
|
||||
return input
|
||||
.map((entry) => {
|
||||
const item = requireRecord(entry, "turn/start input entry");
|
||||
return item.type === "text" ? optionalString(item.text) : "";
|
||||
return item.type === "text" ? (readStringValue(item.text) ?? "") : "";
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
@@ -343,7 +340,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
expect(assembleParams.availableTools).toEqual(new Set());
|
||||
|
||||
const threadStartParams = requireRequestParams(harness, "thread/start");
|
||||
expect(optionalString(threadStartParams.developerInstructions)).toContain(
|
||||
expect(readStringValue(threadStartParams.developerInstructions) ?? "").toContain(
|
||||
"context-engine system",
|
||||
);
|
||||
expectRequestInputTextContains(harness, "OpenClaw assembled context for this turn:");
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import type { PluginStateSyncKeyedStore } from "openclaw/plugin-sdk/plugin-state-runtime";
|
||||
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
CODEX_PLUGINS_MARKETPLACE_NAME,
|
||||
@@ -493,7 +494,7 @@ export function createStoredCodexAppServerBinding(
|
||||
lookup?: Omit<CodexAppServerAuthProfileLookup, "authProfileId">;
|
||||
} = {},
|
||||
): Extract<StoredCodexAppServerBinding, { state: "active" }> | undefined {
|
||||
const rawRecord = asRecord(value);
|
||||
const rawRecord = asOptionalRecord(value);
|
||||
if (!rawRecord) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1392,12 +1393,6 @@ function stripUndefinedValue(value: unknown): unknown {
|
||||
);
|
||||
}
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function readTimestamp(value: unknown): string | undefined {
|
||||
return optionalTimestampSchema.parse(value);
|
||||
}
|
||||
@@ -1406,17 +1401,17 @@ function readPluginAppPolicyContext(
|
||||
value: unknown,
|
||||
bindingSchemaVersion: 1 | 2,
|
||||
): PluginAppPolicyContext | undefined {
|
||||
const record = asRecord(value);
|
||||
const record = asOptionalRecord(value);
|
||||
if (!record || typeof record.fingerprint !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const apps = asRecord(record.apps);
|
||||
const apps = asOptionalRecord(record.apps);
|
||||
if (!apps) {
|
||||
return undefined;
|
||||
}
|
||||
const parsedApps: PluginAppPolicyContext["apps"] = {};
|
||||
for (const [appId, rawEntry] of Object.entries(apps)) {
|
||||
const entry = asRecord(rawEntry);
|
||||
const entry = asOptionalRecord(rawEntry);
|
||||
if (!entry) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
type NativeHookRelayRegistrationHandle,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveCodexAppServerForModelProvider } from "./app-server-policy.js";
|
||||
import { handleCodexAppServerApprovalRequest } from "./approval-bridge.js";
|
||||
import {
|
||||
@@ -1356,11 +1357,6 @@ function readNotificationTurnId(record: JsonObject): string | undefined {
|
||||
return readCodexNotificationTurnId(record);
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function formatCodexErrorMessage(params: JsonObject, rateLimits: JsonValue | undefined): Error {
|
||||
const error = isJsonObject(params.error) ? params.error : undefined;
|
||||
const message =
|
||||
|
||||
@@ -8,14 +8,10 @@ import {
|
||||
type EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { markAuthProfileBlockedUntil } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { CODEX_CONTROL_METHODS } from "./capabilities.js";
|
||||
import type { CodexAppServerClient } from "./client.js";
|
||||
import {
|
||||
isJsonObject,
|
||||
type CodexServerNotification,
|
||||
type JsonObject,
|
||||
type JsonValue,
|
||||
} from "./protocol.js";
|
||||
import { isJsonObject, type CodexServerNotification, type JsonValue } from "./protocol.js";
|
||||
import {
|
||||
readCodexRateLimitsRevision,
|
||||
readRecentCodexRateLimits,
|
||||
@@ -257,8 +253,3 @@ function readCodexErrorPayload(error: unknown): {
|
||||
rateLimits,
|
||||
};
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
type AgentHarnessUserInputQuestion,
|
||||
type EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readStringField as readString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { formatCodexDisplayText } from "../command-formatters.js";
|
||||
import {
|
||||
isJsonObject,
|
||||
@@ -314,11 +315,6 @@ function emptyUserInputResponse(): JsonObject {
|
||||
return emptyAgentHarnessUserInputAnswers() as unknown as JsonObject;
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" ? value : undefined;
|
||||
}
|
||||
|
||||
function readRequestId(record: JsonObject): string | number | undefined {
|
||||
const value = record.requestId;
|
||||
return typeof value === "string" || typeof value === "number" ? value : undefined;
|
||||
|
||||
@@ -10,9 +10,12 @@ import {
|
||||
type AuthProfileStore,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { PluginCommandContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
normalizeOptionalString,
|
||||
normalizeUniqueStringEntries,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { CODEX_CONTROL_METHODS, type CodexControlMethod } from "./app-server/capabilities.js";
|
||||
import { isJsonObject, type JsonObject, type JsonValue } from "./app-server/protocol.js";
|
||||
import { isJsonObject, type JsonValue } from "./app-server/protocol.js";
|
||||
import {
|
||||
summarizeCodexAccountUsage,
|
||||
type CodexAccountUsageSummary,
|
||||
@@ -278,9 +281,9 @@ function resolveLiveAccountProfileId(params: {
|
||||
const account = isJsonObject(params.account.value.account)
|
||||
? params.account.value.account
|
||||
: params.account.value;
|
||||
const type = readString(account, "type")?.toLowerCase();
|
||||
const type = normalizeOptionalString(account.type)?.toLowerCase();
|
||||
if (type === "chatgpt") {
|
||||
const email = readString(account, "email")?.toLowerCase();
|
||||
const email = normalizeOptionalString(account.email)?.toLowerCase();
|
||||
const firstSubscription = params.order.find((profileId) =>
|
||||
isChatGptSubscriptionProfile(params.store.profiles[profileId]),
|
||||
);
|
||||
@@ -437,11 +440,6 @@ function formatUsageLineForDisplay(value: string): string {
|
||||
return value.replace(/^weekly\b/u, "Weekly").replace(/\bshort-term\b/u, "Short-term");
|
||||
}
|
||||
|
||||
function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function isChatGptSubscriptionProfile(credential: AuthProfileCredential | undefined): boolean {
|
||||
return credential?.type === "oauth" || credential?.type === "token";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { PluginCommandContext, PluginCommandResult } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveCodexAppServerAuthProfileIdForAgent } from "./app-server/auth-bridge.js";
|
||||
import { resolveCodexBindingAppServerConnection } from "./app-server/binding-connection.js";
|
||||
import { isJsonObject } from "./app-server/protocol.js";
|
||||
@@ -29,7 +30,6 @@ import {
|
||||
readPendingCodexDiagnosticsConfirmation,
|
||||
recordCodexDiagnosticsUpload,
|
||||
} from "./command-diagnostics-support.js";
|
||||
import { readString } from "./command-formatters.js";
|
||||
import { CODEX_CONTROL_METHODS, type CodexCommandDeps } from "./command-handler-deps.js";
|
||||
import { resolveControlTarget } from "./command-handler-scope.js";
|
||||
|
||||
@@ -345,7 +345,7 @@ async function sendCodexDiagnosticsFeedbackForTargets(
|
||||
continue;
|
||||
}
|
||||
const responseThreadId = isJsonObject(response.value)
|
||||
? readString(response.value, "threadId")
|
||||
? normalizeOptionalString(response.value.threadId)
|
||||
: undefined;
|
||||
sent.push({ ...target, threadId: responseThreadId ?? target.threadId });
|
||||
recordCodexDiagnosticsUpload(target.threadId, ctx, now, options.cooldownScope);
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
* Formats Codex command responses for safe chat display, including status,
|
||||
* lists, account summaries, and user-facing help text.
|
||||
*/
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { CodexComputerUseStatus } from "./app-server/computer-use.js";
|
||||
import type { CodexAppServerModelListResult } from "./app-server/models.js";
|
||||
import { isJsonObject, type JsonObject, type JsonValue } from "./app-server/protocol.js";
|
||||
import { isJsonObject, type JsonValue } from "./app-server/protocol.js";
|
||||
import {
|
||||
hasCodexRateLimitSnapshots,
|
||||
summarizeCodexAccountRateLimits,
|
||||
@@ -96,13 +97,18 @@ export function formatThreads(response: JsonValue | undefined): string {
|
||||
"Codex threads:",
|
||||
...threads.slice(0, 10).map((thread) => {
|
||||
const record = isJsonObject(thread) ? thread : {};
|
||||
const id = readString(record, "threadId") ?? readString(record, "id") ?? "<unknown>";
|
||||
const id =
|
||||
normalizeOptionalString(record.threadId) ??
|
||||
normalizeOptionalString(record.id) ??
|
||||
"<unknown>";
|
||||
const title =
|
||||
readString(record, "title") ?? readString(record, "name") ?? readString(record, "summary");
|
||||
normalizeOptionalString(record.title) ??
|
||||
normalizeOptionalString(record.name) ??
|
||||
normalizeOptionalString(record.summary);
|
||||
const details = [
|
||||
readString(record, "model"),
|
||||
readString(record, "cwd"),
|
||||
readString(record, "updatedAt") ?? readString(record, "lastUpdatedAt"),
|
||||
normalizeOptionalString(record.model),
|
||||
normalizeOptionalString(record.cwd),
|
||||
normalizeOptionalString(record.updatedAt) ?? normalizeOptionalString(record.lastUpdatedAt),
|
||||
].filter((value): value is string => Boolean(value));
|
||||
return `- ${formatCodexDisplayText(id)}${title ? ` - ${formatCodexDisplayText(title)}` : ""}${
|
||||
details.length > 0 ? ` (${details.map(formatCodexDisplayText).join(", ")})` : ""
|
||||
@@ -222,7 +228,9 @@ export function formatList(response: JsonValue | undefined, label: string): stri
|
||||
...entries.slice(0, 25).map((entry) => {
|
||||
const record = isJsonObject(entry) ? entry : {};
|
||||
return `- ${formatCodexDisplayText(
|
||||
readString(record, "name") ?? readString(record, "id") ?? JSON.stringify(entry),
|
||||
normalizeOptionalString(record.name) ??
|
||||
normalizeOptionalString(record.id) ??
|
||||
JSON.stringify(entry),
|
||||
)}`;
|
||||
}),
|
||||
].join("\n");
|
||||
@@ -267,7 +275,7 @@ export function formatSkills(response: JsonValue | undefined): string {
|
||||
|
||||
function formatCodexSkillEntry(entry: JsonValue): string {
|
||||
const record = isJsonObject(entry) ? entry : {};
|
||||
const name = readString(record, "name") ?? "<unknown>";
|
||||
const name = normalizeOptionalString(record.name) ?? "<unknown>";
|
||||
return `\`${formatCodexDisplayText(name)}\``;
|
||||
}
|
||||
|
||||
@@ -406,15 +414,15 @@ function summarizeAccount(value: JsonValue | undefined): string {
|
||||
return "unavailable";
|
||||
}
|
||||
const account = isJsonObject(value.account) ? value.account : value;
|
||||
const accountType = readString(account, "type");
|
||||
const accountType = normalizeOptionalString(account.type);
|
||||
if (accountType === "amazonBedrock") {
|
||||
return "Amazon Bedrock";
|
||||
}
|
||||
return (
|
||||
readString(account, "email") ??
|
||||
readString(account, "accountEmail") ??
|
||||
readString(account, "planType") ??
|
||||
readString(account, "id") ??
|
||||
normalizeOptionalString(account.email) ??
|
||||
normalizeOptionalString(account.accountEmail) ??
|
||||
normalizeOptionalString(account.planType) ??
|
||||
normalizeOptionalString(account.id) ??
|
||||
"available"
|
||||
);
|
||||
}
|
||||
@@ -501,7 +509,8 @@ function isMeaningfulRateLimitSnapshot(value: JsonValue | undefined): boolean {
|
||||
return false;
|
||||
}
|
||||
const reachedType =
|
||||
readString(value, "rateLimitReachedType") ?? readString(value, "rate_limit_reached_type");
|
||||
normalizeOptionalString(value.rateLimitReachedType) ??
|
||||
normalizeOptionalString(value.rate_limit_reached_type);
|
||||
if (reachedType) {
|
||||
return true;
|
||||
}
|
||||
@@ -526,9 +535,3 @@ function extractArray(value: JsonValue | undefined): JsonValue[] {
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/** Reads and trims a non-empty string field from a JSON object. */
|
||||
export function readString(record: JsonObject, key: string): string | undefined {
|
||||
const value = record[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { MODEL_SELECTION_LOCKED_MESSAGE } from "openclaw/plugin-sdk/model-session-runtime";
|
||||
import type { PluginCommandContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveCodexBindingAppServerConnection } from "./app-server/binding-connection.js";
|
||||
import type { CodexComputerUseSetupParams } from "./app-server/computer-use.js";
|
||||
import { isJsonObject, type JsonValue } from "./app-server/protocol.js";
|
||||
@@ -9,11 +10,7 @@ import {
|
||||
resolveCodexNativeSandboxBlock,
|
||||
} from "./app-server/sandbox-guard.js";
|
||||
import { canMutateCodexHost } from "./command-authorization.js";
|
||||
import {
|
||||
formatCodexDisplayText,
|
||||
formatComputerUseStatus,
|
||||
readString,
|
||||
} from "./command-formatters.js";
|
||||
import { formatCodexDisplayText, formatComputerUseStatus } from "./command-formatters.js";
|
||||
import {
|
||||
formatComputerUsePersistentIdentityMigration,
|
||||
parseBindArgs,
|
||||
@@ -260,8 +257,8 @@ function formatNativeGoal(response: JsonValue | undefined): string {
|
||||
if (!goal) {
|
||||
return "No Codex goal is active.";
|
||||
}
|
||||
const objective = readString(goal, "objective") ?? "unknown";
|
||||
const status = readString(goal, "status") ?? "unknown";
|
||||
const objective = normalizeOptionalString(goal.objective) ?? "unknown";
|
||||
const status = normalizeOptionalString(goal.status) ?? "unknown";
|
||||
const tokensUsed = typeof goal.tokensUsed === "number" ? goal.tokensUsed : 0;
|
||||
const tokenBudget = typeof goal.tokenBudget === "number" ? goal.tokenBudget : undefined;
|
||||
return [
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
import { createHash, randomUUID } from "node:crypto";
|
||||
import process from "node:process";
|
||||
import type { PluginConversationBinding } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { asOptionalRecord as readRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asOptionalRecord as readRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
const APP_SERVER_BINDING_DATA_VERSION = 2;
|
||||
const CLI_BINDING_DATA_VERSION = 1;
|
||||
@@ -160,10 +163,10 @@ export function readCodexConversationBindingDataRecord(
|
||||
function readConversationSource(
|
||||
value: CodexAppServerConversationSource | Record<string, unknown> | undefined,
|
||||
): CodexAppServerConversationSource | undefined {
|
||||
const agentId = readString(value, "agentId");
|
||||
const sessionId = readString(value, "sessionId");
|
||||
const threadId = readString(value, "threadId");
|
||||
const sessionKey = readString(value, "sessionKey");
|
||||
const agentId = normalizeOptionalString(value?.agentId);
|
||||
const sessionId = normalizeOptionalString(value?.sessionId);
|
||||
const threadId = normalizeOptionalString(value?.threadId);
|
||||
const sessionKey = normalizeOptionalString(value?.sessionKey);
|
||||
if (!agentId || !sessionId || !threadId) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -182,15 +185,10 @@ export function legacyCodexConversationBindingId(sessionFile: string): string {
|
||||
|
||||
export function resolveCodexDefaultWorkspaceDir(pluginConfig: unknown): string {
|
||||
const appServer = readRecord(readRecord(pluginConfig)?.appServer);
|
||||
const configured = readString(appServer, "defaultWorkspaceDir");
|
||||
const configured = normalizeOptionalString(appServer?.defaultWorkspaceDir);
|
||||
return configured ?? process.cwd();
|
||||
}
|
||||
|
||||
function readString(record: Record<string, unknown> | undefined, key: string) {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readConversationStart(
|
||||
value: CodexAppServerConversationStart | Record<string, unknown> | undefined,
|
||||
): CodexAppServerConversationStart | undefined {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Codex plugin module implements conversation turn collector behavior.
|
||||
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
||||
import { asOptionalRecord as readRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
asOptionalRecord as readRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { isAssistantCommentaryCompletionNotification } from "./app-server/attempt-notifications.js";
|
||||
import { isCodexNotificationForTurn } from "./app-server/notification-correlation.js";
|
||||
import {
|
||||
@@ -57,7 +60,7 @@ export function createCodexConversationTurnCollector(threadId: string) {
|
||||
return;
|
||||
}
|
||||
if (notification.method === "item/agentMessage/delta") {
|
||||
const itemId = readString(params, "itemId") ?? "assistant";
|
||||
const itemId = normalizeOptionalString(params.itemId) ?? "assistant";
|
||||
const delta = readTextString(params, "delta");
|
||||
if (!delta) {
|
||||
return;
|
||||
@@ -68,7 +71,8 @@ export function createCodexConversationTurnCollector(threadId: string) {
|
||||
if (notification.method === "item/completed") {
|
||||
const item = isJsonObject(params.item) ? params.item : undefined;
|
||||
if (item?.type === "agentMessage") {
|
||||
const itemId = readString(item, "id") ?? readString(params, "itemId") ?? "assistant";
|
||||
const itemId =
|
||||
normalizeOptionalString(item.id) ?? normalizeOptionalString(params.itemId) ?? "assistant";
|
||||
assistantTextByItem.delete(itemId);
|
||||
if (isAssistantCommentaryCompletionNotification(notification)) {
|
||||
return;
|
||||
@@ -82,10 +86,11 @@ export function createCodexConversationTurnCollector(threadId: string) {
|
||||
}
|
||||
if (notification.method === "turn/completed") {
|
||||
const turn = isJsonObject(params.turn) ? params.turn : undefined;
|
||||
const status = readString(turn, "status");
|
||||
const status = normalizeOptionalString(turn?.status);
|
||||
if (status === "failed") {
|
||||
failedError =
|
||||
readString(readRecord(turn?.error), "message") ?? "codex app-server turn failed";
|
||||
normalizeOptionalString(readRecord(turn?.error)?.message) ??
|
||||
"codex app-server turn failed";
|
||||
} else if (status === "interrupted") {
|
||||
// Codex reports an interrupted turn as a terminal completion without a
|
||||
// final answer; streamed partial text must not become a successful reply.
|
||||
@@ -99,7 +104,8 @@ export function createCodexConversationTurnCollector(threadId: string) {
|
||||
if (!isJsonObject(item) || item.type !== "agentMessage") {
|
||||
continue;
|
||||
}
|
||||
const itemId = readString(item, "id") ?? `assistant-${assistantTextByItem.size + 1}`;
|
||||
const itemId =
|
||||
normalizeOptionalString(item.id) ?? `assistant-${assistantTextByItem.size + 1}`;
|
||||
assistantTextByItem.delete(itemId);
|
||||
const text = item.phase === "commentary" ? undefined : readTextString(item, "text");
|
||||
if (text?.trim()) {
|
||||
@@ -139,11 +145,6 @@ export function createCodexConversationTurnCollector(threadId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function readString(record: Record<string, unknown> | JsonObject | undefined, key: string) {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function readTextString(record: Record<string, unknown> | JsonObject | undefined, key: string) {
|
||||
const value = record?.[key];
|
||||
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
ModelSelectionLockedError,
|
||||
} from "openclaw/plugin-sdk/model-session-runtime";
|
||||
import type { OpenClawPluginToolContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { asBoolean, asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { Type } from "typebox";
|
||||
import { resolveCodexBindingAppServerConnection } from "./app-server/binding-connection.js";
|
||||
import { CODEX_CONTROL_METHODS } from "./app-server/capabilities.js";
|
||||
@@ -111,16 +112,6 @@ type CodexThreadsToolOptions = {
|
||||
request?: typeof codexControlRequest;
|
||||
};
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> {
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: {};
|
||||
}
|
||||
|
||||
function readBoolean(value: unknown, fallback = false): boolean {
|
||||
return typeof value === "boolean" ? value : fallback;
|
||||
}
|
||||
|
||||
function readLimit(value: unknown): number | undefined {
|
||||
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= 100
|
||||
? value
|
||||
@@ -279,7 +270,7 @@ export function createCodexThreadsTool(options: CodexThreadsToolOptions): AnyAge
|
||||
"Manage native Codex threads: list, read, fork, rename, archive (confirm:true), unarchive. When supervision is enabled, raw transcript reads and every mutation require their matching supervision policy option.",
|
||||
parameters: CodexThreadsParamsSchema,
|
||||
async execute(_toolCallId, rawParams) {
|
||||
const params = asRecord(rawParams);
|
||||
const params = asOptionalRecord(rawParams) ?? {};
|
||||
const action = readStringParam(params, "action", { required: true, label: "action" });
|
||||
const pluginConfig = options.getPluginConfig();
|
||||
const plugin = readCodexPluginConfig(pluginConfig);
|
||||
@@ -299,7 +290,7 @@ export function createCodexThreadsTool(options: CodexThreadsToolOptions): AnyAge
|
||||
pluginConfig,
|
||||
CODEX_CONTROL_METHODS.listThreads,
|
||||
{
|
||||
archived: readBoolean(params.archived),
|
||||
archived: asBoolean(params.archived) ?? false,
|
||||
limit: readLimit(params.limit) ?? 20,
|
||||
modelProviders: [],
|
||||
sortKey: "recency_at",
|
||||
@@ -315,7 +306,7 @@ export function createCodexThreadsTool(options: CodexThreadsToolOptions): AnyAge
|
||||
|
||||
const threadId = readThreadId(params);
|
||||
if (action === "read") {
|
||||
const includeTurns = readBoolean(params.include_turns);
|
||||
const includeTurns = asBoolean(params.include_turns) ?? false;
|
||||
if (includeTurns && !mayReadRawTranscripts) {
|
||||
throw new Error(
|
||||
"Codex raw transcript reads are disabled for this codex plugin supervision config.",
|
||||
@@ -429,7 +420,7 @@ export function createCodexThreadsTool(options: CodexThreadsToolOptions): AnyAge
|
||||
throw new Error(`unsupported codex_threads action: ${action}`);
|
||||
}
|
||||
|
||||
const attach = readBoolean(params.attach, true);
|
||||
const attach = asBoolean(params.attach) ?? true;
|
||||
if (attach && !session) {
|
||||
throw new Error("cannot attach a Codex fork without an active OpenClaw session");
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export function normalizeLimit(value: unknown, key: string): number {
|
||||
return value as number;
|
||||
}
|
||||
|
||||
export function readOptionalString(
|
||||
export function readBoundedOptionalString(
|
||||
params: Record<string, unknown>,
|
||||
key: string,
|
||||
maxLength: number,
|
||||
@@ -217,9 +217,9 @@ export function readPageParams(value: unknown): CodexSessionCatalogPageParams {
|
||||
}
|
||||
const params = value;
|
||||
requireOnlyKeys(params, new Set(["cursor", "limit", "searchTerm", "cwd"]));
|
||||
const cursor = readOptionalString(params, "cursor", MAX_CURSOR_LENGTH);
|
||||
const searchTerm = readOptionalString(params, "searchTerm", MAX_SEARCH_LENGTH);
|
||||
const cwd = readOptionalString(params, "cwd", MAX_CWD_LENGTH);
|
||||
const cursor = readBoundedOptionalString(params, "cursor", MAX_CURSOR_LENGTH);
|
||||
const searchTerm = readBoundedOptionalString(params, "searchTerm", MAX_SEARCH_LENGTH);
|
||||
const cwd = readBoundedOptionalString(params, "cwd", MAX_CWD_LENGTH);
|
||||
return {
|
||||
limit: normalizeLimit(params.limit, "limit"),
|
||||
...(cursor ? { cursor } : {}),
|
||||
@@ -234,7 +234,7 @@ export function readGatewayParams(value: unknown): CodexSessionCatalogParams {
|
||||
}
|
||||
const params = isRecord(value) ? value : {};
|
||||
requireOnlyKeys(params, new Set(["search", "limitPerHost", "hostIds", "cursors"]));
|
||||
const search = readOptionalString(params, "search", MAX_SEARCH_LENGTH);
|
||||
const search = readBoundedOptionalString(params, "search", MAX_SEARCH_LENGTH);
|
||||
let hostIds: string[] | undefined;
|
||||
if (params.hostIds !== undefined) {
|
||||
if (!Array.isArray(params.hostIds) || params.hostIds.length > MAX_HOST_COUNT) {
|
||||
|
||||
@@ -87,7 +87,7 @@ import {
|
||||
parseTranscriptPage,
|
||||
readControlCursor,
|
||||
readGatewayParams,
|
||||
readOptionalString,
|
||||
readBoundedOptionalString,
|
||||
readPageParams,
|
||||
requireBoundThread,
|
||||
requireOnlyKeys,
|
||||
@@ -731,11 +731,11 @@ function readNodeTranscriptParams(value: unknown): CodexNodeSessionTranscriptPar
|
||||
throw new CatalogParamsError("Codex session read parameters must be an object");
|
||||
}
|
||||
requireOnlyKeys(value, new Set(["threadId", "cursor", "limit"]));
|
||||
const threadId = readOptionalString(value, "threadId", MAX_SESSION_ID_LENGTH);
|
||||
const threadId = readBoundedOptionalString(value, "threadId", MAX_SESSION_ID_LENGTH);
|
||||
if (!threadId) {
|
||||
throw new CatalogParamsError("threadId is required");
|
||||
}
|
||||
const cursor = readOptionalString(value, "cursor", MAX_CURSOR_LENGTH);
|
||||
const cursor = readBoundedOptionalString(value, "cursor", MAX_CURSOR_LENGTH);
|
||||
const limit = readBoundedLimit(
|
||||
value.limit,
|
||||
"limit",
|
||||
|
||||
@@ -157,10 +157,6 @@ type CodexSupervisionToolsOptions = {
|
||||
useLegacyMcpPolicyEnv?: boolean;
|
||||
};
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> {
|
||||
return isRecord(value) ? value : {};
|
||||
}
|
||||
|
||||
function asRecordArray(value: unknown): Record<string, unknown>[] {
|
||||
return Array.isArray(value) ? value.filter(isRecord) : [];
|
||||
}
|
||||
@@ -1081,7 +1077,7 @@ export function createCodexSupervisionTools(options: CodexSupervisionToolsOption
|
||||
description: "List Codex sessions visible to the OpenClaw supervisor.",
|
||||
parameters: SessionsListParamsSchema,
|
||||
execute: async (_toolCallId, rawParams) => {
|
||||
const params = asRecord(rawParams);
|
||||
const params = isRecord(rawParams) ? rawParams : {};
|
||||
const { endpoints } = current();
|
||||
const result = await listSessionSnapshot({
|
||||
endpoints,
|
||||
@@ -1107,7 +1103,7 @@ export function createCodexSupervisionTools(options: CodexSupervisionToolsOption
|
||||
execute: async (_toolCallId, rawParams) => {
|
||||
const { endpoints, pluginConfig } = current();
|
||||
requireRawTranscriptAccess(options, pluginConfig);
|
||||
const params = asRecord(rawParams);
|
||||
const params = isRecord(rawParams) ? rawParams : {};
|
||||
const threadId = readStringParam(params, "thread_id", { required: true });
|
||||
const endpoint = await resolveEndpointForThread({
|
||||
endpoints,
|
||||
@@ -1137,7 +1133,7 @@ export function createCodexSupervisionTools(options: CodexSupervisionToolsOption
|
||||
execute: async (_toolCallId, rawParams) => {
|
||||
const { endpoints, pluginConfig } = current();
|
||||
requireWriteAccess(options, pluginConfig);
|
||||
const params = asRecord(rawParams);
|
||||
const params = isRecord(rawParams) ? rawParams : {};
|
||||
const threadId = readStringParam(params, "thread_id", { required: true });
|
||||
const text = readStringParam(params, "text", { required: true, allowEmpty: false });
|
||||
const mode = readModeParam(params) ?? "auto";
|
||||
@@ -1186,7 +1182,7 @@ export function createCodexSupervisionTools(options: CodexSupervisionToolsOption
|
||||
execute: async (_toolCallId, rawParams) => {
|
||||
const { endpoints, pluginConfig } = current();
|
||||
requireWriteAccess(options, pluginConfig);
|
||||
const params = asRecord(rawParams);
|
||||
const params = isRecord(rawParams) ? rawParams : {};
|
||||
const threadId = readStringParam(params, "thread_id", { required: true });
|
||||
const endpoint = await resolveEndpointForThread({
|
||||
endpoints,
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
awaitAgentEndSideEffects,
|
||||
runAgentEndSideEffects,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { toError } from "./attempt-config.js";
|
||||
import { toCopilotError } from "./attempt-config.js";
|
||||
import {
|
||||
BACKGROUND_COMPACTION_CANCEL_TIMEOUT_MS,
|
||||
type AgentHarnessAttemptResult,
|
||||
@@ -31,7 +31,7 @@ export async function finalizeCopilotAttempt(
|
||||
messages: result.messagesSnapshot,
|
||||
success: !aborted && !failure && !timedOut,
|
||||
...(failure
|
||||
? { error: toError(failure.error).message }
|
||||
? { error: toCopilotError(failure.error).message }
|
||||
: timedOut
|
||||
? { error: "Copilot SDK turn timed out." }
|
||||
: {}),
|
||||
|
||||
@@ -129,8 +129,8 @@ export function createResult(
|
||||
messagingToolSentTargets: [],
|
||||
messagingToolSentTexts: [],
|
||||
replayMetadata,
|
||||
sessionFileUsed: readString(params.sessionFile),
|
||||
sessionIdUsed: state.sessionIdUsed ?? readString(params.sessionId) ?? "copilot-session",
|
||||
sessionFileUsed: readNonEmptyString(params.sessionFile),
|
||||
sessionIdUsed: state.sessionIdUsed ?? readNonEmptyString(params.sessionId) ?? "copilot-session",
|
||||
toolMetas,
|
||||
yieldDetected: state.yieldDetected === true,
|
||||
};
|
||||
@@ -323,7 +323,7 @@ export function createSystemMessageContent(
|
||||
if (bootstrap) {
|
||||
sections.push(bootstrap);
|
||||
}
|
||||
const extraSystemPrompt = readString(params.extraSystemPrompt)?.trim();
|
||||
const extraSystemPrompt = readNonEmptyString(params.extraSystemPrompt)?.trim();
|
||||
if (extraSystemPrompt) {
|
||||
const contextHeader =
|
||||
params.promptMode === "minimal" ? "## Subagent Context" : "## Conversation Context";
|
||||
@@ -334,11 +334,11 @@ export function createSystemMessageContent(
|
||||
export function isRawCopilotModelRun(params: AttemptParamsLike): boolean {
|
||||
return params.modelRun === true || params.promptMode === "none";
|
||||
}
|
||||
export function readString(value: unknown): string | undefined {
|
||||
export function readNonEmptyString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||
}
|
||||
export function readResolvedAttemptPath(value: unknown): string | undefined {
|
||||
const raw = readString(value)?.trim();
|
||||
const raw = readNonEmptyString(value)?.trim();
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -354,20 +354,20 @@ export function resolveModelRef(params: AttemptParamsLike): ModelRef {
|
||||
const requestTransport = getModelProviderRequestTransport(rawModel);
|
||||
const rawRequest = model.request;
|
||||
return {
|
||||
api: readString(model.api),
|
||||
api: readNonEmptyString(model.api),
|
||||
id:
|
||||
readString(model.id) ??
|
||||
readString((params as { modelId?: unknown }).modelId) ??
|
||||
readNonEmptyString(model.id) ??
|
||||
readNonEmptyString((params as { modelId?: unknown }).modelId) ??
|
||||
"unknown-model",
|
||||
provider:
|
||||
readString(model.provider) ??
|
||||
readString((params as { provider?: unknown }).provider) ??
|
||||
readNonEmptyString(model.provider) ??
|
||||
readNonEmptyString((params as { provider?: unknown }).provider) ??
|
||||
"unknown-provider",
|
||||
baseUrl: readString(model.baseUrl),
|
||||
azureApiVersion: readString(model.azureApiVersion ?? model.params?.azureApiVersion),
|
||||
baseUrl: readNonEmptyString(model.baseUrl),
|
||||
azureApiVersion: readNonEmptyString(model.azureApiVersion ?? model.params?.azureApiVersion),
|
||||
headers: model.headers,
|
||||
authHeader: model.authHeader,
|
||||
requestAuthMode: readString(requestTransport?.auth?.mode ?? rawRequest?.auth?.mode),
|
||||
requestAuthMode: readNonEmptyString(requestTransport?.auth?.mode ?? rawRequest?.auth?.mode),
|
||||
requestProxy: requestTransport?.proxy ?? rawRequest?.proxy,
|
||||
requestTls: requestTransport?.tls ?? rawRequest?.tls,
|
||||
requestAllowPrivateNetwork:
|
||||
@@ -379,10 +379,10 @@ export function resolveModelRef(params: AttemptParamsLike): ModelRef {
|
||||
}
|
||||
return {
|
||||
id:
|
||||
readString(typeof rawModel === "string" ? rawModel : undefined) ??
|
||||
readString((params as { modelId?: unknown }).modelId) ??
|
||||
readNonEmptyString(typeof rawModel === "string" ? rawModel : undefined) ??
|
||||
readNonEmptyString((params as { modelId?: unknown }).modelId) ??
|
||||
"unknown-model",
|
||||
provider: readString((params as { provider?: unknown }).provider) ?? "unknown-provider",
|
||||
provider: readNonEmptyString((params as { provider?: unknown }).provider) ?? "unknown-provider",
|
||||
};
|
||||
}
|
||||
export function resolvePoolAcquire(params: AttemptParamsLike): {
|
||||
@@ -394,28 +394,28 @@ export function resolvePoolAcquire(params: AttemptParamsLike): {
|
||||
const model = resolveModelRef(params);
|
||||
const provider = resolveCopilotProvider({
|
||||
model,
|
||||
resolvedApiKey: readString(params.resolvedApiKey),
|
||||
authProfileId: readString(params.authProfileId),
|
||||
resolvedApiKey: readNonEmptyString(params.resolvedApiKey),
|
||||
authProfileId: readNonEmptyString(params.authProfileId),
|
||||
});
|
||||
const auth =
|
||||
provider.mode === "byok"
|
||||
? createCopilotByokAuth({
|
||||
agentId: readString(params.agentId),
|
||||
agentDir: readString(params.agentDir),
|
||||
workspaceDir: readString(params.workspaceDir),
|
||||
copilotHome: readString(params.copilotHome),
|
||||
agentId: readNonEmptyString(params.agentId),
|
||||
agentDir: readNonEmptyString(params.agentDir),
|
||||
workspaceDir: readNonEmptyString(params.workspaceDir),
|
||||
copilotHome: readNonEmptyString(params.copilotHome),
|
||||
authProfileId: provider.authProfileId,
|
||||
authProfileVersion: provider.authProfileVersion,
|
||||
})
|
||||
: resolveCopilotAuth({
|
||||
agentId: readString(params.agentId),
|
||||
agentDir: readString(params.agentDir),
|
||||
workspaceDir: readString(params.workspaceDir),
|
||||
copilotHome: readString(params.copilotHome),
|
||||
agentId: readNonEmptyString(params.agentId),
|
||||
agentDir: readNonEmptyString(params.agentDir),
|
||||
workspaceDir: readNonEmptyString(params.workspaceDir),
|
||||
copilotHome: readNonEmptyString(params.copilotHome),
|
||||
auth: params.auth,
|
||||
resolvedApiKey: readString(params.resolvedApiKey),
|
||||
authProfileId: readString(params.authProfileId),
|
||||
profileVersion: readString(params.profileVersion),
|
||||
resolvedApiKey: readNonEmptyString(params.resolvedApiKey),
|
||||
authProfileId: readNonEmptyString(params.authProfileId),
|
||||
profileVersion: readNonEmptyString(params.profileVersion),
|
||||
});
|
||||
return {
|
||||
key: {
|
||||
@@ -440,7 +440,7 @@ export function resolvePoolAcquire(params: AttemptParamsLike): {
|
||||
provider,
|
||||
};
|
||||
}
|
||||
export function toError(error: unknown): Error {
|
||||
export function toCopilotError(error: unknown): Error {
|
||||
return error instanceof Error ? error : new Error(String(error));
|
||||
}
|
||||
export function isSdkSendAndWaitTimeoutError(error: unknown): boolean {
|
||||
|
||||
@@ -20,10 +20,10 @@ import {
|
||||
createPromptError,
|
||||
createResult,
|
||||
isSdkSendAndWaitTimeoutError,
|
||||
readNonEmptyString,
|
||||
readResolvedAttemptPath,
|
||||
readString,
|
||||
resolvePoolAcquire,
|
||||
toError,
|
||||
toCopilotError,
|
||||
} from "./attempt-config.js";
|
||||
import { completeCopilotAttempt } from "./attempt-finalize.js";
|
||||
import { resolveCopilotAttemptSandbox } from "./attempt-prepare.js";
|
||||
@@ -179,7 +179,7 @@ export async function runCopilotExecution(context: {
|
||||
now,
|
||||
promptError: createPromptError(
|
||||
"sandbox_resolution_failure",
|
||||
`[copilot-attempt] sandbox resolution failed: ${toError(error).message}`,
|
||||
`[copilot-attempt] sandbox resolution failed: ${toCopilotError(error).message}`,
|
||||
error,
|
||||
),
|
||||
sdkSessionId: undefined,
|
||||
@@ -237,7 +237,7 @@ export async function runCopilotExecution(context: {
|
||||
createResult(input, {
|
||||
messagesSnapshot: messages,
|
||||
now,
|
||||
promptError: createPromptError("model_not_supported", toError(error).message, error),
|
||||
promptError: createPromptError("model_not_supported", toCopilotError(error).message, error),
|
||||
sdkSessionId: undefined,
|
||||
sessionIdUsed: input.sessionId,
|
||||
}),
|
||||
@@ -265,10 +265,10 @@ export async function runCopilotExecution(context: {
|
||||
allowModelTools: poolAcquire.provider.mode === "byok",
|
||||
modelProvider: modelRef.provider,
|
||||
modelId: modelRef.id,
|
||||
agentId: readString(params.agentId) ?? "copilot",
|
||||
sessionId: readString(input.sessionId) ?? "copilot-session",
|
||||
sessionKey: readString((input as { sessionKey?: unknown }).sessionKey),
|
||||
agentDir: readString(input.agentDir),
|
||||
agentId: readNonEmptyString(params.agentId) ?? "copilot",
|
||||
sessionId: readNonEmptyString(input.sessionId) ?? "copilot-session",
|
||||
sessionKey: readNonEmptyString((input as { sessionKey?: unknown }).sessionKey),
|
||||
agentDir: readNonEmptyString(input.agentDir),
|
||||
workspaceDir: effectiveWorkspaceDir,
|
||||
cwd: effectiveCwd,
|
||||
sandbox,
|
||||
@@ -309,7 +309,7 @@ export async function runCopilotExecution(context: {
|
||||
now,
|
||||
promptError: createPromptError(
|
||||
"tool_bridge_failure",
|
||||
`[copilot-attempt] tool-bridge construction failed: ${toError(error).message}`,
|
||||
`[copilot-attempt] tool-bridge construction failed: ${toCopilotError(error).message}`,
|
||||
error,
|
||||
),
|
||||
sdkSessionId: undefined,
|
||||
@@ -366,7 +366,7 @@ export async function runCopilotExecution(context: {
|
||||
if (settledToolFinalization) {
|
||||
throw createPromptError(
|
||||
"settled_finalization_resume_failed",
|
||||
`[copilot-attempt] settled tool finalization could not resume the existing Copilot SDK session: ${toError(error).message}`,
|
||||
`[copilot-attempt] settled tool finalization could not resume the existing Copilot SDK session: ${toCopilotError(error).message}`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
@@ -386,8 +386,8 @@ export async function runCopilotExecution(context: {
|
||||
}
|
||||
sessionRef.current = session;
|
||||
sdkSessionId =
|
||||
readString(session.sessionId) ??
|
||||
readString(session.id) ??
|
||||
readNonEmptyString(session.sessionId) ??
|
||||
readNonEmptyString(session.id) ??
|
||||
(resumeFailureRecovered ? undefined : resumeSessionId);
|
||||
if (!sdkSessionId) {
|
||||
throw createPromptError(
|
||||
@@ -428,7 +428,7 @@ export async function runCopilotExecution(context: {
|
||||
if (settledToolFinalization) {
|
||||
return;
|
||||
}
|
||||
const sessionFile = readString(input.sessionFile);
|
||||
const sessionFile = readNonEmptyString(input.sessionFile);
|
||||
if (!sessionFile) {
|
||||
return;
|
||||
}
|
||||
@@ -441,7 +441,7 @@ export async function runCopilotExecution(context: {
|
||||
if (settledToolFinalization) {
|
||||
return;
|
||||
}
|
||||
const sessionFile = readString(input.sessionFile);
|
||||
const sessionFile = readNonEmptyString(input.sessionFile);
|
||||
if (!success || !sessionFile) {
|
||||
return;
|
||||
}
|
||||
@@ -525,15 +525,15 @@ export async function runCopilotExecution(context: {
|
||||
try {
|
||||
await transcriptJournal?.barrier("timeout");
|
||||
} catch (transcriptError) {
|
||||
promptError = toError(transcriptError);
|
||||
promptError = toCopilotError(transcriptError);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
bridge?.flushTranscriptProjection();
|
||||
await transcriptJournal?.barrier("attempt error");
|
||||
promptError = toError(error);
|
||||
promptError = toCopilotError(error);
|
||||
} catch (transcriptError) {
|
||||
promptError = toError(transcriptError);
|
||||
promptError = toCopilotError(transcriptError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -543,7 +543,7 @@ export async function runCopilotExecution(context: {
|
||||
bridge?.flushTranscriptProjection();
|
||||
await transcriptJournal?.barrier("bridge detach");
|
||||
} catch (transcriptError) {
|
||||
promptError = toError(transcriptError);
|
||||
promptError = toCopilotError(transcriptError);
|
||||
}
|
||||
userInputBridgeRef?.cancelPending();
|
||||
if (activeRunHandleRef) {
|
||||
@@ -612,7 +612,7 @@ export async function runCopilotExecution(context: {
|
||||
try {
|
||||
await session.disconnect();
|
||||
} catch (error: unknown) {
|
||||
disconnectError = toError(error);
|
||||
disconnectError = toCopilotError(error);
|
||||
if (!promptError && !timedOut) {
|
||||
promptError = disconnectError;
|
||||
}
|
||||
@@ -622,7 +622,7 @@ export async function runCopilotExecution(context: {
|
||||
try {
|
||||
await deps.pool.release(handle);
|
||||
} catch (error: unknown) {
|
||||
const releaseFailure = toError(error);
|
||||
const releaseFailure = toCopilotError(error);
|
||||
if (promptError) {
|
||||
console.warn(
|
||||
"[copilot-attempt] pool.release failed after primary error",
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
resolveSandboxContext as defaultResolveSandboxContext,
|
||||
resolveSessionAgentIds,
|
||||
} from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import { readResolvedAttemptPath, readString, resolveModelRef } from "./attempt-config.js";
|
||||
import { readNonEmptyString, readResolvedAttemptPath, resolveModelRef } from "./attempt-config.js";
|
||||
import type {
|
||||
AttemptParamsLike,
|
||||
CopilotAttemptDeps,
|
||||
@@ -58,13 +58,13 @@ export function prepareCopilotAttemptContext(
|
||||
const resolvedWorkspaceForSandbox =
|
||||
readResolvedAttemptPath(input.workspaceDir) ?? readResolvedAttemptPath(input.cwd);
|
||||
const sandboxSessionKey =
|
||||
readString((input as { sandboxSessionKey?: unknown }).sandboxSessionKey) ??
|
||||
readString((input as { sessionKey?: unknown }).sessionKey) ??
|
||||
readString(input.sessionId);
|
||||
readNonEmptyString((input as { sandboxSessionKey?: unknown }).sandboxSessionKey) ??
|
||||
readNonEmptyString((input as { sessionKey?: unknown }).sessionKey) ??
|
||||
readNonEmptyString(input.sessionId);
|
||||
const { sessionAgentId } = resolveSessionAgentIds({
|
||||
sessionKey: readString((input as { sessionKey?: unknown }).sessionKey),
|
||||
sessionKey: readNonEmptyString((input as { sessionKey?: unknown }).sessionKey),
|
||||
config: input.config,
|
||||
agentId: readString(params.agentId),
|
||||
agentId: readNonEmptyString(params.agentId),
|
||||
});
|
||||
const hookContextWindowFields = {
|
||||
...(input.contextWindowInfo?.tokens
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
type SessionTranscriptTargetParams,
|
||||
type TranscriptEntryAnchor,
|
||||
} from "openclaw/plugin-sdk/session-transcript-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { AttemptParamsLike } from "./attempt-types.js";
|
||||
|
||||
type TranscriptMessage = Extract<AgentMessage, { role: "user" | "assistant" | "toolResult" }>;
|
||||
@@ -606,9 +607,9 @@ function createPersistenceReceipt(): PersistenceReceipt {
|
||||
}
|
||||
|
||||
function resolveTranscriptTarget(attempt: AttemptParamsLike): SessionTranscriptTargetParams {
|
||||
const sessionId = readString(attempt.sessionTarget?.sessionId);
|
||||
const sessionKey = readString(attempt.sessionTarget?.sessionKey);
|
||||
const storePath = readString(attempt.sessionTarget?.storePath);
|
||||
const sessionId = normalizeOptionalString(attempt.sessionTarget?.sessionId);
|
||||
const sessionKey = normalizeOptionalString(attempt.sessionTarget?.sessionKey);
|
||||
const storePath = normalizeOptionalString(attempt.sessionTarget?.storePath);
|
||||
if (!sessionId || !sessionKey || !storePath) {
|
||||
const error = new Error(
|
||||
"[copilot-attempt] canonical transcript persistence requires an exact runtime session target",
|
||||
@@ -616,7 +617,7 @@ function resolveTranscriptTarget(attempt: AttemptParamsLike): SessionTranscriptT
|
||||
error.code = "transcript_persistence_failed";
|
||||
throw error;
|
||||
}
|
||||
const agentId = readString(attempt.sessionTarget?.agentId ?? attempt.agentId);
|
||||
const agentId = normalizeOptionalString(attempt.sessionTarget?.agentId ?? attempt.agentId);
|
||||
return { sessionId, sessionKey, storePath, ...(agentId ? { agentId } : {}) };
|
||||
}
|
||||
|
||||
@@ -738,7 +739,3 @@ function userText(content: unknown): string {
|
||||
}
|
||||
return JSON.stringify(content) ?? "";
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ import { finalizeCopilotAttempt } from "./attempt-cleanup.js";
|
||||
import {
|
||||
createPromptError,
|
||||
createResult,
|
||||
readString,
|
||||
readNonEmptyString,
|
||||
resolvePoolAcquire,
|
||||
toError,
|
||||
toCopilotError,
|
||||
} from "./attempt-config.js";
|
||||
import { runCopilotExecution } from "./attempt-execution.js";
|
||||
import { prepareCopilotAttemptContext } from "./attempt-prepare.js";
|
||||
@@ -55,22 +55,22 @@ export async function runCopilotAttempt(
|
||||
try {
|
||||
resolveCopilotProvider({
|
||||
model: modelRef,
|
||||
resolvedApiKey: readString(params.resolvedApiKey),
|
||||
authProfileId: readString(params.authProfileId),
|
||||
resolvedApiKey: readNonEmptyString(params.resolvedApiKey),
|
||||
authProfileId: readNonEmptyString(params.authProfileId),
|
||||
});
|
||||
} catch (error) {
|
||||
return finishAttempt(
|
||||
createResult(input, {
|
||||
messagesSnapshot: messages,
|
||||
now,
|
||||
promptError: createPromptError("model_not_supported", toError(error).message, error),
|
||||
promptError: createPromptError("model_not_supported", toCopilotError(error).message, error),
|
||||
sdkSessionId: undefined,
|
||||
sessionIdUsed: input.sessionId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
const settledFinalizationSessionId = settledToolFinalization
|
||||
? readString(input.initialReplayState?.sdkSessionId)
|
||||
? readNonEmptyString(input.initialReplayState?.sdkSessionId)
|
||||
: undefined;
|
||||
if (settledToolFinalization && !settledFinalizationSessionId) {
|
||||
return finishAttempt(
|
||||
|
||||
@@ -149,18 +149,19 @@ export function resolveCopilotAuth(input: ResolveCopilotAuthInput): ResolvedCopi
|
||||
|
||||
const agentId = sanitizeAgentId(input.agentId);
|
||||
const copilotHome = resolveCopilotHome({
|
||||
explicit: readString(input.copilotHome),
|
||||
agentDir: readString(input.agentDir),
|
||||
workspaceDir: readString(input.workspaceDir),
|
||||
explicit: readNonEmptyString(input.copilotHome),
|
||||
agentDir: readNonEmptyString(input.agentDir),
|
||||
workspaceDir: readNonEmptyString(input.workspaceDir),
|
||||
agentId,
|
||||
env,
|
||||
homeDir,
|
||||
});
|
||||
|
||||
const explicitToken = readString(input.auth?.gitHubToken);
|
||||
const explicitProfileId = readString(input.auth?.profileId) ?? readString(input.authProfileId);
|
||||
const explicitToken = readNonEmptyString(input.auth?.gitHubToken);
|
||||
const explicitProfileId =
|
||||
readNonEmptyString(input.auth?.profileId) ?? readNonEmptyString(input.authProfileId);
|
||||
const explicitProfileVersion =
|
||||
readString(input.auth?.profileVersion) ?? readString(input.profileVersion);
|
||||
readNonEmptyString(input.auth?.profileVersion) ?? readNonEmptyString(input.profileVersion);
|
||||
|
||||
if (input.auth?.useLoggedInUser === true) {
|
||||
return {
|
||||
@@ -192,9 +193,9 @@ export function resolveCopilotAuth(input: ResolveCopilotAuthInput): ResolvedCopi
|
||||
// We synthesise the pool-key version from the token fingerprint so
|
||||
// rotation busts the cache cleanly (matching the env-fallback
|
||||
// strategy). The contract does not carry a separate `profileVersion`.
|
||||
const contractToken = readString(input.resolvedApiKey);
|
||||
const contractToken = readNonEmptyString(input.resolvedApiKey);
|
||||
if (contractToken) {
|
||||
const contractProfileId = readString(input.authProfileId);
|
||||
const contractProfileId = readNonEmptyString(input.authProfileId);
|
||||
return {
|
||||
authMode: "gitHubToken",
|
||||
gitHubToken: contractToken,
|
||||
@@ -268,7 +269,7 @@ function resolveCopilotHome(args: {
|
||||
return resolve(join(args.agentDir, "copilot"));
|
||||
}
|
||||
|
||||
const openClawHome = readString(args.env.OPENCLAW_HOME);
|
||||
const openClawHome = readNonEmptyString(args.env.OPENCLAW_HOME);
|
||||
const rootHome = openClawHome ? resolve(openClawHome) : safeHomeDir(args.homeDir);
|
||||
// Per-agent isolation per proposal section 3.6:
|
||||
// <openClawHome>/.openclaw/agents/<agentId>/copilot
|
||||
@@ -301,10 +302,10 @@ function readEnvTokenFallback(
|
||||
// agentRuntime.id: "copilot" gets the token they configured rather
|
||||
// than silently falling through to the logged-in CLI user.
|
||||
const candidates: Array<{ name: string; value: string | undefined }> = [
|
||||
{ name: "OPENCLAW_GITHUB_TOKEN", value: readString(env.OPENCLAW_GITHUB_TOKEN) },
|
||||
{ name: "COPILOT_GITHUB_TOKEN", value: readString(env.COPILOT_GITHUB_TOKEN) },
|
||||
{ name: "GH_TOKEN", value: readString(env.GH_TOKEN) },
|
||||
{ name: "GITHUB_TOKEN", value: readString(env.GITHUB_TOKEN) },
|
||||
{ name: "OPENCLAW_GITHUB_TOKEN", value: readNonEmptyString(env.OPENCLAW_GITHUB_TOKEN) },
|
||||
{ name: "COPILOT_GITHUB_TOKEN", value: readNonEmptyString(env.COPILOT_GITHUB_TOKEN) },
|
||||
{ name: "GH_TOKEN", value: readNonEmptyString(env.GH_TOKEN) },
|
||||
{ name: "GITHUB_TOKEN", value: readNonEmptyString(env.GITHUB_TOKEN) },
|
||||
];
|
||||
for (const { name, value } of candidates) {
|
||||
if (value) {
|
||||
@@ -331,6 +332,6 @@ export function tokenFingerprint(token: string): string {
|
||||
return `sha256:${hex}`;
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
function readNonEmptyString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ export function resolveAssistantUsage(
|
||||
latest: AssistantUsageSnapshot | undefined,
|
||||
byApiCallId: Map<string, AssistantUsageSnapshot>,
|
||||
): AssistantUsageSnapshot | undefined {
|
||||
const apiCallId = readString(event?.data.apiCallId);
|
||||
const apiCallId = readNonEmptyString(event?.data.apiCallId);
|
||||
return apiCallId ? (byApiCallId.get(apiCallId) ?? latest) : latest;
|
||||
}
|
||||
|
||||
@@ -162,6 +162,6 @@ export function sanitizeToolDetailText(text: string): string {
|
||||
return typeof value === "string" ? value : "";
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
function readNonEmptyString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ export function attachEventBridge(
|
||||
if (!projection) {
|
||||
return;
|
||||
}
|
||||
const source = readString(event.data.source);
|
||||
const source = readNonEmptyString(event.data.source);
|
||||
const transformedContent =
|
||||
typeof event.data.transformedContent === "string" ? event.data.transformedContent : undefined;
|
||||
const openClawMeta = projectSdkUserMetadata(event.data.attachments, source);
|
||||
@@ -229,7 +229,7 @@ export function attachEventBridge(
|
||||
if (!isRootSessionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
const messageId = readString(event.data.messageId) ?? "assistant-message";
|
||||
const messageId = readNonEmptyString(event.data.messageId) ?? "assistant-message";
|
||||
const delta = event.data.deltaContent;
|
||||
if (!delta) {
|
||||
return;
|
||||
@@ -266,7 +266,7 @@ export function attachEventBridge(
|
||||
if (!isRootSessionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
const reasoningId = readString(event.data.reasoningId) ?? "assistant-reasoning";
|
||||
const reasoningId = readNonEmptyString(event.data.reasoningId) ?? "assistant-reasoning";
|
||||
const delta = event.data.deltaContent;
|
||||
if (!delta) {
|
||||
return;
|
||||
@@ -311,7 +311,7 @@ export function attachEventBridge(
|
||||
return;
|
||||
}
|
||||
usage = normalizeCopilotUsage(event.data);
|
||||
const apiCallId = readString(event.data.apiCallId);
|
||||
const apiCallId = readNonEmptyString(event.data.apiCallId);
|
||||
if (apiCallId && usage) {
|
||||
usageByApiCallId.set(apiCallId, usage);
|
||||
}
|
||||
@@ -664,7 +664,7 @@ export function attachEventBridge(
|
||||
transcriptAssistantTexts: [event.data.content ?? ""],
|
||||
...(transcriptReasoningText ? { transcriptReasoningText } : {}),
|
||||
};
|
||||
const apiCallId = readString(event.data.apiCallId);
|
||||
const apiCallId = readNonEmptyString(event.data.apiCallId);
|
||||
if (!apiCallId) {
|
||||
if (projectedAssistantMessageIdsWithoutApiCall.has(event.data.messageId)) {
|
||||
options.transcriptProjection?.journal.markReplayIncomplete();
|
||||
@@ -969,7 +969,7 @@ function splitPlanText(text: string | undefined): string[] {
|
||||
.filter((line) => line.length > 0);
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
function readNonEmptyString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.length > 0 ? value : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { ProviderConfig } from "@github/copilot-sdk";
|
||||
import { isNonSecretApiKeyMarker } from "openclaw/plugin-sdk/provider-auth";
|
||||
import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { tokenFingerprint } from "./auth-bridge.js";
|
||||
|
||||
const COPILOT_BYOK_PROVIDER_ERROR =
|
||||
@@ -83,7 +84,7 @@ export function resolveCopilotProvider(params: {
|
||||
return { mode: "github-copilot" };
|
||||
}
|
||||
|
||||
const baseUrl = readString(params.model.baseUrl);
|
||||
const baseUrl = normalizeOptionalString(params.model.baseUrl);
|
||||
if (!baseUrl) {
|
||||
throw new Error(COPILOT_BYOK_PROVIDER_ERROR);
|
||||
}
|
||||
@@ -92,11 +93,11 @@ export function resolveCopilotProvider(params: {
|
||||
throw new Error(COPILOT_BYOK_TRANSPORT_POLICY_ERROR);
|
||||
}
|
||||
|
||||
const api = readString(params.model.api)?.toLowerCase() ?? "openai-responses";
|
||||
const api = normalizeOptionalString(params.model.api)?.toLowerCase() ?? "openai-responses";
|
||||
const provider = resolveProviderType(api, baseUrl, params.model.azureApiVersion);
|
||||
const resolvedApiKey = resolveProviderCredential(params.resolvedApiKey);
|
||||
const headers = resolveProviderHeaders(params.model.headers);
|
||||
const requestAuthMode = readString(params.model.requestAuthMode)?.toLowerCase();
|
||||
const requestAuthMode = normalizeOptionalString(params.model.requestAuthMode)?.toLowerCase();
|
||||
const usePreparedRequestAuth =
|
||||
requestAuthMode !== undefined && requestAuthMode !== "provider-default";
|
||||
const providerConfig: ProviderConfig = {
|
||||
@@ -156,16 +157,16 @@ export function supportsCopilotByokProviderShape(
|
||||
"api" | "baseUrl" | "requestProxy" | "requestTls" | "requestAllowPrivateNetwork"
|
||||
>,
|
||||
): boolean {
|
||||
if (!readString(model.baseUrl) || hasUnsupportedTransportPolicy(model)) {
|
||||
if (!normalizeOptionalString(model.baseUrl) || hasUnsupportedTransportPolicy(model)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
resolveProviderType(
|
||||
readString(model.api)?.toLowerCase() ?? "openai-responses",
|
||||
readString(model.baseUrl)!,
|
||||
normalizeOptionalString(model.api)?.toLowerCase() ?? "openai-responses",
|
||||
normalizeOptionalString(model.baseUrl)!,
|
||||
undefined,
|
||||
);
|
||||
assertByokEndpointHostAllowed(readString(model.baseUrl)!);
|
||||
assertByokEndpointHostAllowed(normalizeOptionalString(model.baseUrl)!);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
@@ -274,7 +275,7 @@ function resolveAzureProviderType(
|
||||
url.pathname = "";
|
||||
url.search = "";
|
||||
url.hash = "";
|
||||
const resolvedApiVersion = readString(apiVersion);
|
||||
const resolvedApiVersion = normalizeOptionalString(apiVersion);
|
||||
return {
|
||||
type: "azure",
|
||||
wireApi: "responses",
|
||||
@@ -317,12 +318,8 @@ function stableSerialize(value: unknown): string {
|
||||
return JSON.stringify(value) ?? "null";
|
||||
}
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
||||
}
|
||||
|
||||
function resolveProviderCredential(value: string | undefined): string | undefined {
|
||||
const credential = readString(value);
|
||||
const credential = normalizeOptionalString(value);
|
||||
return credential && !isNonSecretApiKeyMarker(credential) ? credential : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ export function createCopilotClientPool(options: CopilotClientPoolOptions = {}):
|
||||
try {
|
||||
return await client.stop();
|
||||
} catch (error: unknown) {
|
||||
return [toError(error)];
|
||||
return [toCopilotRuntimeError(error)];
|
||||
} finally {
|
||||
entry.state = { kind: "stopped" };
|
||||
maybeDeleteEntry(entry);
|
||||
@@ -136,7 +136,7 @@ export function createCopilotClientPool(options: CopilotClientPoolOptions = {}):
|
||||
await entry.state.promise;
|
||||
} catch (error: unknown) {
|
||||
maybeDeleteEntry(entry);
|
||||
return [toError(error)];
|
||||
return [toCopilotRuntimeError(error)];
|
||||
}
|
||||
return stopEntry(entry);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ export function createCopilotClientPool(options: CopilotClientPoolOptions = {}):
|
||||
} catch (error: unknown) {
|
||||
entry.state = { kind: "stopped" };
|
||||
maybeDeleteEntry(entry);
|
||||
throw toError(error);
|
||||
throw toCopilotRuntimeError(error);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -220,7 +220,7 @@ export function createCopilotClientPool(options: CopilotClientPoolOptions = {}):
|
||||
}
|
||||
return { key: created.entry.key, client };
|
||||
} catch (error: unknown) {
|
||||
throw toError(error);
|
||||
throw toCopilotRuntimeError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ export function createCopilotClientPool(options: CopilotClientPoolOptions = {}):
|
||||
}
|
||||
return { key: existing.key, client };
|
||||
} catch (error: unknown) {
|
||||
throw toError(error);
|
||||
throw toCopilotRuntimeError(error);
|
||||
}
|
||||
}
|
||||
case "ready":
|
||||
@@ -390,7 +390,7 @@ function normalizeCopilotHome(copilotHome: string): string {
|
||||
return normalizedHome;
|
||||
}
|
||||
|
||||
function toError(error: unknown): Error {
|
||||
function toCopilotRuntimeError(error: unknown): Error {
|
||||
if (error instanceof Error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ export async function createCopilotToolBridge(
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
throw createError(
|
||||
`[copilot-tool-bridge] createOpenClawCodingTools failed: ${toError(error).message}`,
|
||||
`[copilot-tool-bridge] createOpenClawCodingTools failed: ${toCopilotToolError(error).message}`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
@@ -547,7 +547,7 @@ function convertOpenClawToolToSdkTool(
|
||||
error: unknown,
|
||||
executionStarted: boolean,
|
||||
): ToolResultObject => {
|
||||
const errorMessage = toError(error).message;
|
||||
const errorMessage = toCopilotToolError(error).message;
|
||||
ctx.observeToolTerminal?.({
|
||||
toolCallId: invocation.toolCallId,
|
||||
toolName: sourceTool.name,
|
||||
@@ -595,7 +595,7 @@ function convertOpenClawToolToSdkTool(
|
||||
args,
|
||||
invocation,
|
||||
startedAt,
|
||||
`[copilot-tool-bridge] beforeExecute failed for tool '${sourceTool.name}': ${toError(error).message}`,
|
||||
`[copilot-tool-bridge] beforeExecute failed for tool '${sourceTool.name}': ${toCopilotToolError(error).message}`,
|
||||
error,
|
||||
false,
|
||||
);
|
||||
@@ -609,7 +609,7 @@ function convertOpenClawToolToSdkTool(
|
||||
args,
|
||||
invocation,
|
||||
startedAt,
|
||||
`[copilot-tool-bridge] prepareArguments failed for tool '${sourceTool.name}': ${toError(error).message}`,
|
||||
`[copilot-tool-bridge] prepareArguments failed for tool '${sourceTool.name}': ${toCopilotToolError(error).message}`,
|
||||
error,
|
||||
false,
|
||||
);
|
||||
@@ -628,7 +628,7 @@ function convertOpenClawToolToSdkTool(
|
||||
preparedArgs,
|
||||
invocation,
|
||||
startedAt,
|
||||
`[copilot-tool-bridge] tool '${sourceTool.name}' failed: ${toError(error).message}`,
|
||||
`[copilot-tool-bridge] tool '${sourceTool.name}' failed: ${toCopilotToolError(error).message}`,
|
||||
error,
|
||||
true,
|
||||
);
|
||||
@@ -756,7 +756,7 @@ async function executeCatalogTool(
|
||||
});
|
||||
return result;
|
||||
} catch (error: unknown) {
|
||||
const message = toError(error).message;
|
||||
const message = toCopilotToolError(error).message;
|
||||
// Completion hooks can throw after the tool terminal outcome. Do not
|
||||
// rewrite that recorded outcome as a second, contradictory tool failure.
|
||||
if (!terminalObserved) {
|
||||
@@ -801,7 +801,7 @@ function createFailureResult(message: string, error: unknown): ToolResultObject
|
||||
// Error object would produce a non-serializable JSON-RPC payload, so we
|
||||
// surface the message string instead.
|
||||
return {
|
||||
error: toError(error).message,
|
||||
error: toCopilotToolError(error).message,
|
||||
resultType: "failure",
|
||||
textResultForLlm: message,
|
||||
};
|
||||
@@ -912,6 +912,6 @@ function findDuplicateToolNames(sourceTools: AnyAgentTool[]): string[] {
|
||||
.toSorted();
|
||||
}
|
||||
|
||||
function toError(error: unknown): Error {
|
||||
function toCopilotToolError(error: unknown): Error {
|
||||
return error instanceof Error ? error : new Error(String(error));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
resolveProviderHttpRequestConfig,
|
||||
requireTranscriptionText,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { asOptionalRecord as asRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
export const DEFAULT_DEEPGRAM_AUDIO_BASE_URL = "https://api.deepgram.com/v1";
|
||||
export const DEFAULT_DEEPGRAM_AUDIO_MODEL = "nova-3";
|
||||
@@ -21,21 +21,21 @@ function resolveModel(model?: string): string {
|
||||
}
|
||||
|
||||
function readDeepgramTranscript(payload: Record<string, unknown>): string | undefined {
|
||||
const results = asRecord(payload.results);
|
||||
const results = asOptionalRecord(payload.results);
|
||||
if (!results) {
|
||||
return undefined;
|
||||
}
|
||||
if (!Array.isArray(results.channels)) {
|
||||
throw new Error("Audio transcription failed: malformed JSON response");
|
||||
}
|
||||
const channel = asRecord(results.channels[0]);
|
||||
const channel = asOptionalRecord(results.channels[0]);
|
||||
if (!channel) {
|
||||
return undefined;
|
||||
}
|
||||
if (!Array.isArray(channel.alternatives)) {
|
||||
throw new Error("Audio transcription failed: malformed JSON response");
|
||||
}
|
||||
const alternative = asRecord(channel.alternatives[0]);
|
||||
const alternative = asOptionalRecord(channel.alternatives[0]);
|
||||
if (!alternative) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Deepinfra provider module implements model/runtime integration.
|
||||
import {
|
||||
asObject,
|
||||
createOpenAiCompatibleSpeechProvider,
|
||||
type SpeechProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/speech";
|
||||
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
DEEPINFRA_BASE_URL,
|
||||
DEEPINFRA_TTS_FALLBACK_MODELS,
|
||||
@@ -44,7 +44,7 @@ export function buildDeepInfraSpeechProvider(options?: {
|
||||
normalizeModel: normalizeDeepInfraModelRef,
|
||||
apiErrorLabel: "DeepInfra TTS API error",
|
||||
missingApiKeyError: "DeepInfra API key missing",
|
||||
readExtraConfig: (raw) => ({ extraBody: asObject(raw?.extraBody) }),
|
||||
readExtraConfig: (raw) => ({ extraBody: asOptionalRecord(raw?.extraBody) }),
|
||||
extraJsonBodyFields: [{ configKey: "extraBody", requestKey: "extra_body" }],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -651,13 +651,13 @@ function createPdfScreenshotter(
|
||||
return { screenshotHtml };
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
function isObjectValue(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
|
||||
function readDetails(result: unknown): Record<string, unknown> {
|
||||
const details = (result as { details?: unknown } | null | undefined)?.details;
|
||||
if (!isRecord(details)) {
|
||||
if (!isObjectValue(details)) {
|
||||
throw new Error("expected diffs tool result details");
|
||||
}
|
||||
return details;
|
||||
@@ -688,7 +688,7 @@ function extractViewerArtifactToken(viewerPath: string): string {
|
||||
}
|
||||
|
||||
function readParametersProperties(parameters: unknown): Record<string, unknown> {
|
||||
if (isRecord(parameters) && isRecord(parameters.properties)) {
|
||||
if (isObjectValue(parameters) && isObjectValue(parameters.properties)) {
|
||||
return parameters.properties;
|
||||
}
|
||||
throw new Error("expected diffs tool parameter properties");
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { DiffViewerPayload } from "./types.js";
|
||||
|
||||
const OVERFLOW_VALUES = ["scroll", "wrap"] as const;
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
function isViewerRecord(value: unknown): value is Record<string, unknown> {
|
||||
return value !== null && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export function parseViewerPayloadJson(raw: string): DiffViewerPayload {
|
||||
}
|
||||
|
||||
function isDiffViewerPayload(value: unknown): value is DiffViewerPayload {
|
||||
if (!isRecord(value)) {
|
||||
if (!isViewerRecord(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ function isDiffViewerPayload(value: unknown): value is DiffViewerPayload {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasFileDiff = isRecord(value.fileDiff);
|
||||
const hasBeforeAfterFiles = isRecord(value.oldFile) && isRecord(value.newFile);
|
||||
const hasFileDiff = isViewerRecord(value.fileDiff);
|
||||
const hasBeforeAfterFiles = isViewerRecord(value.oldFile) && isViewerRecord(value.newFile);
|
||||
if (!hasFileDiff && !hasBeforeAfterFiles) {
|
||||
return false;
|
||||
}
|
||||
@@ -50,11 +50,11 @@ function isDiffViewerPayload(value: unknown): value is DiffViewerPayload {
|
||||
}
|
||||
|
||||
function isViewerOptions(value: unknown): boolean {
|
||||
if (!isRecord(value)) {
|
||||
if (!isViewerRecord(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isRecord(value.theme)) {
|
||||
if (!isViewerRecord(value.theme)) {
|
||||
return false;
|
||||
}
|
||||
if (value.theme.light !== "pierre-light" || value.theme.dark !== "pierre-dark") {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Discord plugin module implements components.parse behavior.
|
||||
import { ButtonStyle, TextInputStyle } from "discord-api-types/v10";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type {
|
||||
DiscordComponentBlock,
|
||||
DiscordComponentButtonSpec,
|
||||
@@ -32,7 +35,11 @@ function requireObject(value: unknown, label: string): Record<string, unknown> {
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function readString(value: unknown, label: string, opts?: { allowEmpty?: boolean }): string {
|
||||
function readRequiredString(
|
||||
value: unknown,
|
||||
label: string,
|
||||
opts?: { allowEmpty?: boolean },
|
||||
): string {
|
||||
if (typeof value !== "string") {
|
||||
throw new Error(`${label} must be a string`);
|
||||
}
|
||||
@@ -43,19 +50,11 @@ function readString(value: unknown, label: string, opts?: { allowEmpty?: boolean
|
||||
return opts?.allowEmpty ? value : trimmed;
|
||||
}
|
||||
|
||||
function readOptionalString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function readOptionalCallbackDataKind(
|
||||
value: unknown,
|
||||
label: string,
|
||||
): DiscordComponentCallbackDataKind | undefined {
|
||||
const kind = readOptionalString(value);
|
||||
const kind = normalizeOptionalString(value);
|
||||
if (kind === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -75,7 +74,7 @@ function readOptionalStringArray(value: unknown, label: string): string[] | unde
|
||||
if (value.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return value.map((entry, index) => readString(entry, `${label}[${index}]`));
|
||||
return value.map((entry, index) => readRequiredString(entry, `${label}[${index}]`));
|
||||
}
|
||||
|
||||
function readOptionalInteger(
|
||||
@@ -104,8 +103,8 @@ function readOptionalEmoji(value: unknown, label: string) {
|
||||
}
|
||||
const obj = value as { name?: unknown; id?: unknown; animated?: unknown };
|
||||
return {
|
||||
name: readString(obj.name, `${label}.name`),
|
||||
id: readOptionalString(obj.id),
|
||||
name: readRequiredString(obj.name, `${label}.name`),
|
||||
id: normalizeOptionalString(obj.id),
|
||||
animated: typeof obj.animated === "boolean" ? obj.animated : undefined,
|
||||
};
|
||||
}
|
||||
@@ -181,9 +180,9 @@ function parseSelectOptions(
|
||||
return raw.map((entry, index) => {
|
||||
const obj = requireObject(entry, `${label}[${index}]`);
|
||||
return {
|
||||
label: readString(obj.label, `${label}[${index}].label`),
|
||||
value: readString(obj.value, `${label}[${index}].value`),
|
||||
description: readOptionalString(obj.description),
|
||||
label: readRequiredString(obj.label, `${label}[${index}].label`),
|
||||
value: readRequiredString(obj.value, `${label}[${index}].value`),
|
||||
description: normalizeOptionalString(obj.description),
|
||||
emoji: readOptionalEmoji(obj.emoji, `${label}[${index}].emoji`),
|
||||
default: typeof obj.default === "boolean" ? obj.default : undefined,
|
||||
};
|
||||
@@ -192,16 +191,16 @@ function parseSelectOptions(
|
||||
|
||||
function parseButtonSpec(raw: unknown, label: string): DiscordComponentButtonSpec {
|
||||
const obj = requireObject(raw, label);
|
||||
const style = readOptionalString(obj.style) as DiscordComponentButtonStyle | undefined;
|
||||
const url = readOptionalString(obj.url);
|
||||
const style = normalizeOptionalString(obj.style) as DiscordComponentButtonStyle | undefined;
|
||||
const url = normalizeOptionalString(obj.url);
|
||||
if ((style === "link" || url) && !url) {
|
||||
throw new Error(`${label}.url is required for link buttons`);
|
||||
}
|
||||
return {
|
||||
label: readString(obj.label, `${label}.label`),
|
||||
label: readRequiredString(obj.label, `${label}.label`),
|
||||
style,
|
||||
url,
|
||||
callbackData: readOptionalString(obj.callbackData),
|
||||
callbackData: normalizeOptionalString(obj.callbackData),
|
||||
callbackDataKind: readOptionalCallbackDataKind(
|
||||
obj.callbackDataKind,
|
||||
`${label}.callbackDataKind`,
|
||||
@@ -214,7 +213,7 @@ function parseButtonSpec(raw: unknown, label: string): DiscordComponentButtonSpe
|
||||
|
||||
function parseSelectSpec(raw: unknown, label: string): DiscordComponentSelectSpec {
|
||||
const obj = requireObject(raw, label);
|
||||
const type = readOptionalString(obj.type) as DiscordComponentSelectType | undefined;
|
||||
const type = normalizeOptionalString(obj.type) as DiscordComponentSelectType | undefined;
|
||||
const allowedTypes: DiscordComponentSelectType[] = [
|
||||
"string",
|
||||
"user",
|
||||
@@ -227,12 +226,12 @@ function parseSelectSpec(raw: unknown, label: string): DiscordComponentSelectSpe
|
||||
}
|
||||
return {
|
||||
type,
|
||||
callbackData: readOptionalString(obj.callbackData),
|
||||
callbackData: normalizeOptionalString(obj.callbackData),
|
||||
callbackDataKind: readOptionalCallbackDataKind(
|
||||
obj.callbackDataKind,
|
||||
`${label}.callbackDataKind`,
|
||||
),
|
||||
placeholder: readOptionalString(obj.placeholder),
|
||||
placeholder: normalizeOptionalString(obj.placeholder),
|
||||
minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, { min: 0, max: 25 }),
|
||||
maxValues: readOptionalInteger(obj.maxValues, `${label}.maxValues`, { min: 1, max: 25 }),
|
||||
options: parseSelectOptions(obj.options, `${label}.options`),
|
||||
@@ -243,7 +242,7 @@ function parseSelectSpec(raw: unknown, label: string): DiscordComponentSelectSpe
|
||||
function parseModalField(raw: unknown, label: string, index: number): DiscordModalFieldSpec {
|
||||
const obj = requireObject(raw, label);
|
||||
const type = normalizeLowercaseStringOrEmpty(
|
||||
readString(obj.type, `${label}.type`),
|
||||
readRequiredString(obj.type, `${label}.type`),
|
||||
) as DiscordComponentModalFieldType;
|
||||
const supported: DiscordComponentModalFieldType[] = [
|
||||
"text",
|
||||
@@ -267,10 +266,10 @@ function parseModalField(raw: unknown, label: string, index: number): DiscordMod
|
||||
const maxValues = type === "checkbox" ? 10 : 25;
|
||||
return {
|
||||
type,
|
||||
name: normalizeModalFieldName(readOptionalString(obj.name), index),
|
||||
label: readString(obj.label, `${label}.label`),
|
||||
description: readOptionalString(obj.description),
|
||||
placeholder: readOptionalString(obj.placeholder),
|
||||
name: normalizeModalFieldName(normalizeOptionalString(obj.name), index),
|
||||
label: readRequiredString(obj.label, `${label}.label`),
|
||||
description: normalizeOptionalString(obj.description),
|
||||
placeholder: normalizeOptionalString(obj.placeholder),
|
||||
required,
|
||||
options,
|
||||
minValues: readOptionalInteger(obj.minValues, `${label}.minValues`, {
|
||||
@@ -283,25 +282,25 @@ function parseModalField(raw: unknown, label: string, index: number): DiscordMod
|
||||
}),
|
||||
minLength: readOptionalInteger(obj.minLength, `${label}.minLength`, { min: 0, max: 4000 }),
|
||||
maxLength: readOptionalInteger(obj.maxLength, `${label}.maxLength`, { min: 1, max: 4000 }),
|
||||
style: readOptionalString(obj.style) as DiscordModalFieldSpec["style"],
|
||||
style: normalizeOptionalString(obj.style) as DiscordModalFieldSpec["style"],
|
||||
};
|
||||
}
|
||||
|
||||
function parseComponentBlock(raw: unknown, label: string): DiscordComponentBlock {
|
||||
const obj = requireObject(raw, label);
|
||||
const typeRaw = normalizeLowercaseStringOrEmpty(readString(obj.type, `${label}.type`));
|
||||
const typeRaw = normalizeLowercaseStringOrEmpty(readRequiredString(obj.type, `${label}.type`));
|
||||
const type = normalizeBlockType(typeRaw);
|
||||
switch (type) {
|
||||
case "text":
|
||||
return {
|
||||
type: "text",
|
||||
text: readString(obj.text, `${label}.text`),
|
||||
text: readRequiredString(obj.text, `${label}.text`),
|
||||
};
|
||||
case "section": {
|
||||
const text = readOptionalString(obj.text);
|
||||
const text = normalizeOptionalString(obj.text);
|
||||
const textsRaw = obj.texts;
|
||||
const texts = Array.isArray(textsRaw)
|
||||
? textsRaw.map((entry, idx) => readString(entry, `${label}.texts[${idx}]`))
|
||||
? textsRaw.map((entry, idx) => readRequiredString(entry, `${label}.texts[${idx}]`))
|
||||
: undefined;
|
||||
if (!text && (!texts || texts.length === 0)) {
|
||||
throw new Error(`${label}.text or ${label}.texts is required for section blocks`);
|
||||
@@ -310,12 +309,12 @@ function parseComponentBlock(raw: unknown, label: string): DiscordComponentBlock
|
||||
if (obj.accessory !== undefined) {
|
||||
const accessoryObj = requireObject(obj.accessory, `${label}.accessory`);
|
||||
const accessoryType = normalizeLowercaseStringOrEmpty(
|
||||
readString(accessoryObj.type, `${label}.accessory.type`),
|
||||
readRequiredString(accessoryObj.type, `${label}.accessory.type`),
|
||||
);
|
||||
if (accessoryType === "thumbnail") {
|
||||
accessory = {
|
||||
type: "thumbnail",
|
||||
url: readString(accessoryObj.url, `${label}.accessory.url`),
|
||||
url: readRequiredString(accessoryObj.url, `${label}.accessory.url`),
|
||||
};
|
||||
} else if (accessoryType === "button") {
|
||||
accessory = {
|
||||
@@ -376,8 +375,8 @@ function parseComponentBlock(raw: unknown, label: string): DiscordComponentBlock
|
||||
const items = itemsRaw.map((entry, idx) => {
|
||||
const itemObj = requireObject(entry, `${label}.items[${idx}]`);
|
||||
return {
|
||||
url: readString(itemObj.url, `${label}.items[${idx}].url`),
|
||||
description: readOptionalString(itemObj.description),
|
||||
url: readRequiredString(itemObj.url, `${label}.items[${idx}].url`),
|
||||
description: normalizeOptionalString(itemObj.description),
|
||||
spoiler: typeof itemObj.spoiler === "boolean" ? itemObj.spoiler : undefined,
|
||||
};
|
||||
});
|
||||
@@ -387,7 +386,7 @@ function parseComponentBlock(raw: unknown, label: string): DiscordComponentBlock
|
||||
};
|
||||
}
|
||||
case "file": {
|
||||
const file = readString(obj.file, `${label}.file`);
|
||||
const file = readRequiredString(obj.file, `${label}.file`);
|
||||
return {
|
||||
type: "file",
|
||||
file: normalizeAttachmentRef(file, `${label}.file`),
|
||||
@@ -424,16 +423,16 @@ export function readDiscordComponentSpec(raw: unknown): DiscordComponentMessageS
|
||||
parseModalField(entry, `components.modal.fields[${idx}]`, idx),
|
||||
);
|
||||
modal = {
|
||||
title: readString(modalObj.title, "components.modal.title"),
|
||||
callbackData: readOptionalString(modalObj.callbackData),
|
||||
triggerLabel: readOptionalString(modalObj.triggerLabel),
|
||||
triggerStyle: readOptionalString(modalObj.triggerStyle) as DiscordComponentButtonStyle,
|
||||
title: readRequiredString(modalObj.title, "components.modal.title"),
|
||||
callbackData: normalizeOptionalString(modalObj.callbackData),
|
||||
triggerLabel: normalizeOptionalString(modalObj.triggerLabel),
|
||||
triggerStyle: normalizeOptionalString(modalObj.triggerStyle) as DiscordComponentButtonStyle,
|
||||
allowedUsers: readOptionalStringArray(modalObj.allowedUsers, "components.modal.allowedUsers"),
|
||||
fields,
|
||||
};
|
||||
}
|
||||
return {
|
||||
text: readOptionalString(obj.text),
|
||||
text: normalizeOptionalString(obj.text),
|
||||
reusable,
|
||||
container:
|
||||
typeof obj.container === "object" && obj.container && !Array.isArray(obj.container)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import { createInboundEventDeliveryCorrelation } from "openclaw/plugin-sdk/inbound-event-delivery";
|
||||
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-payload";
|
||||
import {
|
||||
asOptionalRecord as readRecord,
|
||||
normalizeOptionalString as readString,
|
||||
asOptionalRecord,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
const DISCORD_INBOUND_EVENT_DELIVERY_KEY = "__openclawInboundEventDelivery";
|
||||
@@ -32,8 +32,8 @@ export function withDiscordInboundEventDeliveryMetadata(
|
||||
if (!sessionKey || params.inboundEventKind !== "room_event") {
|
||||
return payload;
|
||||
}
|
||||
const channelData = readRecord(payload.channelData) ?? {};
|
||||
const discordData = readRecord(channelData.discord) ?? {};
|
||||
const channelData = asOptionalRecord(payload.channelData) ?? {};
|
||||
const discordData = asOptionalRecord(channelData.discord) ?? {};
|
||||
return {
|
||||
...payload,
|
||||
channelData: {
|
||||
@@ -54,15 +54,15 @@ export function notifyDiscordInboundEventOutboundPayloadSuccess(params: {
|
||||
to: string;
|
||||
accountId?: string | null;
|
||||
}): void {
|
||||
const channelData = readRecord(params.payload.channelData);
|
||||
const discordData = readRecord(channelData?.discord);
|
||||
const metadata = readRecord(discordData?.[DISCORD_INBOUND_EVENT_DELIVERY_KEY]);
|
||||
const channelData = asOptionalRecord(params.payload.channelData);
|
||||
const discordData = asOptionalRecord(channelData?.discord);
|
||||
const metadata = asOptionalRecord(discordData?.[DISCORD_INBOUND_EVENT_DELIVERY_KEY]);
|
||||
if (!metadata) {
|
||||
return;
|
||||
}
|
||||
discordInboundEventDelivery.notify({
|
||||
sessionKey: readString(metadata.sessionKey),
|
||||
inboundEventKind: readString(metadata.inboundEventKind),
|
||||
sessionKey: normalizeOptionalString(metadata.sessionKey),
|
||||
inboundEventKind: normalizeOptionalString(metadata.inboundEventKind),
|
||||
to: params.to,
|
||||
accountId: params.accountId,
|
||||
});
|
||||
|
||||
@@ -415,7 +415,13 @@ vi.mock("openclaw/plugin-sdk/channel-inbound", async (importOriginal) => {
|
||||
cfg,
|
||||
dispatcherOptions: {
|
||||
...plan.dispatcherOptions,
|
||||
deliver: (delivery.deliverWithProviderMessageSending ?? delivery.deliver)!,
|
||||
deliver: (payload, info) => {
|
||||
const providerInfo = {
|
||||
...info,
|
||||
onPlatformSendDispatch: async () => undefined,
|
||||
};
|
||||
return delivery.deliverWithProviderMessageSending(payload, providerInfo);
|
||||
},
|
||||
onError: delivery.onError,
|
||||
},
|
||||
toolsAllow: plan.toolsAllow,
|
||||
|
||||
@@ -43,7 +43,7 @@ export function buildPreferenceModelKey(scopeKey: string, modelRef: string): str
|
||||
return `v1:${hashSegment(scopeKey, 32)}:${hashSegment(modelRef, 24)}`;
|
||||
}
|
||||
|
||||
export function timestampMs(value: unknown): number {
|
||||
export function preferenceTimestampMs(value: unknown): number {
|
||||
const parsed = typeof value === "string" ? Date.parse(value) : Number.NaN;
|
||||
return Number.isFinite(parsed) ? parsed : 0;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
} from "../command-deploy-store.js";
|
||||
import {
|
||||
buildPreferenceModelKey,
|
||||
preferenceTimestampMs,
|
||||
sanitizeRecentModels,
|
||||
timestampMs,
|
||||
} from "./model-picker-preference-primitives.js";
|
||||
import {
|
||||
normalizePersistedBinding,
|
||||
@@ -74,7 +74,7 @@ function normalizeLegacyPreferenceKey(key: string): string | undefined {
|
||||
}
|
||||
|
||||
function legacyUpdatedAtForIndex(updatedAt: unknown, index: number, total: number): string {
|
||||
const baseMs = timestampMs(updatedAt);
|
||||
const baseMs = preferenceTimestampMs(updatedAt);
|
||||
const anchorMs = Math.min(baseMs + Math.max(0, total), MAX_DATE_TIMESTAMP_MS);
|
||||
const shiftedMs = anchorMs - Math.max(0, index);
|
||||
return (
|
||||
|
||||
@@ -10,8 +10,8 @@ import { getDiscordRuntime } from "../runtime.js";
|
||||
import {
|
||||
buildPreferenceModelKey,
|
||||
normalizeModelRef,
|
||||
preferenceTimestampMs,
|
||||
sanitizeRecentModels,
|
||||
timestampMs,
|
||||
} from "./model-picker-preference-primitives.js";
|
||||
|
||||
const DEFAULT_RECENT_LIMIT = 5;
|
||||
@@ -96,7 +96,7 @@ function comparePreferenceEntries(
|
||||
right: { key: string; value: ModelPickerPreferencesEntry },
|
||||
): number {
|
||||
return (
|
||||
timestampMs(right.value.updatedAt) - timestampMs(left.value.updatedAt) ||
|
||||
preferenceTimestampMs(right.value.updatedAt) - preferenceTimestampMs(left.value.updatedAt) ||
|
||||
timestampOrder(right.value.updatedOrder) - timestampOrder(left.value.updatedOrder) ||
|
||||
left.key.localeCompare(right.key)
|
||||
);
|
||||
@@ -107,7 +107,7 @@ function nextPreferenceTimestamp(existingEntries: ModelPickerPreferencesEntry[])
|
||||
updatedOrder: number;
|
||||
} {
|
||||
const existingMaxTimestampMs = existingEntries.reduce(
|
||||
(max, entry) => Math.max(max, timestampMs(entry.updatedAt)),
|
||||
(max, entry) => Math.max(max, preferenceTimestampMs(entry.updatedAt)),
|
||||
0,
|
||||
);
|
||||
lastPreferenceTimestampMs = Math.min(
|
||||
|
||||
@@ -228,13 +228,13 @@ type MockCalls = {
|
||||
mock: { calls: unknown[][] };
|
||||
};
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
function isObjectValue(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
|
||||
function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
||||
expect(isRecord(value), `${label} should be an object`).toBe(true);
|
||||
if (!isRecord(value)) {
|
||||
expect(isObjectValue(value), `${label} should be an object`).toBe(true);
|
||||
if (!isObjectValue(value)) {
|
||||
throw new Error(`${label} should be an object`);
|
||||
}
|
||||
return value;
|
||||
@@ -292,7 +292,7 @@ function expectFollowUpFields(
|
||||
|
||||
function expectNoFollowUpContent(interaction: MockCommandInteraction, content: string) {
|
||||
const calls = (interaction.followUp as unknown as MockCalls).mock.calls;
|
||||
const matched = calls.some(([payload]) => isRecord(payload) && payload.content === content);
|
||||
const matched = calls.some(([payload]) => isObjectValue(payload) && payload.content === content);
|
||||
expect(matched).toBe(false);
|
||||
}
|
||||
|
||||
@@ -1896,7 +1896,7 @@ describe("Discord native plugin command dispatch", () => {
|
||||
const replyCalls = (interaction.reply as unknown as MockCalls).mock.calls;
|
||||
const blockedReply = replyCalls.some(
|
||||
([payload]) =>
|
||||
isRecord(payload) &&
|
||||
isObjectValue(payload) &&
|
||||
payload.content === "Configured ACP binding is unavailable right now. Please try again.",
|
||||
);
|
||||
expect(blockedReply).toBe(false);
|
||||
|
||||
@@ -115,7 +115,8 @@ export function createThreadBindingSessionAdapter(params: {
|
||||
resolveCurrentCfg: () => OpenClawConfig;
|
||||
resolveCurrentToken: () => string | undefined;
|
||||
}): SessionBindingAdapter {
|
||||
const toRecord = (entry: ThreadBindingRecord) => toSessionBindingRecord(entry, params.defaults);
|
||||
const serializeBinding = (entry: ThreadBindingRecord) =>
|
||||
toSessionBindingRecord(entry, params.defaults);
|
||||
|
||||
return {
|
||||
channel: "discord",
|
||||
@@ -184,16 +185,16 @@ export function createThreadBindingSessionAdapter(params: {
|
||||
introText,
|
||||
metadata,
|
||||
});
|
||||
return bound ? toRecord(bound) : null;
|
||||
return bound ? serializeBinding(bound) : null;
|
||||
},
|
||||
listBySession: (targetSessionKey) =>
|
||||
params.manager.listBySessionKey(targetSessionKey).map(toRecord),
|
||||
params.manager.listBySessionKey(targetSessionKey).map(serializeBinding),
|
||||
resolveByConversation: (ref) => {
|
||||
if (ref.channel !== "discord") {
|
||||
return null;
|
||||
}
|
||||
const binding = params.manager.getByThreadId(ref.conversationId);
|
||||
return binding ? toRecord(binding) : null;
|
||||
return binding ? serializeBinding(binding) : null;
|
||||
},
|
||||
touch: (bindingId, at) => {
|
||||
const threadId = resolveThreadBindingConversationIdFromBindingId({
|
||||
@@ -211,7 +212,7 @@ export function createThreadBindingSessionAdapter(params: {
|
||||
targetSessionKey: input.targetSessionKey,
|
||||
reason: input.reason,
|
||||
});
|
||||
return removed.map(toRecord);
|
||||
return removed.map(serializeBinding);
|
||||
}
|
||||
const threadId = resolveThreadBindingConversationIdFromBindingId({
|
||||
accountId: params.accountId,
|
||||
@@ -224,7 +225,7 @@ export function createThreadBindingSessionAdapter(params: {
|
||||
threadId,
|
||||
reason: input.reason,
|
||||
});
|
||||
return removed ? [toRecord(removed)] : [];
|
||||
return removed ? [serializeBinding(removed)] : [];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ import type {
|
||||
} from "openclaw/plugin-sdk/channel-contract";
|
||||
import {
|
||||
appendMatchMetadata,
|
||||
asString,
|
||||
isRecord,
|
||||
readAccountStatusSnapshot,
|
||||
resolveEnabledConfiguredAccountId,
|
||||
} from "openclaw/plugin-sdk/status-helpers";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
type DiscordIntentSummary = {
|
||||
messageContent?: "enabled" | "limited" | "disabled";
|
||||
@@ -66,17 +66,17 @@ function readDiscordPermissionsAuditSummary(value: unknown): DiscordPermissionsA
|
||||
if (!isRecord(entry)) {
|
||||
return null;
|
||||
}
|
||||
const channelId = asString(entry.channelId);
|
||||
const channelId = normalizeOptionalString(entry.channelId);
|
||||
if (!channelId) {
|
||||
return null;
|
||||
}
|
||||
const ok = typeof entry.ok === "boolean" ? entry.ok : undefined;
|
||||
const missing = Array.isArray(entry.missing)
|
||||
? entry.missing.map((v) => asString(v)).filter(Boolean)
|
||||
? entry.missing.map((v) => normalizeOptionalString(v)).filter(Boolean)
|
||||
: undefined;
|
||||
const error = asString(entry.error) ?? null;
|
||||
const matchKey = asString(entry.matchKey) ?? undefined;
|
||||
const matchSource = asString(entry.matchSource) ?? undefined;
|
||||
const error = normalizeOptionalString(entry.error) ?? null;
|
||||
const matchKey = normalizeOptionalString(entry.matchKey);
|
||||
const matchSource = normalizeOptionalString(entry.matchSource);
|
||||
return {
|
||||
channelId,
|
||||
ok,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user