diff --git a/docs/.generated/plugin-sdk-api-baseline/agent-harness-runtime.json b/docs/.generated/plugin-sdk-api-baseline/agent-harness-runtime.json index 57dac44fd419..ba22e9cb9f50 100644 --- a/docs/.generated/plugin-sdk-api-baseline/agent-harness-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/agent-harness-runtime.json @@ -1 +1 @@ -{"contentHash":"606504bb06b321f5a4fef507f322c297a9295dccdc2e5996ac64603049113408","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"} +{"contentHash":"48dad42d04caeb62f04f9dbe32b4562ecef695e9f0c97fb891040408400f37bd","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/agent-harness.json b/docs/.generated/plugin-sdk-api-baseline/agent-harness.json index 2a8b60ee0264..69b4ae7e72f2 100644 --- a/docs/.generated/plugin-sdk-api-baseline/agent-harness.json +++ b/docs/.generated/plugin-sdk-api-baseline/agent-harness.json @@ -1 +1 @@ -{"contentHash":"40d137a31b2ac9f1da776aafcc77b54422b1610c91fe2d6594068e1f7285e91b","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"} +{"contentHash":"3d1c84bcc585b57a93054889e16fb3be02ff4d599d7d2a0566df6f463f2254a8","entrypoint":"agent-harness","importSpecifier":"openclaw/plugin-sdk/agent-harness"} diff --git a/docs/.generated/plugin-sdk-api-baseline/agent-runtime.json b/docs/.generated/plugin-sdk-api-baseline/agent-runtime.json index 61def1e61738..ce3ba2b55349 100644 --- a/docs/.generated/plugin-sdk-api-baseline/agent-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/agent-runtime.json @@ -1 +1 @@ -{"contentHash":"6667d863dee0c991c58196b0a77fa812fc1800fca9885c866abd04f3df1a03ce","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"} +{"contentHash":"fac71b2c80db2874419a589646fd560e8a8ad43dba93f5a6d26a73c171a0b4ba","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/channel-core.json b/docs/.generated/plugin-sdk-api-baseline/channel-core.json index 156c909f3056..fdf18fa93eb5 100644 --- a/docs/.generated/plugin-sdk-api-baseline/channel-core.json +++ b/docs/.generated/plugin-sdk-api-baseline/channel-core.json @@ -1 +1 @@ -{"contentHash":"6257c43a60153049dac1af0d828435081f10f6bcd2554e2a67d1c8adb6df973c","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"} +{"contentHash":"4245891bae7517cf001f637e80d1d813c11385d695eebbd69a61258e83399c4e","entrypoint":"channel-core","importSpecifier":"openclaw/plugin-sdk/channel-core"} diff --git a/docs/.generated/plugin-sdk-api-baseline/channel-entry-contract.json b/docs/.generated/plugin-sdk-api-baseline/channel-entry-contract.json index 876806d33a11..7dd5ca16f266 100644 --- a/docs/.generated/plugin-sdk-api-baseline/channel-entry-contract.json +++ b/docs/.generated/plugin-sdk-api-baseline/channel-entry-contract.json @@ -1 +1 @@ -{"contentHash":"88113b5ae8119ca780a3d93b0e033c87d0c387b21a29b72e72b375f5c77f08b3","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"} +{"contentHash":"f719599ed89a658109698bc1ef1309e1709e5ae3385b7ce3f1c583343ea23b33","entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract"} diff --git a/docs/.generated/plugin-sdk-api-baseline/channel-message.json b/docs/.generated/plugin-sdk-api-baseline/channel-message.json index 12d12f0322ff..86450cb57afe 100644 --- a/docs/.generated/plugin-sdk-api-baseline/channel-message.json +++ b/docs/.generated/plugin-sdk-api-baseline/channel-message.json @@ -1 +1 @@ -{"contentHash":"a85b4bbcd416a76bde8d58af34fab58bdb416a1b2c8476b46a3ffd8540754e04","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"} +{"contentHash":"d531b32d0544c42f375f628bd7a6b3d3582a91078db37bc048af7c3f23a9e59f","entrypoint":"channel-message","importSpecifier":"openclaw/plugin-sdk/channel-message"} diff --git a/docs/.generated/plugin-sdk-api-baseline/channel-outbound.json b/docs/.generated/plugin-sdk-api-baseline/channel-outbound.json index 051fa3974425..b8ae76a44c49 100644 --- a/docs/.generated/plugin-sdk-api-baseline/channel-outbound.json +++ b/docs/.generated/plugin-sdk-api-baseline/channel-outbound.json @@ -1 +1 @@ -{"contentHash":"12e07b9ba7b5b35c1f4e0f4510a073adac00671d292a72700025c86376db22b0","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"} +{"contentHash":"40b25681a1ee102cf1d2d5b23a29f96e2501ea521404deed59303e59c35089ec","entrypoint":"channel-outbound","importSpecifier":"openclaw/plugin-sdk/channel-outbound"} diff --git a/docs/.generated/plugin-sdk-api-baseline/channel-plugin-common.json b/docs/.generated/plugin-sdk-api-baseline/channel-plugin-common.json index 41cf20d4e926..ff23b7afdb69 100644 --- a/docs/.generated/plugin-sdk-api-baseline/channel-plugin-common.json +++ b/docs/.generated/plugin-sdk-api-baseline/channel-plugin-common.json @@ -1 +1 @@ -{"contentHash":"f36ace33d1e16649ed888032751d5db67e826cdc59f06732a5c13b5185f971ed","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"} +{"contentHash":"67884fcf5fc91b8b40a3c83e83080e69f54f7750cdd780368af63363f84ddc40","entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common"} diff --git a/docs/.generated/plugin-sdk-api-baseline/config-mutation.json b/docs/.generated/plugin-sdk-api-baseline/config-mutation.json index 9106b41a163f..f7ad9d6ff24a 100644 --- a/docs/.generated/plugin-sdk-api-baseline/config-mutation.json +++ b/docs/.generated/plugin-sdk-api-baseline/config-mutation.json @@ -1 +1 @@ -{"contentHash":"b70eb302db749674e237eb2d740dacca2c20f883cd7f0581299cf010d3a71863","entrypoint":"config-mutation","importSpecifier":"openclaw/plugin-sdk/config-mutation"} +{"contentHash":"a7c63538d37122bfe240f75944916a3f01806f7fb7de3ecb976c6fd3f5dcd72e","entrypoint":"config-mutation","importSpecifier":"openclaw/plugin-sdk/config-mutation"} diff --git a/docs/.generated/plugin-sdk-api-baseline/config-runtime.json b/docs/.generated/plugin-sdk-api-baseline/config-runtime.json index 7123ed1c0dbf..6cc903f9d13d 100644 --- a/docs/.generated/plugin-sdk-api-baseline/config-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/config-runtime.json @@ -1 +1 @@ -{"contentHash":"4339bf4856bafcbf691b25df94a564a9b7bde09c041b9c0b31df3636a6e58462","entrypoint":"config-runtime","importSpecifier":"openclaw/plugin-sdk/config-runtime"} +{"contentHash":"3f128cc41bb2e44b40402774acd3a967501c72ae5d7b2f9d149a262cc0d5a2da","entrypoint":"config-runtime","importSpecifier":"openclaw/plugin-sdk/config-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/core.json b/docs/.generated/plugin-sdk-api-baseline/core.json index 775825f24dd0..12f84c8b1167 100644 --- a/docs/.generated/plugin-sdk-api-baseline/core.json +++ b/docs/.generated/plugin-sdk-api-baseline/core.json @@ -1 +1 @@ -{"contentHash":"7451e2a5ffc615f6e8fedebbf4327caf3a64a30973828ca776ca8e298052eebf","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"} +{"contentHash":"ab54be164a2b0affece4d6c196ee64ae9259cac072d4ac6c32dd27daf4941565","entrypoint":"core","importSpecifier":"openclaw/plugin-sdk/core"} diff --git a/docs/.generated/plugin-sdk-api-baseline/discord.json b/docs/.generated/plugin-sdk-api-baseline/discord.json index 4be0b091d72d..b8fce271f0c0 100644 --- a/docs/.generated/plugin-sdk-api-baseline/discord.json +++ b/docs/.generated/plugin-sdk-api-baseline/discord.json @@ -1 +1 @@ -{"contentHash":"726e1cc6c7c0463333587b25908a0b4274c9ca2e1c7d696ab7af5cb392aeca07","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"} +{"contentHash":"21823a6741645b81797b4be6bf16a2d067e7e2a007177fbc5c7a6cab98b08027","entrypoint":"discord","importSpecifier":"openclaw/plugin-sdk/discord"} diff --git a/docs/.generated/plugin-sdk-api-baseline/inbound-reply-dispatch.json b/docs/.generated/plugin-sdk-api-baseline/inbound-reply-dispatch.json index d84bd6799495..430076fe058e 100644 --- a/docs/.generated/plugin-sdk-api-baseline/inbound-reply-dispatch.json +++ b/docs/.generated/plugin-sdk-api-baseline/inbound-reply-dispatch.json @@ -1 +1 @@ -{"contentHash":"da9273b6213137fdfc3c2f0f22de681c7bd664dfb4fd0fd0f7636b70cad9835b","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"} +{"contentHash":"80686774b5023519466038e4a20604d9efce462b0cd2915ab5597fb1087ef8af","entrypoint":"inbound-reply-dispatch","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch"} diff --git a/docs/.generated/plugin-sdk-api-baseline/meeting-runtime.json b/docs/.generated/plugin-sdk-api-baseline/meeting-runtime.json index d024143ffc6d..539f07550335 100644 --- a/docs/.generated/plugin-sdk-api-baseline/meeting-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/meeting-runtime.json @@ -1 +1 @@ -{"contentHash":"2328445ee010703050ecce3ea4b823881172b1da8ffd061cb149a7324ac3b967","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"} +{"contentHash":"9eb227dd27a3d08b868b1144bd64e1ff22da707af353699b9eb0f6438d4d98c1","entrypoint":"meeting-runtime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/model-session-runtime.json b/docs/.generated/plugin-sdk-api-baseline/model-session-runtime.json index de80d5630d4c..e1e954a02924 100644 --- a/docs/.generated/plugin-sdk-api-baseline/model-session-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/model-session-runtime.json @@ -1 +1 @@ -{"contentHash":"b1b9afd14967ec92dad01bc0a00997b578b9c4ca0f8601597fc58b503fc13606","entrypoint":"model-session-runtime","importSpecifier":"openclaw/plugin-sdk/model-session-runtime"} +{"contentHash":"ecb40006fc5ea974a3e31d0782c86e50c054e19164f864a564bb6f3f3d00dae9","entrypoint":"model-session-runtime","importSpecifier":"openclaw/plugin-sdk/model-session-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/plugin-entry.json b/docs/.generated/plugin-sdk-api-baseline/plugin-entry.json index a7e49f33706f..ecfbe38df1a8 100644 --- a/docs/.generated/plugin-sdk-api-baseline/plugin-entry.json +++ b/docs/.generated/plugin-sdk-api-baseline/plugin-entry.json @@ -1 +1 @@ -{"contentHash":"cd50a67407a27b36d6f3e22af00940d1031bfe907fc15be5a72187e68f04d822","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"} +{"contentHash":"696f33ed5d8f059b82ff4159183b80f7e4af086abb2383bae5c02d909427fe43","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry"} diff --git a/docs/.generated/plugin-sdk-api-baseline/plugin-runtime.json b/docs/.generated/plugin-sdk-api-baseline/plugin-runtime.json index 79ea9f3b1493..3b669bec3c96 100644 --- a/docs/.generated/plugin-sdk-api-baseline/plugin-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/plugin-runtime.json @@ -1 +1 @@ -{"contentHash":"ba7ea5cfd334e44f5c5c2571a2161961a44f51e64e45074917fab3e69ac7652f","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"} +{"contentHash":"411769ac67fd1a5b0ea4ada41b45678688e86194d03adc8d8efcad65c5f0c38c","entrypoint":"plugin-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/provider-auth.json b/docs/.generated/plugin-sdk-api-baseline/provider-auth.json index e0d55cfede16..11124ace8d6d 100644 --- a/docs/.generated/plugin-sdk-api-baseline/provider-auth.json +++ b/docs/.generated/plugin-sdk-api-baseline/provider-auth.json @@ -1 +1 @@ -{"contentHash":"7233a8bb04605b4022cb18569b93f062d4f7986ae5ab5dd09e6c655984b56542","entrypoint":"provider-auth","importSpecifier":"openclaw/plugin-sdk/provider-auth"} +{"contentHash":"d56a974704a97ae438b03ba82aa84314e77bf65a7e7dd9096fd2ab2bc8cbcbec","entrypoint":"provider-auth","importSpecifier":"openclaw/plugin-sdk/provider-auth"} diff --git a/docs/.generated/plugin-sdk-api-baseline/provider-catalog-runtime.json b/docs/.generated/plugin-sdk-api-baseline/provider-catalog-runtime.json index 8dbf79d536d2..22f4ce4ef442 100644 --- a/docs/.generated/plugin-sdk-api-baseline/provider-catalog-runtime.json +++ b/docs/.generated/plugin-sdk-api-baseline/provider-catalog-runtime.json @@ -1 +1 @@ -{"contentHash":"6f6b852b66e41c6f2c15b617bc00148efbafc2d737049b19b45fe3b25eebb9fe","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"} +{"contentHash":"6539e277a49a27344f2844bcce06f609c5e463bb5a9be9eb1532994f9fec6479","entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime"} diff --git a/docs/.generated/plugin-sdk-api-baseline/tool-plugin.json b/docs/.generated/plugin-sdk-api-baseline/tool-plugin.json index e7cf05ffec50..06bfdb667c76 100644 --- a/docs/.generated/plugin-sdk-api-baseline/tool-plugin.json +++ b/docs/.generated/plugin-sdk-api-baseline/tool-plugin.json @@ -1 +1 @@ -{"contentHash":"0686a3b02b9bae23e46af30fdddf46487db53ec6ffe0833ce9cf298aded54362","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"} +{"contentHash":"9d1c23c498e989db4592749e735d0a09fc41ffeb86ab66f70b6894a2161e1212","entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin"} diff --git a/docs/.generated/plugin-sdk-api-baseline/webhook-ingress.json b/docs/.generated/plugin-sdk-api-baseline/webhook-ingress.json index 3e29106b8dd2..e25b523b4985 100644 --- a/docs/.generated/plugin-sdk-api-baseline/webhook-ingress.json +++ b/docs/.generated/plugin-sdk-api-baseline/webhook-ingress.json @@ -1 +1 @@ -{"contentHash":"80e15361b1e42280548074fc349fd32a45b55dd622c33bc37a0e2db963852790","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"} +{"contentHash":"d0b42cb31d5b2e84acb3a63ca79fdd2bc988bde3505de54dc07dd85bb76fd60c","entrypoint":"webhook-ingress","importSpecifier":"openclaw/plugin-sdk/webhook-ingress"} diff --git a/docs/concepts/context-engine.md b/docs/concepts/context-engine.md index 03ca332eb3fc..674dd5223887 100644 --- a/docs/concepts/context-engine.md +++ b/docs/concepts/context-engine.md @@ -213,13 +213,13 @@ Required members: | `assemble(params)` | Method | Build context for a model run (returns `AssembleResult`) | | `compact(params)` | Method | Summarize/reduce context | -Set `info.acceptedHostParams` to the host-added lifecycle fields the engine -accepts. Current keys are `sessionKey`, `prompt`, `runtimeSettings`, +Set `info.acceptedHostParams` to restrict the host-added lifecycle fields the +engine receives. Current keys are `sessionKey`, `prompt`, `runtimeSettings`, `sessionTarget`, and `runtimeContext`. OpenClaw intersects the declaration with the fields available for each lifecycle method, so undeclared or unknown keys -are never injected. Engines without this declaration receive the pre-host-field -legacy parameter set through 2026-08-12; after that date, undeclared engines -receive every current host field. +are never injected. Engines without this declaration receive every current +host field; declare an explicit list, including `[]`, when the engine validates +a narrower input shape. For durable admitted turns, declare both transcript semantics: @@ -308,9 +308,9 @@ rendered directly to users and does not create a dedicated reporting surface. - `diagnostics`: closed fallback and degraded reason codes when known Fields that can be unknown are represented as `null`; discriminator fields such -as runtime mode and selection source remain non-nullable. Engines that accept -`runtimeSettings` must include it in `info.acceptedHostParams` during the -compatibility window. +as runtime mode and selection source remain non-nullable. Engines that restrict +host parameters and accept `runtimeSettings` must include it in +`info.acceptedHostParams`. ### Host requirements diff --git a/docs/plugins/sdk-migration.md b/docs/plugins/sdk-migration.md index 6cd730ef1aaf..98f5be775480 100644 --- a/docs/plugins/sdk-migration.md +++ b/docs/plugins/sdk-migration.md @@ -198,14 +198,14 @@ artifact reader count is zero. Audit the current migration queue with `pnpm plugins:boundary-report`: -| Flag | Effect | -| ------------------------------------------------------- | ------------------------------------------------------------------------------ | -| `--summary` (or `pnpm plugins:boundary-report:summary`) | Compact counts instead of full detail. | -| `--json` | Machine-readable report. | -| `--owner ` | Filter to one plugin or compatibility owner. | -| `--fail-on-cross-owner` | Exit non-zero on cross-owner reserved SDK imports. | -| `--fail-on-eligible-compat` | Exit non-zero when a deprecated compat record's `removeAfter` date has passed. | -| `--fail-on-unclassified-unused-reserved` | Exit non-zero on unused reserved SDK shims. | +| Flag | Effect | +| ------------------------------------------------------- | -------------------------------------------------------------------------- | +| `--summary` (or `pnpm plugins:boundary-report:summary`) | Compact counts instead of full detail. | +| `--json` | Machine-readable report. | +| `--owner ` | Filter to one plugin or compatibility owner. | +| `--fail-on-cross-owner` | Exit non-zero on cross-owner reserved SDK imports. | +| `--fail-on-eligible-compat` | Exit non-zero on or after a deprecated compat record's `removeAfter` date. | +| `--fail-on-unclassified-unused-reserved` | Exit non-zero on unused reserved SDK shims. | `pnpm plugins:boundary-report:ci` runs with all three fail flags. Deprecated records normally have an explicit `removeAfter` date. A contract tied to a @@ -1069,7 +1069,7 @@ apps own device capture/playback UX. | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | **Now** | Warning-capable deprecated surfaces emit runtime warnings; repository guards reject deprecated SDK imports from core and bundled plugins. | | **Pending owner decision** | Records without `removeAfter` or `removalGate` remain deprecated and ineligible until their owner publishes a gate. | -| **Each compat record's `removeAfter` date** | That dated surface becomes eligible for removal; `pnpm plugins:boundary-report --fail-on-eligible-compat` fails CI once the date passes. | +| **Each compat record's `removeAfter` date** | That dated surface becomes eligible for removal; `pnpm plugins:boundary-report --fail-on-eligible-compat` fails CI on or after that date. | | **Next Plugin SDK major** | `inbound-reply-dispatch` reaches its explicit `next-plugin-sdk-major` gate; it is not date-eligible before that version boundary. | The remaining public SDK subpaths below have registry-backed removal windows. diff --git a/docs/plugins/sdk-overview.md b/docs/plugins/sdk-overview.md index f674421fe98c..f14cff72dc0f 100644 --- a/docs/plugins/sdk-overview.md +++ b/docs/plugins/sdk-overview.md @@ -619,10 +619,10 @@ For an end-to-end authoring guide, see ### Exclusive slots -| Method | What it registers | -| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `api.registerContextEngine(id, factory)` | Context engine (one active at a time). Declare accepted host-added lifecycle fields with `info.acceptedHostParams`; undeclared engines receive the legacy field set through 2026-08-12, then receive all current host fields. | -| `api.registerMemoryCapability(capability)` | Unified memory capability | +| Method | What it registers | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `api.registerContextEngine(id, factory)` | Context engine (one active at a time). Use `info.acceptedHostParams` to restrict accepted host-added lifecycle fields; undeclared engines receive all current host fields. | +| `api.registerMemoryCapability(capability)` | Unified memory capability | To participate in durable admitted turns, context engines must declare `currentTurnFence: "before-current-turn-entry-v1"` and diff --git a/src/context-engine/host-param-projection.test.ts b/src/context-engine/host-param-projection.test.ts index 2945e43a87a6..8aefbad0c59a 100644 --- a/src/context-engine/host-param-projection.test.ts +++ b/src/context-engine/host-param-projection.test.ts @@ -128,27 +128,6 @@ describe("context-engine host parameter projection", () => { }); }); - it("uses the legacy parameter set for undeclared engines during the window", async () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date("2026-07-29T12:00:00Z")); - const assembleCalls: Array> = []; - const compactCalls: Array> = []; - const engineId = registerProbeEngine({ assembleCalls, compactCalls }); - - await invokeHostParamMethods( - await resolveContextEngine({ plugins: { slots: { contextEngine: engineId } } }), - ); - - for (const call of [...assembleCalls, ...compactCalls]) { - expect(call).not.toHaveProperty("sessionKey"); - expect(call).not.toHaveProperty("runtimeSettings"); - } - expect(assembleCalls[0]).not.toHaveProperty("prompt"); - expect(compactCalls[0]).not.toHaveProperty("sessionTarget"); - expect(compactCalls[0]).not.toHaveProperty("runtimeContext"); - expect(compactCalls[0]).toHaveProperty("sessionId", "session-1"); - }); - it("projects host parameters on fresh logical-turn engines", async () => { const assembleCalls: Array> = []; const compactCalls: Array> = []; @@ -234,9 +213,7 @@ describe("context-engine host parameter projection", () => { ]); }); - it("passes every host parameter to fresh undeclared engines after the window", async () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date("2026-08-13T00:00:00Z")); + it("passes every host parameter to fresh undeclared engines", async () => { const assembleCalls: Array> = []; const compactCalls: Array> = []; const engineId = registerProbeEngine({ assembleCalls, compactCalls }); @@ -265,15 +242,12 @@ describe("context-engine host parameter projection", () => { ]); }); - it("switches undeclared engines to full parameters after the window", async () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date("2026-07-29T12:00:00Z")); + it("passes every host parameter to resolved undeclared engines", async () => { const assembleCalls: Array> = []; const compactCalls: Array> = []; const engineId = registerProbeEngine({ assembleCalls, compactCalls }); const engine = await resolveContextEngine({ plugins: { slots: { contextEngine: engineId } } }); - vi.setSystemTime(new Date("2026-08-13T00:00:00Z")); await invokeHostParamMethods(engine); expect(assembleCalls[0]).toMatchObject({ @@ -317,15 +291,13 @@ describe("context-engine host parameter projection", () => { }); it("does not mutate frozen engines reused by a factory", async () => { - vi.useFakeTimers(); - vi.setSystemTime(new Date("2026-07-29T12:00:00Z")); const engineId = `host-param-frozen-${++engineCounter}`; const assemble = vi.fn(async (params) => ({ messages: params.messages, estimatedTokens: 0, })); class FrozenProbeEngine implements ContextEngine { - readonly #info = { id: engineId, name: "Frozen Probe" }; + readonly #info = { id: engineId, name: "Frozen Probe", acceptedHostParams: [] }; get info() { return this.#info; @@ -346,7 +318,7 @@ describe("context-engine host parameter projection", () => { const first = await resolveContextEngine({ plugins: { slots: { contextEngine: engineId } } }); const second = await resolveContextEngine({ plugins: { slots: { contextEngine: engineId } } }); - expect(first.info).toEqual({ id: engineId, name: "Frozen Probe" }); + expect(first.info).toEqual({ id: engineId, name: "Frozen Probe", acceptedHostParams: [] }); await first.assemble({ sessionId: "session-1", sessionKey: "first", messages: [message] }); await second.assemble({ sessionId: "session-2", sessionKey: "second", messages: [message] }); diff --git a/src/context-engine/registry.ts b/src/context-engine/registry.ts index b499974bc010..26508562e5a9 100644 --- a/src/context-engine/registry.ts +++ b/src/context-engine/registry.ts @@ -2,7 +2,6 @@ import { sanitizeForLog } from "../../packages/terminal-core/src/ansi.js"; import type { OpenClawConfig } from "../config/types.js"; import { createAbortError } from "../infra/abort-signal.js"; -import { getPluginCompatRecord } from "../plugins/compat/registry.js"; import type { ContextEngineFactory, ContextEngineFactoryContext, @@ -55,20 +54,11 @@ type ResolvedContextEngineMetadata = { }; const resolvedEngineMetadata = new WeakMap(); -const legacyHostParamDefaultRemoveAfter = getPluginCompatRecord( - "context-engine-legacy-host-param-default", -).removeAfter; - function projectContextEngineHostParams( engine: ContextEngine, params: Record, ): Record { - // Removal(2026-08-12): undeclared engines get full params. - // Contract: context-engine-legacy-host-param-default. - const useLegacyDefault = - legacyHostParamDefaultRemoveAfter !== undefined && - new Date().toISOString().slice(0, 10) <= legacyHostParamDefaultRemoveAfter; - const accepted = engine.info.acceptedHostParams ?? (useLegacyDefault ? [] : undefined); + const accepted = engine.info.acceptedHostParams; if (!accepted) { return params; } diff --git a/src/plugins/compat/registry-records.ts b/src/plugins/compat/registry-records.ts index 52417921850a..333555f81311 100644 --- a/src/plugins/compat/registry-records.ts +++ b/src/plugins/compat/registry-records.ts @@ -13,18 +13,17 @@ export const PLUGIN_COMPAT_RECORDS = [ MEDIA_LEGACY_PROJECTION_COMPAT_RECORD, { code: "context-engine-legacy-host-param-default", - status: "deprecated", + status: "removed", owner: "sdk", introduced: "2026-07-29", - deprecated: "2026-07-29", - warningStarts: "2026-07-29", - removeAfter: "2026-08-12", replacement: - "declare `ContextEngineInfo.acceptedHostParams`; full host params after the window", + "`ContextEngineInfo.acceptedHostParams` for restricted projection; omitted declarations receive full host params", docsPath: "/concepts/context-engine#the-contextengine-interface", surfaces: ["ContextEngineInfo.acceptedHostParams and undeclared-engine default projection"], - diagnostics: ["plugin compatibility registry and dated runtime removal marker"], + diagnostics: ["plugin compatibility registry and context engine guide"], tests: ["src/context-engine/host-param-projection.test.ts"], + releaseNote: + "The undeclared context-engine host-parameter compatibility default was removed; engines without `acceptedHostParams` now receive all current host fields.", }, { code: "removed-global-api-provider-publication", diff --git a/src/plugins/compat/registry.test.ts b/src/plugins/compat/registry.test.ts index b728f341abe8..cc8ac652cc36 100644 --- a/src/plugins/compat/registry.test.ts +++ b/src/plugins/compat/registry.test.ts @@ -176,17 +176,17 @@ describe("plugin compatibility registry", () => { ); }); - it("tracks the context-engine legacy host-param default through its two-week window", () => { + it("keeps the removed context-engine host-param default as a migration tombstone", () => { const record = listPluginCompatRecords().find( (candidate) => candidate.code === "context-engine-legacy-host-param-default", ); expect(record).toMatchObject({ - status: "deprecated", - deprecated: "2026-07-29", - warningStarts: "2026-07-29", - removeAfter: "2026-08-12", + status: "removed", + replacement: + "`ContextEngineInfo.acceptedHostParams` for restricted projection; omitted declarations receive full host params", }); + expect(record?.removeAfter).toBeUndefined(); }); it("keeps deprecated explicit target parser calls inside compatibility shims", () => {