From 3aa35514917e0ce7f4c33562cbc97cab9f36beac Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 24 Apr 2026 03:15:41 +0100 Subject: [PATCH] test: cover OpenAI server compaction docs --- docs/gateway/configuration-reference.md | 3 ++- docs/providers/openai.md | 4 ++- extensions/openai/openai-provider.test.ts | 5 ++++ .../openai-responses-payload-policy.test.ts | 27 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/gateway/configuration-reference.md b/docs/gateway/configuration-reference.md index 61f5a9953ca..5a5811c148a 100644 --- a/docs/gateway/configuration-reference.md +++ b/docs/gateway/configuration-reference.md @@ -1235,9 +1235,10 @@ Time format in system prompt. Default: `auto` (OS preference). - `verboseDefault`: default verbose level for agents. Values: `"off"`, `"on"`, `"full"`. Default: `"off"`. - `elevatedDefault`: default elevated-output level for agents. Values: `"off"`, `"on"`, `"ask"`, `"full"`. Default: `"on"`. - `model.primary`: format `provider/model` (e.g. `openai/gpt-5.4` for API-key access or `openai-codex/gpt-5.5` for Codex OAuth). If you omit the provider, OpenClaw tries an alias first, then a unique configured-provider match for that exact model id, and only then falls back to the configured default provider (deprecated compatibility behavior, so prefer explicit `provider/model`). If that provider no longer exposes the configured default model, OpenClaw falls back to the first configured provider/model instead of surfacing a stale removed-provider default. -- `models`: the configured model catalog and allowlist for `/model`. Each entry can include `alias` (shortcut) and `params` (provider-specific, for example `temperature`, `maxTokens`, `cacheRetention`, `context1m`). +- `models`: the configured model catalog and allowlist for `/model`. Each entry can include `alias` (shortcut) and `params` (provider-specific, for example `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`). - Safe edits: use `openclaw config set agents.defaults.models '' --strict-json --merge` to add entries. `config set` refuses replacements that would remove existing allowlist entries unless you pass `--replace`. - Provider-scoped configure/onboarding flows merge selected provider models into this map and preserve unrelated providers already configured. + - For direct OpenAI Responses models, server-side compaction is enabled automatically. Use `params.responsesServerCompaction: false` to stop injecting `context_management`, or `params.responsesCompactThreshold` to override the threshold. See [OpenAI server-side compaction](/providers/openai#server-side-compaction-responses-api). - `params`: global default provider parameters applied to all models. Set at `agents.defaults.params` (e.g. `{ cacheRetention: "long" }`). - `params` merge precedence (config): `agents.defaults.params` (global base) is overridden by `agents.defaults.models["provider/model"].params` (per-model), then `agents.list[].params` (matching agent id) overrides by key. See [Prompt Caching](/reference/prompt-caching) for details. - `embeddedHarness`: default low-level embedded agent runtime policy. Use `runtime: "auto"` to let registered plugin harnesses claim supported models, `runtime: "pi"` to force the built-in PI harness, or a registered harness id such as `runtime: "codex"`. Set `fallback: "none"` to disable automatic PI fallback. diff --git a/docs/providers/openai.md b/docs/providers/openai.md index 5981056a301..c79a26d0f3f 100644 --- a/docs/providers/openai.md +++ b/docs/providers/openai.md @@ -661,12 +661,14 @@ the Server-side compaction accordion below. - For direct OpenAI Responses models (`openai/*` on `api.openai.com`), OpenClaw auto-enables server-side compaction: + For direct OpenAI Responses models (`openai/*` on `api.openai.com`), the OpenAI plugin's Pi-harness stream wrapper auto-enables server-side compaction: - Forces `store: true` (unless model compat sets `supportsStore: false`) - Injects `context_management: [{ type: "compaction", compact_threshold: ... }]` - Default `compact_threshold`: 70% of `contextWindow` (or `80000` when unavailable) + This applies to the built-in Pi harness path and to OpenAI provider hooks used by embedded runs. The native Codex app-server harness manages its own context through Codex and is configured separately with `agents.defaults.embeddedHarness.runtime`. + Useful for compatible endpoints like Azure OpenAI Responses: diff --git a/extensions/openai/openai-provider.test.ts b/extensions/openai/openai-provider.test.ts index ec8d9fdee79..af69f829092 100644 --- a/extensions/openai/openai-provider.test.ts +++ b/extensions/openai/openai-provider.test.ts @@ -447,6 +447,7 @@ describe("buildOpenAIProvider", () => { provider: "openai", id: "gpt-5.4", baseUrl: "https://api.openai.com/v1", + contextWindow: 200_000, } as Model<"openai-responses">, payload: { reasoning: { effort: "none" }, @@ -457,6 +458,10 @@ describe("buildOpenAIProvider", () => { transport: "auto", openaiWsWarmup: true, }); + expect(result.payload.store).toBe(true); + expect(result.payload.context_management).toEqual([ + { type: "compaction", compact_threshold: 140_000 }, + ]); expect(result.payload.service_tier).toBe("priority"); expect(result.payload.text).toEqual({ verbosity: "low" }); expect(result.payload.reasoning).toEqual({ effort: "none" }); diff --git a/src/agents/openai-responses-payload-policy.test.ts b/src/agents/openai-responses-payload-policy.test.ts index 28b219bc313..83fa36954ea 100644 --- a/src/agents/openai-responses-payload-policy.test.ts +++ b/src/agents/openai-responses-payload-policy.test.ts @@ -32,6 +32,33 @@ describe("openai responses payload policy", () => { }); }); + it("couples native Responses server compaction to provider-managed store", () => { + const model = { + id: "gpt-5.4", + api: "openai-responses", + provider: "openai", + baseUrl: "https://api.openai.com/v1", + contextWindow: 200_000, + } satisfies Pick< + Model<"openai-responses">, + "api" | "baseUrl" | "contextWindow" | "id" | "provider" + >; + const payload = {} satisfies Record; + + applyOpenAIResponsesPayloadPolicy( + payload, + resolveOpenAIResponsesPayloadPolicy(model, { + enableServerCompaction: true, + storeMode: "provider-policy", + }), + ); + + expect(payload).toEqual({ + store: true, + context_management: [{ type: "compaction", compact_threshold: 140_000 }], + }); + }); + it("strips store and prompt cache for proxy-like responses routes when requested", () => { const policy = resolveOpenAIResponsesPayloadPolicy( {