fix(gateway): accept Paperclip adapter root-level paperclip metadata in agent params#69139
fix(gateway): accept Paperclip adapter root-level paperclip metadata in agent params#69139ztexydt-cqh wants to merge 2 commits into
Conversation
Greptile SummaryThis PR adds an optional Confidence Score: 5/5Safe to merge — single optional field added to a strict schema, accompanied by a targeted test. The change is minimal and well-scoped: one optional field on an already-strict schema (additionalProperties: false), typed as a generic record to stay intentionally opaque, with a matching test verifying acceptance. No existing behaviour is altered. No files require special attention. Reviews (1): Last reviewed commit: "test(gateway): verify Paperclip papercli..." | Re-trigger Greptile |
|
Sorry for the wrong ping above — @joaomdmoura is not a maintainer of this repo. Friendly ping to the actual core maintainers @steipete @vincentkoc — this PR is ready for review. Would appreciate a look when you have time. Thanks! |
|
Corroboration from live triage on 2026-04-22. I hit this exact bug in production debugging a separate Ollama latency issue. Every Paperclip heartbeat dispatch to a local OpenClaw gateway returns in under 1ms with: Traced to Applied this exact fix locally (patched the compiled
Your Tracked internally as CLAAA-413. |
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as duplicate/superseded. The Paperclip So I’m closing this here and keeping the remaining discussion on the canonical linked item. Review detailsBest possible solution: Consolidate the Paperclip compatibility work into one canonical additive gateway protocol change that accepts the adapter metadata without weakening unrelated validation, regenerates protocol artifacts, adds focused validator/handler tests, and records the user-facing fix in the changelog. Do we have a high-confidence way to reproduce the issue? Yes. A current-main Is this the best way to solve the issue? No as posted. Accepting adapter metadata is the right narrow direction, but this branch should not land as-is because it omits generated protocol artifacts/changelog and is superseded by the open #74974 replacement. Security review: Security review cleared: The PR diff only changes a gateway protocol schema and focused tests; it does not touch workflows, dependencies, lockfiles, install/build/release scripts, package publishing metadata, downloaded artifacts, or secret handling. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 068b33de8717. |
…tadata The first commit on this branch added `paperclip: Type.Optional(Type.Unknown())` to AgentParamsSchema as a vendor-named root-level tolerance field. The review on openclaw#74974 (and the surrounding history of openclaw#62102, openclaw#74635, openclaw#72565, openclaw#69139, openclaw#75901 — three earlier PRs proposing the same vendor-named shape, all closed without merge) makes the underlying request clear: the right contract is a generic opaque-metadata namespace any external agent or plugin adapter can write under, not a name-per-vendor field that grows the gateway protocol surface every time a new adapter ships. This commit lands that namespace alongside the existing alias: - AgentParamsSchema gains `adapterMeta: Type.Optional(Type.Record( Type.String(), Type.Unknown()))`. Each adapter writes its own top-level key under it (`adapterMeta: { paperclip: {...}, greptile: {...} }`); the gateway accepts the bag as opaque and never inspects it. - The existing `paperclip: Type.Optional(Type.Unknown())` field is kept as a backward-compatibility alias, with a comment documenting that new adapter metadata should use `adapterMeta` and that this field can be removed once the published Paperclip adapter cuts a release that nests its payload under `adapterMeta.paperclip`. Heartbeats from current Paperclip releases keep dispatching during the transition. - `additionalProperties: false` on AgentParamsSchema is left intact, so a typo'd root field (e.g. `idempotnecyKey`) still fails validation before dispatch — the fix doesn't widen the schema, it just adds two named landing pads. Tests in src/gateway/protocol/agent-params-validator.test.ts now cover: - adapterMeta with multiple adapter keys (paperclip + greptile) accepted - empty adapterMeta and adapterMeta with primitive values accepted - both surfaces side by side (paperclip + adapterMeta.paperclip) accepted - adapterMeta with a non-object value rejected - existing paperclip-only path unchanged - truly unknown root properties still rejected - canonical message + idempotencyKey still required Swift bindings in apps/shared/OpenClawKit/Sources/OpenClawProtocol/ GatewayModels.swift mirror the new field as `adaptermeta: [String: AnyCodable]?` in the four codegen sites (declaration, init signature, init body, CodingKeys = "adapterMeta"), matching the pattern used for `inputprovenance` and the existing `paperclip` mirror. CHANGELOG.md gets a `Gateway/protocol:` entry under `## Unreleased` describing the namespace + alias and citing openclaw#74635 and openclaw#62102 as the issues being closed. Refs openclaw#74974, openclaw#74635, openclaw#62102
… alias on AgentParamsSchema
Paperclip and other external agents inject a root-level metadata blob
when invoking agents via the openclaw_gateway adapter, but
AgentParamsSchema is declared with additionalProperties: false so the
gateway rejects the entire payload before dispatch:
invalid agent params: at root: unexpected property 'paperclip'
Reported by openclaw#74635 (Paperclip rev 3494e84 vs OpenClaw 2026.4.26
be8c246) and openclaw#62102. Three earlier PRs proposed a vendor-named root
field (openclaw#69139, openclaw#72565, openclaw#75901) - all closed without merge - so this
lands the fix as a generic namespace plus a backward-compatibility
alias instead.
Schema (src/gateway/protocol/schema/agent.ts)
- AgentParamsSchema gains 'adapterMeta: Type.Optional(Type.Record(
Type.String(), Type.Unknown()))'. Each external agent or plugin
adapter writes under its own top-level key here
(adapterMeta: { paperclip: {...}, greptile: {...} }); the gateway
accepts the bag as-is and never inspects it. New adapters can land
protocol-side without growing the schema.
- AgentParamsSchema also gains 'paperclip: Type.Optional(Type.Unknown())'
as a backward-compatibility alias, with a comment marking it for
removal once the published Paperclip adapter cuts a release that
nests under adapterMeta.paperclip. Heartbeats from current Paperclip
releases keep dispatching during the transition.
- additionalProperties: false on AgentParamsSchema is intentionally
untouched. Truly unknown root fields (e.g. typo'd 'idempotnecyKey')
still fail validation before dispatch.
Swift bindings (apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
Mirror the two new fields on the AgentParams struct in all four
codegen positions (declaration, init signature, init body, CodingKeys),
following the existing 'inputprovenance' and 'cleanupbundlemcponrunend'
pattern:
public let adaptermeta: [String: AnyCodable]?
public let paperclip: AnyCodable?
The macOS-side mirror was deleted upstream so only the shared one needs
to be regenerated.
Tests (src/gateway/protocol/agent-params-validator.test.ts, new)
- minimal canonical payload accepted, missing message/idempotencyKey rejected
- root-level paperclip alias accepts object, string, number, boolean, null
- adapterMeta with one or more adapter keys accepted
- empty adapterMeta and adapterMeta with primitive entry values accepted
- both surfaces side by side (paperclip + adapterMeta.paperclip) accepted
- adapterMeta with non-object value rejected (string, number, boolean, null, array)
- truly unknown root properties still rejected (additionalProperties guard intact)
Verification
- pnpm exec oxfmt --check --threads=1 on the touched .ts files: clean.
- Standalone tsx reproducer importing the schema body and compiling it
with the same Ajv configuration as src/gateway/protocol/index.ts:
19/19 cases pass (covering the 8 PR test scenarios above plus their
primitive variants).
- pnpm test src/gateway/protocol/agent-params-validator.test.ts is
expected to pass on CI; local run was blocked by registry access
while preparing the github-pinned @openclaw/fs-safe workspace dep.
Changelog
Added one bullet under ## Unreleased -> ### Changes describing the
namespace + alias and citing openclaw#74635 and openclaw#62102.
Fixes openclaw#74635.
Fixes openclaw#62102.
Refs openclaw#69139, openclaw#72565, openclaw#75901.
… alias on AgentParamsSchema
Paperclip and other external agents inject a root-level metadata blob
when invoking agents via the openclaw_gateway adapter, but
AgentParamsSchema is declared with additionalProperties: false so the
gateway rejects the entire payload before dispatch:
invalid agent params: at root: unexpected property 'paperclip'
Reported by openclaw#74635 (Paperclip rev 3494e84 vs OpenClaw 2026.4.26
be8c246) and openclaw#62102. Three earlier PRs proposed a vendor-named root
field (openclaw#69139, openclaw#72565, openclaw#75901) - all closed without merge - so this
lands the fix as a generic namespace plus a backward-compatibility
alias instead.
Schema (src/gateway/protocol/schema/agent.ts)
- AgentParamsSchema gains 'adapterMeta: Type.Optional(Type.Record(
Type.String(), Type.Unknown()))'. Each external agent or plugin
adapter writes under its own top-level key here
(adapterMeta: { paperclip: {...}, greptile: {...} }); the gateway
accepts the bag as-is and never inspects it. New adapters can land
protocol-side without growing the schema.
- AgentParamsSchema also gains 'paperclip: Type.Optional(Type.Unknown())'
as a backward-compatibility alias, with a comment marking it for
removal once the published Paperclip adapter cuts a release that
nests under adapterMeta.paperclip. Heartbeats from current Paperclip
releases keep dispatching during the transition.
- additionalProperties: false on AgentParamsSchema is intentionally
untouched. Truly unknown root fields (e.g. typo'd 'idempotnecyKey')
still fail validation before dispatch.
Swift bindings (apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
Mirror the two new fields on the AgentParams struct in all four
codegen positions (declaration, init signature, init body, CodingKeys),
following the existing 'inputprovenance' and 'cleanupbundlemcponrunend'
pattern:
public let adaptermeta: [String: AnyCodable]?
public let paperclip: AnyCodable?
The macOS-side mirror was deleted upstream so only the shared one needs
to be regenerated.
Tests (src/gateway/protocol/agent-params-validator.test.ts, new)
- minimal canonical payload accepted, missing message/idempotencyKey rejected
- root-level paperclip alias accepts object, string, number, boolean, null
- adapterMeta with one or more adapter keys accepted
- empty adapterMeta and adapterMeta with primitive entry values accepted
- both surfaces side by side (paperclip + adapterMeta.paperclip) accepted
- adapterMeta with non-object value rejected (string, number, boolean, null, array)
- truly unknown root properties still rejected (additionalProperties guard intact)
Verification
- pnpm exec oxfmt --check --threads=1 on the touched .ts files: clean.
- Standalone tsx reproducer importing the schema body and compiling it
with the same Ajv configuration as src/gateway/protocol/index.ts:
19/19 cases pass (covering the 8 PR test scenarios above plus their
primitive variants).
- pnpm test src/gateway/protocol/agent-params-validator.test.ts is
expected to pass on CI; local run was blocked by registry access
while preparing the github-pinned @openclaw/fs-safe workspace dep.
Changelog
Added one bullet under ## Unreleased -> ### Changes describing the
namespace + alias and citing openclaw#74635 and openclaw#62102.
Fixes openclaw#74635.
Fixes openclaw#62102.
Refs openclaw#69139, openclaw#72565, openclaw#75901.
Closes #69137
The Paperclip sends a root-level object in every payload, but OpenClaw's rejected it because is . This broke the documented Paperclip integration end-to-end after onboarding/auth succeeded.