eve 0.47.7 → 0.48.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 +20 -0
- package/dist/src/channel/delivery-metadata.d.ts +1 -0
- package/dist/src/channel/delivery-metadata.js +1 -1
- package/dist/src/channel/types.d.ts +10 -8
- package/dist/src/chunks/{use-eve-agent-Dg5S44kG.js → use-eve-agent-BZnOzAVd.js} +25 -5
- package/dist/src/chunks/{use-eve-agent-B5zw1dwj.js → use-eve-agent-Bgp6INfi.js} +25 -5
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +2 -1
- package/dist/src/cli/commands/integration-connect.js +1 -1
- package/dist/src/cli/commands/register-integration-commands.d.ts +3 -1
- package/dist/src/cli/commands/register-integration-commands.js +1 -1
- package/dist/src/cli/dev/command-options.d.ts +2 -0
- package/dist/src/cli/dev/run-interactive-ui.js +1 -1
- package/dist/src/cli/dev/tui/blocks.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/registry-result-message.d.ts +17 -0
- package/dist/src/cli/dev/tui/registry-result-message.js +3 -0
- package/dist/src/cli/dev/tui/runner.d.ts +11 -4
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -3
- package/dist/src/cli/dev/tui/setup-commands.js +2 -3
- package/dist/src/cli/dev/tui/setup-flow.d.ts +15 -5
- package/dist/src/cli/dev/tui/setup-panel.d.ts +6 -1
- package/dist/src/cli/dev/tui/setup-panel.js +4 -4
- package/dist/src/cli/dev/tui/setup-selection-input.d.ts +1 -0
- package/dist/src/cli/dev/tui/setup-selection-input.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +3 -4
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/run.js +2 -2
- package/dist/src/client/agent-info-schema.d.ts +1 -0
- package/dist/src/client/agent-info-schema.js +1 -1
- package/dist/src/client/open-stream.d.ts +1 -0
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -1
- package/dist/src/compiled/@opentelemetry/api/index.d.ts +6 -0
- package/dist/src/compiled/@workflow/builders/LICENSE.md +201 -0
- package/dist/src/compiled/@workflow/builders/index.d.ts +62 -0
- package/dist/src/compiled/@workflow/builders/index.js +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +2 -2
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/keys.d.ts +3 -8
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/types.d.ts +7 -7
- package/dist/src/execution/accepted-delivery-deployment.d.ts +7 -0
- package/dist/src/execution/accepted-delivery-deployment.js +1 -0
- package/dist/src/execution/cancel-descendant-turns-step.d.ts +4 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/delegation-tool.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +7 -2
- package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-turn-step.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.d.ts +2 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow-v1-to-v2.js +1 -0
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +25 -3
- package/dist/src/execution/durable-session-migrations/turn-workflow.js +1 -1
- package/dist/src/execution/eve-workflow-attributes.js +1 -1
- package/dist/src/execution/finalize-terminal-session.d.ts +17 -0
- package/dist/src/execution/finalize-terminal-session.js +1 -0
- package/dist/src/execution/inline-turn.d.ts +29 -0
- package/dist/src/execution/inline-turn.js +1 -0
- package/dist/src/execution/next-driver-action.d.ts +4 -0
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/parked-delivery-wait.js +1 -1
- package/dist/src/execution/pending-turn-state.d.ts +1 -0
- package/dist/src/execution/pending-turn-state.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +2 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/stable-workflow-names.d.ts +12 -0
- package/dist/src/execution/stable-workflow-names.js +1 -0
- package/dist/src/execution/subagent-event-proxy-step.d.ts +3 -0
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.d.ts +2 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/subagent-start-remote.d.ts +2 -0
- package/dist/src/execution/subagent-start-remote.js +1 -1
- package/dist/src/execution/tasks/child/steps.d.ts +2 -0
- 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/dispatch-task-step.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch.js +1 -1
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/terminal-session-completion-step.js +1 -1
- package/dist/src/execution/terminal-session-event.d.ts +13 -0
- package/dist/src/execution/terminal-session-event.js +1 -0
- package/dist/src/execution/terminal-session-failure-step.d.ts +1 -0
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/tool-run/answer.d.ts +3 -0
- package/dist/src/execution/tool-run/answer.js +1 -0
- package/dist/src/execution/tool-run/background.d.ts +14 -0
- package/dist/src/execution/tool-run/background.js +1 -0
- package/dist/src/execution/tool-run/cancel.d.ts +7 -0
- package/dist/src/execution/tool-run/cancel.js +1 -0
- package/dist/src/execution/tool-run/dispatch.d.ts +24 -0
- package/dist/src/execution/tool-run/dispatch.js +1 -0
- package/dist/src/execution/tool-run/emit-run-report-step.d.ts +7 -0
- package/dist/src/execution/tool-run/emit-run-report-step.js +1 -0
- package/dist/src/execution/tool-run/messages.d.ts +70 -0
- package/dist/src/execution/tool-run/messages.js +1 -0
- package/dist/src/execution/tool-run/owner-channels.d.ts +29 -0
- package/dist/src/execution/tool-run/owner-channels.js +1 -0
- package/dist/src/execution/tool-run/owner-inbox.d.ts +11 -0
- package/dist/src/execution/tool-run/owner-inbox.js +1 -0
- package/dist/src/execution/tool-run/owner.d.ts +13 -0
- package/dist/src/execution/tool-run/owner.js +1 -0
- package/dist/src/execution/tool-run/resume-hook-step.d.ts +4 -0
- package/dist/src/execution/tool-run/resume-hook-step.js +1 -0
- package/dist/src/execution/tool-run/run-control.d.ts +18 -0
- package/dist/src/execution/tool-run/run-control.js +1 -0
- package/dist/src/execution/tool-run/start.d.ts +11 -0
- package/dist/src/execution/tool-run/start.js +1 -0
- package/dist/src/execution/tool-run/types.d.ts +21 -0
- package/dist/src/execution/tool-run/types.js +1 -0
- package/dist/src/execution/tool-run/workflow.d.ts +9 -0
- package/dist/src/execution/tool-run/workflow.js +1 -0
- package/dist/src/execution/tools/subagent/local.js +1 -1
- package/dist/src/execution/turn-cancellation-control.d.ts +2 -0
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-control-receiver.js +1 -1
- package/dist/src/execution/turn-dispatch.d.ts +4 -2
- package/dist/src/execution/turn-dispatch.js +1 -1
- package/dist/src/execution/turn-execution-cursor.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/wire/session-inbox-contract.d.ts +2 -2
- package/dist/src/execution/wire/session-inbox-contract.js +1 -1
- package/dist/src/execution/wire/session-inbox-encoder.d.ts +6 -2
- package/dist/src/execution/wire/session-inbox-encoder.js +1 -1
- package/dist/src/execution/wire/session-inbox-resume.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v2-migration.d.ts +0 -2
- package/dist/src/execution/wire/session-inbox-wire.v2-migration.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v2.migration.d.ts +3 -0
- package/dist/src/execution/wire/session-inbox-wire.v2.migration.js +1 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.d.ts +480 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.js +1 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.migration.d.ts +3 -0
- package/dist/src/execution/wire/session-inbox-wire.v3.migration.js +1 -0
- package/dist/src/execution/workflow-entry-finalization.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-registry.d.ts +5 -0
- package/dist/src/execution/workflow-registry.js +1 -0
- package/dist/src/execution/workflow-runtime.d.ts +9 -11
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/execution/workflow-webhook-route.d.ts +4 -0
- package/dist/src/execution/workflow-webhook-route.js +1 -0
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +10 -0
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.d.ts +2 -0
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/tool-runs.d.ts +21 -0
- package/dist/src/harness/tool-runs.js +1 -0
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/instrumentation/content-policy.d.ts +3 -1
- package/dist/src/instrumentation/content-policy.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +2 -2
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/errors.d.ts +3 -0
- package/dist/src/internal/authored-module-loader.d.ts +7 -1
- package/dist/src/internal/authored-module-loader.js +3 -3
- package/dist/src/internal/authored-package-boundary.js +1 -1
- package/dist/src/internal/authored-runtime-modules.d.ts +2 -0
- package/dist/src/internal/authored-runtime-modules.js +1 -1
- package/dist/src/internal/nitro/development-generation.d.ts +2 -0
- package/dist/src/internal/nitro/development-generation.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.d.ts +17 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-directives.js +1 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +19 -0
- package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +1 -0
- package/dist/src/internal/workflow-bundle/builder-support.d.ts +17 -2
- package/dist/src/internal/workflow-bundle/builder-support.js +4 -3
- package/dist/src/internal/workflow-bundle/builder.d.ts +2 -2
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.d.ts +2 -0
- package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +3 -0
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +6 -2
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-core-shim.d.ts +3 -0
- package/dist/src/internal/workflow-bundle/workflow-core-shim.js +1 -1
- package/dist/src/internal/workflow-bundle/workflow-directive-ast.d.ts +7 -0
- package/dist/src/internal/workflow-bundle/workflow-directive-ast.js +1 -0
- package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +15 -1
- package/dist/src/internal/workflow-bundle/workflow-transformer.js +4 -4
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/baggage.d.ts +6 -0
- package/dist/src/protocol/baggage.js +1 -0
- package/dist/src/public/channels/slack/attachments.js +1 -1
- package/dist/src/public/channels/teams/attachments.d.ts +2 -2
- package/dist/src/public/channels/teams/attachments.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/attachments.js +1 -1
- package/dist/src/public/definitions/remote-agent.d.ts +6 -3
- package/dist/src/public/workflow/index.d.ts +3 -0
- package/dist/src/public/workflow/index.js +1 -0
- package/dist/src/public/workflow-modules.d.js +1 -0
- package/dist/src/public/workflow-modules.d.ts +11 -0
- package/dist/src/runtime/actions/keys.js +1 -1
- package/dist/src/runtime/tools/registry.js +1 -1
- package/dist/src/setup/connection-connector.d.ts +4 -2
- package/dist/src/setup/connection-connector.js +2 -2
- package/dist/src/setup/flows/login.js +1 -1
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/flows/provider.d.ts +5 -0
- package/dist/src/setup/flows/provider.js +4 -4
- package/dist/src/setup/flows/registry-session.d.ts +24 -7
- package/dist/src/setup/flows/registry-session.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +35 -29
- package/dist/src/setup/flows/registry.js +2 -1
- package/dist/src/setup/integrations/web/setup.d.ts +0 -2
- package/dist/src/setup/integrations/web/setup.js +1 -1
- package/dist/src/setup/prompter.d.ts +24 -4
- package/dist/src/setup/prompter.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/dispatch-action.d.ts +6 -0
- package/dist/src/shared/forwarded-trace-policy.d.ts +28 -0
- package/dist/src/shared/forwarded-trace-policy.js +1 -0
- package/dist/src/shared/instrumentation-decision.d.ts +3 -0
- package/dist/src/shared/instrumentation-decision.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/behavior.d.ts +6 -0
- package/dist/src/tools/definition.d.ts +39 -3
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-session-context.js +1 -1
- package/dist/src/tracing/agent-trace-context-store.d.ts +1 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -1
- package/dist/src/tracing/otel-declaration.d.ts +5 -3
- package/dist/src/tracing/otel-registration.d.ts +1 -1
- package/dist/src/tracing/otel-registration.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/custom.mdx +2 -0
- package/docs/channels/eve.mdx +5 -1
- package/docs/channels/teams.mdx +6 -1
- package/docs/concepts/sessions-runs-and-streaming.md +4 -2
- package/docs/guides/auth-and-route-protection.md +5 -1
- package/docs/guides/client/messages.mdx +6 -0
- package/docs/guides/dev-tui.md +30 -18
- package/docs/guides/remote-agents.md +25 -0
- package/docs/reference/cli.md +2 -2
- package/docs/tools/meta.json +1 -1
- package/docs/tools/overview.mdx +7 -0
- package/docs/tools/workflows.mdx +288 -0
- package/package.json +12 -1
- package/dist/src/internal/authored-directive-prologue.d.ts +0 -4
- package/dist/src/internal/authored-directive-prologue.js +0 -1
|
@@ -143,6 +143,31 @@ Forwarding is explicit on both sides. The receiver names which forwarders it tru
|
|
|
143
143
|
|
|
144
144
|
A receiver on an eve version that predates all principal forwarding may instead drop the unknown field and run the session as your app's service identity; per-user connections there fail with `principal_required`. On remote requests where the dispatching turn has no auth, the field is omitted and the call proceeds on transport trust alone.
|
|
145
145
|
|
|
146
|
+
## Preserving trace content
|
|
147
|
+
|
|
148
|
+
With `forwardPrincipal: true`, a sampled trace carries its original audience and the maximum content the next hop may record. For example, `eve.audience=private;ceiling=i0o1` allows outputs but not inputs. eve sends this as [W3C Baggage](https://www.w3.org/TR/baggage/).
|
|
149
|
+
|
|
150
|
+
The receiver uses it only after `trustedForwarders` accepts the authenticated calling deployment:
|
|
151
|
+
|
|
152
|
+
```ts title="agent/channels/eve.ts"
|
|
153
|
+
import { eveChannel } from "eve/channels/eve";
|
|
154
|
+
import { vercelOidc, vercelSubject } from "eve/channels/auth";
|
|
155
|
+
|
|
156
|
+
export default eveChannel({
|
|
157
|
+
auth: [vercelOidc()],
|
|
158
|
+
trustedForwarders: (forwarder) =>
|
|
159
|
+
forwarder.subject === vercelSubject({ teamSlug: "acme", projectName: "router" }),
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The request must also include a callback and a valid sampled `traceparent`. Those fields identify a remote call, but they do not establish trust. `trustedForwarders` is the authorization boundary.
|
|
164
|
+
|
|
165
|
+
The receiver combines the incoming ceiling with its own trace policy. Each hop may narrow the result, but it cannot restore inputs or outputs removed earlier. The original audience stays the same across remote and local subagent hops. Public origins may include content by default; private and unknown origins stay metadata-only unless both deployments explicitly allow them.
|
|
166
|
+
|
|
167
|
+
The live delivery audience still matters. An unknown callback delivery, or one matching the origin, uses the session decision. A different explicit audience applies its own hard ceiling, so a private delivery stays redacted even when the trace began in public.
|
|
168
|
+
|
|
169
|
+
Missing, malformed, duplicate, unsampled, untrusted, and mixed-version assertions fall back to metadata-only tracing. Dropped traces use only the unsampled trace flag. The decision is fixed when the remote session starts and reused by continuations. Agent Runs shows Workflow content only when both inputs and outputs are allowed.
|
|
170
|
+
|
|
146
171
|
## How remote dispatch and callbacks work
|
|
147
172
|
|
|
148
173
|
A local subagent runs inline. A remote one runs in its own deployment, so dispatch is asynchronous:
|
package/docs/reference/cli.md
CHANGED
|
@@ -210,7 +210,7 @@ Pass a bare URL and the UI connects to that server instead of booting a local on
|
|
|
210
210
|
| `-H, --header <header>` | string | none | Request header for a URL target, in `Name: value` form; repeat for multiple headers |
|
|
211
211
|
| `--no-ui` | flag | UI on | Start the server without an interactive UI |
|
|
212
212
|
| `--name <name>` | string | app folder name | Title shown in the terminal UI |
|
|
213
|
-
| `--input <text>` | string | none | Pre-fill the prompt input
|
|
213
|
+
| `--input <text>` | string | none | Pre-fill the prompt input |
|
|
214
214
|
| `--tools <mode>` | enum | `auto-collapsed` | Tool-call rendering: `full` \| `collapsed` \| `auto-collapsed` \| `hidden` |
|
|
215
215
|
| `--reasoning <mode>` | enum | `full` | Reasoning rendering: `full` \| `collapsed` \| `auto-collapsed` \| `hidden` |
|
|
216
216
|
| `--subagents <mode>` | enum | `auto-collapsed` | Subagent-section rendering: `full` \| `collapsed` \| `auto-collapsed` \| `hidden` |
|
|
@@ -221,7 +221,7 @@ Pass a bare URL and the UI connects to that server instead of booting a local on
|
|
|
221
221
|
|
|
222
222
|
`eve acp` reserves stdin and stdout for newline-delimited JSON-RPC and sends diagnostics to stderr. Without a URL, it supervises an isolated local development server. With a URL, it bridges ACP to that server's existing eve HTTP API and accepts the same URL credentials and request headers as `eve dev <url>`. Pass `--scope <team>` when the active Vercel scope does not own the deployment; `EVE_VERCEL_SCOPE` provides the same value for managed harnesses. See [Agent Client Protocol (ACP)](../protocols/acp) for client configuration and capability limits.
|
|
223
223
|
|
|
224
|
-
A fresh `eve init`
|
|
224
|
+
A fresh `eve init` starts onboarding before the first prompt: the TUI installs the Vercel CLI if needed, asks you to log in if needed, guides you through model configuration, then lets you choose channels and integrations. Other `--input` text stays editable in the prompt.
|
|
225
225
|
|
|
226
226
|
For a URL target protected by HTTP Basic auth, put the credentials in the URL. eve sends them as a Basic `Authorization` header and strips them from the server URL before connecting:
|
|
227
227
|
|
package/docs/tools/meta.json
CHANGED
package/docs/tools/overview.mdx
CHANGED
|
@@ -78,6 +78,13 @@ Later task-triggered parent turns receive fresh state for the same cohort. The m
|
|
|
78
78
|
to keep related intermediate results silent while any task remains pending. Once every related
|
|
79
79
|
task is terminal, the state includes their outputs so the model can combine the useful results.
|
|
80
80
|
|
|
81
|
+
### Durable tools
|
|
82
|
+
|
|
83
|
+
A tool whose `execute` starts with `"use workflow"` runs as a durable Workflow run instead of
|
|
84
|
+
inside the model step. It can wait for a person, a webhook, or a timer for as long as it takes, with
|
|
85
|
+
nothing running in between, and its return value still settles the tool call. See
|
|
86
|
+
[Durable tools](/docs/tools/workflows).
|
|
87
|
+
|
|
81
88
|
### The `ctx` parameter
|
|
82
89
|
|
|
83
90
|
`execute` gets a `ctx` carrying the runtime accessors:
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Durable Tools"
|
|
3
|
+
description: "Write a tool as a workflow so it can wait for a person, a webhook, or a timer for as long as it takes, with nothing running in between."
|
|
4
|
+
url: /tools/workflows
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A tool's `execute` may be a workflow. eve starts one durable run per tool call and, by default,
|
|
8
|
+
waits for it: the run's return value is the tool result, however long it takes. While the run waits
|
|
9
|
+
on a person, a webhook, or a sleep, the turn is parked and nothing is running. Mark the same tool
|
|
10
|
+
`execution: "background"` and the model gets a receipt instead; eve wakes the agent with the return
|
|
11
|
+
value when the run ends.
|
|
12
|
+
|
|
13
|
+
Inside the tool, everything is the [Workflow SDK](https://workflow-sdk.dev): `"use workflow"`,
|
|
14
|
+
`"use step"`, `createHook`, `createWebhook`, `sleep`, retries, replay. eve adds `ask` from
|
|
15
|
+
`eve/workflow` — a question the human on the session's channel answers — and treats each `yield` as
|
|
16
|
+
a durable progress report.
|
|
17
|
+
|
|
18
|
+
## Write one
|
|
19
|
+
|
|
20
|
+
```ts title="agent/tools/deploy.ts"
|
|
21
|
+
import { defineTool } from "eve/tools";
|
|
22
|
+
import { ask } from "eve/workflow";
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
25
|
+
export default defineTool({
|
|
26
|
+
description: "Deploy a service to production. Pauses for a human to approve the plan.",
|
|
27
|
+
inputSchema: z.object({ service: z.string() }),
|
|
28
|
+
async execute({ service }, ctx) {
|
|
29
|
+
"use workflow";
|
|
30
|
+
|
|
31
|
+
const plan = await planDeploy(service);
|
|
32
|
+
const answer = await ask(ctx, {
|
|
33
|
+
prompt: `Deploy ${service}?\n\n${plan.summary}`,
|
|
34
|
+
display: "confirmation",
|
|
35
|
+
options: [
|
|
36
|
+
{ id: "approve", label: "Deploy", style: "primary" },
|
|
37
|
+
{ id: "cancel", label: "Cancel" },
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (answer.optionId !== "approve") {
|
|
42
|
+
return { deployed: false, reason: "rejected" };
|
|
43
|
+
}
|
|
44
|
+
return { deployed: true, url: await applyDeploy(plan) };
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
async function planDeploy(service: string) {
|
|
49
|
+
"use step";
|
|
50
|
+
return computePlan(service);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function applyDeploy(plan: DeployPlan) {
|
|
54
|
+
"use step";
|
|
55
|
+
return runDeploy(plan);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The model calls `deploy`. The turn parks while the human reads the plan. When they answer, minutes
|
|
60
|
+
or days later, the run resumes, deploys, and returns. The model sees one tool result.
|
|
61
|
+
|
|
62
|
+
### Rules
|
|
63
|
+
|
|
64
|
+
- `"use workflow"` goes on its own line as the first statement of `execute`, or of a top-level
|
|
65
|
+
`async function` you reference as `execute: deploy`.
|
|
66
|
+
- `"use step"` marks a top-level `async function` in the tool module, or any module it imports, as a
|
|
67
|
+
step. Side effects, clocks, randomness, `process.env`, and Node.js APIs belong in steps; the body
|
|
68
|
+
is replayed and must stay deterministic.
|
|
69
|
+
- Import `createHook`, `createWebhook`, `sleep`, and `FatalError` from `workflow` in the body.
|
|
70
|
+
`start`, `getRun`, and `resumeHook` from `workflow/api` belong in steps. Your app does not install
|
|
71
|
+
the SDK; for types, new projects list `eve/workflow-modules` in the tsconfig `types`.
|
|
72
|
+
- In the body, `ctx` has `session`, `callId`, `toolName`, and `abortSignal`. `getSandbox`,
|
|
73
|
+
`getSkill`, `getToken`, and `requireAuth` throw there; read credentials in a step instead.
|
|
74
|
+
- The tool's input must be a JSON object. Workflow bodies are for static tools under `agent/tools/`,
|
|
75
|
+
not tools returned from `defineDynamic` resolvers.
|
|
76
|
+
|
|
77
|
+
## Wait or run in the background
|
|
78
|
+
|
|
79
|
+
| | default | `execution: "background"` |
|
|
80
|
+
| ------------------------ | ----------------------------------- | ------------------------------------------- |
|
|
81
|
+
| tool result | the run's return value | `{ status: "working", taskId }` |
|
|
82
|
+
| turn while the run lives | parked | continues |
|
|
83
|
+
| when the run ends | result lands in the tool call | agent is woken with the result or the error |
|
|
84
|
+
| progress (`yield`) | `action.partial` on the turn | wakes the agent with a note |
|
|
85
|
+
| cancel | cancelling the turn cancels the run | `task_cancel`, or the session ending |
|
|
86
|
+
|
|
87
|
+
Wait when the model needs the answer to continue. Go background when the wait may outlive the
|
|
88
|
+
conversation or the user should keep talking in the meantime. Background tools require
|
|
89
|
+
`experimental.tasks` on the root agent, like every background tool.
|
|
90
|
+
|
|
91
|
+
## Ask a human: `ask`
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { ask } from "eve/workflow";
|
|
95
|
+
|
|
96
|
+
const answer = await ask(ctx, {
|
|
97
|
+
prompt: string,
|
|
98
|
+
display?: "confirmation" | "select" | "text",
|
|
99
|
+
options?: { id: string; label: string; description?: string; style?: "primary" | "danger" | "default" }[],
|
|
100
|
+
allowFreeform?: boolean,
|
|
101
|
+
}); // { optionId?: string; text?: string }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`ask` publishes an `input.requested` event on the session — rendered the way channels render
|
|
105
|
+
`ask_question` and tool approvals — and returns the hook the answer resumes, the way `createHook`
|
|
106
|
+
returns one. Awaiting it suspends the run until a response arrives. Because it is a hook, it composes
|
|
107
|
+
with the SDK's own constructs; race it against a deadline:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const pending = ask(ctx, { prompt: `Deploy ${service}?`, options: APPROVE_OR_CANCEL });
|
|
111
|
+
const answer = await Promise.race([pending, sleep("4h")]);
|
|
112
|
+
if (answer === undefined) return { deployed: false, reason: "timed out" };
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- The request belongs to the run, not the turn. It stays answerable until it is answered or the run
|
|
116
|
+
ends. In a background tool that means long after the turn that started it.
|
|
117
|
+
- A request is answered once. Ask again for the next answer.
|
|
118
|
+
- Ending the run, by returning, throwing, or cancellation, withdraws its pending requests.
|
|
119
|
+
- Several requests may be outstanding at once.
|
|
120
|
+
- A response never steers. A new human message while a request is pending follows the session's
|
|
121
|
+
normal `turnPolicy`.
|
|
122
|
+
|
|
123
|
+
Compare the [`approval`](/docs/human-in-the-loop) policy, which gates the call before `execute` runs
|
|
124
|
+
and can only show the model's input. Both compose: `approval` before the run, `ask` inside it.
|
|
125
|
+
|
|
126
|
+
## Report progress: `yield`
|
|
127
|
+
|
|
128
|
+
A workflow body may be an async generator. Each `yield` is a durable progress snapshot; the return
|
|
129
|
+
value is the result, or the last `yield` when the body returns nothing.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
async *execute({ service }, ctx) {
|
|
133
|
+
"use workflow";
|
|
134
|
+
yield { status: "planning" };
|
|
135
|
+
const plan = await planDeploy(service);
|
|
136
|
+
yield { status: "deploying" };
|
|
137
|
+
return { deployed: true, url: await applyDeploy(plan) };
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For a waiting tool each `yield` streams as an `action.partial` event, last-write-wins by tool call
|
|
142
|
+
id, and never enters model history — the same contract as an in-process generator tool. For a
|
|
143
|
+
background tool each `yield` wakes the owning agent with a note. Returning ends the run with the
|
|
144
|
+
result; throwing ends it with the failure.
|
|
145
|
+
|
|
146
|
+
## Cancel and clean up: `ctx.abortSignal`
|
|
147
|
+
|
|
148
|
+
`ctx.abortSignal` aborts when the run is cancelled: a steered turn for a waiting tool, `task_cancel`
|
|
149
|
+
or the session ending for a background one. It is durable — it survives replay, and a step that
|
|
150
|
+
receives it observes the abort. Pass it into the steps that should stop, and clean up in
|
|
151
|
+
`try/finally`:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
async execute({ projectId }, ctx) {
|
|
155
|
+
"use workflow";
|
|
156
|
+
const jobId = await submitRender(projectId);
|
|
157
|
+
try {
|
|
158
|
+
return await waitForRender(jobId, ctx.abortSignal);
|
|
159
|
+
} finally {
|
|
160
|
+
if (ctx.abortSignal.aborted) await abortRender(jobId);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
After the signal fires, the run waits up to 30 seconds for the body to finish unwinding, then ends
|
|
166
|
+
as cancelled whether or not it did. A body parked on a hook or a `sleep` does not observe the signal;
|
|
167
|
+
it is abandoned when the grace period ends. Steps that received the signal are how you clean up
|
|
168
|
+
first.
|
|
169
|
+
|
|
170
|
+
## Flows
|
|
171
|
+
|
|
172
|
+
### Approve with a deadline and an escalation
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
async execute({ service }, ctx) {
|
|
176
|
+
"use workflow";
|
|
177
|
+
|
|
178
|
+
const plan = await planDeploy(service);
|
|
179
|
+
const pending = ask(ctx, { prompt: `Deploy ${service}?`, display: "confirmation", options: APPROVE_OR_CANCEL });
|
|
180
|
+
|
|
181
|
+
let answer = await Promise.race([pending, sleep("4h")]);
|
|
182
|
+
if (answer === undefined) {
|
|
183
|
+
await pageOnCall(service);
|
|
184
|
+
answer = await Promise.race([pending, sleep("20h")]);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (answer === undefined) return { deployed: false, reason: "timed out" };
|
|
188
|
+
if (answer.optionId !== "approve") return { deployed: false, reason: "rejected" };
|
|
189
|
+
return { deployed: true, url: await applyDeploy(plan) };
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
One request stays on the channel the whole time. `sleep` is the deadline, `pageOnCall` is a step,
|
|
194
|
+
and returning withdraws the request.
|
|
195
|
+
|
|
196
|
+
### Wait for an external system to call back
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import { createWebhook, FatalError } from "workflow";
|
|
200
|
+
|
|
201
|
+
export default defineTool({
|
|
202
|
+
description: "Render a video. Returns the URL once the render farm finishes.",
|
|
203
|
+
inputSchema: z.object({ projectId: z.string() }),
|
|
204
|
+
async execute({ projectId }) {
|
|
205
|
+
"use workflow";
|
|
206
|
+
|
|
207
|
+
const done = createWebhook();
|
|
208
|
+
const jobId = await submitRender(projectId, done.url);
|
|
209
|
+
const callback = await done;
|
|
210
|
+
const { status, url } = await callback.json();
|
|
211
|
+
|
|
212
|
+
if (status !== "ok") throw new FatalError(`Render ${jobId} failed: ${status}`);
|
|
213
|
+
return { url };
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`createWebhook` mints a URL under `/.well-known/workflow/v1/webhook/` that eve serves. The external
|
|
219
|
+
system posts to it when it is done. Nothing runs in between.
|
|
220
|
+
|
|
221
|
+
### Ask now, act when answered
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
import { ask } from "eve/workflow";
|
|
225
|
+
|
|
226
|
+
export default defineTool({
|
|
227
|
+
description: "Request approval to refund an order, then issue the refund once approved.",
|
|
228
|
+
inputSchema: z.object({ orderId: z.string(), amount: z.number() }),
|
|
229
|
+
execution: "background",
|
|
230
|
+
async execute({ orderId, amount }, ctx) {
|
|
231
|
+
"use workflow";
|
|
232
|
+
|
|
233
|
+
const decision = await ask(ctx, {
|
|
234
|
+
prompt: `Refund $${amount} on order ${orderId}?`,
|
|
235
|
+
display: "confirmation",
|
|
236
|
+
options: [
|
|
237
|
+
{ id: "approve", label: "Refund", style: "primary" },
|
|
238
|
+
{ id: "deny", label: "Deny" },
|
|
239
|
+
],
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
if (decision.optionId !== "approve") return { refunded: false };
|
|
243
|
+
return { refunded: true, receipt: await issueRefund(orderId, amount) };
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The model reports that approval is pending and the conversation continues. The approval card stays
|
|
249
|
+
on the channel. When it is answered, the refund runs and the agent is woken with the outcome.
|
|
250
|
+
|
|
251
|
+
### Remind me later
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
import { sleep } from "workflow";
|
|
255
|
+
|
|
256
|
+
export default defineTool({
|
|
257
|
+
description: "Remind the user about something after a delay.",
|
|
258
|
+
inputSchema: z.object({ note: z.string(), delay: z.string() }),
|
|
259
|
+
execution: "background",
|
|
260
|
+
async execute({ note, delay }) {
|
|
261
|
+
"use workflow";
|
|
262
|
+
await sleep(delay);
|
|
263
|
+
return { reminder: note };
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The session parks between the receipt and the wake. The agent receives the return value and relays
|
|
269
|
+
it.
|
|
270
|
+
|
|
271
|
+
## Semantics
|
|
272
|
+
|
|
273
|
+
One call, one result. A waiting tool's call resolves once, with the return value, the error, or a
|
|
274
|
+
cancellation. A background tool's call resolves once, with the receipt; everything after arrives as
|
|
275
|
+
separate session input.
|
|
276
|
+
|
|
277
|
+
While a waiting tool runs, the turn is parked. A `queue` message waits for it. A `steer` message
|
|
278
|
+
cancels the turn, which cancels the run, which withdraws its requests. Input responses never steer.
|
|
279
|
+
|
|
280
|
+
Background runs belong to the session. They survive turn completion and cancellation, appear in the
|
|
281
|
+
session's task index, can be cancelled with `task_cancel`, and are cancelled when the session ends.
|
|
282
|
+
|
|
283
|
+
Errors follow the SDK. A thrown error in a step retries per the step's policy; `FatalError` does
|
|
284
|
+
not. An error that escapes the body fails the run.
|
|
285
|
+
|
|
286
|
+
Identity follows the tool. The workflow id derives from the tool's path, so renaming or moving the
|
|
287
|
+
file creates a new workflow. Runs in flight finish on the deployment that started them; a run that
|
|
288
|
+
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.48.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
|
|
6
6
|
"keywords": [
|
|
@@ -181,6 +181,16 @@
|
|
|
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
|
+
"./workflow-modules": {
|
|
191
|
+
"eve-source": "./src/public/workflow-modules.d.ts",
|
|
192
|
+
"types": "./dist/src/public/workflow-modules.d.ts"
|
|
193
|
+
},
|
|
184
194
|
"./models/openai": {
|
|
185
195
|
"types": "./dist/src/public/models/openai/index.d.ts",
|
|
186
196
|
"import": "./dist/src/public/models/openai/index.js",
|
|
@@ -417,6 +427,7 @@
|
|
|
417
427
|
"@vercel/sandbox-delete": "npm:@vercel/sandbox@3.2.0",
|
|
418
428
|
"@vercel/sandbox-drives": "npm:@vercel/sandbox@2.10.0-beta.0",
|
|
419
429
|
"@vercel/sdk": "1.28.8",
|
|
430
|
+
"@workflow/builders": "5.0.0-beta.44",
|
|
420
431
|
"@workflow/core": "5.0.0-beta.43",
|
|
421
432
|
"@workflow/errors": "5.0.0-beta.17",
|
|
422
433
|
"@workflow/serde": "5.0.0-beta.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{parseWithNitroRolldownAst}from"#internal/bundler/nitro-rolldown.js";const UNSUPPORTED_WORKFLOW_DIRECTIVES=new Set([`use step`,`use workflow`]);async function assertNoWorkflowDirectivePrologue(t){let n=await parseWithNitroRolldownAst(t.filePath,t.source);if(!Array.isArray(n.body))throw Error(`Failed to parse authored module "${t.filePath}".`);for(let e of n.body){if(typeof e.directive!=`string`)break;if(UNSUPPORTED_WORKFLOW_DIRECTIVES.has(e.directive))throw Error(`Authored module "${t.filePath}" contains an actual "${e.directive}" directive. Workflow directives are reserved for eve-generated workflow entrypoints.`)}}export{assertNoWorkflowDirectivePrologue};
|