Skip to content

feat: Split get-actor-run into data + -widget tools#734

Merged
jirispilka merged 8 commits intomasterfrom
claude/implement-get-actor-run-MUTXI
Apr 29, 2026
Merged

feat: Split get-actor-run into data + -widget tools#734
jirispilka merged 8 commits intomasterfrom
claude/implement-get-actor-run-MUTXI

Conversation

@jirispilka
Copy link
Copy Markdown
Collaborator

@jirispilka jirispilka commented Apr 20, 2026

PR chain — part of #577

Step 6 of 6 in the #577 umbrella rollout.
Stacked on #724 (branch claude/call-actor-split-I2C7T); rebase to master once #720#724 merge.

# Issue PR Status
1 #714 — Rename openaiapps #720 in review
2 #715 — Capability auto-detect + gating #721 in review
3 #716fetch-actor-details split (pilot) #722 in review
4 #717search-actors split #723 in review
5 #718call-actor split #724 in review
6 #719get-actor-run split this PR in review

Closes #719. Completes the umbrella.


Summary

Final application of the decoupled pattern validated in #722 / #723 / #724.

  • get-actor-run is now mode-independent and data-only. No tool-level widget _meta in
    either mode; the runs category entry is a plain ToolEntry instead of a mode map.
  • New get-actor-run-widget (apps-only) renders the live progress widget. Input is
    strict: { runId } only. Tool- and response-level widget _meta with
    ui.resourceUri = ui://widget/actor-run.html, visibility = ['model','app'], non-empty
    csp. Reuses the shared buildGetActorRunSuccessResponse({ widget: true }) helper.
  • buildGetActorRunSuccessResponse widget branch now also sets openai/widgetDescription
    on response _meta, matching the other three widget tools.
  • Server instructions: added the fourth disambiguation bullet pairing get-actor-run
    (silent data lookup) with get-actor-run-widget (live progress widget), using the same
    vocabulary as the three preceding splits. WORKFLOW_RULES untouched — the "NEVER poll
    get-actor-run after call-actor-widget" rule is orthogonal to this split and still
    valid under today's auto-polling call-actor-widget.
  • Deleted src/tools/apps/get_actor_run.ts — widget rendering now lives in the sibling
    tool rather than a mode toggle on a shared handler.

No -internal equivalent existed for get-actor-run, so no deletion on that side.

Tests

  • npm run type-check — passes
  • npm run lint — passes
  • npm run test:unit — 615 passed
  • npm run build — passes

Test plan

  • npm run type-check
  • npm run lint
  • npm run test:unit
  • npm run build
  • mcpc probe matrix — default vs apps, base schema byte-compare
  • Integration tests (npm run test:integration) — human-run per CLAUDE.md
  • MCPJam widget parity — manual
  • Live tools/call with a real APIFY_TOKEN and runId — manual

apify-mcp-server-internal impact

Purely additive surface on the widget side. Base get-actor-run keeps the same name and
byte-identical input/output schemas across modes, so the hosted server should continue
working with no edits. The only potentially-breaking rename is the shared
buildGetActorRunSuccessResponse now emits openai/widgetDescription on the response —
harmless for consumers that ignore extra _meta keys. Please confirm on the internal
side.

https://claude.ai/code/session_01SF9P6g91UrVMahn4bLsUNf

@jirispilka jirispilka force-pushed the claude/call-actor-split-I2C7T branch from 57df5bc to 8b19378 Compare April 20, 2026 21:36
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from f837504 to 4e18bed Compare April 20, 2026 21:36
@jirispilka jirispilka force-pushed the claude/call-actor-split-I2C7T branch from 8b19378 to 66c1cae Compare April 22, 2026 15:39
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from 4e18bed to e98eb0c Compare April 22, 2026 15:40
@jirispilka jirispilka force-pushed the claude/call-actor-split-I2C7T branch from 66c1cae to 153dc48 Compare April 24, 2026 14:42
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from e98eb0c to 2fb2e87 Compare April 24, 2026 14:51
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from 2fb2e87 to 293b758 Compare April 24, 2026 21:49
@jirispilka jirispilka force-pushed the claude/call-actor-split-I2C7T branch from 5422636 to 48ac831 Compare April 27, 2026 11:35
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from 7ad1d42 to 2d70f8c Compare April 27, 2026 11:41
@jirispilka jirispilka requested a review from Copilot April 27, 2026 19:47
@jirispilka jirispilka force-pushed the claude/call-actor-split-I2C7T branch from 48ac831 to f1764e6 Compare April 27, 2026 19:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the decoupled “data tool + -widget tool” rollout for Actor run status retrieval by making get-actor-run mode-independent and adding an apps-only get-actor-run-widget tool for rendering the live progress UI.

