Add Think workflow prompt integration#1598
Merged
Merged
Conversation
Introduce @cloudflare/think/workflows with ThinkAgentWorkflow and step.prompt() so Workflows can run a durable Think reasoning turn, wait for completion through Workflow events, and resume with validated structured output. The API infers submission idempotency from workflow identity, step name, and an optional string key to keep repeated workflow execution retry-safe without exposing low-level keys. Wire Think submissions to Workflows through a private durable notification outbox that records terminal submission events, retries sendWorkflowEvent(), and marks delivered rows while clearing payloads. This avoids long-lived RPCs between Workflow steps and Agents while still letting the Workflow own the final durable result. Add a server-side think-workflows example, docs for starting workflows from an Agent with runWorkflow(), and focused tests for the step extension hook plus workflow notification recovery, delivery, and retry behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 200fde5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
Shorten the public workflow API names from ThinkAgentWorkflow and ThinkAgentWorkflowStep to ThinkWorkflow and ThinkWorkflowStep so the new @cloudflare/think/workflows surface reads more naturally in user code and docs. Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the AI SDK streamText output promise when a turn is configured for structured output, and pass workflow prompt metadata through the same shape that step.prompt stores on submissions. This lets workflow submissions install the JSON schema on streamText and include the parsed structured output in the terminal workflow notification. Add a regression test that runs a workflow-tagged durable submission with a JSON schema and verifies the delivered workflow event contains the captured output. Co-authored-by: Cursor <cursoragent@cursor.com>
Stop deriving workflow structured-output configuration from the public turn body. Durable workflow submissions now pass the parsed workflow prompt context through an internal inference-loop option, leaving client and app body data available to hooks without allowing workflow-shaped body fields to alter output mode. Add a regression test proving workflow-shaped client body data on a normal submission does not configure structured output or emit workflow events. Co-authored-by: Cursor <cursoragent@cursor.com>
Make the submission cancellation attempt after a prompt wait timeout best-effort so a transient Agent RPC failure cannot mask the documented ThinkPromptTimeoutError outcome from step.prompt(). Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the extra outbox-level this.retry() wrapper around sendWorkflowEvent(). The Agent workflow helper already retries transient sendEvent failures, and the durable notification outbox plus alarm backoff provides the long-horizon retry loop without multiplying immediate delivery attempts. Co-authored-by: Cursor <cursoragent@cursor.com>
Move Think workflow prompt control data under a private metadata envelope so public submitMessages metadata that happens to use workflow-shaped keys cannot enable structured output or enqueue workflow notifications. Add regression coverage for public workflow/workflowPrompt metadata remaining ordinary caller metadata. Co-authored-by: Cursor <cursoragent@cursor.com>
Merged
threepointone
added a commit
that referenced
this pull request
May 28, 2026
* Add Think workflow prompt integration Introduce @cloudflare/think/workflows with ThinkAgentWorkflow and step.prompt() so Workflows can run a durable Think reasoning turn, wait for completion through Workflow events, and resume with validated structured output. The API infers submission idempotency from workflow identity, step name, and an optional string key to keep repeated workflow execution retry-safe without exposing low-level keys. Wire Think submissions to Workflows through a private durable notification outbox that records terminal submission events, retries sendWorkflowEvent(), and marks delivered rows while clearing payloads. This avoids long-lived RPCs between Workflow steps and Agents while still letting the Workflow own the final durable result. Add a server-side think-workflows example, docs for starting workflows from an Agent with runWorkflow(), and focused tests for the step extension hook plus workflow notification recovery, delivery, and retry behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * Rename Think workflow exports Shorten the public workflow API names from ThinkAgentWorkflow and ThinkAgentWorkflowStep to ThinkWorkflow and ThinkWorkflowStep so the new @cloudflare/think/workflows surface reads more naturally in user code and docs. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix Think workflow structured output capture Preserve the AI SDK streamText output promise when a turn is configured for structured output, and pass workflow prompt metadata through the same shape that step.prompt stores on submissions. This lets workflow submissions install the JSON schema on streamText and include the parsed structured output in the terminal workflow notification. Add a regression test that runs a workflow-tagged durable submission with a JSON schema and verifies the delivered workflow event contains the captured output. Co-authored-by: Cursor <cursoragent@cursor.com> * Keep workflow prompt config internal Stop deriving workflow structured-output configuration from the public turn body. Durable workflow submissions now pass the parsed workflow prompt context through an internal inference-loop option, leaving client and app body data available to hooks without allowing workflow-shaped body fields to alter output mode. Add a regression test proving workflow-shaped client body data on a normal submission does not configure structured output or emit workflow events. Co-authored-by: Cursor <cursoragent@cursor.com> * Preserve Think workflow timeout errors Make the submission cancellation attempt after a prompt wait timeout best-effort so a transient Agent RPC failure cannot mask the documented ThinkPromptTimeoutError outcome from step.prompt(). Co-authored-by: Cursor <cursoragent@cursor.com> * Simplify workflow notification delivery retries Remove the extra outbox-level this.retry() wrapper around sendWorkflowEvent(). The Agent workflow helper already retries transient sendEvent failures, and the durable notification outbox plus alarm backoff provides the long-horizon retry loop without multiplying immediate delivery attempts. Co-authored-by: Cursor <cursoragent@cursor.com> * Reserve workflow prompt metadata Move Think workflow prompt control data under a private metadata envelope so public submitMessages metadata that happens to use workflow-shaped keys cannot enable structured output or enqueue workflow notifications. Add regression coverage for public workflow/workflowPrompt metadata remaining ordinary caller metadata. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
threepointone
added a commit
that referenced
this pull request
May 28, 2026
* Add Think workflow prompt integration Introduce @cloudflare/think/workflows with ThinkAgentWorkflow and step.prompt() so Workflows can run a durable Think reasoning turn, wait for completion through Workflow events, and resume with validated structured output. The API infers submission idempotency from workflow identity, step name, and an optional string key to keep repeated workflow execution retry-safe without exposing low-level keys. Wire Think submissions to Workflows through a private durable notification outbox that records terminal submission events, retries sendWorkflowEvent(), and marks delivered rows while clearing payloads. This avoids long-lived RPCs between Workflow steps and Agents while still letting the Workflow own the final durable result. Add a server-side think-workflows example, docs for starting workflows from an Agent with runWorkflow(), and focused tests for the step extension hook plus workflow notification recovery, delivery, and retry behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * Rename Think workflow exports Shorten the public workflow API names from ThinkAgentWorkflow and ThinkAgentWorkflowStep to ThinkWorkflow and ThinkWorkflowStep so the new @cloudflare/think/workflows surface reads more naturally in user code and docs. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix Think workflow structured output capture Preserve the AI SDK streamText output promise when a turn is configured for structured output, and pass workflow prompt metadata through the same shape that step.prompt stores on submissions. This lets workflow submissions install the JSON schema on streamText and include the parsed structured output in the terminal workflow notification. Add a regression test that runs a workflow-tagged durable submission with a JSON schema and verifies the delivered workflow event contains the captured output. Co-authored-by: Cursor <cursoragent@cursor.com> * Keep workflow prompt config internal Stop deriving workflow structured-output configuration from the public turn body. Durable workflow submissions now pass the parsed workflow prompt context through an internal inference-loop option, leaving client and app body data available to hooks without allowing workflow-shaped body fields to alter output mode. Add a regression test proving workflow-shaped client body data on a normal submission does not configure structured output or emit workflow events. Co-authored-by: Cursor <cursoragent@cursor.com> * Preserve Think workflow timeout errors Make the submission cancellation attempt after a prompt wait timeout best-effort so a transient Agent RPC failure cannot mask the documented ThinkPromptTimeoutError outcome from step.prompt(). Co-authored-by: Cursor <cursoragent@cursor.com> * Simplify workflow notification delivery retries Remove the extra outbox-level this.retry() wrapper around sendWorkflowEvent(). The Agent workflow helper already retries transient sendEvent failures, and the durable notification outbox plus alarm backoff provides the long-horizon retry loop without multiplying immediate delivery attempts. Co-authored-by: Cursor <cursoragent@cursor.com> * Reserve workflow prompt metadata Move Think workflow prompt control data under a private metadata envelope so public submitMessages metadata that happens to use workflow-shaped keys cannot enable structured output or enqueue workflow notifications. Add regression coverage for public workflow/workflowPrompt metadata remaining ordinary caller metadata. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.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.
Summary
This adds a first-class Think integration for Cloudflare Workflows via
@cloudflare/think/workflows.The main new API is
ThinkWorkflowplusstep.prompt(), which lets a Workflow run a single durable Think reasoning turn and resume with typed structured output:The call reads like a blocking Workflow step, but it is implemented as an event-driven submit-and-resume flow so it does not hold a long-lived Durable Object RPC open.
What Changed
@cloudflare/think/workflowswithThinkWorkflow,ThinkWorkflowStep,ThinkPromptOptions, and typed prompt errors.AgentWorkflow.extendStep()so framework-specific workflow integrations can add helpers to the wrapped Workflow step without duplicating the base Agent workflow machinery.step.prompt(name, options)for Think workflows:prompt: stringand a Zod objectoutputschemakeybodydata cannot accidentally trigger workflow structured-output mode.workflow/workflowPromptmetadata remains ordinary caller metadata.sendWorkflowEvent()once per drain pass and relies on its built-in transient retry plus outbox alarm retryaborted,skipped, anderrorsubmissions can be recovered into missing notifications on startupexamples/think-workflowsexample showing:runWorkflow()step.prompt()for a report draftstep.waitForEvent()runWorkflow()rather than directenv.WORKFLOW.create()@cloudflare/thinkandagents.API Shape
New import:
Workflow definition:
Agent entry point:
Design Notes
The important design choice is that
step.prompt()does not synchronously wait on the Agent RPC. It submits a durable Think submission insidestep.do(), then waits for a Workflow event. Think sends that event from a private notification outbox when the submission reaches a terminal state.This gives the API a simple blocking shape while preserving the durable execution model:
sendWorkflowEvent()succeeds.step.waitForEvent().step.prompt()validates structured output or throws a typed error.Tests
npm run test -w @cloudflare/think -- submissions.test.tsnpx vitest --run -c packages/agents/src/tests/vitest.config.ts packages/agents/src/tests/workflow-prototype.test.tsnpx nx run @cloudflare/think:buildnpx nx run agents:buildnpm run checknpx nx run @cloudflare/think:buildnpm run typecheck -- examples/think-workflows/tsconfig.json packages/think/tsconfig.json packages/think/src/tests/tsconfig.jsonnpm run test -w @cloudflare/think -- submissions.test.tsnpx nx run @cloudflare/think:buildnpm run typecheck -- packages/think/tsconfig.json packages/think/src/tests/tsconfig.json examples/think-workflows/tsconfig.jsonnpm run test -w @cloudflare/think -- submissions.test.tsnpx nx run @cloudflare/think:buildnpm run typecheck -- packages/think/tsconfig.json packages/think/src/tests/tsconfig.json examples/think-workflows/tsconfig.jsonnpx nx run @cloudflare/think:buildnpm run typecheck -- packages/think/tsconfig.json examples/think-workflows/tsconfig.jsonnpm run test -w @cloudflare/think -- submissions.test.tsnpx nx run @cloudflare/think:buildnpm run typecheck -- packages/think/tsconfig.json packages/think/src/tests/tsconfig.json examples/think-workflows/tsconfig.jsonnpm run test -w @cloudflare/think -- submissions.test.tsnpx nx run @cloudflare/think:buildnpm run typecheck -- packages/think/tsconfig.json packages/think/src/tests/tsconfig.json examples/think-workflows/tsconfig.jsonThe original full
npm run checkpassed before the rename, with only the repo's existing sherif warnings. After the rename,@cloudflare/thinkbuilds and the newexamples/think-workflowsproject typechecks; a fullnpm run checkrerun reached typecheck and failed in unrelatedexamples/mcp-rpc-transportbecause TypeScript could not resolveworkers-ai-providerfrom that example.Remaining Follow-Up
There is not yet a true end-to-end Workflows runtime test that drives
step.prompt()through an actualwaitForEvent()resume. The focused tests cover the risky durable pieces added here: the base step-extension hook, workflow notification recovery, successful delivery, payload clearing, retry state after failed delivery, structured output capture in terminal workflow notifications, and isolation from workflow-shaped client body/metadata data.