eve 0.74.0 → 0.75.1
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 +34 -0
- package/dist/src/channel/auth/result.d.ts +4 -0
- package/dist/src/channel/auth/result.js +1 -0
- package/dist/src/channel/types.d.ts +14 -2
- package/dist/src/chunks/{use-eve-agent-mP0M7SrL.js → use-eve-agent-B2Kne9z6.js} +7 -2
- package/dist/src/chunks/{use-eve-agent-DOOXadF0.js → use-eve-agent-DK_T88EP.js} +7 -2
- package/dist/src/cli/commands/deploy.js +1 -1
- package/dist/src/cli/commands/integration-connect.d.ts +2 -0
- package/dist/src/cli/commands/integration-connect.js +1 -1
- package/dist/src/cli/commands/integration-setup.js +1 -1
- package/dist/src/cli/commands/link.d.ts +2 -1
- package/dist/src/cli/commands/link.js +1 -1
- package/dist/src/cli/commands/registry-declared-setups.d.ts +19 -0
- package/dist/src/cli/commands/registry-declared-setups.js +1 -1
- package/dist/src/cli/commands/registry-recovery.d.ts +3 -1
- package/dist/src/cli/commands/registry-recovery.js +1 -1
- package/dist/src/cli/commands/registry.d.ts +12 -4
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/commands/vercel-non-interactive.d.ts +6 -4
- package/dist/src/cli/commands/vercel-non-interactive.js +1 -1
- package/dist/src/cli/dev/tui/registry-result-message.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +2 -0
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/client/index.d.ts +1 -0
- package/dist/src/client/session.d.ts +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +1 -1
- package/dist/src/client/types.d.ts +6 -0
- package/dist/src/compiled/.vendor-stamp.json +8 -8
- package/dist/src/compiled/@eve/catalog/index.js +1 -1
- package/dist/src/compiled/@workflow/core/global.d.ts +10 -0
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/private.d.ts +11 -0
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +36 -8
- package/dist/src/compiled/@workflow/core/runtime/helpers.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime/lifecycle-hooks.d.ts +10 -6
- package/dist/src/compiled/@workflow/core/runtime/out-of-band-observation.d.ts +159 -0
- package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +28 -4
- package/dist/src/compiled/@workflow/core/runtime.js +4 -4
- package/dist/src/compiled/@workflow/core/serialization.js +1 -1
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world-local/index.js +5 -5
- package/dist/src/compiled/@workflow/world-vercel/index.js +4 -4
- package/dist/src/compiled/_chunks/workflow/{attribute-changes-CSqvJx6j.js → attribute-changes-BW-kbMMn.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/dist-CyBgVS7g.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{helpers-BXCuoPUb.js → helpers-DlLD3ov_.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/private-tQUuwBoQ.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{resume-hook-CvENCrxc.js → resume-hook-DMsV_b4n.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{run-8pLWuR2U.js → run-DzdAqdb1.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{serialization-vDozzDhh.js → serialization-DPdYS_w2.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/sleep-BY6leHh8.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{token-BKeK6DmC.js → token-D5ugC3PI.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{token-util-CddTZ_ef.js → token-util-Bla5Z0G9.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/undici-D-ILjOKD.js +95 -0
- package/dist/src/compiled/_chunks/workflow/{wait-until-A344L2AG.js → wait-until-xbRRDuUf.js} +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +18 -12
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/dynamic-connection-lifecycle.d.ts +6 -0
- package/dist/src/context/dynamic-connection-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +4 -1
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/providers/sandbox.js +1 -1
- package/dist/src/context/providers/tool-stubs-key.d.ts +8 -0
- package/dist/src/context/providers/tool-stubs-key.js +1 -0
- package/dist/src/context/providers/tool-stubs.d.ts +10 -0
- package/dist/src/context/providers/tool-stubs.js +1 -0
- package/dist/src/context/run-step.js +1 -1
- package/dist/src/evals/index.d.ts +1 -0
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/session-manager.d.ts +2 -0
- package/dist/src/evals/session-manager.js +1 -1
- package/dist/src/eve-channel/create-request.d.ts +2 -0
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/execution/agent-sessions/context.d.ts +2 -0
- package/dist/src/execution/agent-sessions/context.js +1 -1
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/dynamic-connection-recovery.d.ts +14 -0
- package/dist/src/execution/dynamic-connection-recovery.js +1 -0
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/forward-session-input.js +1 -1
- package/dist/src/execution/legacy-session/authorization.js +1 -1
- package/dist/src/execution/legacy-session/completion-step.js +1 -1
- package/dist/src/execution/legacy-session/inbox.js +1 -1
- package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
- package/dist/src/execution/ndjson-stream.d.ts +6 -6
- package/dist/src/execution/ndjson-stream.js +3 -3
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/ensure.d.ts +3 -1
- package/dist/src/execution/sandbox/ensure.js +1 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/admission.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/end-sandbox-step.d.ts +12 -0
- package/dist/src/execution/session/end-sandbox-step.js +1 -0
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -1
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/timeout-steps.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session-inbox/inbox.d.ts +6 -1
- package/dist/src/execution/session-inbox/inbox.js +1 -1
- package/dist/src/execution/session-inbox/release-step.js +1 -1
- package/dist/src/execution/session-inbox/resume.d.ts +2 -1
- package/dist/src/execution/session-inbox/resume.js +1 -1
- package/dist/src/execution/session-workflow-tool-run.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/model-step.js +1 -1
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/tasks/table.d.ts +7 -1
- package/dist/src/execution/tasks/table.js +1 -1
- package/dist/src/execution/tool-stubs/playback.d.ts +11 -0
- package/dist/src/execution/tool-stubs/playback.js +1 -0
- package/dist/src/execution/tool-stubs/steps.d.ts +18 -0
- package/dist/src/execution/tool-stubs/steps.js +1 -0
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/connection-tools.d.ts +0 -6
- package/dist/src/execution/tools/connection-tools.js +2 -2
- package/dist/src/execution/tools/workflow/authorization-completion.js +1 -1
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/serve.js +1 -1
- package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-webhook-route.js +1 -1
- package/dist/src/harness/compaction/engine.d.ts +8 -19
- package/dist/src/harness/compaction/engine.js +1 -1
- package/dist/src/harness/compaction/step.d.ts +7 -1
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/coordination.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +2 -0
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +9 -1
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +2 -3
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/model.d.ts +4 -5
- package/dist/src/harness/model-call/model.js +1 -1
- package/dist/src/harness/model-call/request.d.ts +1 -2
- package/dist/src/harness/model-call/request.js +1 -1
- package/dist/src/harness/model-call/retry.d.ts +1 -1
- package/dist/src/harness/model-call/retry.js +1 -1
- package/dist/src/harness/model-call/run.js +1 -1
- package/dist/src/harness/model-call/tools.d.ts +3 -4
- package/dist/src/harness/model-call/tools.js +1 -1
- package/dist/src/harness/model-call/usage.js +1 -1
- package/dist/src/harness/model-profile.d.ts +23 -0
- package/dist/src/harness/model-profile.js +1 -0
- package/dist/src/harness/prompt-cache.d.ts +5 -53
- package/dist/src/harness/prompt-cache.js +1 -1
- package/dist/src/harness/provider-safety.d.ts +3 -5
- package/dist/src/harness/provider-safety.js +1 -1
- package/dist/src/harness/provider-tools.d.ts +5 -13
- package/dist/src/harness/provider-tools.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +17 -6
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/session-machine/current.d.ts +4 -0
- package/dist/src/harness/session-machine/current.js +1 -1
- package/dist/src/harness/step/after-model.js +1 -1
- package/dist/src/harness/step/context.d.ts +7 -2
- package/dist/src/harness/step/context.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +2 -3
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-call-io.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +2 -3
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +12 -0
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/gateway.d.ts +0 -13
- package/dist/src/internal/gateway.js +1 -1
- package/dist/src/internal/invocation/workflow-execution.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow/cancel-expired-development-run.js +1 -1
- package/dist/src/protocol/routes.d.ts +4 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/auth.d.ts +21 -4
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/mcp.js +1 -1
- package/dist/src/public/schedules/providers/in-memory.js +1 -1
- package/dist/src/public/schedules/providers/vercel.js +1 -1
- package/dist/src/public/schedules/subscription.d.ts +0 -1
- package/dist/src/sandbox/state.d.ts +1 -0
- package/dist/src/self-modification/extension/subagents/agent/instructions.js +1 -1
- package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.js +1 -1
- package/dist/src/setup/flows/registry-session.d.ts +10 -2
- package/dist/src/setup/flows/registry-session.js +1 -1
- package/dist/src/setup/flows/registry.d.ts +2 -0
- package/dist/src/setup/flows/registry.js +1 -1
- package/dist/src/setup/integrations/shared/prerequisite.d.ts +8 -0
- package/dist/src/setup/integrations/shared/prerequisite.js +1 -1
- package/dist/src/setup/registry-setup-client.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +3 -2
- package/dist/src/setup/scaffold/create/web-template.js +383 -411
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/vercel-project.d.ts +2 -3
- package/dist/src/setup/vercel-project.js +0 -0
- package/dist/src/shared/sandbox-provider.d.ts +9 -2
- package/dist/src/subagents/adapter.d.ts +3 -2
- package/dist/src/subagents/adapter.js +1 -1
- package/dist/src/subagents/callback-route.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +4 -3
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/subagents/parent-notification.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tool-stubs/execute.d.ts +13 -0
- package/dist/src/tool-stubs/execute.js +1 -0
- package/dist/src/tool-stubs/output.d.ts +4 -0
- package/dist/src/tool-stubs/output.js +1 -0
- package/dist/src/tool-stubs/playback.d.ts +15 -0
- package/dist/src/tool-stubs/playback.js +1 -0
- package/dist/src/tool-stubs/rules.d.ts +3 -0
- package/dist/src/tool-stubs/rules.js +1 -0
- package/dist/src/tool-stubs/schema.d.ts +4 -0
- package/dist/src/tool-stubs/schema.js +1 -0
- package/dist/src/tool-stubs/target.d.ts +8 -0
- package/dist/src/tool-stubs/target.js +1 -0
- package/dist/src/tool-stubs/types.d.ts +56 -0
- package/dist/src/tool-stubs/types.js +1 -0
- package/dist/src/tool-stubs/validate-targets.d.ts +6 -0
- package/dist/src/tool-stubs/validate-targets.js +1 -0
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +2 -2
- package/docs/evals/meta.json +10 -1
- package/docs/evals/overview.mdx +2 -0
- package/docs/evals/tool-stubs.mdx +257 -0
- package/docs/extensions.md +1 -1
- package/docs/guides/auth-and-route-protection.md +25 -0
- package/docs/guides/dynamic-capabilities.md +10 -3
- package/docs/guides/frontend/nextjs.mdx +17 -4
- package/docs/sandbox/index.mdx +10 -2
- package/docs/subagents/index.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tools/overview.mdx +8 -4
- package/docs/tools/workflows.mdx +15 -7
- package/package.json +6 -6
- package/dist/src/compiled/_chunks/workflow/dist-DmXynLVH.js +0 -1
- package/dist/src/compiled/_chunks/workflow/private-Dlf90Zvn.js +0 -1
- package/dist/src/compiled/_chunks/workflow/signal-exit-iIdjQcCK.js +0 -95
- package/dist/src/compiled/_chunks/workflow/sleep-BMqbraZM.js +0 -1
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Tool Stubs"
|
|
3
|
+
description: "Define tool outcomes and outcome sequences in your evals."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Pass `stubs` when creating an eval session to replace selected tool executions with JSON responses. The same rules work against local and deployed agents, without deploying mock functions or keeping the runner connected to answer tool calls.
|
|
7
|
+
|
|
8
|
+
Stubs specify what tools return. [Assertions](./assertions) check what the agent does and tells the user. Unused stubs produce a warning without failing the eval.
|
|
9
|
+
|
|
10
|
+
## Author an eval
|
|
11
|
+
|
|
12
|
+
```ts title="evals/complete-task.eval.ts"
|
|
13
|
+
import { defineEval } from "eve/evals";
|
|
14
|
+
|
|
15
|
+
export default defineEval({
|
|
16
|
+
async test(t) {
|
|
17
|
+
const session = await t.session({
|
|
18
|
+
stubs: [
|
|
19
|
+
{
|
|
20
|
+
id: "tasks",
|
|
21
|
+
tool: "list_tasks",
|
|
22
|
+
outcomes: [
|
|
23
|
+
{
|
|
24
|
+
response: {
|
|
25
|
+
tasks: [
|
|
26
|
+
{ id: "milk", title: "Buy milk" },
|
|
27
|
+
{ id: "dog", title: "Walk dog" },
|
|
28
|
+
{ id: "rent", title: "Pay rent" },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
response: {
|
|
34
|
+
tasks: [
|
|
35
|
+
{ id: "dog", title: "Walk dog" },
|
|
36
|
+
{ id: "rent", title: "Pay rent" },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "complete-milk",
|
|
44
|
+
tool: "complete_task",
|
|
45
|
+
match: { task_id: { const: "milk" } },
|
|
46
|
+
outcome: { response: { success: true } },
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const first = await session.send("What tasks do I have?");
|
|
52
|
+
first.expectOk();
|
|
53
|
+
first.calledTool("list_tasks", { count: 1 });
|
|
54
|
+
first.messageIncludes("Buy milk");
|
|
55
|
+
|
|
56
|
+
const second = await session.send("Complete Buy milk, then list my remaining tasks.");
|
|
57
|
+
second.expectOk();
|
|
58
|
+
second.calledTool("complete_task", { input: { task_id: "milk" }, count: 1 });
|
|
59
|
+
second.toolOrder(["complete_task", "list_tasks"]);
|
|
60
|
+
second.messageIncludes("Walk dog");
|
|
61
|
+
second.messageIncludes("Pay rent");
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Use your agent's actual tool names and response shapes. The client accepts the same option on `client.sessions.create({ stubs })` or `client.sessions.create({ message, stubs })`.
|
|
67
|
+
|
|
68
|
+
These responses describe a sequence, not a simulated task database. The second `list_tasks` call returns two tasks even if `complete_task` was never called. The completion and order assertions check that the agent actually requested the write; testing a real database update requires the real tool.
|
|
69
|
+
|
|
70
|
+
## Stub fields
|
|
71
|
+
|
|
72
|
+
| Field | Meaning |
|
|
73
|
+
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
+
| `id` | Your session-unique rule identifier. eve uses it to track this rule's response sequence. It is neither a tool name nor a tool-call ID. |
|
|
75
|
+
| `tool` | The existing tool's name, optionally qualified by its local subagent path. |
|
|
76
|
+
| `match` | Optional input-property constraints, expressed as JSON Schema. Omit it or use `{}` to match any valid input. |
|
|
77
|
+
| `outcome` | One outcome repeated on every matching call, such as `{ response: { tasks: [] } }`. |
|
|
78
|
+
| `outcomes` | A nonempty array of outcomes returned in sequence. Use exactly one of `outcome` or `outcomes`. |
|
|
79
|
+
|
|
80
|
+
Each outcome contains exactly one of `response` or `throw`. `response` holds the JSON returned by the tool; `throw` describes an error raised immediately instead. The enclosing outcome is not part of the tool's response. Top-level `response` and `responses` are not accepted.
|
|
81
|
+
|
|
82
|
+
Exposing rule IDs and response positions in traces is a follow-up: [AX-5157](https://linear.app/vercel/issue/AX-5157).
|
|
83
|
+
|
|
84
|
+
Stubs are plain JSON and can be shared between evals:
|
|
85
|
+
|
|
86
|
+
```ts title="evals/fixtures/tasks.ts"
|
|
87
|
+
import type { ToolStub } from "eve/evals";
|
|
88
|
+
|
|
89
|
+
export const taskStubs = [
|
|
90
|
+
{ id: "tasks", tool: "list_tasks", outcome: { response: { tasks: [] } } },
|
|
91
|
+
] satisfies readonly ToolStub[];
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Pass the fixture to `t.session({ stubs: taskStubs })`. Each session has its own sequence position. Both `eve/evals` and `eve/client` export `ToolStub` and `ToolStubOutcome`. These types check the JSON contract; they do not infer the response type from your tool definition.
|
|
95
|
+
|
|
96
|
+
## Match tool arguments
|
|
97
|
+
|
|
98
|
+
**Rules are evaluated from top to bottom. The first matching stub wins.** Put specific rules before an unconditional fallback:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const stubs = [
|
|
102
|
+
{
|
|
103
|
+
id: "milk",
|
|
104
|
+
tool: "complete_task",
|
|
105
|
+
match: { task_id: { const: "milk" } },
|
|
106
|
+
outcome: { response: { success: true } },
|
|
107
|
+
},
|
|
108
|
+
{ id: "other-tasks", tool: "complete_task", outcome: { response: { success: false } } },
|
|
109
|
+
];
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
A call for milk receives success; other valid calls receive the fallback. Reversing these rules makes the unconditional rule win every time. If no rule matches, eve executes the real tool. A broken stub or failure processing its response fails the eval, even if the agent recovers. An intentional `throw` outcome is a normal tool failure that the eval can assert on. Neither falls back to real execution.
|
|
113
|
+
|
|
114
|
+
If eve cannot record an output-processing failure, it cancels the workflow serving stubs. The original tool error or fallback is preserved, but verification rejects the eval. Failed or cancelled stub sessions cannot pass verification.
|
|
115
|
+
|
|
116
|
+
Every property listed in `match` must exist and satisfy its constraint. Extra top-level properties are allowed:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"id": "open-tasks",
|
|
121
|
+
"tool": "search_tasks",
|
|
122
|
+
"match": {
|
|
123
|
+
"filter": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"properties": { "status": { "const": "open" } },
|
|
126
|
+
"required": ["status"]
|
|
127
|
+
},
|
|
128
|
+
"query": { "type": "string", "pattern": "\\b(?i:milk)\\b" },
|
|
129
|
+
"tags": { "type": "array", "contains": { "const": "urgent" } }
|
|
130
|
+
},
|
|
131
|
+
"outcome": { "response": { "tasks": ["Buy milk"] } }
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Nested properties are optional unless listed in `required`. Matching does not coerce values, apply defaults, or change arguments. The real tool schema validates input before replacement; normal approvals and output processing still apply.
|
|
136
|
+
|
|
137
|
+
Constraints use a reference-free subset of JSON Schema 2020-12: types, scalar `const` and `enum`, string patterns and bounds, numeric bounds, array items/contains, object properties/required/additionalProperties, and logical/conditional schemas. `pattern` uses JavaScript regular expressions. Schema validation, regex syntax checks, and validator initialization run before session creation.
|
|
138
|
+
|
|
139
|
+
Unsupported constraints fail setup: `patternProperties`, references, formats, `multipleOf`, `minContains`, `maxContains`, `uniqueItems`, dependencies, and object/array values in `const` or `enum`. Nested `properties` and `required` cannot use inherited property names such as `constructor` or `toString`. Use nested properties or array items to match structured values.
|
|
140
|
+
|
|
141
|
+
Unknown static tool names, invalid local-agent paths, and paths into remote agents fail session creation. Dynamic names and connection operations are checked where possible; unresolved names are allowed. After the eval, unused rule IDs are reported as warnings. Use tool assertions when a call must happen.
|
|
142
|
+
|
|
143
|
+
Configuration is limited to 100 rules, 20,000 JSON nodes, nesting depth 32, and approximately one million characters. The `__proto__` property name is reserved.
|
|
144
|
+
|
|
145
|
+
## Sequences and session scope
|
|
146
|
+
|
|
147
|
+
`outcome` repeats on every matching call. `outcomes` advances on each new matching call, then repeats its final entry. For example, `outcomes: [{ response: "pending" }, { response: "completed" }]` returns `"pending"` once and `"completed"` thereafter. Only the selected rule advances; exhaustion never selects a later rule.
|
|
148
|
+
|
|
149
|
+
Two calls within one agent turn consume two entries. Later turns continue the same sequence. Calls awaiting or denied approval do not consume entries. Each session supports up to 10,000 recorded calls.
|
|
150
|
+
|
|
151
|
+
Choose the rules at session creation; they stay fixed for that session. Local subagents share playback through explicit tool paths, and deployment handoffs preserve it. An independent session starts at the first response.
|
|
152
|
+
|
|
153
|
+
eve's transparent internal workflow replay reuses the recorded outcome without consuming another entry.
|
|
154
|
+
|
|
155
|
+
Parallel calls consume responses in arrival order, which can vary. Use separate argument matchers when particular arguments must receive particular responses.
|
|
156
|
+
|
|
157
|
+
## Permit tool replacement
|
|
158
|
+
|
|
159
|
+
Tool replacement is denied by default, including in development. With [Vercel OIDC](../guides/auth-and-route-protection#verceloidc), put the permission on the eval runner's verified subject:
|
|
160
|
+
|
|
161
|
+
```ts title="agent/channels/eve.ts"
|
|
162
|
+
import { vercelOidc, vercelSubject } from "eve/channels/auth";
|
|
163
|
+
import { eveChannel } from "eve/channels/eve";
|
|
164
|
+
|
|
165
|
+
export default eveChannel({
|
|
166
|
+
auth: [
|
|
167
|
+
vercelOidc({
|
|
168
|
+
subjects: [
|
|
169
|
+
vercelSubject({ teamSlug: "acme", projectName: "app" }),
|
|
170
|
+
{
|
|
171
|
+
subject: vercelSubject({ teamSlug: "acme", projectName: "eval-runner" }),
|
|
172
|
+
allowToolStubs: true,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
}),
|
|
176
|
+
],
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Both projects can authenticate; only the eval runner receives replacement permission. `vercelSubject` defaults to production; pass `environment: "*"` to include all environments. The target's server configuration supplies the grant after token verification. Request JSON cannot grant permission, and user principals do not inherit project grants.
|
|
181
|
+
|
|
182
|
+
Custom authenticators can return the same `allowToolStubs: true` after verifying the caller. See [authentication and route protection](../guides/auth-and-route-protection#tool-replacement-permission) for the grant rules and a local development example.
|
|
183
|
+
|
|
184
|
+
Permission is checked at session creation before identity projection. Later messages and result reads use normal channel authentication. Anyone your channel admits to an existing session can use its stubs. Your application's session-access policy must provide the required isolation; an isolated eval deployment can use the same agent code.
|
|
185
|
+
|
|
186
|
+
The stub verification endpoint also requires `allowToolStubs`, checked before reading workflow status.
|
|
187
|
+
|
|
188
|
+
## Supported tools and subagents
|
|
189
|
+
|
|
190
|
+
Stubs replace execution of existing ordinary, dynamic, and workflow tools. They retain the real tool's input schema, approvals, and output processing. A stub does not register a new tool or make it visible to the model.
|
|
191
|
+
|
|
192
|
+
Ordinary tools with configured stub rules can emit an extra `action.partial` containing the final response. This also applies when no rule matches and the real tool returns a non-streaming result. The final `action.result` remains correct, and real streaming still delivers progress. Use `action.result` for final-result assertions. Removing the extra event is tracked in [AX-5164](https://linear.app/vercel/issue/AX-5164).
|
|
193
|
+
|
|
194
|
+
### Subagents
|
|
195
|
+
|
|
196
|
+
Stubbing a delegation tool returns its configured result without starting the subagent. Persistent tools implemented with `serve`, including the built-in `agent`, require an unconditional stub: omit `match` or use `{}`. Mixing real and mocked calls to the same persistent tool is unsupported.
|
|
197
|
+
|
|
198
|
+
To let a local subagent run but replace its tools, use `/` to qualify the delegation path:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const stubs = [
|
|
202
|
+
{ id: "root-tasks", tool: "list_tasks", outcome: { response: ["Root task"] } },
|
|
203
|
+
{ id: "research-tasks", tool: "researcher/list_tasks", outcome: { response: ["Research task"] } },
|
|
204
|
+
{ id: "nested-tasks", tool: "researcher/assistant/list_tasks", outcome: { response: [] } },
|
|
205
|
+
];
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`researcher` replaces the whole delegation; `researcher/list_tasks` replaces only that subagent's list tool. The built-in `agent` uses `agent/list_tasks`. Model-visible names stay unchanged. A root rule never implicitly matches a subagent's same-named tool.
|
|
209
|
+
|
|
210
|
+
Repeated subagent sessions at the same path share that rule's sequence. Different paths use different rules. Remote agents do not receive the configuration; replace their whole delegation tool instead.
|
|
211
|
+
|
|
212
|
+
### Connections and provider tools
|
|
213
|
+
|
|
214
|
+
Use the qualified operation name, such as `linear__list_issues` or `researcher/linear__list_issues`. Put operation arguments in `match` and its JSON result in `outcome.response`, or in each sequence entry's `response`.
|
|
215
|
+
|
|
216
|
+
Connection authentication and discovery stay live so eve can validate the operation and its arguments. Stubs do not provide an offline connection. The framework's `connection_search` and `connection_execute` tools cannot themselves be replaced.
|
|
217
|
+
|
|
218
|
+
Tools executed by the model provider, such as provider-hosted web search, have no eve executor to replace. A search tool implemented in your own agent can be stubbed.
|
|
219
|
+
|
|
220
|
+
## Inject tool errors
|
|
221
|
+
|
|
222
|
+
Use `throw` to test how the agent handles a failed tool call. Mix errors and responses to test recovery:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
const stubs = [
|
|
226
|
+
{
|
|
227
|
+
id: "tasks",
|
|
228
|
+
tool: "list_tasks",
|
|
229
|
+
outcomes: [
|
|
230
|
+
{ throw: { name: "TimeoutError", message: "Task service timed out" } },
|
|
231
|
+
{ response: { tasks: [] } },
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
];
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`throw.message` is required. `throw.name` is optional and defaults to `"Error"`. eve creates an ordinary JavaScript `Error` with that name and message; it does not instantiate custom error classes. `TimeoutError` reports a timeout immediately, without delaying the call or testing an actual deadline.
|
|
238
|
+
|
|
239
|
+
Ordinary tools and connection operations expose the error message to the model, without the error name. Workflow task errors also retain the name. Put any details the model needs to act on in `message`.
|
|
240
|
+
|
|
241
|
+
Use `outcome: { throw: { message: "Service unavailable" } }` to fail every matching call. A sequence consumes one entry per new call, whether it returns or throws, and repeats its final entry. Workflow replay reuses the same recorded outcome.
|
|
242
|
+
|
|
243
|
+
An injected exception follows the tool's normal error handling. Ordinary and blocking workflow calls are recorded as failed; background tasks report failure when they settle. The model can report the failure or try again. Assert the failed call explicitly:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
const turn = await session.send(
|
|
247
|
+
"List my tasks once. If the service fails, explain the failure and wait for me to retry.",
|
|
248
|
+
);
|
|
249
|
+
turn.expectOk();
|
|
250
|
+
turn.calledTool("list_tasks", { status: "failed", count: 1 });
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The eval can pass when the agent handles the failure correctly. `noFailedActions()` still rejects the failed call, so use explicit assertions for expected failures. Stub infrastructure and response-processing failures still fail verification.
|
|
254
|
+
|
|
255
|
+
This works for ordinary tools, workflow tools, whole-agent replacements, and qualified connection operations. An exception in a persistent workflow tool ends that task; retry with a new call, rather than its failed task ID. Normal approvals apply before an outcome is consumed.
|
|
256
|
+
|
|
257
|
+
Returning `{ response: { error: "timeout" } }` remains ordinary JSON. Only `throw` raises an exception.
|
package/docs/extensions.md
CHANGED
|
@@ -178,7 +178,7 @@ A mount gives the extension's contributions a namespace. Updating the package up
|
|
|
178
178
|
|
|
179
179
|
### Install the package
|
|
180
180
|
|
|
181
|
-
Install the extension with the package manager already used by the consumer's agent project.
|
|
181
|
+
Install the extension with the package manager already used by the consumer's agent project. For example, in a pnpm project:
|
|
182
182
|
|
|
183
183
|
```bash
|
|
184
184
|
pnpm add @acme/crm
|
|
@@ -113,6 +113,8 @@ Verifies a bearer JWT against the [Vercel OIDC issuer](https://vercel.com/docs/o
|
|
|
113
113
|
|
|
114
114
|
Auth fails closed: routes reject unauthenticated traffic by default, and the OIDC user branch verifies `external_sub` against `VERCEL_PROJECT_ID` and the deployment environment, returning `false` when either is unset. An external-subject token cannot authenticate on a deployment that hasn't pinned its project.
|
|
115
115
|
|
|
116
|
+
Subject entries can also be objects: `{ subject: vercelSubject({ teamSlug: "acme", projectName: "eval-runner" }), allowToolStubs: true }`. This explicitly permits that verified service/runtime caller to create [stubbed eval sessions](../evals/tool-stubs). Plain subject strings and implicit current-project acceptance grant ordinary access only. Custom authenticators can return the same permission in their authentication result; it is not part of persisted or forwarded session identity.
|
|
117
|
+
|
|
116
118
|
#### `subjects` patterns and `vercelSubject(...)`
|
|
117
119
|
|
|
118
120
|
Each `subjects` entry is matched against the token's `sub` claim, which Vercel shapes as `owner:<team>:project:<name>:environment:<env>`. Hand-writing that string is a footgun: a typo silently rejects every caller, and an over-broad `*` wildcard silently lets unrelated ones in. Build the pattern with `vercelSubject(...)` instead. It rejects malformed input at construction time, and defaults `environment` to `"production"` when you omit it, so an unspecified environment cannot silently accept preview or development tokens:
|
|
@@ -298,6 +300,29 @@ Use the principal on `auth.current` (or `auth.initiator`) to scope tools, resolv
|
|
|
298
300
|
|
|
299
301
|
Route auth does not enforce session ownership. If multiple users or tenants can reach the same route, you must implement the per-user, per-tenant, or per-session authorization your application requires.
|
|
300
302
|
|
|
303
|
+
## Tool replacement permission
|
|
304
|
+
|
|
305
|
+
Creating a [stubbed eval session](../evals/tool-stubs) requires an explicit `allowToolStubs: true` in the verified route authentication result. The target's server configuration grants permission; request JSON cannot. With `vercelOidc`, put the grant on a `subjects` entry as shown above. Any matching entry with the grant permits replacement; other entries do not revoke it. Implicit current-project acceptance and user principals do not inherit project grants.
|
|
306
|
+
|
|
307
|
+
Custom authenticators return the same grant after verifying their caller. For example, this alternative channel permits stubs only in local development:
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
import { localDev } from "eve/channels/auth";
|
|
311
|
+
import { eveChannel } from "eve/channels/eve";
|
|
312
|
+
|
|
313
|
+
const authenticate = localDev();
|
|
314
|
+
export default eveChannel({
|
|
315
|
+
auth: async (request) => {
|
|
316
|
+
const caller = await authenticate(request);
|
|
317
|
+
return caller ? { ...caller, allowToolStubs: true } : null;
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
The channel checks the grant before forwarded-principal handling or `onMessage` projection. It removes the grant before using the identity for forwarding, audience classification, or session persistence. This is an authentication-result permission, not a session attribute.
|
|
323
|
+
|
|
324
|
+
Later messages, approvals, controls, and result reads use normal channel authentication. There is no additional creator-only rule or replacement-permission recheck. Anyone your channel admits to an existing session can use its configured stubs; apply the same application-specific session-access policy you need for ordinary sessions.
|
|
325
|
+
|
|
301
326
|
## Tool and connection auth
|
|
302
327
|
|
|
303
328
|
Tool and connection auth is how your agent reaches an external service that wants an interactive sign-in, like an OAuth MCP server. Connections declare `auth` on the connection definition. Tools should resolve providers inline with `ctx.getToken(provider)` and call `ctx.requireAuth(provider)` only when a downstream service rejects a token; eve drives the sign-in, caches the token per step, and re-runs the call once the caller authorizes.
|
|
@@ -221,9 +221,16 @@ same name; namespace one map key to remove the ambiguity.
|
|
|
221
221
|
|
|
222
222
|
Dynamic connections support `session.started` and `turn.started`. A turn result
|
|
223
223
|
replaces that file's session result for the turn, including when the turn
|
|
224
|
-
handler returns `null`. A throwing or invalid handler fails the
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
handler returns `null`. A throwing or invalid handler fails the current turn
|
|
225
|
+
and parks the session, so a later message can retry after the dependency
|
|
226
|
+
recovers. The failed lifecycle does not rebuild the registry, so a static
|
|
227
|
+
connection shadowed by the dynamic result cannot reappear as a fallback.
|
|
228
|
+
|
|
229
|
+
Recovery needs another message. eve does not keep the input from the failed
|
|
230
|
+
turn or replay it, so the caller must send it again once the dependency is
|
|
231
|
+
back. This applies to the first message of a session too. A scheduled run
|
|
232
|
+
whose resolver fails is not retried; the session stays idle until the next
|
|
233
|
+
scheduled run or message arrives.
|
|
227
234
|
|
|
228
235
|
eve may run the active session and turn handlers again when a parked turn
|
|
229
236
|
resumes or a durable step retries. This rebuilds live auth, header, approval,
|
|
@@ -11,21 +11,34 @@ Use this integration when Next.js owns the application's development and deploym
|
|
|
11
11
|
|
|
12
12
|
- The `eve` package installed in your project (`npm install eve@latest`).
|
|
13
13
|
- An existing eve agent directory. If you don't have one, start from [Getting Started](../../getting-started).
|
|
14
|
-
- A Next.js app, or
|
|
14
|
+
- A Next.js app, or an eve project where you want to generate one below.
|
|
15
15
|
|
|
16
16
|
## Add the generated Web Chat app
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Install the generated Next.js Web Chat app from a standalone agent project:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
eve add channel/web
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
For an agent workspace, select the member the chat should call:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
eve add channel/web --agent support
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The installer configures the chat for the selected agent. By default, it adds a shared Next.js
|
|
31
|
+
application under `apps/web`; if a root Web Chat app already exists, it configures that app instead.
|
|
32
|
+
For Next.js hosting, the installer wraps `next.config.ts` with `withEve()`. When setting up a new
|
|
33
|
+
app, choose **Next.js** to host the integration. The generated chat uses same-origin `/eve/v1/*`
|
|
34
|
+
routes for a standalone agent or `/eve/<name>/v1/*` routes for a workspace member. Running the
|
|
35
|
+
installer from a workspace root without selecting a member is not supported.
|
|
25
36
|
|
|
26
37
|
Before accepting production browser traffic, replace the generated placeholder authorization policy. See [Authenticate browser requests](./overview#authenticate-browser-requests).
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
To integrate an existing Next.js application without generating a chat UI, follow the steps below.
|
|
40
|
+
To deploy the frontend and agents as separate Vercel services, choose **Vercel services** during
|
|
41
|
+
setup instead; see the [workspace layout guidance](/docs/concepts/project-structure#configure-a-web-deployment).
|
|
29
42
|
|
|
30
43
|
## Wrap the Next.js config
|
|
31
44
|
|
package/docs/sandbox/index.mdx
CHANGED
|
@@ -182,6 +182,10 @@ export const AcmeSandbox = defineSandboxProvider<
|
|
|
182
182
|
const client = createAcmeClient(options);
|
|
183
183
|
|
|
184
184
|
return {
|
|
185
|
+
async onSessionEnd(_ctx, _artifact, state, { reason }) {
|
|
186
|
+
await client.delete({ id: state.remoteId, reason });
|
|
187
|
+
},
|
|
188
|
+
|
|
185
189
|
async prepare(ctx) {
|
|
186
190
|
const temporary = await client.createTemporary({
|
|
187
191
|
files: await ctx.files.list(),
|
|
@@ -213,7 +217,11 @@ export const AcmeSandbox = defineSandboxProvider<
|
|
|
213
217
|
});
|
|
214
218
|
```
|
|
215
219
|
|
|
216
|
-
`prepare()` returns the complete JSON-serializable artifact. Core calls `start()` once for a new durable sandbox session and persists its minimal JSON-compatible state. Process restarts call `resume()` with only the current context, that state, and the target deployment's exact artifact.
|
|
220
|
+
`prepare()` returns the complete JSON-serializable artifact. Core calls `start()` once for a new durable sandbox session and persists its minimal JSON-compatible state. Process restarts call `resume()` with only the current context, that state, and the target deployment's exact artifact.
|
|
221
|
+
|
|
222
|
+
`onSessionEnd()` is invoked when the durable session reaches a completed, expired, or failed terminal outcome. It receives the exact prepared artifact, persisted provider state, and a `reason` of `"completed"`, `"expired"`, or `"failed"`. Implement idempotent permanent cleanup from those values rather than depending on a live handle. eve retries the cleanup step and logs an exhausted failure without replacing the session's terminal outcome. A session that never opened a sandbox and a child that borrows its parent's sandbox do not call the hook.
|
|
223
|
+
|
|
224
|
+
Provider handles implement `onSandboxStop()`, `onRuntimeShutdown()`, and `onSandboxDelete()`. These handle-level methods cover authored stop or delete calls, process shutdown, and failed initialization; `onSessionEnd()` is the single provider hook for durable terminal session cleanup.
|
|
217
225
|
|
|
218
226
|
Open options belong to `start()` and are not serialized or passed to `resume()`. A provider must put any immutable option-derived data needed for reconnection in its session state. With the current immutable-state contract, `resume()` reconnects existing native state and fails if it is gone rather than recreating callback side effects. A custom provider may define start-only callback fields, but built-in providers initialize the sandbox in `defineSandbox()` after `open()`.
|
|
219
227
|
|
|
@@ -231,7 +239,7 @@ Preparation discovers authored files through `ctx.files`; core keeps project lay
|
|
|
231
239
|
|
|
232
240
|
## Lifecycle
|
|
233
241
|
|
|
234
|
-
Session-owned sandboxes persist across turns and deployments while their provider state remains available. `sandbox.stop()` stops compute without deleting persisted state; a later access resumes that state directly. `sandbox.delete()` clears provider state, so the next `ctx.getSandbox()` reruns the selector and starts a fresh sandbox from the current environment.
|
|
242
|
+
Session-owned sandboxes persist across turns and deployments while their provider state remains available. `sandbox.stop()` stops compute without deleting persisted state; a later access resumes that state directly. `sandbox.delete()` clears provider state, so the next `ctx.getSandbox()` reruns the selector and starts a fresh sandbox from the current environment. When the durable session reaches a terminal outcome, eve calls the provider's `onSessionEnd()` hook to release any remaining session-owned resources.
|
|
235
243
|
|
|
236
244
|
Changing sandbox source, preparation code, Dockerfile content, environment options, workspace resources, or skills produces a new environment generation. Existing durable sessions retain their recorded sandbox state; new sessions use the current generation.
|
|
237
245
|
|
package/docs/subagents/index.mdx
CHANGED
|
@@ -229,7 +229,7 @@ By default, a subagent named `researcher` collides with an authored tool named `
|
|
|
229
229
|
|
|
230
230
|
Do not rely on subagent delegation by itself as an approval boundary. Put sensitive tools behind `approval`, connection approval, route/session authorization, or other controls wherever those tools can be called.
|
|
231
231
|
|
|
232
|
-
Each delegated subagent spins up its own child session and stream. The parent stream carries the call's `task.started` and `task.settled` events, `agent.started` when the child session opens, plus interactive `input.requested`, `authorization.required`, and `authorization.completed` events proxied from descendants so the root channel can prompt the user. The parent emits `input.resolved` when it routes an answer back down to the descendant that asked. `task.settled` carries the child's reply as `output` when the call completes, or `error.message` when it fails, along with the same tool `name` and `kind: "agent"` as the call's `task.started`. To follow the child's other progress, pass the `agent.started` event to [`session.agent()`](./guides/client/streaming#follow-a-subagent) on a client session attached to the parent and follow the child with `stream()`. It reads `agent.started.data.streamPath`: the child's own session stream for a local child, or a parent-origin proxy for a remote child, which the parent authenticates to the remote deployment.
|
|
232
|
+
Each delegated subagent spins up its own child session and stream. The parent stream carries the call's `task.started` and `task.settled` events, `agent.started` when the child session opens, plus interactive `input.requested`, `authorization.required`, and `authorization.completed` events proxied from descendants so the root channel can prompt the user. The parent emits `input.resolved` when it routes an answer back down to the descendant that asked. A tool approval is the exception: the descendant decides it, since its response policy can refuse the person who answered, so the approval stays open on the parent until the descendant settles or resolves it. The parent relays the descendant's `approval.settled` and `input.resolved` for it. On text-only channels, a typed reply that matches an option of the first open prompt, such as `approve` for a tool approval or `continue` for a session limit, answers it as the person who typed it, so a person answers several proxied prompts one message at a time. `task.settled` carries the child's reply as `output` when the call completes, or `error.message` when it fails, along with the same tool `name` and `kind: "agent"` as the call's `task.started`. To follow the child's other progress, pass the `agent.started` event to [`session.agent()`](./guides/client/streaming#follow-a-subagent) on a client session attached to the parent and follow the child with `stream()`. It reads `agent.started.data.streamPath`: the child's own session stream for a local child, or a parent-origin proxy for a remote child, which the parent authenticates to the remote deployment.
|
|
233
233
|
|
|
234
234
|
`agent.started` carries the `callId` and `turnId` of the call that opened the session, the call's `taskId`, the agent `name`, and the child's `sessionId`. Later calls with the same `taskId` reach the same session and do not announce it again, so match a child to its calls by `taskId`. A session an authored workflow tool opens with `ctx.agent` is announced the same way, with its `taskId` only when the workflow tool call runs as a task.
|
|
235
235
|
|
|
@@ -219,7 +219,7 @@ Approvals and questions share one protocol:
|
|
|
219
219
|
3. The run parks durably, for as long as it takes. The turn stays open: the stream emits `turn.waiting`, and after the answer the turn resumes under the same `turnId`. That `turn.waiting` carries `on: "input"`, since a person must act.
|
|
220
220
|
4. The client answers with `inputResponses` (structured, keyed by `requestId`) or a normal follow-up `message`. A follow-up whose text matches an option ID, option label, or numeric option index resolves automatically, including approval options such as `approve` and `cancel`.
|
|
221
221
|
|
|
222
|
-
For `ctx.ask()` questions from tools, a follow-up message answers the first open request, as described in [Several requests at once](#several-requests-at-once). The message must match an option, or the question must allow free text. Otherwise the message follows the session's `turnPolicy`. A steering message, the default, aborts the `ctx.abortSignal` of each `execute` workflow tool call the turn waits on, so a question such a call asked, such as `ask_question`'s, is withdrawn and resolves as `cancelled`. The model reads the message once those calls settle.
|
|
222
|
+
For `ctx.ask()` questions from tools and prompts proxied from subagents, a follow-up message answers the first open request, as described in [Several requests at once](#several-requests-at-once). The message must match an option, or the question must allow free text. Otherwise the message follows the session's `turnPolicy`. A steering message, the default, aborts the `ctx.abortSignal` of each `execute` workflow tool call the turn waits on, so a question such a call asked, such as `ask_question`'s, is withdrawn and resolves as `cancelled`. The model reads the message once those calls settle.
|
|
223
223
|
|
|
224
224
|
Each request includes a `kind` discriminator: `tool-approval`, `question`, or
|
|
225
225
|
`session-limit`. Clients should use `kind` to choose behavior and presentation.
|
package/docs/tools/overview.mdx
CHANGED
|
@@ -176,8 +176,8 @@ receive only the projected text.
|
|
|
176
176
|
|
|
177
177
|
### Durable waits
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
can wait durably while the call is pending:
|
|
179
|
+
A tool call with an `execute` entry point finishes before the model continues. The definition
|
|
180
|
+
decides whether the executor can wait durably while the call is pending:
|
|
181
181
|
|
|
182
182
|
| Definition | Durable waits inside `execute` | Result delivered to the model |
|
|
183
183
|
| -------------------- | -------------------------------------------------------- | ---------------------------------- |
|
|
@@ -191,11 +191,15 @@ the call returns a receipt at once, and the workflow's output reaches the model
|
|
|
191
191
|
[resumable task](/docs/tools/workflows#resumable-tasks-serve), which the model can send more calls
|
|
192
192
|
by its `taskId`.
|
|
193
193
|
|
|
194
|
+
Built-in, declared local, and remote subagent tools run as resumable tasks: each call returns a
|
|
195
|
+
receipt at once, and the child's reply reaches the model later in a `task.result` message.
|
|
196
|
+
Inside an authored workflow, awaiting a [`ctx.agent` session's `response.result()`](/docs/tools/workflows#delegate-work-ctxagent)
|
|
197
|
+
waits for the child's turn to end instead.
|
|
198
|
+
|
|
194
199
|
The `TaskExec` argument and `task.postMessage` have been removed. Return the result. In a workflow
|
|
195
200
|
body, keep values needed after a wait in local variables; workflow replay reconstructs them across
|
|
196
201
|
durable waits. Use [`ctx.ask`](/docs/tools/workflows#ask-a-human-ctxask) when the body needs an
|
|
197
|
-
answer from the human.
|
|
198
|
-
returns the child's reply as its tool result.
|
|
202
|
+
answer from the human.
|
|
199
203
|
|
|
200
204
|
### Yield and return
|
|
201
205
|
|
package/docs/tools/workflows.mdx
CHANGED
|
@@ -347,10 +347,14 @@ described in [Tasks](/docs/tools/tasks). What differs:
|
|
|
347
347
|
share one identity, so don't keep per-person data for them. Any caller in the session can
|
|
348
348
|
continue or cancel the task; see [Tasks](/docs/tools/tasks#ownership-and-limits).
|
|
349
349
|
- **Agents belong to the call that opened them:** a session the body opens with `ctx.agent` while
|
|
350
|
-
serving a call is that call's child. Its `session.parent` names the call's `callId` and turn
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
350
|
+
serving a call is that call's child. Its `session.parent` names the call's `callId` and turn.
|
|
351
|
+
The first turn of a local child uses the call's tool span as its parent when trace context is
|
|
352
|
+
available. A remote child starts its own trace; its first turn links to the call's tool span
|
|
353
|
+
with `eve.link.type=agent.dispatch` when trace context is available. Later child turns start new
|
|
354
|
+
traces. Parent session lineage stays tied to the opening call, even after the task receives
|
|
355
|
+
another call; a remote receiver accepts that lineage only from a trusted forwarder. Each message
|
|
356
|
+
uses the auth of the call being served; remote identity follows the
|
|
357
|
+
[forwarding rules](../guides/remote-agents#forwarding-the-caller-identity).
|
|
354
358
|
- **Results:** `ctx.reply(output)` settles every call received so far with `output`, all at once.
|
|
355
359
|
Each settled call reports its own `task.settled`, and the model receives the reply once. The task
|
|
356
360
|
then goes idle until its next call. A reply with
|
|
@@ -541,9 +545,13 @@ client's `MessageResult` fields, plus `error` when the turn failed:
|
|
|
541
545
|
| `error` | `{ message }` with the reason the turn failed, present only when `status` is `"failed"`. |
|
|
542
546
|
|
|
543
547
|
Every `ctx.agent(name)` call returns a new session that only the workflow run can address. The model
|
|
544
|
-
does not see it; it sees what the tool returns.
|
|
545
|
-
caller's capabilities
|
|
546
|
-
|
|
548
|
+
does not see it; it sees what the tool returns. A local child runs as the caller's principal with the
|
|
549
|
+
caller's capabilities. A remote child does not inherit the caller's session principal by default;
|
|
550
|
+
the receiving deployment determines its identity from the outbound request. To forward the caller's
|
|
551
|
+
identity, set `forwardPrincipal: true` on the remote agent and configure the receiver's
|
|
552
|
+
`trustedForwarders` (see [Forwarding the caller identity](../guides/remote-agents#forwarding-the-caller-identity)).
|
|
553
|
+
A person answers the child's questions and sign-ins at the root session, as for any subagent.
|
|
554
|
+
The session ends when the run finishes, which cancels any turn still running.
|
|
547
555
|
|
|
548
556
|
The parent stream announces each session with `agent.started`, which carries the `callId` and
|
|
549
557
|
`turnId` of the tool call the run is serving when it opens the session (for a `serve` task, the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.75.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
|
|
6
6
|
"keywords": [
|
|
@@ -580,12 +580,12 @@
|
|
|
580
580
|
"@vercel/sandbox": "3.3.0",
|
|
581
581
|
"@vercel/schedules": "0.0.0-alpha.11",
|
|
582
582
|
"@vercel/sdk": "1.28.8",
|
|
583
|
-
"@workflow/core": "5.
|
|
584
|
-
"@workflow/errors": "5.0.
|
|
583
|
+
"@workflow/core": "5.2.0",
|
|
584
|
+
"@workflow/errors": "5.0.3",
|
|
585
585
|
"@workflow/serde": "5.0.0",
|
|
586
|
-
"@workflow/world": "5.0.
|
|
587
|
-
"@workflow/world-local": "5.0
|
|
588
|
-
"@workflow/world-vercel": "5.
|
|
586
|
+
"@workflow/world": "5.0.3",
|
|
587
|
+
"@workflow/world-local": "5.1.0",
|
|
588
|
+
"@workflow/world-vercel": "5.2.0",
|
|
589
589
|
"ai": "^7.0.128",
|
|
590
590
|
"chat": "4.41.0",
|
|
591
591
|
"chokidar": "5.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-B_knIduE.js";import*as t from"#compiled/zod/index.js";import{z as n}from"#compiled/zod/index.js";import r from"node:crypto";function i(e,t,n){let r=Symbol.for(`${e}/v${t}`),i=globalThis,a=i[r];if(a!==void 0)return a;let o=n();return i[r]=o,o}const a=Symbol.for(`@workflow/world//warnedEnvValues/v1`),o=globalThis,s=o[a]??=new Set;function c(e,t){s.has(e)||(s.add(e),console.warn(`[workflow] ${t}`))}function l(e,t,n={}){let r=process.env[e];if(r===void 0||r===``)return t;let{min:i=0,max:a,integer:o=!1}=n,s=Number(r);return!Number.isFinite(s)||o&&!Number.isInteger(s)?(c(`${e}=${r}`,`Ignoring ${e}: not a ${o?`finite integer`:`finite number`}; using default ${t}`),t):s<i?(c(`${e}=${r}`,`${e} below minimum ${i}; clamped`),i):a!==void 0&&s>a?(c(`${e}=${r}`,`${e} above maximum ${a}; clamped`),a):s}function u(e,t,n=process.env){let r=n[e];if(r===void 0||r===``)return t;let i=r.toLowerCase();return i===`0`||i===`false`?!1:i===`1`||i===`true`||(c(`${e}=${r}`,`Ignoring ${e}: expected 0/1/true/false; using default ${t}`),t)}const d=25e3;function ee(){let e=l(`WORKFLOW_MAX_EVENTS`,d,{integer:!0});return e>0?e:d}const f=`0123456789ABCDEFGHJKMNPQRSTVWXYZ`;var p;(function(e){e.Base32IncorrectEncoding=`B32_ENC_INVALID`,e.DecodeTimeInvalidCharacter=`DEC_TIME_CHAR`,e.DecodeTimeValueMalformed=`DEC_TIME_MALFORMED`,e.EncodeTimeNegative=`ENC_TIME_NEG`,e.EncodeTimeSizeExceeded=`ENC_TIME_SIZE_EXCEED`,e.EncodeTimeValueMalformed=`ENC_TIME_MALFORMED`,e.PRNGDetectFailure=`PRNG_DETECT`,e.ULIDInvalid=`ULID_INVALID`,e.Unexpected=`UNEXPECTED`,e.UUIDInvalid=`UUID_INVALID`})(p||={});var m=class extends Error{constructor(e,t){super(`${t} (${e})`),this.name=`ULIDError`,this.code=e}};function te(e){let t=Math.floor(e()*32)%32;return f.charAt(t)}function h(e,t,n){return t>e.length-1?e:e.substr(0,t)+n+e.substr(t+1)}function ne(e){let t,n=e.length,r,i,a=e;for(;!t&&n-->=0;){if(r=a[n],i=f.indexOf(r),i===-1)throw new m(p.Base32IncorrectEncoding,`Incorrectly encoded string`);if(i===31){a=h(a,n,f[0]);continue}t=h(a,n,f[i+1])}if(typeof t==`string`)return t;throw new m(p.Base32IncorrectEncoding,`Failed incrementing string`)}function re(e){if(e.length!==26)throw new m(p.DecodeTimeValueMalformed,`Malformed ULID`);let t=e.substr(0,10).toUpperCase().split(``).reverse().reduce((e,t,n)=>{let r=f.indexOf(t);if(r===-1)throw new m(p.DecodeTimeInvalidCharacter,`Time decode error: Invalid character: ${t}`);return e+=r*32**n},0);if(t>0xffffffffffff)throw new m(p.DecodeTimeValueMalformed,`Malformed ULID: timestamp too large: ${t}`);return t}function ie(e){let t=ae(),n=t&&(t.crypto||t.msCrypto)||(r===void 0?null:r);if(typeof n?.getRandomValues==`function`)return()=>{let e=new Uint8Array(1);return n.getRandomValues(e),e[0]/256};if(typeof n?.randomBytes==`function`)return()=>n.randomBytes(1).readUInt8()/256;if(r?.randomBytes)return()=>r.randomBytes(1).readUInt8()/256;throw new m(p.PRNGDetectFailure,`Failed to find a reliable PRNG`)}function ae(){return se()?self:typeof window<`u`?window:typeof global<`u`?global:typeof globalThis<`u`?globalThis:null}function oe(e,t){let n=``;for(;e>0;e--)n=te(t)+n;return n}function g(e,t=10){if(isNaN(e))throw new m(p.EncodeTimeValueMalformed,`Time must be a number: ${e}`);if(e>0xffffffffffff)throw new m(p.EncodeTimeSizeExceeded,`Cannot encode a time larger than 281474976710655: ${e}`);if(e<0)throw new m(p.EncodeTimeNegative,`Time must be positive: ${e}`);if(Number.isInteger(e)===!1)throw new m(p.EncodeTimeValueMalformed,`Time must be an integer: ${e}`);let n,r=``;for(let i=t;i>0;i--)n=e%32,r=f.charAt(n)+r,e=(e-n)/32;return r}function se(){return typeof WorkerGlobalScope<`u`&&self instanceof WorkerGlobalScope}function ce(e){let t=e||ie(),n=0,r;return function(e){let i=!e||isNaN(e)?Date.now():e;if(i<=n){let e=r=ne(r);return g(n,10)+e}n=i;let a=r=oe(16,t);return g(i,10)+a}}function le(e,t){let n=t||ie();return g(!e||isNaN(e)?Date.now():e,10)+oe(16,n)}const ue=`$rootRunId`,de=`$parentRunId`,_=`$retention`,v=`default`,fe=/^(?:0|[1-9]\d*)$/;function pe(e){let t=e?.[_];return t===void 0?{mode:`default`,wellFormed:!1,unsupported:!1}:fe.test(t)?t===`0`?{mode:`none`,raw:t,wellFormed:!0,unsupported:!1}:{mode:`default`,raw:t,wellFormed:!0,unsupported:!0}:{mode:`default`,raw:t,wellFormed:!1,unsupported:t!==v}}const y=8192,b=new TextEncoder;var x=class extends Error{constructor(e){super(e),this.name=`AttributeValidationError`}};function me(e){let t=b.encode(JSON.stringify(e)).length;if(t>8192)throw new x(`Attribute eventData exceeds limit ${y} UTF-8 JSON bytes (received ${t} bytes). Split the changes into smaller setAttributes() calls.`)}function he(e,t){if(typeof e!=`string`)throw new x(`Attribute key must be a string, got ${typeof e}`);if(e.length===0)throw new x(`Attribute key must not be empty`);if(e.length>256)throw new x(`Attribute key length ${e.length} exceeds limit 256: ${JSON.stringify(e.slice(0,32))}…`);if(!t&&e.startsWith(`$`))throw new x(`Attribute key ${JSON.stringify(e)} starts with reserved prefix "\$" — that namespace is reserved for framework/library code. Set { allowReservedAttributes: true } only if your caller is framework-level.`)}function ge(e){if(e!==null&&typeof e!=`string`)throw new x(`Attribute value must be a string or null, got ${typeof e}`);if(e===null)return;let t=b.encode(e).length;if(t>256)throw new x(`Attribute value byte length ${t} exceeds limit 256`)}function _e(e,t,n){return t===null?n?.has(e)?-1:0:+(n===void 0||!n.has(e))}function S(e,t={}){let n=new Set,r=t.existingKeys===void 0?void 0:t.existingKeys instanceof Set?t.existingKeys:new Set(t.existingKeys),i=r?.size??0;for(let{key:t,value:a}of e){if(n.has(t))throw new x(`Attribute key ${JSON.stringify(t)} appears more than once in the same batch`);n.add(t),i+=_e(t,a,r)}if(i>64)throw new x(`Run attribute count would exceed limit 64 (post-merge ${i})`)}function ve(e,t={}){for(let{key:n,value:r}of e)he(n,t.allowReservedAttributes===!0),ge(r);S(e,t)}function ye(e,t){let n={...e??{}};for(let{key:e,value:r}of t)r===null?delete n[e]:n[e]=r;return n}const be=new TextEncoder,C=t.compile(t.string().min(1,{error:`Attribute key must not be empty`}).max(256,{error:`Attribute key exceeds limit 256`})),w=t.compile(t.string().refine(e=>be.encode(e).length<=256,{error:`Attribute value exceeds limit 256 UTF-8 bytes`}).nullable()),xe=t.compile(t.object({key:C,value:w})),Se=t.compile(t.array(xe).superRefine((e,t)=>{try{S(e)}catch(n){if(!(n instanceof x))throw n;t.addIssue({code:`custom`,message:n.message,input:e})}}));function T(e,t){return Object.hasOwn(e,t)?e[t]:void 0}function Ce(e){return e.eventType===`noop`}const we={attr_set:`attr_set`,step_created:`step_created`,step_started:`step_started`,step_retrying:`step_retrying`,step_completed:`step_terminal`,step_failed:`step_terminal`,wait_created:`wait_created`,wait_completed:`wait_completed`,hook_created:`hook_created`,hook_disposed:`hook_disposed`,run_started:`run_started`};function Te(e){return T(we,e)}function Ee(e){let t=Te(e.eventType);if(t!==void 0)return t===`run_started`?{eventClass:t,entity:``}:e.correlationId?{eventClass:t,entity:e.correlationId}:void 0}const De={run_created:[`input`],run_started:[`input`],run_completed:[`output`],run_failed:[`error`],step_created:[`input`],step_started:[`input`],step_completed:[`result`],step_failed:[`error`],step_retrying:[`error`],hook_created:[`metadata`],hook_received:[`payload`]},Oe=[];function E(e){return T(De,e)??Oe}function ke(e){return E(e)[0]}const Ae=n.compile(n.instanceof(Uint8Array)),je=n.compile(n.any()),D=n.compile(n.union([Ae,je])),O=n.compile(n.enum([`run_created`,`run_started`,`run_completed`,`run_failed`,`run_cancelled`,`attr_set`,`step_created`,`step_completed`,`step_failed`,`step_retrying`,`step_started`,`hook_created`,`hook_received`,`hook_disposed`,`hook_conflict`,`wait_created`,`wait_completed`,`noop`]));n.compile(O.extract([`run_created`,`run_started`,`run_completed`,`run_failed`,`run_cancelled`])).options;const Me=n.compile(O.extract([`run_completed`,`run_failed`,`run_cancelled`])).options;function Ne(e){return Me.includes(e)}const Pe=n.compile(O.extract([`step_created`,`step_completed`,`step_failed`,`step_retrying`,`step_started`])).options;function Fe(e){return Pe.includes(e)}n.compile(O.extract([`step_completed`,`step_failed`])).options;const Ie=n.compile(O.extract([`hook_created`,`hook_received`,`hook_disposed`])).options;function Le(e){return Ie.includes(e)}const Re=n.compile(O.extract([`hook_disposed`,`hook_received`])).options;function ze(e){return Re.includes(e)}n.compile(O.extract([`wait_created`,`wait_completed`])).options;const Be=n.compile(O.extract([`step_created`,`hook_created`,`wait_created`])).options;function Ve(e){return Be.includes(e)}function He(e,t){if(t!==`none`||!(`eventData`in e))return e;let n=e.eventData;if(!n||typeof n!=`object`){let{eventData:t,...n}=e;return n}let r=E(e.eventType);if(r.length===0)return e;let i={...n};for(let e of r)delete i[e];let{eventData:a,...o}=e;return{...o,...Object.keys(i).length>0?{eventData:i}:{}}}const k=n.compile(n.object({eventType:O,correlationId:n.string().optional(),specVersion:n.number().optional()})),A={ttfs:n.number().optional(),stso:n.number().optional(),stepCount:n.number().int().positive().optional(),eventCount:n.number().int().positive().optional(),rsfs:n.number().optional(),finalSchedulingReplay:n.number().optional(),optimizations:n.array(n.string()).optional()},j=n.compile(k.extend({eventType:n.literal(`step_completed`),correlationId:n.string(),eventData:n.object({stepName:n.string().optional(),workflowName:n.string().optional(),result:D,...A})})),M=n.compile(k.extend({eventType:n.literal(`step_failed`),correlationId:n.string(),eventData:n.object({stepName:n.string().optional(),error:D,...A})})),N=n.compile(k.extend({eventType:n.literal(`step_retrying`),correlationId:n.string(),eventData:n.object({stepName:n.string().optional(),error:D,retryAfter:n.coerce.date().optional()})})),P=n.compile(k.extend({eventType:n.literal(`step_started`),correlationId:n.string(),eventData:n.object({stepName:n.string().optional(),attempt:n.number().optional(),workflowName:n.string().optional(),input:D.optional(),ownerMessageId:n.string().optional()}).optional()})),F=n.compile(k.extend({eventType:n.literal(`step_created`),correlationId:n.string(),eventData:n.object({stepName:n.string(),workflowName:n.string().optional(),input:D})})),I=n.compile(k.extend({eventType:n.literal(`hook_created`),correlationId:n.string(),eventData:n.object({token:n.string(),tokenRetentionUntil:n.coerce.date().optional(),metadata:D.optional(),isWebhook:n.boolean().optional(),isSystem:n.boolean().optional(),force:n.boolean().optional(),forceClaimedFrom:n.object({runId:n.string(),hookId:n.string(),workflowName:n.string().optional(),deploymentId:n.string().optional(),runSpecVersion:n.number().optional()}).optional()})})),L=n.compile(k.extend({eventType:n.literal(`hook_received`),correlationId:n.string(),eventData:n.object({token:n.string().optional(),payload:D})})),Ue=n.compile(k.extend({eventType:n.literal(`hook_disposed`),correlationId:n.string(),eventData:n.object({token:n.string().optional(),forceClaimedBy:n.object({runId:n.string(),hookId:n.string()}).optional()}).optional()})),We=n.compile(k.extend({eventType:n.literal(`hook_conflict`),correlationId:n.string(),eventData:n.object({token:n.string(),conflictingRunId:n.string().optional(),forceRefusedReason:n.literal(`victim-spec-version`).optional()})})),Ge=n.compile(k.extend({eventType:n.literal(`noop`),eventData:n.object({sealed:n.boolean().optional()}).passthrough().optional()})),R=n.compile(k.extend({eventType:n.literal(`wait_created`),correlationId:n.string(),eventData:n.object({resumeAt:n.coerce.date()})})),z=n.compile(k.extend({eventType:n.literal(`wait_completed`),correlationId:n.string(),eventData:n.object({resumeAt:n.coerce.date().optional()}).optional()})),Ke=n.compile(n.discriminatedUnion(`type`,[n.object({type:n.literal(`workflow`)}),n.object({type:n.literal(`step`),stepId:n.string(),attempt:n.number()})])),B=n.compile(k.extend({eventType:n.literal(`attr_set`),correlationId:n.string().optional(),eventData:n.object({changes:Se,writer:Ke,allowReservedAttributes:n.literal(!0).optional()})})),V=n.compile(k.extend({eventType:n.literal(`run_created`),eventData:n.object({deploymentId:n.string(),workflowName:n.string(),input:D,executionContext:n.record(n.string(),n.any()).optional(),attributes:n.record(n.string(),n.string()).optional(),allowReservedAttributes:n.literal(!0).optional(),dynamicWorkflowCode:D.optional(),dynamicWorkflowCodeRef:n.string().optional(),encryptionPublicKey:n.string().optional()}).refine(e=>e.dynamicWorkflowCode===void 0||e.dynamicWorkflowCodeRef===void 0,{path:[`dynamicWorkflowCodeRef`],message:`dynamicWorkflowCode and dynamicWorkflowCodeRef are mutually exclusive`})})),H=n.compile(k.extend({eventType:n.literal(`run_started`),eventData:n.object({input:D.optional(),deploymentId:n.string().optional(),workflowName:n.string().optional(),executionContext:n.record(n.string(),n.any()).optional(),attributes:n.record(n.string(),n.string()).optional(),allowReservedAttributes:n.literal(!0).optional(),encryptionPublicKey:n.string().optional(),dynamicWorkflowCode:D.optional(),dynamicWorkflowCodeRef:n.string().optional()}).refine(e=>e.dynamicWorkflowCode===void 0||e.dynamicWorkflowCodeRef===void 0,{path:[`dynamicWorkflowCodeRef`],message:`dynamicWorkflowCode and dynamicWorkflowCodeRef are mutually exclusive`}).optional()})),U=n.compile(k.extend({eventType:n.literal(`run_completed`),eventData:n.object({output:D.optional()})})),W=n.compile(k.extend({eventType:n.literal(`run_failed`),eventData:n.object({error:D,errorCode:n.string().optional()})})),qe=n.compile(k.extend({eventType:n.literal(`run_cancelled`),eventData:n.object({cancelReason:n.string().max(512).optional()}).optional()}));n.compile(n.discriminatedUnion(`eventType`,[V,H,U,W,qe,B,F,j,M,N,P,I,L,Ue,R,z]));const Je=n.compile(n.discriminatedUnion(`eventType`,[V,H,U,W,qe,B,F,j,M,N,P,I,L,Ue,We,R,z,Ge])),Ye=n.compile(Je.and(n.object({runId:n.string(),eventId:n.string(),createdAt:n.coerce.date(),occurredAt:n.coerce.date().optional(),specVersion:n.number().optional(),resumeId:n.string().optional()})));function Xe(e){return Ve(e.eventType)?!0:e.eventType===`step_started`&&typeof e.eventData?.stepName==`string`&&e.eventData.input!==void 0}const G=n.compile(n.enum([`pending`,`running`,`completed`,`failed`,`cancelled`])),Ze=n.compile(G.extract([`completed`,`failed`,`cancelled`])).options;function Qe(e){return Ze.includes(e)}const K=n.compile(n.object({runId:n.string(),status:G,deploymentId:n.string(),workflowName:n.string(),specVersion:n.number().optional(),executionContext:n.record(n.string(),n.any()).optional(),input:D.optional(),output:D.optional(),dynamicWorkflowCode:D.optional(),error:D.optional(),errorCode:n.string().optional(),attributes:n.record(n.string(),n.string()).default({}),encryptionPublicKey:n.string().optional(),expiredAt:n.coerce.date().optional(),startedAt:n.coerce.date().optional(),completedAt:n.coerce.date().optional(),createdAt:n.coerce.date(),updatedAt:n.coerce.date()})),$e=n.compile(n.discriminatedUnion(`status`,[K.extend({status:n.enum([`pending`,`running`]),output:n.undefined().optional(),error:n.undefined().optional(),completedAt:n.undefined().optional()}),K.extend({status:n.literal(`cancelled`),output:n.undefined().optional(),error:n.undefined().optional(),completedAt:n.coerce.date()}),K.extend({status:n.literal(`completed`),output:D.optional(),error:n.undefined().optional(),completedAt:n.coerce.date()}),K.extend({status:n.literal(`failed`),output:n.undefined().optional(),error:D.optional(),completedAt:n.coerce.date()})])),et=n.compile(n.object({runIds:n.array(n.string()).min(1).max(500).refine(e=>new Set(e).size===e.length,{message:`runIds must not contain duplicates`}),cancelReason:n.string().max(512).optional()})),tt=n.compile(n.discriminatedUnion(`outcome`,[n.object({runId:n.string(),outcome:n.literal(`cancelled`)}),n.object({runId:n.string(),outcome:n.literal(`already_cancelled`)}),n.object({runId:n.string(),outcome:n.literal(`not_cancellable`),status:n.string()}),n.object({runId:n.string(),outcome:n.literal(`not_found`)}),n.object({runId:n.string(),outcome:n.literal(`failed`),code:n.string(),retryable:n.boolean()})])),nt=n.compile(n.object({summary:n.object({requested:n.number(),cancelled:n.number(),alreadyCancelled:n.number(),notCancellable:n.number(),notFound:n.number(),failed:n.number()}),results:n.array(tt)})),q=n.compile(n.enum([`pending`,`running`,`completed`,`failed`,`cancelled`])),rt=n.compile(n.object({runId:n.string(),stepId:n.string(),stepName:n.string(),status:q,input:D.optional(),output:D.optional(),error:D.optional(),attempt:n.number(),startedAt:n.coerce.date().optional(),completedAt:n.coerce.date().optional(),createdAt:n.coerce.date(),updatedAt:n.coerce.date(),retryAfter:n.coerce.date().optional(),specVersion:n.number().optional()})),it=n.compile(q.extract([`completed`,`failed`,`cancelled`])).options;function at(e){return it.includes(e)}const ot=n.compile(n.enum([`waiting`,`completed`])),st=n.compile(n.object({waitId:n.string(),runId:n.string(),status:ot,resumeAt:n.coerce.date().optional(),completedAt:n.coerce.date().optional(),createdAt:n.coerce.date(),updatedAt:n.coerce.date(),specVersion:n.number().optional()})),ct=/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/,J=n.compile(n.preprocess(e=>typeof e==`string`&&ct.test(e)?`${e.replace(` `,`T`)}Z`:e,n.coerce.date())),Y=n.compile(J.nullable().optional()),X=n.compile(n.string().nullable().optional()),Z=n.compile(n.boolean().nullable().optional()),lt=n.compile(n.object({runId:n.string(),status:G,deploymentId:n.string(),workflowName:n.string(),specVersion:n.coerce.number().optional(),attributes:n.record(n.string(),n.string()).default({}),createdAt:J,updatedAt:J,startedAt:Y,completedAt:Y,errorCode:X,workflowCoreVersion:X,workflowEncryptionEnabled:Z})),ut=n.compile(n.object({runId:n.string(),stepId:n.string(),stepName:X,status:q,attempt:n.number().optional(),createdAt:J,updatedAt:J,startedAt:Y,completedAt:Y,retryAfter:Y,errorCode:X,workflowCoreVersion:X,workflowEncryptionEnabled:Z,computeInstanceId:X})),dt=n.compile(n.object({runId:n.string(),eventId:n.string(),eventType:O,correlationId:X,entityId:X,stepName:X,workflowName:n.string(),deploymentId:n.string(),specVersion:n.coerce.number().optional(),runCreatedAt:J,createdAt:J,region:X,vercelId:X,requestId:X,computeInstanceId:X,resumeAt:Y,retryAfter:Y,errorCode:X,workflowCoreVersion:X,isWebhook:Z,isSystem:Z,workflowEncryptionEnabled:Z})),ft=n.compile(n.object({runId:n.string(),hookId:n.string(),status:n.enum([`created`,`received`,`disposed`,`conflict`]),createdAt:J,updatedAt:J,receivedAt:Y,disposedAt:Y,isWebhook:Z,isSystem:Z,workflowCoreVersion:X,workflowEncryptionEnabled:Z})),pt=n.compile(n.object({runId:n.string(),waitId:n.string(),status:ot,resumeAt:Y,createdAt:J,updatedAt:J,completedAt:Y,workflowCoreVersion:X,workflowEncryptionEnabled:Z})),mt=n.compile(n.object({key:n.string(),runCount:n.coerce.number(),firstSeenAt:J,lastSeenAt:J})),ht=1e3,gt=n.compile(n.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_$/,`Must match __wkf_workflow_ or __{namespace}_wkf_workflow_`)),_t=n.compile(n.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_.+$/,`Must be a valid queue name with a recognized prefix`)),vt=n.compile(n.string().regex(/^[a-z][a-z0-9]*$/,`Must be lowercase alphanumeric, starting with a letter`));function yt(e){return e??process.env.WORKFLOW_QUEUE_NAMESPACE??void 0}function bt(e,t){if(e!==`workflow`)throw Error(`Unsupported queue kind: ${e}`);return t===void 0?`__wkf_workflow_`:(vt.parse(t),`__${t}_wkf_workflow_`)}function xt(e){let t=e.match(/^(__(?:[a-z][a-z0-9]*_)?wkf_workflow_)(.+)$/);if(!t)throw Error(`Invalid queue name: ${e}`);return{prefix:gt.parse(t[1]),id:t[2]}}const St=n.compile(n.string().brand().describe(`A stored queue message ID`)),Ct=n.compile(n.record(n.string(),n.string())),wt=n.compile(n.object({input:n.unknown(),deploymentId:n.string(),workflowName:n.string(),specVersion:n.number(),executionContext:n.record(n.string(),n.any()).optional(),dynamicWorkflowCode:D.optional(),dynamicWorkflowCodeRef:n.string().optional(),attributes:n.record(n.string(),n.string()).optional(),allowReservedAttributes:n.literal(!0).optional(),environment:n.string().optional()}).refine(e=>e.dynamicWorkflowCode===void 0||e.dynamicWorkflowCodeRef===void 0,{path:[`dynamicWorkflowCodeRef`],message:`dynamicWorkflowCode and dynamicWorkflowCodeRef are mutually exclusive`})),Tt=n.compile(n.object({input:n.custom(e=>e instanceof Uint8Array,{message:`stepInput.input must be a Uint8Array`})})),Et=n.compile(n.object({deploymentId:n.string(),specVersion:n.number(),startedAt:n.number().optional(),rootRunId:n.string().optional()})),Dt=n.compile(n.object({resumeId:n.string(),hookId:n.string(),token:n.string(),payload:n.unknown(),payloadDigest:n.string(),deploymentId:n.string().optional()})),Ot=n.compile(n.object({resumeRequestedAtMs:n.number(),queuePublishRequestedAtMs:n.number(),strategy:n.string().optional(),consumerStartedAtMs:n.number().optional(),replayStartedAtMs:n.number().optional(),nextStepEncounteredAtMs:n.number().optional(),setupSource:n.string().optional()})),kt=n.compile(n.object({runId:n.string(),invoke:n.literal(!0).optional(),requestId:n.string().optional(),input:n.unknown().optional(),traceCarrier:Ct.optional(),requestedAt:n.coerce.date().optional(),replayDivergence:n.object({eventId:n.string(),count:n.number().int().positive(),eventIds:n.array(n.string()).optional().catch(void 0)}).optional(),preconditionReinvocations:n.number().int().positive().optional(),serverErrorRetryCount:n.number().int().optional(),deploymentMismatchRetryCount:n.number().int().nonnegative().optional(),waitContinuation:n.object({correlationId:n.string(),attempt:n.number().int().nonnegative()}).optional().catch(void 0),stepId:n.string().optional(),stepName:n.string().optional(),runInput:wt.optional(),hookInput:Dt.optional(),stepInput:Tt.optional(),runContext:Et.optional(),hookResumeTiming:Ot.optional().catch(void 0)})),At=n.compile(n.object({__healthCheck:n.literal(!0),correlationId:n.string(),runId:n.string().optional()})),jt=n.compile(n.union([At,kt])),Mt=n.compile(n.object({deploymentId:n.string(),workflowName:n.string(),runSpecVersion:n.number().optional(),workflowCoreVersion:n.string().optional(),nodeVersion:n.string().optional(),traceCarrier:Ct.optional(),encryptionPublicKey:n.string().optional(),hookResumeInputVersion:n.number().optional()})),Nt=n.compile(n.object({hookResumeDedupVersion:n.number()})),Pt=n.compile(n.object({runId:n.string(),hookId:n.string(),workflowName:n.string().optional(),deploymentId:n.string().optional(),runSpecVersion:n.number().optional()})),Ft=n.compile(n.object({runId:n.string(),hookId:n.string(),token:n.string(),ownerId:n.string(),projectId:n.string(),environment:n.string(),metadata:D.optional(),createdAt:n.coerce.date(),specVersion:n.number().optional(),isWebhook:n.boolean().optional(),isSystem:n.boolean().optional(),tokenRetentionUntil:n.coerce.date().optional(),resumeContext:Mt.optional(),resumeCapabilities:Nt.optional(),claimedFrom:Pt.optional()})),It=`WORKFLOW_NODE_HTTP`;function Lt(e=process.env){return u(It,!1,e)}async function Rt(e,t,n,r){let i=bt(`workflow`,yt(r)),a=0,o,s=!0;for(;s;){let r=await e.list({status:[`pending`,`running`],resolveData:`none`,pagination:{cursor:o}});for(let e of r.data)try{await t(`${i}${e.workflowName}`,{runId:e.runId}),a++}catch(t){console.warn(`[${n}] Failed to re-enqueue run ${e.runId}: ${t}`)}s=r.hasMore,o=r.cursor??void 0}a>0&&zt()&&console.debug(`[${n}] Re-enqueued ${a} active run(s) on startup`)}function zt(){let e=typeof process<`u`?process.env.DEBUG:void 0;return typeof e==`string`?e.includes(`workflow:`)||e===`*`:!1}const Bt=n.lazy(()=>n.union([n.string(),n.number(),n.boolean(),n.null(),n.array(Bt),n.record(n.string(),Bt)])),Vt=n.compile(n.object({currentLookbackDays:n.number(),maxLookbackDays:n.number(),currentWindowStart:n.coerce.date(),maxWindowStart:n.coerce.date(),upgradeAvailable:n.boolean()})),Ht=e=>n.compile(n.object({data:n.array(e),cursor:n.string().nullable(),hasMore:n.boolean(),pageInfo:Vt.optional()}));function Ut(e){return e===`skip-step-inputs`?`all`:e}const Wt=n.compile(n.object({message:n.string(),stack:n.string().optional(),code:n.string().optional()})),Gt=`evnt_`;function Q(e){if(e.length!==26)return!1;for(let t=0;t<10;t++)if(e[t]!==`0`)return!1;for(let t=10;t<26;t++){let n=e.charCodeAt(t);if(n<48||n>57)return!1}return!0}function Kt(e){let t=e.indexOf(`_`);return t===-1?e:e.slice(t+1)}function qt(e){return Q(Kt(e))}function Jt(e){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`Invalid event slot: ${e}`);return`${Gt}${String(e).padStart(26,`0`)}`}function Yt(e){let t=Kt(e);if(!Q(t))return null;let n=Number(t);return Number.isSafeInteger(n)&&n>=1?n:null}function Xt(e){let t=Yt(e);if(t===null)throw Error(`Event id is not slot-numbered: ${e}. This World allocates event positions the runtime cannot read.`);return t}const Zt=n.object({eventsCursor:n.string().nullable(),createdAt:n.coerce.date(),eventCount:n.number().int().nonnegative().optional(),rngDraws:n.number().int().nonnegative().optional(),serdeRootPtr:n.number().int().optional(),lastUlid:n.string().optional(),engineVersion:n.string().optional(),clockMs:n.number().optional(),formatVersion:n.number().int().optional()}),$=[87,83,78,80];function Qt(e,t){let n=new TextEncoder().encode(JSON.stringify(e)),r=new Uint8Array(9+n.length+t.length);return r.set($,0),r[4]=1,new DataView(r.buffer).setUint32(5,n.length,!0),r.set(n,9),r.set(t,9+n.length),r}function $t(e){if(e.length<9)return null;for(let t=0;t<$.length;t++)if(e[t]!==$[t])return null;if(e[4]!==1)return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(5,!0);if(9+t>e.length)return null;try{let n=new TextDecoder().decode(e.subarray(9,9+t));return{metadata:Zt.passthrough().parse(JSON.parse(n)),data:e.subarray(9+t)}}catch{return null}}function en(e=process.env){return u(`WORKFLOW_SEALED_LOG`,!0,e)?8:6}function tn(e){return e==null||e<=1}function nn(e){return e!=null&&e>8}const rn=n.compile(n.string().ulid()),an=n.compile(n.templateLiteral([`wrun_`,n.ulid()])),on=864e5,sn=3e5;function cn(e){if(Q(e))return null;let t=rn.safeParse(e);return t.success?new Date(re(t.data)):null}function ln(e,t,n=on,r=sn){let i=cn(e.startsWith(t)?e.slice(t.length):e);if(!i)return`Invalid runId: "${e}" is not a valid ULID`;let a=new Date().getTime()-i.getTime();return a>0&&a<=n||a<=0&&-a<=r?null:`Invalid runId timestamp: embedded timestamp is ${Math.round(Math.abs(a)/1e3)}s in the ${a>0?`past`:`future`} (threshold: ${Math.round((a>0?n:r)/1e3)}s)`}var un=e({ANALYTICS_EVENTS_GET_MANY_LIMIT:()=>100,ANALYTICS_MAX_ATTRIBUTE_FILTERS:()=>8,ANALYTICS_PAGE_LIMIT:()=>100,ANALYTICS_RUN_SCOPED_PAGE_LIMIT:()=>ht,ATTRIBUTE_EVENT_DATA_MAX_BYTES:()=>y,ATTRIBUTE_KEY_MAX_LENGTH:()=>256,ATTRIBUTE_MAX_PER_RUN:()=>64,ATTRIBUTE_VALUE_MAX_BYTES:()=>256,BULK_CANCEL_MAX_RUN_IDS:()=>500,DEFAULT_TIMESTAMP_THRESHOLD_FUTURE_MS:()=>sn,DEFAULT_TIMESTAMP_THRESHOLD_MS:()=>DEFAULT_TIMESTAMP_THRESHOLD_MS,DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS:()=>on,EVENT_ID_BODY_LENGTH:()=>26,EVENT_ID_PREFIX:()=>Gt,FIRST_EVENT_SLOT:()=>1,HOOK_RESUME_DEDUP_VERSION:()=>1,HOOK_RESUME_INPUT_VERSION:()=>1,HookSchema:()=>Ft,NODE_HTTP_DEFAULT:()=>!1,NODE_HTTP_ENV_VAR:()=>It,RESERVED_ATTRIBUTE_KEY_PREFIX:()=>`$`,RETENTION_DEFAULT:()=>v,RETENTION_ZERO:()=>`0`,RUN_ENTITY_KEY:()=>``,SEALED_LOG_ENV_VAR:()=>`WORKFLOW_SEALED_LOG`,SNAPSHOT_FORMAT_VERSION:()=>3,SPEC_VERSION_CURRENT:()=>8,SPEC_VERSION_LEGACY:()=>1,SPEC_VERSION_MAX_SUPPORTED:()=>8,SPEC_VERSION_SUPPORTS_ATTRIBUTES:()=>4,SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT:()=>3,SPEC_VERSION_SUPPORTS_COMPRESSION:()=>5,SPEC_VERSION_SUPPORTS_EVENT_SOURCING:()=>2,SPEC_VERSION_SUPPORTS_HOOK_FORCE_CLAIM:()=>8,SPEC_VERSION_SUPPORTS_SEALED_LOG:()=>7,SPEC_VERSION_SUPPORTS_SLOT_IDENTITY:()=>6});export{ke as $,dt as A,K as B,_t as C,yt as D,xt as E,st as F,Xe as G,Qe as H,rt as I,Fe as J,ze as K,at as L,lt as M,ut as N,ht as O,pt as P,Ee as Q,et as R,jt as S,bt as T,Ye as U,$e as V,O as W,He as X,Ne as Y,D as Z,Rt as _,i as _t,tn as a,de as at,At as b,$t as c,ye as ct,qt as d,me as dt,E as et,Xt as f,re as ft,Ut as g,ee as gt,Wt as h,l as ht,an as i,x as it,ft as j,mt as k,Qt as l,pe as lt,Ht as m,le as mt,cn as n,C as nt,en as o,_ as ot,Jt as p,ce as pt,Le as q,ln as r,w as rt,nn as s,ue as st,un as t,Ce as tt,Yt as u,ve as ut,Lt as v,kt as w,St as x,Ft as y,nt as z};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as e,F as t}from"./dist-T5NnW-0k.js";function n(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function r(e){let t={get value(){let n=e();return Object.defineProperty(t,"value",{value:n}),n}};return t}var i=class e extends Error{items;steps;globalThis;stepCount;hookCount;waitCount;attributeCount;hookDisposedCount;abortCount;constructor(e,n){let r=[...e.values()],i=0,a=0,o=0,s=0,c=0,l=0;for(let e of r)e.type===`step`?i++:e.type===`hook`?e.disposed?c++:e.abortRequested?l++:a++:e.type===`wait`?o++:e.type===`attribute`&&s++;let u=[];i>0&&u.push(`${i} ${t(`step`,`steps`,i)}`),a>0&&u.push(`${a} ${t(`hook`,`hooks`,a)}`),o>0&&u.push(`${o} ${t(`wait`,`waits`,o)}`),s>0&&u.push(`${s} ${t(`attribute write`,`attribute writes`,s)}`),c>0&&u.push(`${c} hook ${t(`disposal`,`disposals`,c)}`);let d=i+a+o+s+c,f=t(`has`,`have`,d),p=+(i>0)+ +(a>0)+ +(o>0)+ +(s>0)+ +(c>0),m;m=p>1?`processed`:i>0?`run`:a>0||o>0?`created`:s>0?`written`:c>0?`processed`:`received`;let h=u.length>0?`${u.join(` and `)} ${f} not been ${m} yet`:`0 steps have not been run yet`;super(h),this.name=`WorkflowSuspension`,this.items=r,this.steps=r,this.globalThis=n,this.stepCount=i,this.hookCount=a,this.waitCount=o,this.attributeCount=s,this.hookDisposedCount=c,this.abortCount=l}static is(t){return t instanceof e}};function a(){throw new e(`This API is not available inside a workflow function. Workflow functions run in a deterministic VM; move the call to a step function for full Node.js access.`)}const o=Symbol.for(`@workflow/core//registeredSteps`),s=globalThis,c=s[o]??=new Map,l=new Set([`__builtin_response_array_buffer`,`__builtin_response_json`,`__builtin_response_text`]);function u(e){let t=e.split(`//`);if(t.length!==3||t[0]!==`step`)return[];let n=t[1],r=t[2],i=new Set,a=e=>{e!==n&&i.add(e)};if(n.startsWith(`./workflows/`)){let e=n.slice(2);a(`./example/${e}`),a(`./src/${e}`)}else if(n.startsWith(`./example/workflows/`)){let e=n.slice(10);a(`./${e}`),a(`./src/${e}`)}else if(n.startsWith(`./src/workflows/`)){let e=n.slice(6);a(`./${e}`),a(`./example/${e}`)}return Array.from(i,e=>`step//${e}//${r}`)}function d(e){if(l.has(e)){for(let[t,n]of c.entries())if(t.endsWith(`//${e}`))return n}}function f(e,t){c.set(e,t),t.stepId=e}function p(e){let t=c.get(e);if(t)return t;for(let t of u(e)){let e=c.get(t);if(e)return e}let n=d(e);if(n)return n}const m={hook:[`hook`,`wait`,`step`],wait:[`hook`,`step`],step:[`wait`,`hook`,`step`]};function h(e,t,n,r){return n>=t||!m[e].includes(r.kind)?!1:!(e===`step`&&!r.armed)}function g(e,t,n,r){let i=r.get(t);if(i!==void 0)return i;let a=_(e,t,n,r);return r.set(t,a),a}function _(e,t,n,r){if(!n.armed)return!1;for(let[i,a]of e)if(h(n.kind,t,i,a)&&!g(e,i,a,r))return!1;return!0}function v(){return process.env.WORKFLOW_LOG_ORDER_DRAWS!==`0`}function y(e){return e===0&&typeof setImmediate==`function`?new Promise(e=>setImmediate(e)):new Promise(t=>setTimeout(t,e))}async function b(e,t){for(;;){let n=e.mintCount??0,r=e.pendingDeliveries;if(await y(await e.promiseQueue.then(()=>!1,()=>!0)?50:0),(e.mintCount??0)!==n||r!==0||e.pendingDeliveries!==0)continue;let i=!1;for(let[n,r]of e.pendingDeliveryBarriers??[])if(n<t&&r.armed){i=!0;break}if(!i)return}}async function x(e,t,n){if(t===void 0||!e.pendingDeliveryBarriers)return;let r=e.pendingDeliveryBarriers,i=[];for(let[e,a]of r)h(n,t,e,a)&&i.push(a.released);if(i.length>0&&await Promise.all(i),v()){await b(e,t);return}i.length>0&&await new Promise(e=>setTimeout(e,0))}function S(t,r,i,a){let o=!1,s=()=>!o&&(o=!0,t.advanceClock?.(a.deliveredAt),!0),c=t.pendingDeliveryBarriers;if(!c||r===void 0)return{markDelivered:()=>{s()},arm:()=>{}};let l=a=>{if(c.has(r))throw new e(`Delivery barrier already registered at event index ${r}`);let{promise:o,resolve:s}=n(),l={kind:i,released:o,armed:a,retired:!1,retire:()=>{l.retired||(l.retired=!0,c.get(r)===l&&c.delete(r),s())}};return c.set(r,l),w(t),l},u=l(a.armed??!0);return{markDelivered:()=>{s()&&u.retire()},arm:()=>{if(!o){if(u.retired){u=l(!0);return}if(c.get(r)!==u)throw new e(`Delivery barrier lost ownership of event index ${r}`);u.armed=!0}}}}const C=new WeakSet;function w(e){let t=e.pendingDeliveryBarriers;if(!t||C.has(e))return;C.add(e);let n=()=>{setTimeout(i,0)},r=()=>{setTimeout(i,50)},i=()=>{if(t.size===0){C.delete(e);return}if(!T(e)){e.promiseQueue.then(n,r);return}for(;t.size>0&&T(e);){let e,n;for(let[r,i]of t)(e===void 0||r<e)&&(e=r,n=i);n?.retire()}setTimeout(i,0)};setTimeout(i,0)}function T(e){return e.pendingDeliveries===0&&!E(e)}function E(e){let t=e.pendingDeliveryBarriers;if(!t||t.size===0)return!1;let n=new Map;for(let[e,r]of t)if(g(t,e,r,n))return!0;return!1}function D(e){return e.pendingDeliveries===0&&(!e.pendingDeliveryBarriers||e.pendingDeliveryBarriers.size===0)}function O(e,t){let n=()=>{D(e)?t():e.promiseQueue.then(()=>{setTimeout(n,0)})};setTimeout(n,0)}function k(e){let t=e.suspensionGeneration;O(e,()=>{t===e.suspensionGeneration&&e.onWorkflowError(new i(e.invocationsQueue,e.globalThis))})}export{S as a,k as c,r as d,n as f,D as i,a as l,p as n,f as o,E as r,O as s,x as t,i as u};
|