Changes:

  • Makes get-actor-run a single shared, data-only tool across default/apps modes and removes widget metadata from the base tool.
  • Adds get-actor-run-widget (apps-only) to render the Actor run progress widget with widget _meta on tool + response.
  • Updates server instructions and unit tests to reflect the split and new disambiguation rules.

Reviewed changes

Copilot reviewed 52 out of 53 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/tools/core/get_actor_run_common.ts Converts base get-actor-run metadata to data-only and adds widget response _meta enhancements.
src/tools/apps/get_actor_run_widget.ts Introduces the new apps-only widget tool for Actor run progress.
src/tools/apps/get_actor_run.ts Removes the former apps-mode variant (widget behavior moved to the new tool).
src/tools/categories.ts Registers get-actor-run as mode-independent and adds get-actor-run-widget under the ui category (apps-only).
src/utils/server-instructions/index.ts Updates widget workflow rules and adds the get-actor-run vs get-actor-run-widget disambiguation bullet.
src/const.ts Adds HelperTools.ACTOR_RUNS_GET_WIDGET.
tests/unit/tools.get_actor_run.widget.response.test.ts Adds unit coverage for widget tool response/tool _meta and schema behavior.
tests/unit/tools.mode_contract.test.ts Updates mode contract assertions to include the new widget tool and base tool category mapping.
tests/unit/tools.categories.test.ts Updates expectation that get-actor-run is the same tool instance across modes.
tests/integration/suite.ts Renames the get-actor-run integration test title to reflect the data-only base tool.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/tools/core/get_actor_run_common.ts
Comment thread src/tools/core/get_actor_run_common.ts Outdated
Comment thread src/tools/apps/get_actor_run_widget.ts
Comment thread src/utils/server-instructions/index.ts
Comment thread src/tools/apps/get_actor_run_widget.ts Outdated
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from 58758b1 to fdc5b62 Compare April 27, 2026 19:53
@jirispilka jirispilka marked this pull request as ready for review April 27, 2026 20:03
@jirispilka jirispilka requested a review from MQ37 April 27, 2026 20:03
Copy link
Copy Markdown
Contributor

@MQ37 MQ37 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Blocker — paymentRequired: true regression breaks agentic-payment run reads

getActorRunMetadata lost paymentRequired: true (src/tools/core/get_actor_run_common.ts), and the new getActorRunWidgetTool doesn't set it either. Both get-actor-run and get-actor-run-widget are now unpaid.

Verified with mcpc against ?payment=x402: master advertises _meta.x402 + x402 description hint, this branch doesn't.

Why this matters: in agentic-payment mode, the paymentRequired flag is what engages the Skyfire/x402 plumbing the MCP server needs to read run data. Without it, run-status calls (and the widget's auto-polling) won't work for agentic-payment users.

Fix: restore paymentRequired: true on getActorRunMetadata (re-inherits into defaultGetActorRun) and add it to getActorRunWidgetTool. Sibling PR #724 kept it on both halves of the call-actor split — same posture expected here. Worth adding a unit assertion to lock this in. Tracked in #766 (automated agentic-payment integration tests).

@MQ37
Copy link
Copy Markdown
Contributor

MQ37 commented Apr 28, 2026

@jirispilka also these integration tests are failing:

 FAIL  tests/integration/actor.server_sse.test.ts > Apify MCP Server SSE > auto mode: client advertising UI capability receives apps-mode tools with widget metadata
 FAIL  tests/integration/actor.server_streamable.test.ts > Apify MCP Server Streamable HTTP > auto mode: client advertising UI capability receives apps-mode tools with widget metadata
 FAIL  tests/integration/stdio.test.ts > MCP stdio > auto mode: client advertising UI capability receives apps-mode tools with widget metadata
AssertionError: expected undefined to be defined
 ❯ expectWidgetToolMeta tests/integration/suite.ts:149:22
    147|     for (const toolName of toolNames) {
    148|         const tool = tools.tools.find((t) => t.name === toolName);
    149|         expect(tool).toBeDefined();
       |                      ^
    150|         expect(tool?._meta).toBeDefined();
    151|         // MCP Apps standard keys (SEP-1865)
 ❯ tests/integration/suite.ts:2549:13

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/5]⎯

 FAIL  tests/integration/actor.server_streamable.test.ts > Apify MCP Server Streamable HTTP > should inject skyfire-pay-id parameter into all SKYFIRE_ENABLED_TOOLS when skyfireMode is enabled
AssertionError: Tool "get-actor-run" should have skyfire-pay-id property in inputSchema: expected undefined to be defined
 ❯ tests/integration/suite.ts:2600:131
    2598|
    2599|                     // skyfire-pay-id property should exist
    2600|                     expect(properties['skyfire-pay-id'], `Tool "${toolName}" should have skyfire-pay-id property in inputSchema`).toBeDefined();
       |                                                                                                                                   ^
    2601|
    2602|                     // Verify skyfire-pay-id has the correct structure

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/5]⎯

 FAIL  tests/integration/actor.server_streamable.test.ts > Apify MCP Server Streamable HTTP > should return required structuredContent fields for get-actor-run
