Skip to content

feat(gateway/sdk): artifact RPCs with cursor pagination, type filter, and provenance fix#75208

Closed
Angfr95 wants to merge 3 commits into
openclaw:mainfrom
Angfr95:feat/artifact-rpcs-cursor-pagination
Closed

feat(gateway/sdk): artifact RPCs with cursor pagination, type filter, and provenance fix#75208
Angfr95 wants to merge 3 commits into
openclaw:mainfrom
Angfr95:feat/artifact-rpcs-cursor-pagination

Conversation

@Angfr95

@Angfr95 Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • New artifact RPCs (artifacts.list, artifacts.get, artifacts.download) exposed via the gateway and the SDK oc.artifacts namespace, with AJV validation and TypeBox schemas
  • Cursor pagination and type filter for artifacts.list: base64url-encoded messageSeq cursors via src/gateway/util/cursor.ts, types array filter, configurable limit (default 50, hard-cap 200)
  • P2 provenance fix: collectArtifactsFromMessages previously dropped all artifacts under runId/taskId queries because transcript writers only write { id, seq } to __openclaw — never runId/taskId. Fix: apply per-message filter only when the field is explicitly present; session-level routing already scopes correctly
  • Hyprland capture stub: extensions/browser/src/browser/hyprland-capture.ts implementing isHyprlandAvailable and captureWithHyprland (resolves pre-existing Cannot find module TS error in agent.snapshot.ts)
  • Swift model generation: artifact schemas added to ProtocolSchemas so protocol:gen:swift produces the corresponding Swift structs in both GatewayModels.swift targets
  • Full test coverage: 42 artifact handler tests (including P2 regression guards), 9 cursor utility tests, 16 SDK namespace tests — all passing

Test 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 formatted
  • OPENCLAW_TESTBOX=1 pnpm check:changed — exits 0
  • Verify artifacts.list({ runId }) returns artifacts when transcript messages lack __openclaw.runId (P2 regression guard test)
  • Verify cursor pagination: first page returns nextCursor, second page with that cursor returns remaining artifacts and no further cursor

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime size: XL labels Apr 30, 2026
@clawsweeper

clawsweeper Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 24, 2026, 4:51 AM ET / 08:51 UTC.

Summary
The branch adds artifact Gateway/SDK RPC pagination and type filtering, docs/generated Swift/tests, and an opt-in Browser Hyprland screenshot path.

PR surface: Source +781, Tests +1093, Docs +41, Generated +3, Other +404. Total +2322 across 26 files.

Reproducibility: yes. at source level for the PR defects: the head code resumes artifact pages with messageSeq-only cursors, and the route checks a resolved Hyprland flag that the config resolver never returns. I did not run a live Gateway or Hyprland repro in this read-only review.

Review metrics: 3 noteworthy metrics.

  • Config surface: 1 added. The PR adds browser.hyprlandCapture, an operator-visible key that needs product and upgrade-safety acceptance.
  • Artifact list API fields: 3 params, 2 result fields added. cursor, limit, types, nextCursor, and total alter the public Gateway/SDK contract beyond the already-merged artifact RPC surface.
  • Native command dependencies: 2 spawned binaries. hyprctl and grim would run from the Gateway process, so unit tests do not settle security, timeout, or live compositor behavior.

Stored data model
Persistent data-model change detected: serialized state: extensions/browser/src/browser/hyprland-capture.ts, unknown-data-model-change: src/gateway/protocol/schema/artifacts.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Rebase onto current main and port artifact cursor/type fields into packages/gateway-protocol while preserving the current SDK call shape.
  • [P1] Replace the messageSeq-only cursor with a stable per-artifact cursor and add a regression covering multiple artifacts in one transcript message.
  • [P1] Remove Hyprland from this branch or leave it to the dedicated PR, then add redacted live proof for the artifact API path.

