diff --git a/package.json b/package.json index ef5b895512..e3cb341dff 100644 --- a/package.json +++ b/package.json @@ -159,8 +159,8 @@ "@homebridge/ciao": "^1.3.4", "@line/bot-sdk": "^10.6.0", "@lydell/node-pty": "1.2.0-beta.3", - "@mariozechner/pi-agent-core": "0.50.7", - "@mariozechner/pi-ai": "0.50.7", + "@mariozechner/pi-agent-core": "0.50.9", + "@mariozechner/pi-ai": "0.50.9", "@mariozechner/pi-coding-agent": "0.50.7", "@mariozechner/pi-tui": "0.50.7", "@mozilla/readability": "^0.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d97cbb1174..41eaa8606a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,11 +40,11 @@ importers: specifier: 1.2.0-beta.3 version: 1.2.0-beta.3 '@mariozechner/pi-agent-core': - specifier: 0.50.7 - version: 0.50.7(ws@8.19.0)(zod@4.3.6) + specifier: 0.50.9 + version: 0.50.9(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-ai': - specifier: 0.50.7 - version: 0.50.7(ws@8.19.0)(zod@4.3.6) + specifier: 0.50.9 + version: 0.50.9(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-coding-agent': specifier: 0.50.7 version: 0.50.7(ws@8.19.0)(zod@4.3.6) @@ -1391,12 +1391,12 @@ packages: resolution: {integrity: sha512-faGUlTcXka5l7rv0lP3K3vGW/ejRuOS24RR2aSFWREUQqzjgdsuWNo/IiPqL3kWRGt6Ahl2+qcDAwtdeWeuGUw==} hasBin: true - '@mariozechner/pi-agent-core@0.50.7': - resolution: {integrity: sha512-iSNh+7QQFVge3co0Au1X6sqXAr+X6e3XlRXM7oE3m6zMWj76A1YCciV2sLI/imBcoFLum8blIaM0empwL477dQ==} + '@mariozechner/pi-agent-core@0.50.9': + resolution: {integrity: sha512-Zsgqs/f2Fxrub1k95vj8kg7M1eTDdS1lP3gTV7h9raBUQzoaPP+9jYGoUL5KKqxsBbt7WgeAQrK3nrev400EHA==} engines: {node: '>=20.0.0'} - '@mariozechner/pi-ai@0.50.7': - resolution: {integrity: sha512-mVqaTE/Ulijd1olduEU02IfIP91aNt6F0UYJQNLR+m3b/6bsn21csZJZnkjYia0kHX7PnOLtikO2jG7dJpYY6g==} + '@mariozechner/pi-ai@0.50.9': + resolution: {integrity: sha512-a6sLIHLH+wo5zTFoo/0AE/P6GPyJzaXnE86z89t6tINzeSdKMApZZ+B4Cy4U3GpsYfxuZ9gBJlcKbfj+oKP3wg==} engines: {node: '>=20.0.0'} hasBin: true @@ -1409,6 +1409,10 @@ packages: resolution: {integrity: sha512-O8H8hXqoWdE+5eUUPiswq+WT+2eeshJHJmXKWMJMoSitNqdwzYZds9umAKdVLII6ZvjnFtd0awnf4VThYQBFIA==} engines: {node: '>=20.0.0'} + '@mariozechner/pi-tui@0.50.9': + resolution: {integrity: sha512-suMWoh+XB3JKkwrXfXSwEAsvkrPUn6Zn8JQ1I+1hcNQqH/lY6e8LFRwVBkkvPt/jwoxBh8jGoiTNVh5i7Yod0g==} + engines: {node: '>=20.0.0'} + '@matrix-org/matrix-sdk-crypto-nodejs@0.4.0': resolution: {integrity: sha512-+qqgpn39XFSbsD0dFjssGO9vHEP7sTyfs8yTpt8vuqWpUpF20QMwpCZi0jpYw7GxjErNTsMshopuo8677DfGEA==} engines: {node: '>= 22'} @@ -6389,10 +6393,10 @@ snapshots: std-env: 3.10.0 yoctocolors: 2.1.2 - '@mariozechner/pi-agent-core@0.50.7(ws@8.19.0)(zod@4.3.6)': + '@mariozechner/pi-agent-core@0.50.9(ws@8.19.0)(zod@4.3.6)': dependencies: - '@mariozechner/pi-ai': 0.50.7(ws@8.19.0)(zod@4.3.6) - '@mariozechner/pi-tui': 0.50.7 + '@mariozechner/pi-ai': 0.50.9(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-tui': 0.50.9 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - aws-crt @@ -6402,7 +6406,7 @@ snapshots: - ws - zod - '@mariozechner/pi-ai@0.50.7(ws@8.19.0)(zod@4.3.6)': + '@mariozechner/pi-ai@0.50.9(ws@8.19.0)(zod@4.3.6)': dependencies: '@anthropic-ai/sdk': 0.71.2(zod@4.3.6) '@aws-sdk/client-bedrock-runtime': 3.980.0 @@ -6430,8 +6434,8 @@ snapshots: dependencies: '@mariozechner/clipboard': 0.3.0 '@mariozechner/jiti': 2.6.5 - '@mariozechner/pi-agent-core': 0.50.7(ws@8.19.0)(zod@4.3.6) - '@mariozechner/pi-ai': 0.50.7(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-agent-core': 0.50.9(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.50.9(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-tui': 0.50.7 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 @@ -6461,6 +6465,14 @@ snapshots: marked: 15.0.12 mime-types: 3.0.2 + '@mariozechner/pi-tui@0.50.9': + dependencies: + '@types/mime-types': 2.1.4 + chalk: 5.6.2 + get-east-asian-width: 1.4.0 + marked: 15.0.12 + mime-types: 3.0.2 + '@matrix-org/matrix-sdk-crypto-nodejs@0.4.0': dependencies: https-proxy-agent: 7.0.6 diff --git a/src/agents/pi-embedded-runner/extra-params.ts b/src/agents/pi-embedded-runner/extra-params.ts index f2a3e1935d..a3314a5caf 100644 --- a/src/agents/pi-embedded-runner/extra-params.ts +++ b/src/agents/pi-embedded-runner/extra-params.ts @@ -20,22 +20,38 @@ export function resolveExtraParams(params: { return modelConfig?.params ? { ...modelConfig.params } : undefined; } -type CacheControlTtl = "5m" | "1h"; +type CacheRetention = "none" | "short" | "long"; -function resolveCacheControlTtl( +/** + * Resolve cacheRetention from extraParams, supporting both new `cacheRetention` + * and legacy `cacheControlTtl` values for backwards compatibility. + * + * Mapping: "5m" → "short", "1h" → "long" + * + * Only applies to Anthropic provider (OpenRouter uses openai-completions API + * with hardcoded cache_control, not the cacheRetention stream option). + */ +function resolveCacheRetention( extraParams: Record | undefined, provider: string, - modelId: string, -): CacheControlTtl | undefined { - const raw = extraParams?.cacheControlTtl; - if (raw !== "5m" && raw !== "1h") { +): CacheRetention | undefined { + if (provider !== "anthropic") { return undefined; } - if (provider === "anthropic") { - return raw; + + // Prefer new cacheRetention if present + const newVal = extraParams?.cacheRetention; + if (newVal === "none" || newVal === "short" || newVal === "long") { + return newVal; } - if (provider === "openrouter" && modelId.startsWith("anthropic/")) { - return raw; + + // Fall back to legacy cacheControlTtl with mapping + const legacy = extraParams?.cacheControlTtl; + if (legacy === "5m") { + return "short"; + } + if (legacy === "1h") { + return "long"; } return undefined; } @@ -44,22 +60,21 @@ function createStreamFnWithExtraParams( baseStreamFn: StreamFn | undefined, extraParams: Record | undefined, provider: string, - modelId: string, ): StreamFn | undefined { if (!extraParams || Object.keys(extraParams).length === 0) { return undefined; } - const streamParams: Partial & { cacheControlTtl?: CacheControlTtl } = {}; + const streamParams: Partial = {}; if (typeof extraParams.temperature === "number") { streamParams.temperature = extraParams.temperature; } if (typeof extraParams.maxTokens === "number") { streamParams.maxTokens = extraParams.maxTokens; } - const cacheControlTtl = resolveCacheControlTtl(extraParams, provider, modelId); - if (cacheControlTtl) { - streamParams.cacheControlTtl = cacheControlTtl; + const cacheRetention = resolveCacheRetention(extraParams, provider); + if (cacheRetention) { + streamParams.cacheRetention = cacheRetention; } if (Object.keys(streamParams).length === 0) { @@ -102,7 +117,7 @@ export function applyExtraParamsToAgent( ) : undefined; const merged = Object.assign({}, extraParams, override); - const wrappedStreamFn = createStreamFnWithExtraParams(agent.streamFn, merged, provider, modelId); + const wrappedStreamFn = createStreamFnWithExtraParams(agent.streamFn, merged, provider); if (wrappedStreamFn) { log.debug(`applying extraParams to agent streamFn for ${provider}/${modelId}`); diff --git a/src/config/config.pruning-defaults.test.ts b/src/config/config.pruning-defaults.test.ts index 5feb03bd1f..3a63c227aa 100644 --- a/src/config/config.pruning-defaults.test.ts +++ b/src/config/config.pruning-defaults.test.ts @@ -100,8 +100,8 @@ describe("config pruning defaults", () => { expect(cfg.agents?.defaults?.contextPruning?.ttl).toBe("1h"); expect(cfg.agents?.defaults?.heartbeat?.every).toBe("30m"); expect( - cfg.agents?.defaults?.models?.["anthropic/claude-opus-4-5"]?.params?.cacheControlTtl, - ).toBe("1h"); + cfg.agents?.defaults?.models?.["anthropic/claude-opus-4-5"]?.params?.cacheRetention, + ).toBe("short"); }); }); diff --git a/src/config/defaults.ts b/src/config/defaults.ts index e944d82115..de5ebcc539 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -392,12 +392,12 @@ export function applyContextPruningDefaults(cfg: OpenClawConfig): OpenClawConfig } const current = entry ?? {}; const params = (current as { params?: Record }).params ?? {}; - if (typeof params.cacheControlTtl === "string") { + if (typeof params.cacheRetention === "string") { continue; } nextModels[key] = { ...(current as Record), - params: { ...params, cacheControlTtl: "1h" }, + params: { ...params, cacheRetention: "short" }, }; modelsMutated = true; } @@ -410,10 +410,10 @@ export function applyContextPruningDefaults(cfg: OpenClawConfig): OpenClawConfig const entry = nextModels[key]; const current = entry ?? {}; const params = (current as { params?: Record }).params ?? {}; - if (typeof params.cacheControlTtl !== "string") { + if (typeof params.cacheRetention !== "string") { nextModels[key] = { ...(current as Record), - params: { ...params, cacheControlTtl: "1h" }, + params: { ...params, cacheRetention: "short" }, }; modelsMutated = true; }