eve 0.51.1 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/src/cli/dev/boot-progress.d.ts +3 -0
- package/dist/src/cli/dev/boot-progress.js +1 -0
- package/dist/src/cli/run.d.ts +4 -0
- package/dist/src/cli/run.js +3 -3
- package/dist/src/cli/telemetry/command.d.ts +9 -0
- package/dist/src/cli/telemetry/command.js +1 -0
- package/dist/src/cli/telemetry/flush.d.ts +2 -0
- package/dist/src/cli/telemetry/flush.js +1 -0
- package/dist/src/cli/telemetry/identity.d.ts +13 -0
- package/dist/src/cli/telemetry/identity.js +1 -0
- package/dist/src/cli/telemetry/index.d.ts +25 -0
- package/dist/src/cli/telemetry/index.js +3 -0
- package/dist/src/cli/telemetry/preference.d.ts +9 -0
- package/dist/src/cli/telemetry/preference.js +1 -0
- package/dist/src/client/types.d.ts +3 -2
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@eve/catalog/index.js +1 -1
- package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +22 -4
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-channel.js +1 -1
- package/dist/src/compiler/normalize-schedule.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/execution/activity-collector.js +1 -1
- package/dist/src/execution/continuation-conflict-step.js +1 -1
- package/dist/src/execution/coordination-dispatch-shared.d.ts +2 -2
- package/dist/src/execution/coordination-dispatch-step.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +1 -1
- package/dist/src/execution/inline-turn.d.ts +2 -2
- package/dist/src/execution/inline-turn.js +1 -1
- package/dist/src/execution/tasks/child/steps.d.ts +11 -1
- package/dist/src/execution/tasks/child/steps.js +1 -1
- package/dist/src/execution/tasks/child/workflow.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/tools/sleep-workflow.js +1 -1
- package/dist/src/execution/tools/subagent/invoke-agent.d.ts +1 -7
- package/dist/src/execution/tools/subagent/invoke-agent.js +1 -1
- package/dist/src/execution/tools/workflow/ask.d.ts +1 -2
- package/dist/src/execution/tools/workflow/ask.js +1 -1
- package/dist/src/execution/tools/workflow/body.d.ts +6 -1
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/cancel.js +1 -1
- package/dist/src/execution/tools/workflow/messages.d.ts +9 -8
- package/dist/src/execution/tools/workflow/messages.js +1 -1
- package/dist/src/execution/tools/workflow/owner-inbox.d.ts +2 -2
- package/dist/src/execution/tools/workflow/owner-inbox.js +1 -1
- package/dist/src/execution/tools/workflow/owner.d.ts +5 -11
- package/dist/src/execution/tools/workflow/owner.js +1 -1
- package/dist/src/execution/tools/workflow/run-control.d.ts +0 -4
- package/dist/src/execution/tools/workflow/run-control.js +1 -1
- package/dist/src/execution/tools/workflow/start.d.ts +5 -14
- package/dist/src/execution/tools/workflow/start.js +1 -1
- package/dist/src/execution/tools/workflow/workflow.d.ts +1 -1
- package/dist/src/execution/tools/workflow/workflow.js +1 -1
- package/dist/src/execution/turn-dispatch.js +1 -1
- package/dist/src/execution/turn-workflow-tool-run.d.ts +2 -8
- package/dist/src/execution/turn-workflow-tool-run.js +1 -1
- package/dist/src/execution/turn-workflow.d.ts +1 -0
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/wire/session-inbox-resume.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/emission-state.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/turn-client-context.d.ts +9 -0
- package/dist/src/harness/turn-client-context.js +1 -0
- package/dist/src/harness/workflow-tool-runs.d.ts +0 -1
- package/dist/src/harness/workflow-tool-runs.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/invocation/workflow-execution.js +1 -1
- package/dist/src/internal/mcp/streamable-http-server.d.ts +29 -1
- package/dist/src/internal/mcp/streamable-http-server.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/workflow/runtime.d.ts +6 -0
- package/dist/src/internal/workflow/runtime.js +1 -1
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.d.ts +1 -3
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.js +1 -1
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +1 -2
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +0 -2
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +1 -1
- package/dist/src/protocol/message.d.ts +3 -2
- package/dist/src/public/channels/mcp.js +1 -1
- package/dist/src/public/models/openai/chatgpt/model.js +2 -2
- package/dist/src/public/models/openai/chatgpt/transport.js +1 -1
- package/dist/src/public/tools/index.d.ts +3 -1
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/workflow-tool-context.d.ts +2 -0
- package/dist/src/shared/workflow-tool-context.js +1 -0
- package/dist/src/tasks/types.d.ts +17 -1
- package/dist/src/tasks/types.js +1 -1
- package/dist/src/tools/behavior.d.ts +5 -0
- package/dist/src/tools/definition.d.ts +16 -12
- package/dist/src/tools/definition.js +1 -1
- package/dist/src/tools/dynamic.d.ts +2 -2
- package/dist/src/tools/provided/sleep.d.ts +2 -2
- package/dist/src/tools/provided/sleep.js +1 -1
- package/dist/src/tools/task.d.ts +28 -80
- package/dist/src/tools/task.js +1 -1
- package/dist/src/tools/workflow-definition.d.ts +60 -0
- package/dist/src/tools/workflow-definition.js +1 -0
- package/docs/channels/mcp.mdx +25 -3
- package/docs/concepts/execution-model-and-durability.mdx +13 -2
- package/docs/guides/client/messages.mdx +1 -1
- package/docs/guides/deployment/vercel.mdx +2 -0
- package/docs/guides/frontend/overview.mdx +1 -1
- package/docs/memory/overview.mdx +40 -11
- package/docs/reference/cli.md +31 -33
- package/docs/reference/meta.json +1 -4
- package/docs/reference/telemetry.md +56 -0
- package/docs/reference/typescript-api.md +38 -35
- package/docs/tools/overview.mdx +59 -18
- package/docs/tools/workflows.mdx +146 -70
- package/package.json +1 -7
- package/dist/src/public/workflow/index.d.ts +0 -5
- package/dist/src/public/workflow/index.js +0 -1
package/docs/tools/workflows.mdx
CHANGED
|
@@ -4,19 +4,20 @@ description: "Define durable workflow tools that wait for people, webhooks, or t
|
|
|
4
4
|
url: /tools/workflows
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
A workflow tool is
|
|
8
|
-
call starts a durable Workflow run. Use one when a tool must wait for a person, webhook, or timer,
|
|
7
|
+
A workflow tool is a static tool defined with `defineWorkflowTool` from `eve/tools`, with
|
|
8
|
+
`"use workflow"` as the first statement of its executor. Each call starts a durable Workflow run. Use one when a tool must wait for a person, webhook, or timer,
|
|
9
9
|
delegate work to subagents, or coordinate retryable steps over a long period.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Durable suspension and background execution are independent. `defineWorkflowTool` lets the body
|
|
12
|
+
suspend at durable waits without holding compute. `execution: "background"` determines whether
|
|
13
|
+
the parent agent receives a task receipt and continues before the body finishes. A workflow can
|
|
14
|
+
suspend in either execution mode; running in the background does not require a suspension.
|
|
15
15
|
|
|
16
|
-
Workflow tools use the [Workflow SDK](https://workflow-sdk.dev): `"use workflow"`, `"use step"`,
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
`
|
|
16
|
+
Workflow tools use the [Workflow SDK](https://workflow-sdk.dev): `"use workflow"`, `"use step"`, `createHook`,
|
|
17
|
+
`createWebhook`, `sleep`, retries, and replay. eve provides `ctx.ask` for questions answered through
|
|
18
|
+
the session's channel and `ctx.agent` for durable subagent delegation. Use `yield` to report
|
|
19
|
+
progress and `await` on a workflow operation to wait durably. Values needed after a durable wait
|
|
20
|
+
stay in local variables in the workflow body.
|
|
20
21
|
|
|
21
22
|
A workflow tool runs code you wrote and appears to the model under its path-derived tool name, such
|
|
22
23
|
as `deploy`.
|
|
@@ -24,19 +25,17 @@ as `deploy`.
|
|
|
24
25
|
## Define a workflow tool
|
|
25
26
|
|
|
26
27
|
```ts title="agent/tools/deploy.ts"
|
|
27
|
-
import {
|
|
28
|
-
import { ask } from "eve/workflow";
|
|
28
|
+
import { defineWorkflowTool } from "eve/tools";
|
|
29
29
|
import { z } from "zod";
|
|
30
30
|
import { computePlan, runDeploy, type DeployPlan } from "../lib/deploy";
|
|
31
31
|
|
|
32
|
-
export default
|
|
32
|
+
export default defineWorkflowTool({
|
|
33
33
|
description: "Deploy a service to production. Pauses for a human to approve the plan.",
|
|
34
34
|
inputSchema: z.object({ service: z.string() }),
|
|
35
35
|
async execute({ service }, ctx) {
|
|
36
36
|
"use workflow";
|
|
37
|
-
|
|
38
37
|
const plan = await planDeploy(service);
|
|
39
|
-
const answer = await ask(
|
|
38
|
+
const answer = await ctx.ask({
|
|
40
39
|
prompt: `Deploy ${service}?\n\n${plan.summary}`,
|
|
41
40
|
display: "confirmation",
|
|
42
41
|
options: [
|
|
@@ -68,39 +67,91 @@ or days later, the run resumes, deploys, and returns. The model sees one tool re
|
|
|
68
67
|
|
|
69
68
|
### Rules
|
|
70
69
|
|
|
71
|
-
-
|
|
72
|
-
|
|
70
|
+
- Export `defineWorkflowTool({ ... })` as the default export. Its `execute` must be an async
|
|
71
|
+
function or async generator, written inline or referenced as a top-level `async function` in
|
|
72
|
+
the same module or an imported application module. Start the executor with `"use workflow"`
|
|
73
|
+
as its first statement. A missing
|
|
74
|
+
directive is a build error, even if another function in the module has one.
|
|
73
75
|
- `"use step"` marks a top-level `async function` in the tool module, or any module it imports, as a
|
|
74
76
|
step. Side effects, clocks, randomness, `process.env`, and Node.js APIs belong in steps; the body
|
|
75
77
|
is replayed and must stay deterministic.
|
|
76
78
|
- Import `createHook`, `createWebhook`, `sleep`, and `FatalError` from `workflow` in the body.
|
|
77
79
|
`start`, `getRun`, and `resumeHook` from `workflow/api` belong in steps. Your app does not install
|
|
78
80
|
the SDK; for types, new projects list `eve/workflow-modules` in the tsconfig `types`.
|
|
79
|
-
- In the body, `ctx` has `session`, `callId`, `toolName`,
|
|
80
|
-
`getSkill`, `getToken`, and `requireAuth`
|
|
81
|
+
- In the body, `ctx` has `session`, `callId`, `toolName`, `abortSignal`, `agent`, and `ask`.
|
|
82
|
+
`getSandbox`, `getSkill`, `getToken`, and `requireAuth` are not part of `WorkflowToolContext`.
|
|
83
|
+
Read credentials from `process.env` in a step; session-scoped workflow authorization is not yet available.
|
|
81
84
|
- The tool's input must be a JSON object. Workflow bodies are for static tools under `agent/tools/`,
|
|
82
85
|
not tools returned from `defineDynamic` resolvers.
|
|
83
86
|
|
|
87
|
+
`ctx.agent` and `ctx.ask` are available only on `WorkflowToolContext`. Ordinary tools, channel
|
|
88
|
+
handlers, and schedule handlers do not receive these methods. A shared helper may accept
|
|
89
|
+
`WorkflowToolContext` from `eve/tools` and use the context supplied by a workflow tool body.
|
|
90
|
+
|
|
91
|
+
Workflow executors require `defineWorkflowTool`. Adding `"use workflow"` to `defineTool`, a bare
|
|
92
|
+
tool object, a channel handler, or a schedule handler fails the build. To start a session from a
|
|
93
|
+
channel or schedule, use the [channel operations](/docs/channels/custom#channel-operations-and-session-handles)
|
|
94
|
+
or [schedule handler](/docs/schedules#handler-form-run) APIs.
|
|
95
|
+
|
|
96
|
+
### Migrate an existing workflow tool
|
|
97
|
+
|
|
98
|
+
Replace `defineTool` with `defineWorkflowTool`, keep the executor's `"use workflow"` directive,
|
|
99
|
+
and replace `agent(ctx, input)` and `ask(ctx, request)` with `ctx.agent(input)` and `ctx.ask(request)`.
|
|
100
|
+
The `eve/workflow` entry point has been removed. Import `WorkflowToolContext`, `AgentInput`,
|
|
101
|
+
`ToolInputRequest`, and `ToolInputResponse` from `eve/tools` when you need explicit types.
|
|
102
|
+
|
|
84
103
|
## Wait or run in the background
|
|
85
104
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| tool result | the run's return value | `{ status: "working", taskId }` |
|
|
89
|
-
| turn while the run lives | parked | continues |
|
|
90
|
-
| when the run ends | result lands in the tool call | agent is woken with the result or the error |
|
|
91
|
-
| progress (`yield`) | `action.partial` on the turn | wakes the agent with a note |
|
|
92
|
-
| cancel | cancelling the turn cancels the run | `task_cancel`, or the session ending |
|
|
105
|
+
Both modes support the same durable waits. Choose the execution mode based on when the parent
|
|
106
|
+
agent should receive a tool result:
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
| | Default execution | `execution: "background"` |
|
|
109
|
+
| ---------------------------- | --------------------------------------------------- | -------------------------------------------------------------------- |
|
|
110
|
+
| Tool result | The workflow's output after it finishes. | `{ status: "working", taskId }` before the body finishes. |
|
|
111
|
+
| Parent turn | Waits for this tool call to finish. | Continues after receiving the receipt. |
|
|
112
|
+
| Durable wait inside the body | Suspends the workflow; the tool call stays pending. | Suspends the workflow; the parent can continue independently. |
|
|
113
|
+
| When the run ends | Settles the pending tool call. | Sends a task completion or failure notification to the parent agent. |
|
|
114
|
+
| Cancel | Cancelling the turn cancels the run. | `task_cancel`, or the session ending. |
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
Use default execution when the model needs the answer to continue. Use background execution when
|
|
117
|
+
the conversation should continue while the task is pending. Background tools need no root-agent
|
|
118
|
+
flag. Ordinary `defineTool` also accepts `execution: "background"`, but its executor still runs
|
|
119
|
+
inside the initiating step and cannot suspend at workflow waits. See the
|
|
120
|
+
[tool execution comparison](/docs/tools#background-execution).
|
|
121
|
+
|
|
122
|
+
### How suspension works
|
|
123
|
+
|
|
124
|
+
Suspension happens when a workflow must wait for an unresolved durable operation, such as
|
|
125
|
+
`ctx.ask`, an awaited hook or webhook, or `sleep`. The runtime persists the wait and releases the
|
|
126
|
+
workflow's compute. When the answer, event, or timer arrives, the runtime replays the workflow,
|
|
127
|
+
reuses recorded step results, and continues past the wait. Put side effects in `"use step"`
|
|
128
|
+
functions so replay does not repeat completed effects.
|
|
129
|
+
|
|
130
|
+
Consider a body that reports progress and then asks for approval:
|
|
99
131
|
|
|
100
132
|
```ts
|
|
101
|
-
|
|
133
|
+
async *execute(input, ctx) {
|
|
134
|
+
"use workflow";
|
|
135
|
+
yield { status: "awaiting approval" };
|
|
136
|
+
const answer = await ctx.ask({ prompt: "Continue?", display: "confirmation" });
|
|
137
|
+
return { answer };
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The yield reports a snapshot, and eve advances the generator to `ctx.ask`. Awaiting the unanswered
|
|
142
|
+
request is the durable wait. In default execution, the original tool call remains pending until
|
|
143
|
+
the answer arrives and the body returns. With `execution: "background"`, the original call has
|
|
144
|
+
already returned a task receipt, and the workflow can suspend while the conversation continues.
|
|
145
|
+
Answering resumes the body in either mode.
|
|
146
|
+
|
|
147
|
+
`yield` itself does not wait for approval or switch a tool into background execution. An ordinary
|
|
148
|
+
Promise or Node.js timer inside a step also does not create a durable workflow suspension; use
|
|
149
|
+
the workflow operations for waits that must survive a restart.
|
|
150
|
+
|
|
151
|
+
## Ask a human: `ctx.ask`
|
|
102
152
|
|
|
103
|
-
|
|
153
|
+
```ts
|
|
154
|
+
const answer = await ctx.ask({
|
|
104
155
|
prompt: string,
|
|
105
156
|
display?: "confirmation" | "select" | "text",
|
|
106
157
|
options?: { id: string; label: string; description?: string; style?: "primary" | "danger" | "default" }[],
|
|
@@ -108,13 +159,12 @@ const answer = await ask(ctx, {
|
|
|
108
159
|
}); // { optionId?: string; text?: string }
|
|
109
160
|
```
|
|
110
161
|
|
|
111
|
-
`ask` publishes an `input.requested` event on the session — rendered the way channels render
|
|
112
|
-
`ask_question` and tool approvals — and returns
|
|
113
|
-
|
|
114
|
-
with the SDK's own constructs; race it against a deadline:
|
|
162
|
+
`ctx.ask` publishes an `input.requested` event on the session — rendered the way channels render
|
|
163
|
+
`ask_question` and tool approvals — and returns an awaitable answer. Awaiting it suspends the run until a response arrives.
|
|
164
|
+
It composes with the SDK's own constructs; race it against a deadline:
|
|
115
165
|
|
|
116
166
|
```ts
|
|
117
|
-
const pending = ask(
|
|
167
|
+
const pending = ctx.ask({ prompt: `Deploy ${service}?`, options: APPROVE_OR_CANCEL });
|
|
118
168
|
const answer = await Promise.race([pending, sleep("4h")]);
|
|
119
169
|
if (answer === undefined) return { deployed: false, reason: "timed out" };
|
|
120
170
|
```
|
|
@@ -128,16 +178,14 @@ if (answer === undefined) return { deployed: false, reason: "timed out" };
|
|
|
128
178
|
normal `turnPolicy`.
|
|
129
179
|
|
|
130
180
|
Compare the [`approval`](/docs/human-in-the-loop) policy, which gates the call before `execute` runs
|
|
131
|
-
and can only show the model's input. Both compose: `approval` before the run, `ask` inside it.
|
|
181
|
+
and can only show the model's input. Both compose: `approval` before the run, `ctx.ask` inside it.
|
|
132
182
|
|
|
133
|
-
## Delegate work: `agent`
|
|
183
|
+
## Delegate work: `ctx.agent`
|
|
134
184
|
|
|
135
185
|
Workflow tools can call a visible subagent and wait for its result:
|
|
136
186
|
|
|
137
187
|
```ts
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const result = await agent(ctx, {
|
|
188
|
+
const result = await ctx.agent({
|
|
141
189
|
key: "security-review",
|
|
142
190
|
target: "reviewer",
|
|
143
191
|
message: "Review the deployment plan for security risks.",
|
|
@@ -151,23 +199,49 @@ keys. `target` is the model-visible subagent name; pass `agentId` to continue an
|
|
|
151
199
|
|
|
152
200
|
## Report progress: `yield`
|
|
153
201
|
|
|
154
|
-
A workflow body may be an async generator.
|
|
155
|
-
|
|
202
|
+
A workflow body may be an async generator. Ordinary yields report progress in both execution
|
|
203
|
+
modes. After processing a yield, eve advances the generator; use an awaited workflow operation
|
|
204
|
+
when the body needs to suspend.
|
|
156
205
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
206
|
+
| Operation | Default execution | `execution: "background"` |
|
|
207
|
+
| --------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
208
|
+
| `yield value` | Emits an `action.partial` snapshot for the pending tool call. | Emits stream-only task progress; does not request a parent-agent turn. |
|
|
209
|
+
| `yield task.postMessage(message)` | Unavailable; there is no `task` argument. | Sends a message requesting a parent-agent turn; the task stays open. |
|
|
210
|
+
| `return value` | Settles the tool call with its output. | Completes the task and delivers its output in a later notification. |
|
|
211
|
+
| No return value | Uses the last yield as output, or `null` if there were no yields. | Completes with `null`; yielded progress is not the task output. |
|
|
212
|
+
|
|
213
|
+
For default execution, an explicit `return null` also falls back to the last yield. Prefer an
|
|
214
|
+
explicit object return when progress snapshots and the final result have different shapes.
|
|
215
|
+
Progress snapshots are last-write-wins by tool call id and do not enter model history as
|
|
216
|
+
intermediate tool results. A snapshot used as the final output does enter history as the tool result.
|
|
217
|
+
|
|
218
|
+
This background workflow reports progress, sends the parent one message, and then suspends:
|
|
219
|
+
|
|
220
|
+
```ts title="agent/tools/remind_with_progress.ts"
|
|
221
|
+
import { defineWorkflowTool } from "eve/tools";
|
|
222
|
+
import { sleep } from "workflow";
|
|
223
|
+
import { z } from "zod";
|
|
224
|
+
|
|
225
|
+
export default defineWorkflowTool({
|
|
226
|
+
description: "Schedule a reminder and report progress before waiting.",
|
|
227
|
+
inputSchema: z.object({ note: z.string(), delay: z.string() }),
|
|
228
|
+
execution: "background",
|
|
229
|
+
async *execute({ note, delay }, ctx, task) {
|
|
230
|
+
"use workflow";
|
|
231
|
+
yield { status: "preparing reminder" }; // Stream-only progress.
|
|
232
|
+
yield task.postMessage(`Reminder scheduled for ${delay}.`); // Parent-agent message.
|
|
233
|
+
await sleep(delay); // Durable suspension while the timer is pending.
|
|
234
|
+
return { reminder: note }; // Task completion notification.
|
|
235
|
+
},
|
|
236
|
+
});
|
|
165
237
|
```
|
|
166
238
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
239
|
+
Calling `task.postMessage` constructs a descriptor; yielding it sends the message. It does not
|
|
240
|
+
wait for a reply. Use [`ctx.ask`](#ask-a-human-ctxask) when the workflow needs a human answer.
|
|
241
|
+
Removing `execution: "background"` requires removing the `task` argument and message yield; the
|
|
242
|
+
ordinary progress yield and `await sleep(delay)` still work, but the model waits for the final
|
|
243
|
+
reminder as the tool result. See [yield and return](/docs/tools#yield-and-return) for the different
|
|
244
|
+
final-output rules of ordinary `defineTool` generators.
|
|
171
245
|
|
|
172
246
|
## Cancel and clean up: `ctx.abortSignal`
|
|
173
247
|
|
|
@@ -200,9 +274,8 @@ first.
|
|
|
200
274
|
```ts
|
|
201
275
|
async execute({ service }, ctx) {
|
|
202
276
|
"use workflow";
|
|
203
|
-
|
|
204
277
|
const plan = await planDeploy(service);
|
|
205
|
-
const pending = ask(
|
|
278
|
+
const pending = ctx.ask({ prompt: `Deploy ${service}?`, display: "confirmation", options: APPROVE_OR_CANCEL });
|
|
206
279
|
|
|
207
280
|
let answer = await Promise.race([pending, sleep("4h")]);
|
|
208
281
|
if (answer === undefined) {
|
|
@@ -222,17 +295,16 @@ and returning withdraws the request.
|
|
|
222
295
|
### Wait for an external system to call back
|
|
223
296
|
|
|
224
297
|
```ts title="agent/tools/render_video.ts"
|
|
225
|
-
import {
|
|
298
|
+
import { defineWorkflowTool } from "eve/tools";
|
|
226
299
|
import { createWebhook, FatalError } from "workflow";
|
|
227
300
|
import { z } from "zod";
|
|
228
301
|
import { submitRender } from "../lib/render";
|
|
229
302
|
|
|
230
|
-
export default
|
|
303
|
+
export default defineWorkflowTool({
|
|
231
304
|
description: "Render a video. Returns the URL once the render farm finishes.",
|
|
232
305
|
inputSchema: z.object({ projectId: z.string() }),
|
|
233
306
|
async execute({ projectId }) {
|
|
234
307
|
"use workflow";
|
|
235
|
-
|
|
236
308
|
const done = createWebhook();
|
|
237
309
|
const jobId = await submitRender(projectId, done.url);
|
|
238
310
|
const callback = await done;
|
|
@@ -250,19 +322,17 @@ system posts to it when it is done. Nothing runs in between.
|
|
|
250
322
|
### Ask now, act when answered
|
|
251
323
|
|
|
252
324
|
```ts title="agent/tools/refund_order.ts"
|
|
253
|
-
import {
|
|
254
|
-
import { ask } from "eve/workflow";
|
|
325
|
+
import { defineWorkflowTool } from "eve/tools";
|
|
255
326
|
import { z } from "zod";
|
|
256
327
|
import { issueRefund } from "../lib/refunds";
|
|
257
328
|
|
|
258
|
-
export default
|
|
329
|
+
export default defineWorkflowTool({
|
|
259
330
|
description: "Request approval to refund an order, then issue the refund once approved.",
|
|
260
331
|
inputSchema: z.object({ orderId: z.string(), amount: z.number() }),
|
|
261
332
|
execution: "background",
|
|
262
333
|
async execute({ orderId, amount }, ctx) {
|
|
263
334
|
"use workflow";
|
|
264
|
-
|
|
265
|
-
const decision = await ask(ctx, {
|
|
335
|
+
const decision = await ctx.ask({
|
|
266
336
|
prompt: `Refund $${amount} on order ${orderId}?`,
|
|
267
337
|
display: "confirmation",
|
|
268
338
|
options: [
|
|
@@ -283,11 +353,11 @@ on the channel. When it is answered, the refund runs and the agent is woken with
|
|
|
283
353
|
### Remind me later
|
|
284
354
|
|
|
285
355
|
```ts title="agent/tools/remind.ts"
|
|
286
|
-
import {
|
|
356
|
+
import { defineWorkflowTool } from "eve/tools";
|
|
287
357
|
import { sleep } from "workflow";
|
|
288
358
|
import { z } from "zod";
|
|
289
359
|
|
|
290
|
-
export default
|
|
360
|
+
export default defineWorkflowTool({
|
|
291
361
|
description: "Remind the user about something after a delay.",
|
|
292
362
|
inputSchema: z.object({ note: z.string(), delay: z.string() }),
|
|
293
363
|
execution: "background",
|
|
@@ -317,6 +387,12 @@ session's task index, can be cancelled with `task_cancel`, and are cancelled whe
|
|
|
317
387
|
Errors follow the SDK. A thrown error in a step retries per the step's policy; `FatalError` does
|
|
318
388
|
not. An error that escapes the body fails the run.
|
|
319
389
|
|
|
320
|
-
|
|
321
|
-
|
|
390
|
+
Starting a waiting workflow tool can also be retried. If dispatch is interrupted after starting a
|
|
391
|
+
run, its retry starts another run, and both may execute. The parent tracks the run returned by the
|
|
392
|
+
successful dispatch attempt. Use an application idempotency key for side effects that must happen
|
|
393
|
+
only once.
|
|
394
|
+
|
|
395
|
+
The workflow id derives from the executor's module path and function name. Inline executors use
|
|
396
|
+
the tool module and the name `execute`; imported executors use their declaring module and name.
|
|
397
|
+
Renaming or moving that function creates a new workflow. Runs in flight finish on the deployment that started them; a run that
|
|
322
398
|
resumes on a deployment without its tool fails with an error naming the missing workflow.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
|
|
6
6
|
"keywords": [
|
|
@@ -181,12 +181,6 @@
|
|
|
181
181
|
"import": "./dist/src/public/tools/workflow.js",
|
|
182
182
|
"default": "./dist/src/public/tools/workflow.js"
|
|
183
183
|
},
|
|
184
|
-
"./workflow": {
|
|
185
|
-
"eve-source": "./src/public/workflow/index.ts",
|
|
186
|
-
"types": "./dist/src/public/workflow/index.d.ts",
|
|
187
|
-
"import": "./dist/src/public/workflow/index.js",
|
|
188
|
-
"default": "./dist/src/public/workflow/index.js"
|
|
189
|
-
},
|
|
190
184
|
"./workflow-modules": {
|
|
191
185
|
"eve-source": "./src/public/workflow-modules.d.ts",
|
|
192
186
|
"types": "./dist/src/public/workflow-modules.d.ts"
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/** `eve/workflow`: what eve adds inside a workflow tool body. The SDK's own constructs come from `workflow`. */
|
|
2
|
-
export { ask } from "#execution/tools/workflow/ask.js";
|
|
3
|
-
export { agent } from "#execution/tools/subagent/invoke-agent.js";
|
|
4
|
-
export type { AgentInput } from "#execution/tools/subagent/invoke-agent.js";
|
|
5
|
-
export type { ToolInputRequest, ToolInputResponse } from "#tools/definition.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ask}from"#execution/tools/workflow/ask.js";import{agent}from"#execution/tools/subagent/invoke-agent.js";export{agent,ask};
|