feat(gateway): add SDK task ledger RPCs#74847
Conversation
|
Codex review: needs changes before merge. Summary Reproducibility: yes. Current main source shows Real behavior proof Next step before merge Security Review findings
Review detailsBest possible solution: Land the additive RPC/SDK surface after Do we have a high-confidence way to reproduce the issue? Yes. Current main source shows Is this the best way to solve the issue? Yes in direction, but not as-is. Additive RPCs over the existing task registry with operator scopes are the narrow maintainable path, but the read handlers need to reuse existing operator reconciliation before exposing statuses. Full review comments:
Overall correctness: patch is incorrect Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 094d0b88a57f. |
06a19cb to
1368f9d
Compare
…er-rpcs # Conflicts: # docs/concepts/openclaw-sdk.md # packages/sdk/src/index.test.ts # src/gateway/server-methods-list.ts
…er-rpcs # Conflicts: # apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
There was a problem hiding this comment.
Pull request overview
This PR adds a public, SDK-facing “task ledger” surface to the Gateway so external app clients can list, fetch, and cancel durable background task records over the existing RPC transport (closing the current oc.tasks.* unsupported gap).
Changes:
- Added Gateway RPC handlers for
tasks.list,tasks.get, andtasks.cancel, including status mapping and pagination cursor support. - Introduced protocol schemas/types + scope classification (
operator.readfor list/get;operator.writefor cancel) with corresponding Gateway/SKD tests. - Implemented
@openclaw/sdktask types and methods, and updated docs + Swift protocol models.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/tasks/task-registry.ts | Adds optional cancel reason propagation into task cancellation and stored task error text. |
| src/tasks/detached-task-runtime-contract.ts | Extends detached task cancel contract to accept an optional reason. |
| src/gateway/server-methods/tasks.ts | Implements the new Gateway RPC handlers and TaskRecord → TaskSummary mapping. |
| src/gateway/server-methods/tasks.test.ts | Adds handler-level coverage for list/get/cancel behavior and status mapping. |
| src/gateway/server-methods.ts | Registers the new tasks handlers in the core Gateway handler map. |
| src/gateway/server-methods-list.ts | Advertises the new tasks.* methods in the base method list. |
| src/gateway/protocol/schema/types.ts | Exposes schema-derived TS types for the new tasks RPCs. |
| src/gateway/protocol/schema/tasks.ts | Defines TypeBox schemas for task summaries, params, and results. |
| src/gateway/protocol/schema/protocol-schemas.ts | Adds tasks schemas to the ProtocolSchemas registry. |
| src/gateway/protocol/schema.ts | Re-exports the tasks schema module. |
| src/gateway/protocol/index.ts | Wires tasks schemas/types + AJV validators into the protocol index exports. |
| src/gateway/protocol/index.test.ts | Adds validation tests ensuring SDK-facing statuses/fields are accepted and internal ones rejected. |
| src/gateway/method-scopes.ts | Adds tasks.list/get to read scope group and tasks.cancel to write scope group. |
| src/gateway/method-scopes.test.ts | Verifies method → scope resolution for new tasks methods. |
| packages/sdk/src/types.ts | Adds SDK task ledger types (TaskSummary, status union, params/results). |
| packages/sdk/src/index.ts | Re-exports the new SDK task types. |
| packages/sdk/src/index.test.ts | Updates SDK unit tests to assert tasks methods call the Gateway methods (instead of throwing unsupported). |
| packages/sdk/src/index.e2e.test.ts | Extends websocket e2e fake gateway to implement tasks.* and asserts SDK integration. |
| packages/sdk/src/client.ts | Implements oc.tasks.list/get/cancel against the RPC namespace with typed return values. |
| docs/concepts/openclaw-sdk.md | Updates docs to mark oc.tasks as Ready, lists exported task types, and adds usage examples. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Adds Swift model bindings for the new tasks RPC shapes. |
|
@copilot apply changes based on the comments in this thread |
|
Thanks @tmimmanuel — this is a useful addition. The task-ledger RPCs give SDK clients a clean way to list, inspect, and cancel durable background tasks through the Gateway. I tightened the public surface before merge with sanitized task status text, stronger Swift typing for |
Summary
@openclaw/sdkexposedoc.tasks.*, butlist,get, andcancelstill threw unsupported errors because Gateway had no SDK-facing task ledger RPCs.tasks.list,tasks.get, andtasks.cancelGateway RPCs, SDK methods/types, protocol schemas, scopes, docs, and regression coverage.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
tasks.list,tasks.get, andtasks.cancelas missing basics.Regression Test Plan (if applicable)
src/gateway/server-methods/tasks.test.ts,src/gateway/protocol/index.test.ts,packages/sdk/src/index.test.ts,packages/sdk/src/index.e2e.test.ts.User-visible / Behavior Changes
oc.tasks.list(),oc.tasks.get(taskId), andoc.tasks.cancel(taskId)now call Gateway task ledger RPCs instead of throwing unsupported errors.Diagram (if applicable)
Security Impact (required)
Yes/No) YesYes/No) NoYes/No) NoYes/No) NoYes/No) YesYes, explain risk + mitigation:tasks.listandtasks.getrequireoperator.read;tasks.cancelrequiresoperator.write. The RPCs expose task metadata from the existing durable task registry and do not expose secrets.Repro + Verification
Environment
@openclaw/sdkSteps
oc.tasks.list(),oc.tasks.get("task-id"), oroc.tasks.cancel("task-id").Expected
Actual
Real behavior proof
Behavior or issue addressed: Issue Gateway RPC: add SDK-facing task ledger APIs #74707 -
@openclaw/sdkexposedoc.tasks.list,oc.tasks.get, andoc.tasks.cancel, but those methods threw unsupported errors because Gateway had no SDK-facing task ledger RPCs. This PR wires the three RPCs end-to-end (Gateway handlers, protocol schemas, scopes, SDK methods) so app clients like OpenMeow can read and cancel detached/background work over WebSocket.Real environment tested: Ubuntu 24.04 workstation, Node 22.22.0 via nvm, repo at PR head
bddac58c51,OPENCLAW_STATE_DIRpointed at a fresh tmp directory so the real durable task registry is exercised. Live invocation of the deployed Gateway RPC handlers vianode(throughtsxfor TypeScript path resolution).Exact steps or command run after this patch:
git rev-parse HEADandgh api /repos/openclaw/openclaw/pulls/74847 --jq .head.sha.nodescript that imports the new handler module (src/gateway/server-methods/tasks.ts) and the durable task registry (src/tasks/runtime-internal.ts) directly, seeds two real task records (one running subagent task, one completed CLI task), then invokes the three newtasks.*Gateway handlers and prints each RPC response.node(viatsxfor ESM TypeScript):node_modules/.bin/tsx /tmp/proof-tasks.mts. The transcript below is the actual stdout.Evidence after fix:
Live console output captured from running
node/tsxagainst the new handlers at PR headbddac58c51(real RPC responses from the deployed handler code, not stubbed):Observed result after fix:
tasks.listwithstatus=running, agentId=mainfilter returned exactly the seeded subagent task and excluded the completed CLI task. The response payload is the SDK-facing shape promised in the protocol schema (id,taskId,kind,runtime,status,title,agentId,sessionKey,childSessionKey,ownerKey,runId,createdAt,updatedAt).tasks.getagainst the seededsucceededregistry record returned the contract statuscompleted, confirming the public-status mapping (internalsucceeded-> SDKcompleted) is wired through the handler.tasks.cancelreturned the documented{ found, cancelled, reason?, task }envelope. Herefound=true, cancelled=false, reason="Subagent task not found."because no live subagent runtime was attached to the seeded record - that is the correct contract response for a registry record without a live runtime, and proves the cancel handler reaches the runtime resolver and reports a clear contract-shaped failure instead of throwing.OPENCLAW_STATE_DIR, confirming the Gateway-side surface routes through the existing task ledger.What was not tested: Cancel against a live attached subagent runtime that actually performs an abort (requires a full Gateway with running detached agent). The macOS app
OpenClawProtocolSwift model bindings (compiled by Xcode in the macOS app build, not exercised here). Auth-scope rejection over a live WebSocket connection (covered bysrc/gateway/method-scopes.test.tsand the SDK-side e2e inpackages/sdk/src/index.e2e.test.ts). Localized docs (publish repo regenerates separately).Evidence
Lint evidence:
git diff --check HEAD~1 HEADoxlinton changed TS filesmarkdownlint-cli2 docs/concepts/openclaw-sdk.mdReview Conversations
Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoRisks and Mitigations
succeededtocompletedandlosttofailed.