Proof guidance:

  • [P1] Needs real behavior proof before merge: No after-fix real behavior proof is present; the PR body/comments list tests but not redacted live Gateway RPC output, terminal output, logs, recording, or Hyprland proof for the current head. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The branch is currently dirty/conflicting and writes protocol changes to a tree that current main no longer has.
  • [P1] The artifact list contract adds public cursor, limit, types, nextCursor, and total behavior that needs compatibility and SDK-shape acceptance before merge.
  • [P1] The messageSeq-only cursor can drop artifacts when one transcript message contains more artifacts than the page limit.
  • [P1] The unrelated Hyprland path adds a Browser config surface and native compositor capture behavior already tracked on fix(browser): fall back to Hyprland grim capture for headed viewport screenshots #71940.
  • [P1] No redacted after-fix real behavior proof is present for either live Gateway artifact pagination/type filtering or the Hyprland path.

Maintainer options:

  1. Narrow and rebase artifact pagination (recommended)
    Port only the artifact cursor/type-filter work onto current main, preserve the existing SDK artifact API shape, and fix cursor stability before reconsidering merge.
  2. Keep Hyprland on the dedicated PR
    Drop the Browser Hyprland files from this branch and let fix(browser): fall back to Hyprland grim capture for headed viewport screenshots #71940 carry native screenshot safety, cleanup, config, and live-proof review.
  3. Pause if the API direction is not accepted
    If maintainers do not want artifact pagination/type filtering as a Gateway contract yet, pause or close this branch after linking the remaining API decision.

Next step before merge

  • [P1] Human review is needed because automation cannot supply contributor real behavior proof, resolve the dirty branch safely, split unrelated Hyprland work, or decide the public Gateway/SDK/config direction.

Security
Needs attention: The diff introduces an unrelated native compositor screenshot path that can run PATH-resolved binaries and capture pixels from the Gateway process without live safety proof.

Review findings

  • [P1] Use a per-artifact cursor key — src/gateway/server-methods/artifacts.ts:388-397
  • [P1] Preserve the current SDK artifact call shape — packages/sdk/src/client.ts:756-765
  • [P1] Resolve compositor tools through a trusted timed path — extensions/browser/src/browser/hyprland-capture.ts:9
Review details

Best possible solution:

Narrow this to maintainer-approved artifact pagination/type filtering on the current packages/gateway-protocol surface, preserve current SDK call shape, use a stable per-artifact cursor, and leave Hyprland capture to its dedicated PR.

Do we have a high-confidence way to reproduce the issue?

Yes at source level for the PR defects: the head code resumes artifact pages with messageSeq-only cursors, and the route checks a resolved Hyprland flag that the config resolver never returns. I did not run a live Gateway or Hyprland repro in this read-only review.

Is this the best way to solve the issue?

No, not as submitted. Artifact pagination/type filtering may be useful, but the current branch is too broad and stale; the safer path is a narrowed rebase on packages/gateway-protocol with a stable per-artifact cursor and Hyprland split out.

Full review comments:

  • [P1] Use a per-artifact cursor key — src/gateway/server-methods/artifacts.ts:388-397
    The cursor stores only messageSeq and the next page filters messageSeq > cursorSeq. If one transcript message contains multiple artifacts and the page cuts within that message, the remaining artifacts from that message are skipped; include a stable per-artifact tiebreaker such as content index or artifact id.
    Confidence: 0.9
  • [P1] Preserve the current SDK artifact call shape — packages/sdk/src/client.ts:756-765
    Current main already exposes scoped artifact helpers with required query scope and get/download(id, params). This stale branch makes list params optional and moves artifactId into the params object, so a rebase must preserve the shipped SDK contract or add an explicit compatibility path.
    Confidence: 0.84
  • [P1] Resolve compositor tools through a trusted timed path — extensions/browser/src/browser/hyprland-capture.ts:9
    This new Gateway path spawns hyprctl and grim by command name without a timeout. Native compositor capture should either be removed from this artifact PR or use the trusted resolver and timeout/cleanup pattern from the dedicated Hyprland work before merge.
    Confidence: 0.86
  • [P2] Wire the resolved Hyprland flag or drop the path — extensions/browser/src/browser/routes/agent.snapshot.ts:496-497
    The screenshot route checks ctx.state().resolved.hyprlandCapture, but resolveBrowserConfig never returns that property. Real browser.hyprlandCapture config will not enable the path; either wire it through with config tests or remove the unrelated Hyprland change from this branch.
    Confidence: 0.88
  • [P2] Port pagination onto the protocol package — src/gateway/protocol/schema/artifacts.ts:44-57
    The branch adds cursor/type fields under src/gateway/protocol, but current main's canonical protocol source is packages/gateway-protocol and src/gateway/protocol is gone. Rebase the contract onto the current package so generated clients and SDK types share one source.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a2725b6a24c8.