AssertionError: expected undefined to be defined
 ❯ tests/integration/suite.ts:2681:74
    2679|                 expect(runContent.structuredContent?.dataset).toBeDefined();
    2680|                 expect(runContent.structuredContent?.dataset?.datasetId).toBeDefined();
    2681|                 expect(runContent.structuredContent?.dataset?.itemCount).toBeDefined();
       |                                                                          ^
    2682|             }
    2683|         });

@MQ37
Copy link
Copy Markdown
Contributor

MQ37 commented Apr 28, 2026

Opened #768 (stacked on this branch) with a small integration test asserting _meta.x402 is advertised on paymentRequired tools and absent on free ones. It will go green once paymentRequired: true is restored on get-actor-run / get-actor-run-widget. Broader agentic-payment integration coverage tracked in #766.

@jirispilka jirispilka requested a review from MQ37 April 28, 2026 12:22
@jirispilka
Copy link
Copy Markdown
Collaborator Author

@MQ37 the tests are passing now.

Base automatically changed from claude/call-actor-split-I2C7T to master April 29, 2026 07:51
claude and others added 8 commits April 29, 2026 10:28
Final step (6 of 6) of the #577 umbrella rollout. Mirrors the
decoupled-pattern recipe from #722 (fetch-actor-details), #723
(search-actors), and #724 (call-actor):

- get-actor-run is now mode-independent and data-only. No tool-level
  widget _meta in either mode; runs category entry is a plain ToolEntry
  instead of a mode map.
- New get-actor-run-widget (apps-only) renders the live progress widget.
  Input is strict: { runId } only. Tool- and response-level widget _meta
  (ui.resourceUri = ui://widget/actor-run.html). Reuses the shared
  buildGetActorRunSuccessResponse({ widget: true }) helper.
- buildGetActorRunSuccessResponse widget branch now also sets
  openai/widgetDescription on the response _meta, matching the other
  three widget tools.
- Apps server instructions: added the fourth disambiguation bullet
  pairing get-actor-run (silent data lookup) with get-actor-run-widget
  (live progress widget), using the same vocabulary as the existing
  three splits. WORKFLOW_RULES untouched — the "NEVER poll
  get-actor-run after call-actor-widget" rule is orthogonal.
- Deleted src/tools/apps/get_actor_run.ts; widget rendering now lives
  in the sibling tool rather than a mode toggle.

https://claude.ai/code/session_01SF9P6g91UrVMahn4bLsUNf
- Drop stale rolling-rollout note from server-instructions header (split is now complete)
- Extend "no polling after widget" rule to also cover get-actor-run-widget
- Rename integration test to drop misleading "widget" label (it exercises the data tool)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…768)

Asserts that tools with paymentRequired: true advertise _meta.x402 with
the expected fields (scheme, network, asset, payTo, amount) when the
server runs in x402 payment mode, and that free tools do not.

Pins the expected paid set with a hardcoded list so silent drift (e.g.
a tool losing paymentRequired) is caught here. Tracks #766.
@jirispilka jirispilka force-pushed the claude/implement-get-actor-run-MUTXI branch from f84b1b3 to 378fb32 Compare April 29, 2026 08:31
@github-actions github-actions Bot added t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics. labels Apr 29, 2026
@jirispilka jirispilka merged commit 8dd6d32 into master Apr 29, 2026
12 checks passed
@jirispilka jirispilka deleted the claude/implement-get-actor-run-MUTXI branch April 29, 2026 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Split get-actor-run into data + -widget tools

5 participants