feat: Replace async logic with waitSecs parameter for call-actor#825
Merged
Conversation
This was referenced May 11, 2026
…tion and streamline response handling
…d key-value stores
…OutputSchemaWithItems for clarity
Apply the same content[]=[json, narrative] pattern to call-actor's canonical-shape sites that landed on #823 for get-actor-run: - src/tools/core/actor_run_response.ts:buildStartRunResponse - src/tools/default/call_actor.ts (terminal-after-wait return) structuredContent itself is unchanged. The narrative (summary + nextStep) moves from content[0] to content[1]; content[0] now carries JSON.stringify(structuredContent) per the spec backwards-compat recommendation. Closes the call-actor side of the conformance gap tracked by #709/#744. Direct actor tools still pending (Phase 2 of #744). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3a6a252 to
712b145
Compare
21f8e81 to
301eff5
Compare
Resolves conflicts after #823 (waitSecs on get-actor-run), #820 (extra callOptions fields), and #842 (unused-export cleanup) landed on master: - callOptionsSchema centralized in call_actor_common.ts; build, maxItems, maxTotalChargeUsd added (kept from #820). Both call-actor and call-actor-widget reuse the shared schema. - waitForRunWithProgress: combine the parallel actorNamePromise (#823) with the caller-supplied actorName short-circuit (this PR), so call-actor skips the lookup it already knows the answer to. - KV_KEYS_LIMIT export dropped (#842); v4 plural comment kept. - previewOutput description flipped to "Deprecated: ignored" per v4 spec (preview is agent-driven via get-dataset-items). - Tests: kept memory-quota recovery + callOptions parsing tests from master alongside the public-search-helper test from this branch. Dropped obsolete isAsync arg (v4 removed the field). - get-actor-run.response test: two leftover singular storages.dataset accesses migrated to storages.datasets.default.
…locking during tests
… task mode behavior
…te comments for clarity
…ate nextStep guidance
…Step hint in apps mode
… and enhance description building
Collaborator
Author
E2E test report (mcpc @
|
MQ37
approved these changes
May 18, 2026
| `); | ||
| } else { | ||
| sections.push(dedent` | ||
| const WIDGET_ADDENDUM = dedent` |
Contributor
There was a problem hiding this comment.
nit: never in my life I saw word "addendum" in a code, but let's keep it 😄
4 tasks
Follow-up from #825 Direct Actor tools now share the same contract as `call-actor` and `get-actor-run`. Finally one uniform experience, this is what I was looking forward to when writing #825 :) Much smaller PR than #825 this time, just the migration and merging two executors into one. It actually removes some code, which is good. About the `itemsSchema` gotcha called out in #852 — LLMs may read \`itemsSchema.properties\` as "these fields are in \`structuredContent\`", which they are not. Rows live in the dataset and you fetch them with \`get-dataset-items\`. The \`itemsSchema.description\` says this explicitly, so it should be fine. I tested it, it works but I did not tested thoroughly, there might be some rough edges. ## Summary - **Direct Actor tools now return the canonical \`RunResponse\` shape** — same as \`call-actor\` and \`get-actor-run\`: \`runId\`, \`status\`, \`storages\`, \`summary\`, \`nextStep\`. No more inlined items; the LLM follows \`nextStep\` to \`get-dataset-items\`. - **Same \`waitSecs\` contract as \`call-actor\`** — same MCP-only opt-in: default 30 s, max 45 s. Task mode overrides \`waitSecs\` and waits until terminal. If the Actor's own input schema happens to declare \`waitSecs\`, ours wins so there's no collision. - **Per-tool \`itemsSchema\` in the dataset metadata** — for direct Actor tools the target Actor is known at \`tools/list\` time, so the historical-inferred row schema lands both in the tool's \`outputSchema\` and in the runtime response under \`storages.datasets.default.itemsSchema\`. LLMs can plan a \`fields\` projection before the first call. - **One mode-agnostic executor** — separate default-mode and apps-mode executors are gone, replaced by a single one. Direct Actor tools never render widgets (\`widget: false\`), so the apps-mode executor was not doing anything different anymore. Closes #852. Phase 2 of #587. --------- Co-authored-by: Jakub Kopecký <themq37@gmail.com>
MQ37
added a commit
that referenced
this pull request
May 18, 2026
`get-actor-run` returns the canonical run shape (status, storages, stats, summary, nextStep) across all 8 Apify states. Text content carries `summary \n nextStep`; structuredContent has the full shape — no inlined items or record bodies. Adds `waitSecs` (0–45, default 30) and emits `notifications/progress` during the wait when `_meta.progressToken` is supplied. `get-actor-run-widget` uses `waitSecs=0` so initial render is non-blocking; widget self-polls. `SUCCEEDED` with `itemCount=0` runs a one-item probe with one retry to absorb Apify's ~5s pagination-counter lag — no false "no output" on a run that did write items. KV shows up in `summary` only; never recommended as `nextStep`, since it rarely carries real output (mostly SDK state). Follow-up PR #825 replaces `call-actor`'s `async` flag with the same `waitSecs` and reshapes `storages` to a plural alias-map. Stacks on this branch and lands together. **Follow-up #847** — consolidate duplicated MCP server test fixtures across three test files (surfaced during review); left out per "one thing per change". ## Why this PR is bulky Splitting the pieces below would leave master in a broken half-state: - New shared module `src/tools/core/actor_run_response.ts` centralizes the canonical shape, 8 status templates, wait+progress loop, lag-fallback probe, and abort race. #825 (`call-actor` v4) reuses every helper. - Test coverage for the new contract — shape, 8 templates, wait/progress, abort, lag-fallback. - Widget UI in `src/web/src/pages/ActorRun/ActorRun.tsx` switched to a `get-dataset-items` preview fetch with its own polling cadence — v4 dropped inlined items, so the UI is broken until the server stops inlining. - Spec, structured-output schema, tool-loader auto-inject, and widget dev stub round out the v4 contract across modes. Closes #822 --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Jakub Kopecký <themq37@gmail.com>
RobertCrupa
pushed a commit
that referenced
this pull request
May 19, 2026
`get-actor-run` returns the canonical run shape (status, storages, stats, summary, nextStep) across all 8 Apify states. Text content carries `summary \n nextStep`; structuredContent has the full shape — no inlined items or record bodies. Adds `waitSecs` (0–45, default 30) and emits `notifications/progress` during the wait when `_meta.progressToken` is supplied. `get-actor-run-widget` uses `waitSecs=0` so initial render is non-blocking; widget self-polls. `SUCCEEDED` with `itemCount=0` runs a one-item probe with one retry to absorb Apify's ~5s pagination-counter lag — no false "no output" on a run that did write items. KV shows up in `summary` only; never recommended as `nextStep`, since it rarely carries real output (mostly SDK state). Follow-up PR #825 replaces `call-actor`'s `async` flag with the same `waitSecs` and reshapes `storages` to a plural alias-map. Stacks on this branch and lands together. **Follow-up #847** — consolidate duplicated MCP server test fixtures across three test files (surfaced during review); left out per "one thing per change". ## Why this PR is bulky Splitting the pieces below would leave master in a broken half-state: - New shared module `src/tools/core/actor_run_response.ts` centralizes the canonical shape, 8 status templates, wait+progress loop, lag-fallback probe, and abort race. #825 (`call-actor` v4) reuses every helper. - Test coverage for the new contract — shape, 8 templates, wait/progress, abort, lag-fallback. - Widget UI in `src/web/src/pages/ActorRun/ActorRun.tsx` switched to a `get-dataset-items` preview fetch with its own polling cadence — v4 dropped inlined items, so the UI is broken until the server stops inlining. - Spec, structured-output schema, tool-loader auto-inject, and widget dev stub round out the v4 contract across modes. Closes #822 --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Jakub Kopecký <themq37@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I'm really sorry :(. This again a heavier PR than desired but I had to touch so many different things that the split would be really painful to test.
While testing, I was so happy with the experience that I think we should push direct Actor tools in this mode too.
This is a follow up issue: #852 (there is an issue with outputSchema, see the issue for details)
Summary
Replace
asyncparam withwaitSecs—call-actorno longer has anasync: true/falseflag. Callers control blocking viawaitSecs(0 = fire-and-forget, >0 = wait up to N seconds, default 30).get-actor-runsimilarly acceptswaitSecsfor polling.Reshape
storagesto plural alias-map —RunResponse.storagesnow mirrors the Apify client'sActorRunStorageIdsstructure:{ datasets: { default: {...} }, keyValueStores: { default: {...} } }instead of the flat{ dataset, keyValueStore }shape. The plural alias-map means named Actor storages (e.g.storages.datasets.results) can be added without introducing new field names, keeping the schema stable as the platform evolves.Rename
callActorOutputSchema→directActorOutputSchema(andbuildEnrichedCallActorOutputSchema→buildDirectActorOutputSchemaWithItems). This schema was previously declared on bothcall-actorand direct actor tools, but with v4call-actormoved togetActorRunOutputSchema(the canonicalRunResponseshape). The schema is now used only by dynamically-registered direct actor tools (e.g.apify--rag-web-browser) that wrap a single actor and return inline dataset items viabuildActorResponseContent. Renamed for accuracy; stale fields (actorName,status,startedAt,input) that were never populated by the runtime were dropped.Closes #824