From e5e493abcf616c92c0dbb6227c344a22b91aeb7d Mon Sep 17 00:00:00 2001 From: Junebugg1214 <82672745+Junebugg1214@users.noreply.github.com> Date: Thu, 12 Mar 2026 22:17:03 -0400 Subject: [PATCH] fix: resolve remaining CI regressions --- .../OpenClawProtocol/GatewayModels.swift | 6 ++- .../OpenClawProtocol/GatewayModels.swift | 6 ++- src/agents/anthropic-payload-log.test.ts | 2 +- src/agents/anthropic-payload-log.ts | 2 +- src/agents/openai-ws-stream.ts | 2 +- .../pi-embedded-runner-extraparams.test.ts | 42 +++++++++---------- .../anthropic-stream-wrappers.ts | 4 +- .../extra-params.kilocode.test.ts | 8 ++-- ...ra-params.openrouter-cache-control.test.ts | 2 +- src/agents/pi-embedded-runner/extra-params.ts | 6 +-- .../extra-params.zai-tool-stream.test.ts | 2 +- .../moonshot-stream-wrappers.ts | 4 +- .../openai-stream-wrappers.ts | 6 +-- .../proxy-stream-wrappers.ts | 6 +-- src/agents/pi-embedded-runner/run/attempt.ts | 4 +- .../tools/web-fetch.cf-markdown.test.ts | 2 +- src/auto-reply/reply/commands.test-harness.ts | 4 +- src/auto-reply/reply/commands.test.ts | 8 +++- src/cli/command-secret-gateway.test.ts | 2 +- src/cli/update-cli.test.ts | 4 +- src/commands/configure.wizard.ts | 6 ++- src/config/types.tools.ts | 6 +++ src/config/zod-schema.agent-runtime.ts | 10 +++++ src/memory/manager-sync-ops.ts | 2 + src/memory/manager.ts | 2 + src/types/pi-ai-oauth.d.ts | 23 ++++++++++ ui/src/ui/views/agents-utils.test.ts | 23 ++++++++++ 27 files changed, 138 insertions(+), 56 deletions(-) create mode 100644 src/types/pi-ai-oauth.d.ts diff --git a/apps/macos/Sources/OpenClawProtocol/GatewayModels.swift b/apps/macos/Sources/OpenClawProtocol/GatewayModels.swift index 3003ae79f7b..578cc8272af 100644 --- a/apps/macos/Sources/OpenClawProtocol/GatewayModels.swift +++ b/apps/macos/Sources/OpenClawProtocol/GatewayModels.swift @@ -304,6 +304,7 @@ public struct Snapshot: Codable, Sendable { public let sessiondefaults: [String: AnyCodable]? public let authmode: AnyCodable? public let updateavailable: [String: AnyCodable]? + public let cortex: [String: AnyCodable]? public init( presence: [PresenceEntry], @@ -314,7 +315,8 @@ public struct Snapshot: Codable, Sendable { statedir: String?, sessiondefaults: [String: AnyCodable]?, authmode: AnyCodable?, - updateavailable: [String: AnyCodable]?) + updateavailable: [String: AnyCodable]?, + cortex: [String: AnyCodable]?) { self.presence = presence self.health = health @@ -325,6 +327,7 @@ public struct Snapshot: Codable, Sendable { self.sessiondefaults = sessiondefaults self.authmode = authmode self.updateavailable = updateavailable + self.cortex = cortex } private enum CodingKeys: String, CodingKey { @@ -337,6 +340,7 @@ public struct Snapshot: Codable, Sendable { case sessiondefaults = "sessionDefaults" case authmode = "authMode" case updateavailable = "updateAvailable" + case cortex } } diff --git a/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift b/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift index 3003ae79f7b..578cc8272af 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift @@ -304,6 +304,7 @@ public struct Snapshot: Codable, Sendable { public let sessiondefaults: [String: AnyCodable]? public let authmode: AnyCodable? public let updateavailable: [String: AnyCodable]? + public let cortex: [String: AnyCodable]? public init( presence: [PresenceEntry], @@ -314,7 +315,8 @@ public struct Snapshot: Codable, Sendable { statedir: String?, sessiondefaults: [String: AnyCodable]?, authmode: AnyCodable?, - updateavailable: [String: AnyCodable]?) + updateavailable: [String: AnyCodable]?, + cortex: [String: AnyCodable]?) { self.presence = presence self.health = health @@ -325,6 +327,7 @@ public struct Snapshot: Codable, Sendable { self.sessiondefaults = sessiondefaults self.authmode = authmode self.updateavailable = updateavailable + self.cortex = cortex } private enum CodingKeys: String, CodingKey { @@ -337,6 +340,7 @@ public struct Snapshot: Codable, Sendable { case sessiondefaults = "sessionDefaults" case authmode = "authMode" case updateavailable = "updateAvailable" + case cortex } } diff --git a/src/agents/anthropic-payload-log.test.ts b/src/agents/anthropic-payload-log.test.ts index fb3cf18e47d..037093fbbf5 100644 --- a/src/agents/anthropic-payload-log.test.ts +++ b/src/agents/anthropic-payload-log.test.ts @@ -29,7 +29,7 @@ describe("createAnthropicPayloadLogger", () => { ], }; const streamFn: StreamFn = ((model, __, options) => { - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); return {} as never; }) as StreamFn; diff --git a/src/agents/anthropic-payload-log.ts b/src/agents/anthropic-payload-log.ts index 2eb5d62e770..d80ed551179 100644 --- a/src/agents/anthropic-payload-log.ts +++ b/src/agents/anthropic-payload-log.ts @@ -145,7 +145,7 @@ export function createAnthropicPayloadLogger(params: { payload: redactedPayload, payloadDigest: digest(redactedPayload), }); - return options?.onPayload?.(payload, model); + return options?.onPayload?.(payload); }; return streamFn(model, context, { ...options, diff --git a/src/agents/openai-ws-stream.ts b/src/agents/openai-ws-stream.ts index 307812e6be5..04550a665f4 100644 --- a/src/agents/openai-ws-stream.ts +++ b/src/agents/openai-ws-stream.ts @@ -797,7 +797,7 @@ export function createOpenAIWebSocketStreamFn( ...(prevResponseId ? { previous_response_id: prevResponseId } : {}), ...extraParams, }; - const nextPayload = options?.onPayload?.(payload, model); + const nextPayload = options?.onPayload?.(payload); const requestPayload = (nextPayload ?? payload) as Parameters< OpenAIWebSocketManager["send"] >[0]; diff --git a/src/agents/pi-embedded-runner-extraparams.test.ts b/src/agents/pi-embedded-runner-extraparams.test.ts index 7a29f30f9eb..65f3c3648ac 100644 --- a/src/agents/pi-embedded-runner-extraparams.test.ts +++ b/src/agents/pi-embedded-runner-extraparams.test.ts @@ -210,7 +210,7 @@ describe("applyExtraParamsToAgent", () => { }) { const payload = params.payload ?? { store: false }; const baseStreamFn: StreamFn = (model, _context, options) => { - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); return {} as ReturnType; }; const agent = { streamFn: baseStreamFn }; @@ -236,7 +236,7 @@ describe("applyExtraParamsToAgent", () => { }) { const payload = params.payload ?? {}; const baseStreamFn: StreamFn = (model, _context, options) => { - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); return {} as ReturnType; }; const agent = { streamFn: baseStreamFn }; @@ -279,7 +279,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { model: "deepseek/deepseek-r1" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -311,7 +311,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = {}; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -335,7 +335,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { reasoning_effort: "high" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -360,7 +360,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { reasoning: { max_tokens: 256 } }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -384,7 +384,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { reasoning_effort: "medium" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -591,7 +591,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { thinking: "off" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -622,7 +622,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { thinking: "off" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -653,7 +653,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = {}; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -677,7 +677,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { tool_choice: "required" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -704,7 +704,7 @@ describe("applyExtraParamsToAgent", () => { const payload: Record = { tool_choice: { type: "tool", name: "read" }, }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -729,7 +729,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = {}; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -766,7 +766,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = { tool_choice: "required" }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -791,7 +791,7 @@ describe("applyExtraParamsToAgent", () => { const payloads: Record[] = []; const baseStreamFn: StreamFn = (_model, _context, options) => { const payload: Record = {}; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -817,7 +817,7 @@ describe("applyExtraParamsToAgent", () => { const payload: Record = { tool_choice: { type: "function", function: { name: "read" } }, }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -858,7 +858,7 @@ describe("applyExtraParamsToAgent", () => { ], tool_choice: { type: "tool", name: "read" }, }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -902,7 +902,7 @@ describe("applyExtraParamsToAgent", () => { }, ], }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -941,7 +941,7 @@ describe("applyExtraParamsToAgent", () => { }, ], }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -1005,7 +1005,7 @@ describe("applyExtraParamsToAgent", () => { }, }, }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; @@ -1052,7 +1052,7 @@ describe("applyExtraParamsToAgent", () => { }, }, }; - options?.onPayload?.(payload, _model); + options?.onPayload?.(payload); payloads.push(payload); return {} as ReturnType; }; diff --git a/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts index efed941762d..7df67acb37d 100644 --- a/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts @@ -319,7 +319,7 @@ export function createAnthropicToolPayloadCompatibilityWrapper( ); } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -351,7 +351,7 @@ export function createAnthropicFastModeWrapper( payloadObj.service_tier = serviceTier; } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; diff --git a/src/agents/pi-embedded-runner/extra-params.kilocode.test.ts b/src/agents/pi-embedded-runner/extra-params.kilocode.test.ts index 35a6cefcbd4..530100b26e7 100644 --- a/src/agents/pi-embedded-runner/extra-params.kilocode.test.ts +++ b/src/agents/pi-embedded-runner/extra-params.kilocode.test.ts @@ -19,7 +19,7 @@ function applyAndCapture(params: { const baseStreamFn: StreamFn = (model, _context, options) => { captured.headers = options?.headers; - options?.onPayload?.({}, model); + options?.onPayload?.({}); return createAssistantMessageEventStream(); }; const agent = { streamFn: baseStreamFn }; @@ -97,7 +97,7 @@ describe("extra-params: Kilocode kilo/auto reasoning", () => { const baseStreamFn: StreamFn = (model, _context, options) => { const payload: Record = { reasoning_effort: "high" }; - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); capturedPayload = payload; return createAssistantMessageEventStream(); }; @@ -125,7 +125,7 @@ describe("extra-params: Kilocode kilo/auto reasoning", () => { const baseStreamFn: StreamFn = (model, _context, options) => { const payload: Record = {}; - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); capturedPayload = payload; return createAssistantMessageEventStream(); }; @@ -158,7 +158,7 @@ describe("extra-params: Kilocode kilo/auto reasoning", () => { const baseStreamFn: StreamFn = (model, _context, options) => { const payload: Record = { reasoning_effort: "high" }; - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); capturedPayload = payload; return createAssistantMessageEventStream(); }; diff --git a/src/agents/pi-embedded-runner/extra-params.openrouter-cache-control.test.ts b/src/agents/pi-embedded-runner/extra-params.openrouter-cache-control.test.ts index 5a36c9c5a4d..a5b9940279f 100644 --- a/src/agents/pi-embedded-runner/extra-params.openrouter-cache-control.test.ts +++ b/src/agents/pi-embedded-runner/extra-params.openrouter-cache-control.test.ts @@ -13,7 +13,7 @@ type StreamPayload = { function runOpenRouterPayload(payload: StreamPayload, modelId: string) { const baseStreamFn: StreamFn = (model, _context, options) => { - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); return createAssistantMessageEventStream(); }; const agent = { streamFn: baseStreamFn }; diff --git a/src/agents/pi-embedded-runner/extra-params.ts b/src/agents/pi-embedded-runner/extra-params.ts index a9d5085e013..e5fe0b2a19f 100644 --- a/src/agents/pi-embedded-runner/extra-params.ts +++ b/src/agents/pi-embedded-runner/extra-params.ts @@ -235,7 +235,7 @@ function createGoogleThinkingPayloadWrapper( thinkingLevel, }); } - return onPayload?.(payload, model); + return onPayload?.(payload); }, }); }; @@ -268,7 +268,7 @@ function createZaiToolStreamWrapper( // Inject tool_stream: true for Z.AI API (payload as Record).tool_stream = true; } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -315,7 +315,7 @@ function createParallelToolCallsWrapper( if (payload && typeof payload === "object") { (payload as Record).parallel_tool_calls = enabled; } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; diff --git a/src/agents/pi-embedded-runner/extra-params.zai-tool-stream.test.ts b/src/agents/pi-embedded-runner/extra-params.zai-tool-stream.test.ts index f7262a66798..2dab69cd15a 100644 --- a/src/agents/pi-embedded-runner/extra-params.zai-tool-stream.test.ts +++ b/src/agents/pi-embedded-runner/extra-params.zai-tool-stream.test.ts @@ -22,7 +22,7 @@ type ToolStreamCase = { function runToolStreamCase(params: ToolStreamCase) { const payload: Record = { model: params.model.id, messages: [] }; const baseStreamFn: StreamFn = (model, _context, options) => { - options?.onPayload?.(payload, model); + options?.onPayload?.(payload); return {} as ReturnType; }; const agent = { streamFn: baseStreamFn }; diff --git a/src/agents/pi-embedded-runner/moonshot-stream-wrappers.ts b/src/agents/pi-embedded-runner/moonshot-stream-wrappers.ts index c066a168a0f..7eca8c17dbd 100644 --- a/src/agents/pi-embedded-runner/moonshot-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/moonshot-stream-wrappers.ts @@ -89,7 +89,7 @@ export function createSiliconFlowThinkingWrapper(baseStreamFn: StreamFn | undefi payloadObj.thinking = null; } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -139,7 +139,7 @@ export function createMoonshotThinkingWrapper( } } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; diff --git a/src/agents/pi-embedded-runner/openai-stream-wrappers.ts b/src/agents/pi-embedded-runner/openai-stream-wrappers.ts index d0b483e83ec..b0be191247f 100644 --- a/src/agents/pi-embedded-runner/openai-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/openai-stream-wrappers.ts @@ -281,7 +281,7 @@ export function createOpenAIResponsesContextManagementWrapper( compactThreshold, }); } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -306,7 +306,7 @@ export function createOpenAIFastModeWrapper(baseStreamFn: StreamFn | undefined): model, }); } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -335,7 +335,7 @@ export function createOpenAIServiceTierWrapper( payloadObj.service_tier = serviceTier; } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; diff --git a/src/agents/pi-embedded-runner/proxy-stream-wrappers.ts b/src/agents/pi-embedded-runner/proxy-stream-wrappers.ts index 4f77c31cfdd..a5f9f5b1d85 100644 --- a/src/agents/pi-embedded-runner/proxy-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/proxy-stream-wrappers.ts @@ -92,7 +92,7 @@ export function createOpenRouterSystemCacheWrapper(baseStreamFn: StreamFn | unde } } } - return originalOnPayload?.(payload, model); + return originalOnPayload?.(payload); }, }); }; @@ -113,7 +113,7 @@ export function createOpenRouterWrapper( }, onPayload: (payload) => { normalizeProxyReasoningPayload(payload, thinkingLevel); - return onPayload?.(payload, model); + return onPayload?.(payload); }, }); }; @@ -138,7 +138,7 @@ export function createKilocodeWrapper( }, onPayload: (payload) => { normalizeProxyReasoningPayload(payload, thinkingLevel); - return onPayload?.(payload, model); + return onPayload?.(payload); }, }); }; diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index 78b3a173ce7..0b3d246fe04 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -414,14 +414,14 @@ export function wrapOllamaCompatNumCtx(baseFn: StreamFn | undefined, numCtx: num ...options, onPayload: (payload: unknown) => { if (!payload || typeof payload !== "object") { - return options?.onPayload?.(payload, model); + return options?.onPayload?.(payload); } const payloadRecord = payload as Record; if (!payloadRecord.options || typeof payloadRecord.options !== "object") { payloadRecord.options = {}; } (payloadRecord.options as Record).num_ctx = numCtx; - return options?.onPayload?.(payload, model); + return options?.onPayload?.(payload); }, }); } diff --git a/src/agents/tools/web-fetch.cf-markdown.test.ts b/src/agents/tools/web-fetch.cf-markdown.test.ts index f22dc10df52..152641638c6 100644 --- a/src/agents/tools/web-fetch.cf-markdown.test.ts +++ b/src/agents/tools/web-fetch.cf-markdown.test.ts @@ -110,7 +110,7 @@ describe("web_fetch Cloudflare Markdown for Agents", () => { }, }, }, - }, + } as unknown as typeof baseToolConfig.config, sandboxed: false, runtimeFirecrawl: { active: false, diff --git a/src/auto-reply/reply/commands.test-harness.ts b/src/auto-reply/reply/commands.test-harness.ts index 84ef0c0f84d..c6ac7c3c956 100644 --- a/src/auto-reply/reply/commands.test-harness.ts +++ b/src/auto-reply/reply/commands.test-harness.ts @@ -1,5 +1,5 @@ import type { OpenClawConfig } from "../../config/config.js"; -import type { MsgContext } from "../templating.js"; +import type { MsgContext, TemplateContext } from "../templating.js"; import type { HandleCommandsParams } from "./commands-types.js"; import { buildCommandContext } from "./commands.js"; import { parseInlineDirectives } from "./directive-handling.js"; @@ -7,7 +7,7 @@ import { parseInlineDirectives } from "./directive-handling.js"; export function buildCommandTestParams( commandBody: string, cfg: OpenClawConfig, - ctxOverrides?: Partial, + ctxOverrides?: Partial, options?: { workspaceDir?: string; }, diff --git a/src/auto-reply/reply/commands.test.ts b/src/auto-reply/reply/commands.test.ts index 4056a0bd124..88d69680900 100644 --- a/src/auto-reply/reply/commands.test.ts +++ b/src/auto-reply/reply/commands.test.ts @@ -14,7 +14,7 @@ import * as internalHooks from "../../hooks/internal-hooks.js"; import { clearPluginCommands, registerPluginCommand } from "../../plugins/commands.js"; import { typedCases } from "../../test-utils/typed-cases.js"; import { INTERNAL_MESSAGE_CHANNEL } from "../../utils/message-channel.js"; -import type { MsgContext } from "../templating.js"; +import type { MsgContext, TemplateContext } from "../templating.js"; import { resetBashChatCommandForTests } from "./bash-command.js"; import { handleCompactCommand } from "./commands-compact.js"; import { buildCommandsPaginationKeyboard } from "./commands-info.js"; @@ -199,7 +199,11 @@ afterAll(async () => { await fs.rm(testWorkspaceDir, { recursive: true, force: true }); }); -function buildParams(commandBody: string, cfg: OpenClawConfig, ctxOverrides?: Partial) { +function buildParams( + commandBody: string, + cfg: OpenClawConfig, + ctxOverrides?: Partial, +) { return buildCommandTestParams(commandBody, cfg, ctxOverrides, { workspaceDir: testWorkspaceDir }); } diff --git a/src/cli/command-secret-gateway.test.ts b/src/cli/command-secret-gateway.test.ts index 6d0f89f6349..3cb12b03138 100644 --- a/src/cli/command-secret-gateway.test.ts +++ b/src/cli/command-secret-gateway.test.ts @@ -267,7 +267,7 @@ describe("resolveCommandSecretRefsViaGateway", () => { }, }, }, - } as OpenClawConfig, + } as unknown as OpenClawConfig, commandName: "agent", targetIds: new Set(["tools.web.fetch.firecrawl.apiKey"]), }); diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index d1713ee0e4c..324f0b3ee35 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -513,7 +513,9 @@ describe("update-cli", () => { call[0][2] === "-g", ); const updateOptions = - typeof updateCall?.[1] === "object" && updateCall[1] !== null ? updateCall[1] : undefined; + updateCall && typeof updateCall[1] === "object" && updateCall[1] !== null + ? (updateCall[1] as { env?: Record }) + : undefined; const mergedPath = updateOptions?.env?.Path ?? updateOptions?.env?.PATH ?? ""; expect(mergedPath.split(path.delimiter).slice(0, 2)).toEqual([ portableGitMingw, diff --git a/src/commands/configure.wizard.ts b/src/commands/configure.wizard.ts index c4349e0f74b..7ed35981349 100644 --- a/src/commands/configure.wizard.ts +++ b/src/commands/configure.wizard.ts @@ -4,6 +4,7 @@ import { formatCliCommand } from "../cli/command-format.js"; import type { OpenClawConfig } from "../config/config.js"; import { readConfigFileSnapshot, resolveGatewayPort, writeConfigFile } from "../config/config.js"; import { logConfigUpdated } from "../config/logging.js"; +import type { AgentCortexConfig } from "../config/types.agent-defaults.js"; import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js"; import type { RuntimeEnv } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; @@ -47,6 +48,7 @@ import { promptRemoteGatewayConfig } from "./onboard-remote.js"; import { setupSkills } from "./onboard-skills.js"; type ConfigureSectionChoice = WizardSection | "__continue"; +type CortexMode = NonNullable; async function resolveGatewaySecretInputForWizard(params: { cfg: OpenClawConfig; @@ -305,7 +307,7 @@ async function promptCortexMemoryConfig( runtime: RuntimeEnv, workspaceDir: string, ): Promise { - const existing = nextConfig.agents?.defaults?.cortex; + const existing: AgentCortexConfig | undefined = nextConfig.agents?.defaults?.cortex; const defaultGraphPath = nodePath.join(workspaceDir, ".cortex", "context.json"); const graphExists = await fsPromises .access(defaultGraphPath) @@ -359,7 +361,7 @@ async function promptCortexMemoryConfig( initialValue: existing?.mode ?? "technical", }), runtime, - ) as NonNullable["defaults"]>["cortex"]["mode"]; + ) as CortexMode; const maxCharsInput = guardCancel( await text({ diff --git a/src/config/types.tools.ts b/src/config/types.tools.ts index 449588839f0..cef4b6a6cfd 100644 --- a/src/config/types.tools.ts +++ b/src/config/types.tools.ts @@ -349,6 +349,12 @@ export type MemorySearchConfig = { model?: string; /** Optional embedding output dimensionality override (for providers that support it). */ outputDimensionality?: number; + /** Optional multimodal indexing for image/audio files in extra paths. */ + multimodal?: { + enabled?: boolean; + modalities?: Array<"image" | "audio" | "all">; + maxFileBytes?: number; + }; /** Local embedding settings (node-llama-cpp). */ local?: { /** GGUF model path or hf: URI. */ diff --git a/src/config/zod-schema.agent-runtime.ts b/src/config/zod-schema.agent-runtime.ts index b1a1ba37efb..84c531c02dd 100644 --- a/src/config/zod-schema.agent-runtime.ts +++ b/src/config/zod-schema.agent-runtime.ts @@ -600,6 +600,16 @@ export const MemorySearchSchema = z .optional(), model: z.string().optional(), outputDimensionality: z.number().int().positive().optional(), + multimodal: z + .object({ + enabled: z.boolean().optional(), + modalities: z + .array(z.union([z.literal("image"), z.literal("audio"), z.literal("all")])) + .optional(), + maxFileBytes: z.number().int().positive().optional(), + }) + .strict() + .optional(), local: z .object({ modelPath: z.string().optional(), diff --git a/src/memory/manager-sync-ops.ts b/src/memory/manager-sync-ops.ts index 22a7deea7ff..776466adad5 100644 --- a/src/memory/manager-sync-ops.ts +++ b/src/memory/manager-sync-ops.ts @@ -144,6 +144,7 @@ export abstract class MemoryManagerSyncOps { protected abstract sync(params?: { reason?: string; force?: boolean; + sessionFiles?: string[]; progress?: (update: MemorySyncProgressUpdate) => void; }): Promise; protected abstract withTimeout( @@ -855,6 +856,7 @@ export abstract class MemoryManagerSyncOps { protected async runSync(params?: { reason?: string; force?: boolean; + sessionFiles?: string[]; progress?: (update: MemorySyncProgressUpdate) => void; }) { const progress = params?.progress ? this.createSyncProgress(params.progress) : undefined; diff --git a/src/memory/manager.ts b/src/memory/manager.ts index d2ba715ca19..3a0ff97f819 100644 --- a/src/memory/manager.ts +++ b/src/memory/manager.ts @@ -443,6 +443,7 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem async sync(params?: { reason?: string; force?: boolean; + sessionFiles?: string[]; progress?: (update: MemorySyncProgressUpdate) => void; }): Promise { if (this.closed) { @@ -509,6 +510,7 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem private async runSyncWithReadonlyRecovery(params?: { reason?: string; force?: boolean; + sessionFiles?: string[]; progress?: (update: MemorySyncProgressUpdate) => void; }): Promise { try { diff --git a/src/types/pi-ai-oauth.d.ts b/src/types/pi-ai-oauth.d.ts new file mode 100644 index 00000000000..ed669062812 --- /dev/null +++ b/src/types/pi-ai-oauth.d.ts @@ -0,0 +1,23 @@ +declare module "@mariozechner/pi-ai/oauth" { + import type { OAuthCredentials, OAuthProvider } from "@mariozechner/pi-ai"; + + export function getOAuthApiKey( + provider: OAuthProvider, + credentialsByProvider: Record, + ): Promise<{ apiKey: string; newCredentials: OAuthCredentials } | null>; + + export function getOAuthProviders(): Array<{ + id: OAuthProvider; + envApiKey?: string; + oauthTokenEnv?: string; + }>; + + export function loginOpenAICodex(params: { + onAuth?: (event: { url: string }) => Promise | void; + onPrompt?: (prompt: { + message: string; + placeholder?: string; + }) => Promise | string | undefined; + onProgress?: (message: string) => void; + }): Promise; +} diff --git a/ui/src/ui/views/agents-utils.test.ts b/ui/src/ui/views/agents-utils.test.ts index e9a57242ecf..a42e45b7059 100644 --- a/ui/src/ui/views/agents-utils.test.ts +++ b/ui/src/ui/views/agents-utils.test.ts @@ -129,6 +129,15 @@ describe("renderOverview", () => { gatewayUrl: "ws://127.0.0.1:18789", token: "", sessionKey: "main", + lastActiveSessionKey: "main", + theme: "claw", + themeMode: "system", + chatFocusMode: false, + chatShowThinking: true, + splitRatio: 0.6, + navCollapsed: false, + navWidth: 220, + navGroupsCollapsed: {}, }, password: "", lastError: null, @@ -138,14 +147,28 @@ describe("renderOverview", () => { cronEnabled: null, cronNext: null, lastChannelsRefresh: null, + usageResult: null, + sessionsResult: null, + skillsReport: null, + cronJobs: [], + cronStatus: null, + attentionItems: [], + eventLog: [], + overviewLogLines: [], + showGatewayToken: false, + showGatewayPassword: false, onSettingsChange: () => {}, onPasswordChange: () => {}, onSessionKeyChange: () => {}, + onToggleGatewayTokenVisibility: () => {}, + onToggleGatewayPasswordVisibility: () => {}, onConnect: () => {}, onRefresh: () => {}, onOpenCortexPreview: () => {}, onOpenCortexConflicts: () => {}, onOpenCortexSync: () => {}, + onNavigate: () => {}, + onRefreshLogs: () => {}, }) as { strings: TemplateStringsArray; values: unknown[] }; expect(template.strings.join("")).toContain("Cortex");