Label changes

Label justifications:

  • P2: This is a normal-priority Gateway/SDK feature PR with useful unique API work, but it is not an urgent live regression fix.
  • merge-risk: 🚨 compatibility: The diff changes public Gateway/SDK/protocol fields, changes artifact SDK call shape on a stale base, and adds operator config surface.
  • merge-risk: 🚨 security-boundary: The Hyprland path captures compositor pixels and runs native binaries from the Gateway process.
  • merge-risk: 🚨 availability: The native capture path lacks trusted timeout/liveness proof and can hang screenshot requests if hyprctl or grim stalls.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: No after-fix real behavior proof is present; the PR body/comments list tests but not redacted live Gateway RPC output, terminal output, logs, recording, or Hyprland proof for the current head. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +781, Tests +1093, Docs +41, Generated +3, Other +404. Total +2322 across 26 files.

View PR surface stats
Area Files Added Removed Net
Source 18 815 34 +781
Tests 4 1103 10 +1093
Docs 1 63 22 +41
Config 0 0 0 0
Generated 1 3 0 +3
Other 2 404 0 +404
Total 26 2388 66 +2322

Security concerns:

  • [medium] Native screenshot binaries run from PATH — extensions/browser/src/browser/hyprland-capture.ts:9
    hyprctl and grim are spawned by command name in the Gateway process, with no trusted binary resolution or timeout in this branch. That is a concrete supply-chain and availability concern for a native screenshot path.
    Confidence: 0.86
  • [medium] Compositor capture can expose unintended pixels — extensions/browser/src/browser/hyprland-capture.ts:43
    The grim path captures a screen rectangle for the browser window; if another client overlaps that rectangle or the compositor state changes, the returned screenshot can include unintended window contents unless the dedicated Hyprland PR's isolation and proof requirements are met.
    Confidence: 0.74

What I checked:

  • Repository policy applied: The full root AGENTS.md and scoped Gateway, Gateway server-methods, extensions, and docs guides were read; their protocol, config, native-runtime, and proof requirements apply to this PR. (AGENTS.md:31, a2725b6a24c8)
  • Live PR state: GitHub reports this PR as open, external-contributor authored, head 07b489a, and mergeStateStatus DIRTY/CONFLICTING with existing needs-proof and merge-risk labels. (07b489ad0765)
  • Current main artifact baseline: Current main already has artifacts.list/get/download wired through the canonical protocol package and gateway handlers, but ArtifactsListParamsSchema is only the query object and ArtifactsListResultSchema only returns artifacts, so cursor/type filtering remains unique work. (packages/gateway-protocol/src/schema/artifacts.ts:55, a2725b6a24c8)
  • Cursor correctness blocker: The PR head decodes a cursor to messageSeq, filters with messageSeq greater than that cursor, and encodes only the last page item's messageSeq, which skips later artifacts from the same transcript message when a page cuts within that message. (src/gateway/server-methods/artifacts.ts:388, 07b489ad0765)
  • Stale protocol tree: The PR adds pagination fields under src/gateway/protocol, while current main no longer has that tree and uses packages/gateway-protocol/src as the canonical protocol source. (src/gateway/protocol/schema/artifacts.ts:44, 07b489ad0765)
  • Hyprland config not resolved: The PR route checks ctx.state().resolved.hyprlandCapture, but resolveBrowserConfig returns no hyprlandCapture property, so real config cannot enable the path as submitted. (extensions/browser/src/browser/config.ts:431, 07b489ad0765)

