feat(gateway/sdk): artifact RPCs with cursor pagination, type filter, and provenance fix#75208
feat(gateway/sdk): artifact RPCs with cursor pagination, type filter, and provenance fix#75208Angfr95 wants to merge 3 commits intoopenclaw:mainfrom
Conversation
|
Codex review: found issues before merge. Summary Reproducibility: yes. The PR cursor bug is source-reproducible with two artifacts sharing one Next step before merge Security Review findings
Review detailsBest possible solution: Keep #74926's shipped artifact API as the base, then split cursor/type filtering into a focused Gateway/SDK follow-up with stable cursor tiebreakers and explicit provenance rules; handle Hyprland capture separately under the browser plugin surface. Do we have a high-confidence way to reproduce the issue? Yes. The PR cursor bug is source-reproducible with two artifacts sharing one Is this the best way to solve the issue? No. The PR overlaps the merged maintainer implementation and is not the best merge vehicle until it preserves current SDK signatures, keeps run/task queries fail-closed, fixes cursor tiebreaking, and separates or fully wires the Hyprland feature. Full review comments:
Overall correctness: patch is incorrect Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 9fff2b779159. |
… and provenance fix
Adds artifacts.list / .get / .download gateway RPCs and an oc.artifacts SDK
namespace. Cursor pagination encodes messageSeq as base64url; types[] filter
uses Set membership; limit defaults to 50 with a hard cap of 200.
Fixes the P2 provenance bug where artifacts.list({ runId }) silently returned
nothing: transcript writers only persist { id, seq } in __openclaw, never
runId/taskId, so the per-message filter was always dropping everything. Fix:
apply the filter only when the field is explicitly present on the message.
Also adds hyprland-capture.ts stub to resolve a pre-existing TS2307 error in
the browser extension, and regenerates Swift GatewayModels for both targets.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bc718ea to
07b489a
Compare
|
@vincentkoc this supersedes #74926 — resolves the P2 provenance blocker and adds cursor pagination with a reusable utility. Ready for review. |
|
#75208 supersedes this PR — resolves the P2 provenance blocker identified in the Codex review (artifacts.list({ runId }) silently returning empty on real transcript data), adds cursor pagination, type filter, and introduces src/gateway/util/cursor.ts as the canonical reusable pagination utility for Gateway list RPCs. All checks pass. |
|
@shakkernerd would you be able to review this? It resolves the P2 provenance blocker on the artifact RPC surface and #74926 currently has conflicts. |
Summary
artifacts.list,artifacts.get,artifacts.download) exposed via the gateway and the SDKoc.artifactsnamespace, with AJV validation and TypeBox schemasartifacts.list: base64url-encodedmessageSeqcursors viasrc/gateway/util/cursor.ts,typesarray filter, configurablelimit(default 50, hard-cap 200)collectArtifactsFromMessagespreviously dropped all artifacts underrunId/taskIdqueries because transcript writers only write{ id, seq }to__openclaw— neverrunId/taskId. Fix: apply per-message filter only when the field is explicitly present; session-level routing already scopes correctlyextensions/browser/src/browser/hyprland-capture.tsimplementingisHyprlandAvailableandcaptureWithHyprland(resolves pre-existingCannot find moduleTS error inagent.snapshot.ts)ProtocolSchemassoprotocol:gen:swiftproduces the corresponding Swift structs in bothGatewayModels.swifttargetsTest plan
pnpm test— 67/67 tests pass (artifacts + cursor + SDK suites)pnpm protocol:check— exits 0 (generated Swift matches working tree)pnpm exec oxfmt --check— all modified files correctly formattedOPENCLAW_TESTBOX=1 pnpm check:changed— exits 0artifacts.list({ runId })returns artifacts when transcript messages lack__openclaw.runId(P2 regression guard test)nextCursor, second page with that cursor returns remaining artifacts and no further cursor🤖 Generated with Claude Code