fix(agents): update cacheControlTtl to cacheRetention for pi-ai 0.50.9

- Update @mariozechner/pi-ai and pi-agent-core to 0.50.9
- Rename cacheControlTtl to cacheRetention with values none/short/long
- Add backwards compatibility mapping: 5m->short, 1h->long
- Remove dead OpenRouter check (uses openai-completions API)
- Default new configs to cacheRetention: short
This commit is contained in:
Mario Zechner
2026-02-01 09:50:52 +01:00
parent 511b2c91e3
commit ba4a55f6d9
5 changed files with 65 additions and 38 deletions

View File

@@ -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<string, unknown> | 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<string, unknown> | undefined,
provider: string,
modelId: string,
): StreamFn | undefined {
if (!extraParams || Object.keys(extraParams).length === 0) {
return undefined;
}
const streamParams: Partial<SimpleStreamOptions> & { cacheControlTtl?: CacheControlTtl } = {};
const streamParams: Partial<SimpleStreamOptions> = {};
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}`);

View File

@@ -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");
});
});

View File

@@ -392,12 +392,12 @@ export function applyContextPruningDefaults(cfg: OpenClawConfig): OpenClawConfig
}
const current = entry ?? {};
const params = (current as { params?: Record<string, unknown> }).params ?? {};
if (typeof params.cacheControlTtl === "string") {
if (typeof params.cacheRetention === "string") {
continue;
}
nextModels[key] = {
...(current as Record<string, unknown>),
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<string, unknown> }).params ?? {};
if (typeof params.cacheControlTtl !== "string") {
if (typeof params.cacheRetention !== "string") {
nextModels[key] = {
...(current as Record<string, unknown>),
params: { ...params, cacheControlTtl: "1h" },
params: { ...params, cacheRetention: "short" },
};
modelsMutated = true;
}