Likely related people:

  • BunsDev: Authored the merged artifact hardening PR that current main uses for the base artifact RPC/provenance surface. (role: artifact RPC hardening contributor; confidence: high; commits: a102f4dede6a, f6cef3504bfc, 6f08365f8746; files: src/gateway/server-methods/artifacts.ts, packages/sdk/src/client.ts, src/tasks/task-status-access.ts)
  • tmimmanuel: Authored the initial commits in the merged artifact RPC stack that added the gateway/protocol/test surface later hardened on main. (role: artifact RPC feature introducer; confidence: high; commits: 5cf62c0bea65, ba19dc906360; files: src/gateway/server-methods/artifacts.ts, src/gateway/protocol/schema/artifacts.ts, src/gateway/server-methods/artifacts.test.ts)
  • vincentkoc: Recent PR and blame context show work on artifact task lookup routing plus adjacent browser/protocol runtime paths relevant to this review. (role: recent Gateway and Browser area contributor; confidence: medium; commits: ef3d9c140374, c645ec4555c0, c638f2beda87; files: src/gateway/server-methods/artifacts.ts, src/tasks/task-status-access.ts, extensions/browser/src/browser/routes/agent.snapshot.ts)
  • steipete: Current main blame/history points to recent Browser route/config maintenance and protocol-package migration work that makes this PR's old protocol tree stale. (role: recent Browser and protocol package contributor; confidence: medium; commits: d9298a74be69, ac52499aca0e, 286883cc5484; files: extensions/browser/src/browser/config.ts, extensions/browser/src/browser/routes/agent.snapshot.ts, packages/gateway-protocol/src/schema/artifacts.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Angfr95 and others added 3 commits April 30, 2026 20:51
… 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 <[email protected]>
@Angfr95

Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

@vincentkoc this supersedes #74926 — resolves the P2 provenance blocker and adds cursor pagination with a reusable utility. Ready for review.

@Angfr95

Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

#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.

@Angfr95

Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

@shakkernerd would you be able to review this? It resolves the P2 provenance blocker on the artifact RPC surface and #74926 currently has conflicts.

@Angfr95

Angfr95 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

@steipete would you be able to review this? It resolves the P2 provenance blocker on the artifact RPC surface and #74926 currently has conflicts. All checks pass.

@barnacle-openclaw

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@barnacle-openclaw barnacle-openclaw Bot added the stale Marked as stale due to inactivity label May 30, 2026
@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label May 30, 2026
@openclaw-barnacle openclaw-barnacle Bot added triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. and removed stale Marked as stale due to inactivity labels May 31, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels May 31, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 15, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jun 20, 2026
@openclaw-barnacle openclaw-barnacle Bot added triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. and removed stale Marked as stale due to inactivity labels Jun 20, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 9, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for the substantial work here. I’m closing this as stale and no longer safely landable, not as a duplicate. The branch has had no source update since April 30, conflicts with current main, targets the removed src/gateway/protocol tree, and has no live Gateway or Hyprland proof. The current implementation also has correctness blockers: its messageSeq-only cursor can skip additional artifacts from the same message, while accepting messages without matching run/task provenance can over-return artifacts from other runs in the resolved session. The unrelated Hyprland path is unwired and launches PATH-resolved binaries without a timeout. The base artifact RPC surface landed separately in #74926, but pagination/type filtering remains unique work; a future contribution should be a focused current-main PR against packages/gateway-protocol with a stable per-artifact cursor and real RPC proof. Thank you.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos app: web-ui App: web-ui docs Improvements or additions to documentation gateway Gateway runtime merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants