eve 0.7.0 → 0.7.2
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 +15 -0
- package/dist/docs/public/README.md +16 -11
- package/dist/docs/public/agent-config.md +9 -9
- package/dist/docs/public/channels/custom.mdx +4 -4
- package/dist/docs/public/channels/discord.mdx +1 -1
- package/dist/docs/public/channels/eve.mdx +9 -9
- package/dist/docs/public/channels/github.mdx +1 -1
- package/dist/docs/public/channels/overview.mdx +21 -15
- package/dist/docs/public/channels/slack.mdx +2 -2
- package/dist/docs/public/channels/teams.mdx +1 -1
- package/dist/docs/public/channels/telegram.mdx +1 -1
- package/dist/docs/public/channels/twilio.mdx +1 -1
- package/dist/docs/public/{advanced → concepts}/context-control.md +3 -3
- package/dist/docs/public/{advanced → concepts}/default-harness.md +3 -3
- package/dist/docs/public/{advanced → concepts}/execution-model-and-durability.md +3 -1
- package/dist/docs/public/concepts/meta.json +10 -0
- package/dist/docs/public/{advanced → concepts}/security-model.md +2 -2
- package/dist/docs/public/{advanced → concepts}/sessions-runs-and-streaming.md +7 -7
- package/dist/docs/public/connections.mdx +3 -3
- package/dist/docs/public/evals/cases.mdx +1 -1
- package/dist/docs/public/evals/overview.mdx +2 -2
- package/dist/docs/public/evals/running.mdx +1 -1
- package/dist/docs/public/evals/targets.mdx +1 -1
- package/dist/docs/public/getting-started.mdx +28 -35
- package/dist/docs/public/{advanced → guides}/auth-and-route-protection.md +2 -2
- package/dist/docs/public/{client → guides/client}/continuations.mdx +2 -2
- package/dist/docs/public/{client → guides/client}/messages.mdx +1 -1
- package/dist/docs/public/{client → guides/client}/meta.json +1 -1
- package/dist/docs/public/{client → guides/client}/output-schema.mdx +2 -2
- package/dist/docs/public/{client → guides/client}/overview.mdx +5 -5
- package/dist/docs/public/{client → guides/client}/streaming.mdx +1 -1
- package/dist/docs/public/{advanced → guides}/deployment.md +9 -1
- package/dist/docs/public/{advanced → guides}/dynamic-capabilities.md +1 -1
- package/dist/docs/public/{advanced → guides}/dynamic-workflows.md +1 -1
- package/dist/docs/public/{frontend → guides/frontend}/nextjs.mdx +3 -3
- package/dist/docs/public/{frontend → guides/frontend}/nuxt.mdx +3 -3
- package/dist/docs/public/{frontend → guides/frontend}/overview.mdx +6 -6
- package/dist/docs/public/{frontend → guides/frontend}/sveltekit.mdx +3 -3
- package/dist/docs/public/{frontend → guides/frontend}/use-eve-agent-svelte.mdx +2 -2
- package/dist/docs/public/{frontend → guides/frontend}/use-eve-agent-vue.mdx +2 -2
- package/dist/docs/public/{advanced → guides}/hooks.md +2 -2
- package/dist/docs/public/{advanced → guides}/instrumentation.md +2 -0
- package/dist/docs/public/{advanced → guides}/meta.json +8 -11
- package/dist/docs/public/{advanced → guides}/session-context.md +2 -2
- package/dist/docs/public/{advanced → guides}/state.md +1 -1
- package/dist/docs/public/instructions.mdx +2 -2
- package/dist/docs/public/introduction.md +5 -2
- package/dist/docs/public/meta.json +3 -3
- package/dist/docs/public/reference/cli.md +3 -3
- package/dist/docs/public/reference/meta.json +1 -1
- package/dist/docs/public/reference/project-layout.md +5 -1
- package/dist/docs/public/reference/typescript-api.md +23 -23
- package/dist/docs/public/sandbox.mdx +1 -1
- package/dist/docs/public/schedules.mdx +2 -2
- package/dist/docs/public/skills.mdx +3 -3
- package/dist/docs/public/subagents.mdx +3 -3
- package/dist/docs/public/tools.mdx +4 -4
- package/dist/docs/public/tutorial/connect-a-warehouse.mdx +2 -2
- package/dist/docs/public/tutorial/first-agent.mdx +1 -1
- package/dist/docs/public/tutorial/guard-the-spend.mdx +1 -1
- package/dist/docs/public/tutorial/how-it-runs.mdx +2 -2
- package/dist/docs/public/tutorial/meta.json +1 -1
- package/dist/docs/public/tutorial/query-sample-data.mdx +1 -1
- package/dist/docs/public/tutorial/remember-definitions.mdx +3 -3
- package/dist/docs/public/tutorial/run-analysis.mdx +1 -1
- package/dist/docs/public/tutorial/ship-it.mdx +4 -4
- package/dist/docs/public/tutorial/team-playbooks.mdx +3 -3
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +2 -2
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@workflow/core/capabilities.d.ts +19 -1
- package/dist/src/compiled/@workflow/core/class-serialization.d.ts +32 -0
- package/dist/src/compiled/@workflow/core/create-hook.d.ts +37 -0
- package/dist/src/compiled/@workflow/core/global.d.ts +11 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/start.d.ts +6 -0
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +15 -2
- package/dist/src/compiled/@workflow/core/runtime/wait-continuation.d.ts +84 -0
- package/dist/src/compiled/@workflow/core/runtime.js +27 -27
- package/dist/src/compiled/@workflow/core/serialization/types.d.ts +21 -0
- package/dist/src/compiled/@workflow/core/serialization.d.ts +72 -6
- package/dist/src/compiled/@workflow/core/symbols.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow/attribute-dispatcher.d.ts +6 -0
- package/dist/src/compiled/@workflow/core/workflow/set-attributes.d.ts +3 -4
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/world/events.d.ts +48 -0
- package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
- package/dist/src/compiled/@workflow/world/queue.d.ts +3 -0
- package/dist/src/compiled/@workflow/world/runs.d.ts +2 -0
- package/dist/src/compiled/@workflow/world/spec-version.d.ts +2 -1
- package/dist/src/compiled/_chunks/workflow/attribute-changes-DGVGRGfw.js +59 -0
- package/dist/src/compiled/_chunks/workflow/resume-hook-DMSadN9o.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-BRdn7zy_.js +1 -0
- package/dist/src/compiled/_chunks/workflow/sleep-CpXfoXLF.js +1 -0
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +2 -6
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/runtime/sandbox/keys.js +1 -1
- package/dist/src/setup/primitives/pm/pnpm.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/update/channels.js +1 -1
- package/package.json +6 -6
- package/dist/docs/public/reference/faqs.md +0 -48
- package/dist/src/compiled/_chunks/workflow/resume-hook-CEAS3opc.js +0 -12
- package/dist/src/compiled/_chunks/workflow/sleep-Cup6vPoA.js +0 -1
- package/dist/src/compiled/_chunks/workflow/symbols-BUTtwS7j.js +0 -48
- /package/dist/docs/public/{advanced → guides}/dev-tui.md +0 -0
- /package/dist/docs/public/{frontend → guides/frontend}/meta.json +0 -0
- /package/dist/docs/public/{advanced → guides}/remote-agents.md +0 -0
|
@@ -30,31 +30,31 @@ export default defineTool({
|
|
|
30
30
|
|
|
31
31
|
## The define\* helpers
|
|
32
32
|
|
|
33
|
-
| Helper | Import from | Authored at | Guide
|
|
34
|
-
| ------------------------------------------------------ | --------------------------------------------- | ------------------------------------ |
|
|
35
|
-
| `defineAgent` | `eve` | `agent/agent.ts` | [agent.ts](../agent-config)
|
|
36
|
-
| `defineTool` | `eve/tools` | `agent/tools/<name>.ts` | [Tools](../tools)
|
|
37
|
-
| `defineDynamic` | `eve/tools`, `eve/skills`, `eve/instructions` | `agent/{tools,skills,instructions}/` | [Dynamic capabilities](../
|
|
38
|
-
| `defineMcpClientConnection`, `defineOpenAPIConnection` | `eve/connections` | `agent/connections/<name>.ts` | [Connections](../connections)
|
|
39
|
-
| `defineChannel` | `eve/channels` | `agent/channels/<name>.ts` | [Custom channels](../channels/custom)
|
|
40
|
-
| `eveChannel`, `slackChannel`, and the other platforms | `eve/channels/<platform>` | `agent/channels/<platform>.ts` | [Channels](../channels/overview)
|
|
41
|
-
| `defineSkill` | `eve/skills` | `agent/skills/<name>.ts` | [Skills](../skills)
|
|
42
|
-
| `defineInstructions` | `eve/instructions` | `agent/instructions.ts` | [Instructions](../instructions)
|
|
43
|
-
| `defineHook` | `eve/hooks` | `agent/hooks/<slug>.ts` | [Hooks](../
|
|
44
|
-
| `defineSchedule` | `eve/schedules` | `agent/schedules/<name>.ts` | [Schedules](../schedules)
|
|
45
|
-
| `defineState` | `eve/context` | tools, hooks, lifecycle | [Session context](../
|
|
46
|
-
| `defineSandbox` | `eve/sandbox` | `agent/sandbox.ts` | [Sandbox](../sandbox)
|
|
47
|
-
| `defineInstrumentation` | `eve/instrumentation` | `agent/instrumentation.ts` | [instrumentation.ts](../
|
|
48
|
-
| `defineRemoteAgent` | `eve` | `agent/subagents/<id>/agent.ts` | [Remote agents](../
|
|
49
|
-
| `defineEval` | `eve/evals` | `evals/*.eval.ts` | [Evals](../evals/overview)
|
|
50
|
-
| `defineEvalConfig` | `eve/evals` | `evals/evals.config.ts` | [Evals](../evals/overview)
|
|
51
|
-
| `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../frontend/overview)
|
|
52
|
-
|
|
53
|
-
A few non-`define*` helpers round out the set: `disableTool` and `ExperimentalWorkflow` from `eve/tools` (see [Default harness](../
|
|
33
|
+
| Helper | Import from | Authored at | Guide |
|
|
34
|
+
| ------------------------------------------------------ | --------------------------------------------- | ------------------------------------ | ------------------------------------------------------ |
|
|
35
|
+
| `defineAgent` | `eve` | `agent/agent.ts` | [agent.ts](../agent-config) |
|
|
36
|
+
| `defineTool` | `eve/tools` | `agent/tools/<name>.ts` | [Tools](../tools) |
|
|
37
|
+
| `defineDynamic` | `eve/tools`, `eve/skills`, `eve/instructions` | `agent/{tools,skills,instructions}/` | [Dynamic capabilities](../guides/dynamic-capabilities) |
|
|
38
|
+
| `defineMcpClientConnection`, `defineOpenAPIConnection` | `eve/connections` | `agent/connections/<name>.ts` | [Connections](../connections) |
|
|
39
|
+
| `defineChannel` | `eve/channels` | `agent/channels/<name>.ts` | [Custom channels](../channels/custom) |
|
|
40
|
+
| `eveChannel`, `slackChannel`, and the other platforms | `eve/channels/<platform>` | `agent/channels/<platform>.ts` | [Channels](../channels/overview) |
|
|
41
|
+
| `defineSkill` | `eve/skills` | `agent/skills/<name>.ts` | [Skills](../skills) |
|
|
42
|
+
| `defineInstructions` | `eve/instructions` | `agent/instructions.ts` | [Instructions](../instructions) |
|
|
43
|
+
| `defineHook` | `eve/hooks` | `agent/hooks/<slug>.ts` | [Hooks](../guides/hooks) |
|
|
44
|
+
| `defineSchedule` | `eve/schedules` | `agent/schedules/<name>.ts` | [Schedules](../schedules) |
|
|
45
|
+
| `defineState` | `eve/context` | tools, hooks, lifecycle | [Session context](../guides/session-context) |
|
|
46
|
+
| `defineSandbox` | `eve/sandbox` | `agent/sandbox.ts` | [Sandbox](../sandbox) |
|
|
47
|
+
| `defineInstrumentation` | `eve/instrumentation` | `agent/instrumentation.ts` | [instrumentation.ts](../guides/instrumentation) |
|
|
48
|
+
| `defineRemoteAgent` | `eve` | `agent/subagents/<id>/agent.ts` | [Remote agents](../guides/remote-agents) |
|
|
49
|
+
| `defineEval` | `eve/evals` | `evals/*.eval.ts` | [Evals](../evals/overview) |
|
|
50
|
+
| `defineEvalConfig` | `eve/evals` | `evals/evals.config.ts` | [Evals](../evals/overview) |
|
|
51
|
+
| `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../guides/frontend/overview) |
|
|
52
|
+
|
|
53
|
+
A few non-`define*` helpers round out the set: `disableTool` and `ExperimentalWorkflow` from `eve/tools` (see [Default harness](../concepts/default-harness)), the route verbs `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`WS` from `eve/channels`, the approval predicates `always`/`once`/`never` from `eve/tools/approval`, and the channel auth helpers `localDev`/`vercelOidc`/`placeholderAuth` from `eve/channels/auth`. To wrap a built-in tool, import its default value from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`).
|
|
54
54
|
|
|
55
55
|
## Runtime context (`ctx`)
|
|
56
56
|
|
|
57
|
-
`ctx` is passed to your tool `execute`, hook handlers, and channel event handlers. It is live only while authored code is actually running, so reaching for it at module top level throws. See [Session context](../
|
|
57
|
+
`ctx` is passed to your tool `execute`, hook handlers, and channel event handlers. It is live only while authored code is actually running, so reaching for it at module top level throws. See [Session context](../guides/session-context) for the full model.
|
|
58
58
|
|
|
59
59
|
| Member | Use |
|
|
60
60
|
| -------------------------- | ----------------------------------------------------------------------------- |
|
|
@@ -90,7 +90,7 @@ A few non-`define*` helpers round out the set: `disableTool` and `ExperimentalWo
|
|
|
90
90
|
| `eve/evals/loaders` | `loadJson`, `loadYaml` |
|
|
91
91
|
| `eve/react`, `eve/vue`, `eve/svelte` | `useEveAgent` |
|
|
92
92
|
| `eve/next`, `eve/nuxt`, `eve/sveltekit` | framework bundler plugins |
|
|
93
|
-
| [`eve/client`](../client/overview)
|
|
93
|
+
| [`eve/client`](../guides/client/overview) | `Client`, `ClientSession` |
|
|
94
94
|
|
|
95
95
|
Exported types ship from the same entrypoint as the helper they describe (for example `ToolDefinition` and `ToolContext` from `eve/tools`). For the exhaustive list, read `packages/eve/src/public/index.ts`.
|
|
96
96
|
|
|
@@ -196,5 +196,5 @@ The `"*": []` catch-all keeps general egress open while the `transform` applies
|
|
|
196
196
|
|
|
197
197
|
- [Subagents](./subagents): each subagent gets its own sandbox, independent of its parent.
|
|
198
198
|
- [Tools](./tools): authored tools run in the app runtime (full `process.env`); only sandbox tools run in the sandbox.
|
|
199
|
-
- [Security model](./
|
|
199
|
+
- [Security model](./concepts/security-model): the app-runtime/sandbox trust boundary in full.
|
|
200
200
|
- [Vercel Sandbox](https://vercel.com/docs/sandbox): platform docs, including credential brokering and persistence limits.
|
|
@@ -90,7 +90,7 @@ curl -X POST http://localhost:3000/eve/v1/dev/schedules/heartbeat
|
|
|
90
90
|
# -> { "scheduleId": "heartbeat", "sessionIds": ["..."] }
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
`:scheduleId` is the path-derived schedule name (`agent/schedules/heartbeat.ts` → `heartbeat`; URL-encode the `/` in nested names). It runs the exact dispatch path the production cron handler uses and returns the started session ids as JSON, so you can subscribe to each one’s [stream](./
|
|
93
|
+
`:scheduleId` is the path-derived schedule name (`agent/schedules/heartbeat.ts` → `heartbeat`; URL-encode the `/` in nested names). It runs the exact dispatch path the production cron handler uses and returns the started session ids as JSON, so you can subscribe to each one’s [stream](./concepts/sessions-runs-and-streaming) at `GET /eve/v1/session/:sessionId/stream`. An unknown id comes back `404` with `availableScheduleIds`, listing the schedules the app actually defines.
|
|
94
94
|
|
|
95
95
|
The route is dev-only. Production builds never mount it, and it needs no auth since the dev server is local-only.
|
|
96
96
|
|
|
@@ -101,4 +101,4 @@ Hosted Vercel builds turn every `defineSchedule(...)` into a Vercel Cron Job, wi
|
|
|
101
101
|
## What to read next
|
|
102
102
|
|
|
103
103
|
- Deliver schedule output to users → [Channels](./channels/overview)
|
|
104
|
-
- Inspect a schedule run → [Sessions, runs & streaming](./
|
|
104
|
+
- Inspect a schedule run → [Sessions, runs & streaming](./concepts/sessions-runs-and-streaming)
|
|
@@ -70,10 +70,10 @@ The handle exposes the skill's `name` and `file(relativePath)`; file content is
|
|
|
70
70
|
|
|
71
71
|
## Dynamic skills
|
|
72
72
|
|
|
73
|
-
Want a different skill per principal, tenant, or channel, like the caller's own team playbook? Wrap `defineSkill` in a `defineDynamic` resolver keyed on `ctx.session.auth`. See [Dynamic capabilities](./
|
|
73
|
+
Want a different skill per principal, tenant, or channel, like the caller's own team playbook? Wrap `defineSkill` in a `defineDynamic` resolver keyed on `ctx.session.auth`. See [Dynamic capabilities](./guides/dynamic-capabilities).
|
|
74
74
|
|
|
75
75
|
## What to read next
|
|
76
76
|
|
|
77
77
|
- [Connections](./connections): add tools from external MCP and OpenAPI servers
|
|
78
|
-
- [Dynamic capabilities](./
|
|
79
|
-
- [Context control](./
|
|
78
|
+
- [Dynamic capabilities](./guides/dynamic-capabilities): resolve skills per caller with `defineDynamic`
|
|
79
|
+
- [Context control](./concepts/context-control): how skills fit the full context model
|
|
@@ -62,7 +62,7 @@ The built-in `agent` tool is the exception: its children share the parent's sand
|
|
|
62
62
|
|
|
63
63
|
## What the parent sees
|
|
64
64
|
|
|
65
|
-
Eve lowers every subagent (built-in copy, declared, or [remote](./
|
|
65
|
+
Eve lowers every subagent (built-in copy, declared, or [remote](./guides/remote-agents)) into a model-visible tool with the same `{ message, outputSchema? }` shape. The parent packs `message` with everything the child needs, since the child never sees the parent's history. Set `outputSchema` and the child runs in task mode, returning structured output as the tool result.
|
|
66
66
|
|
|
67
67
|
Each delegated subagent spins up its own child session and stream. The parent stream carries only the control-plane events `subagent.called` and `subagent.completed`. To follow the child's full progress, read `subagent.called.data.childSessionId` and subscribe at `GET /eve/v1/session/:childSessionId/stream`.
|
|
68
68
|
|
|
@@ -72,5 +72,5 @@ Split out a subagent when the task needs a different prompt or specialist role,
|
|
|
72
72
|
|
|
73
73
|
## What to read next
|
|
74
74
|
|
|
75
|
-
- Call another Eve deployment as a subagent → [Remote agents](./
|
|
76
|
-
- Have the model orchestrate its subagents programmatically (fan-out, map-reduce) → [Dynamic workflows](./
|
|
75
|
+
- Call another Eve deployment as a subagent → [Remote agents](./guides/remote-agents)
|
|
76
|
+
- Have the model orchestrate its subagents programmatically (fan-out, map-reduce) → [Dynamic workflows](./guides/dynamic-workflows)
|
|
@@ -85,7 +85,7 @@ Approvals and questions share one protocol:
|
|
|
85
85
|
|
|
86
86
|
The run picks back up exactly where it parked, and channels render the request for you. The Slack adapter, for example, turns approvals into buttons and questions into select menus.
|
|
87
87
|
|
|
88
|
-
See [Sessions, runs & streaming](./
|
|
88
|
+
See [Sessions, runs & streaming](./concepts/sessions-runs-and-streaming) for the event and resume contract.
|
|
89
89
|
|
|
90
90
|
## Shape what the model sees with `toModelOutput`
|
|
91
91
|
|
|
@@ -102,6 +102,6 @@ It receives the full, typed `execute` return and only affects the model. Channel
|
|
|
102
102
|
## What to read next
|
|
103
103
|
|
|
104
104
|
- [Skills](./skills): on-demand procedures the model loads when relevant
|
|
105
|
-
- [Default harness](./
|
|
106
|
-
- [Dynamic capabilities](./
|
|
107
|
-
- [Auth & route protection](./
|
|
105
|
+
- [Default harness](./concepts/default-harness): the built-in tools and how to override or disable them
|
|
106
|
+
- [Dynamic capabilities](./guides/dynamic-capabilities): tools whose set is resolved per session with `defineDynamic`
|
|
107
|
+
- [Auth & route protection](./guides/auth-and-route-protection): authenticate a tool to an external service
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Step 4: Connect a
|
|
2
|
+
title: "Step 4: Connect a Warehouse"
|
|
3
3
|
description: "Let each user connect their own warehouse over an OAuth MCP via Vercel Connect."
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -44,4 +44,4 @@ If you want more control, gate the connection behind approval (`approval: once()
|
|
|
44
44
|
|
|
45
45
|
→ Next: [Step 5: Run analysis](./run-analysis)
|
|
46
46
|
|
|
47
|
-
Depth: [Connections](../connections) · [Auth & route protection](../
|
|
47
|
+
Depth: [Connections](../connections) · [Auth & route protection](../guides/auth-and-route-protection)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Step 2: How
|
|
2
|
+
title: "Step 2: How It Runs"
|
|
3
3
|
description: "Session, turn, and durable steps: what you just watched, and why it survives a crash."
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -21,4 +21,4 @@ Your job is to author capabilities: tools, instructions, channels, skills. Eve d
|
|
|
21
21
|
|
|
22
22
|
→ Next: [Step 3: Query sample data](./query-sample-data)
|
|
23
23
|
|
|
24
|
-
Depth: [Execution model & durability](../
|
|
24
|
+
Depth: [Execution model & durability](../concepts/execution-model-and-durability)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Step 6: Remember
|
|
2
|
+
title: "Step 6: Remember Definitions"
|
|
3
3
|
description: "Use defineState to remember the team's metric glossary across turns."
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -65,8 +65,8 @@ export default defineTool({
|
|
|
65
65
|
|
|
66
66
|
The second turn is a separate turn in the same session, yet the definition is still there. State checkpoints at step boundaries, so it's the same durability from [Step 2](./how-it-runs), now applied to your own data.
|
|
67
67
|
|
|
68
|
-
State is scoped to a session and isolated per agent, so a subagent starts with fresh state and never sees the parent's. Need to reset something each turn? Call `update(() => fresh)` in a lifecycle hook. More in [State](../
|
|
68
|
+
State is scoped to a session and isolated per agent, so a subagent starts with fresh state and never sees the parent's. Need to reset something each turn? Call `update(() => fresh)` in a lifecycle hook. More in [State](../guides/state).
|
|
69
69
|
|
|
70
70
|
→ Next: [Step 7: Team playbooks](./team-playbooks)
|
|
71
71
|
|
|
72
|
-
Depth: [State](../
|
|
72
|
+
Depth: [State](../guides/state)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Step 9: Ship
|
|
2
|
+
title: "Step 9: Ship It"
|
|
3
3
|
description: "Put a web dashboard on the agent with useEveAgent, replace placeholderAuth, and deploy to Vercel."
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -51,7 +51,7 @@ export function AnalyticsChat() {
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
`agent.data.messages` and `agent.status` cover most chat UIs. The hook also surfaces HITL prompts (the spend approval from [Step 8](./guard-the-spend)), so the dashboard can render approve/deny controls. Full API: [Frontend](../frontend/overview).
|
|
54
|
+
`agent.data.messages` and `agent.status` cover most chat UIs. The hook also surfaces HITL prompts (the spend approval from [Step 8](./guard-the-spend)), so the dashboard can render approve/deny controls. Full API: [Frontend](../guides/frontend/overview).
|
|
55
55
|
|
|
56
56
|
## Replace `placeholderAuth`
|
|
57
57
|
|
|
@@ -95,6 +95,6 @@ eve dev https://your-analytics-app.vercel.app
|
|
|
95
95
|
|
|
96
96
|
That's the full assistant, deployed and authed. It queries the warehouse, runs analysis in a sandbox, charts the results, remembers your team's definitions, loads the right playbook per team, and asks before it spends.
|
|
97
97
|
|
|
98
|
-
Depth: [Frontend](../frontend/overview) · [Auth & route protection](../
|
|
98
|
+
Depth: [Frontend](../guides/frontend/overview) · [Auth & route protection](../guides/auth-and-route-protection) · [Deployment](../guides/deployment)
|
|
99
99
|
|
|
100
|
-
Go deeper on this same example in [Advanced](../
|
|
100
|
+
Go deeper on this same example in [Advanced](../guides/dynamic-capabilities): schema-derived dynamic tools, a read-only analyst subagent, and model-authored report workflows.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Step 7: Team
|
|
2
|
+
title: "Step 7: Team Playbooks"
|
|
3
3
|
description: "Load the caller's team playbook with a dynamic skill keyed on the principal."
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -56,8 +56,8 @@ A Growth user asks "what's our 8-week retention?" The model sees the playbook fi
|
|
|
56
56
|
|
|
57
57
|
The team comes from authenticated claims, not from the message, so one tenant can't borrow another's playbook by asking nicely. (Those `attributes` are set by the auth layer in [Step 9](./ship-it).)
|
|
58
58
|
|
|
59
|
-
The same `defineDynamic` resolver drives dynamic tools and instructions too. For the full mechanism, see [Dynamic capabilities](../
|
|
59
|
+
The same `defineDynamic` resolver drives dynamic tools and instructions too. For the full mechanism, see [Dynamic capabilities](../guides/dynamic-capabilities).
|
|
60
60
|
|
|
61
61
|
→ Next: [Step 8: Guard the spend](./guard-the-spend)
|
|
62
62
|
|
|
63
|
-
Depth: [Skills](../skills) · [Dynamic capabilities](../
|
|
63
|
+
Depth: [Skills](../skills) · [Dynamic capabilities](../guides/dynamic-capabilities)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function createPromptCommandHandler(
|
|
1
|
+
import{toErrorMessage}from"#shared/errors.js";function createPromptCommandHandler(t){return{async handle(n,r){let i=t.appRoot;if(i===void 0)return{message:`/${n.name} needs eve dev running the local server (it is not available with --url).`};if(n.name===`model`&&n.argument.length>0)try{let{changeAgentModel:e,formatApplyModelOutcome:r}=await import(`#setup/flows/model.js`);return{message:r(await(t.applyModel??e)({appRoot:i,slug:n.argument}))}}catch(t){return{message:`Couldn't change the model: ${toErrorMessage(t)}`}}let a=r.renderer.setupFlow;if(a===void 0)return{message:`/${n.name} is not supported by this renderer.`};let o;try{o=await import(`./setup-commands.js`)}catch(t){return{message:`/${n.name} failed: ${toErrorMessage(t)}`}}let{runTuiSetupCommand:s,SETUP_FLOW_TITLES:c}=o;a.begin(c[n.name]);let l=!0;try{let e={command:n.name,appRoot:i,renderer:a};t.flows!==void 0&&(e.flows=t.flows);let r=await s(e);l=r.preserveFlowDiagnostics;let o={message:r.message};return r.vercelEffect!==void 0&&(o.vercelEffect=r.vercelEffect),o}finally{a.end({preserveDiagnostics:l})}}}}export{createPromptCommandHandler};
|
|
@@ -194,8 +194,8 @@ export type AgentTUIRenderer = {
|
|
|
194
194
|
*/
|
|
195
195
|
reset?(): void;
|
|
196
196
|
/**
|
|
197
|
-
* Tears down interactive mode and restores the terminal
|
|
198
|
-
*
|
|
197
|
+
* Tears down interactive mode and restores the terminal when the runner's
|
|
198
|
+
* lifecycle ends.
|
|
199
199
|
*/
|
|
200
200
|
shutdown?(): void;
|
|
201
201
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pickAgentHeaderTip}from"./agent-header.js";import{formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{BOOT_DETECTIONS,detectSetupIssues,formatSetupIssuesLine}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";import{toErrorMessage}from"#shared/errors.js";var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_=pickAgentHeaderTip();#v;#y=new Map;#b=new Map;#x=new Map;#S=new Map;#C=new Set;#w=!1;constructor(e){if(this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e),this.#r=e.name??`Eve`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??toErrorMessage,e.appRoot!==void 0){this.#p=e.appRoot;let t={appRoot:e.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};e.detectProjectIdentity!==void 0&&(t.detectIdentity=e.detectProjectIdentity),this.#g=createVercelStatusTracker(t)}e.promptCommandHandler!==void 0&&(this.#m=e.promptCommandHandler),this.#h=e.bootDetections??BOOT_DETECTIONS,e.serverUrl!==void 0&&(this.#f=e.serverUrl,this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#T(){let e=this.#f;if(e===void 0){await this.#A(void 0);return}let t;try{t=await this.#t?.info()}catch{t=void 0}this.#v=t;let n={name:this.#r,serverUrl:e};t!==void 0&&(n.info=t),this.#p!==void 0&&(n.tip=this.#_),this.#n.renderAgentHeader?.(n),await this.#A(t)}async run(){try{await this.#E()}finally{this.#g?.dispose()}}async#E(){let e=this.#r,r,i,a=!1,o=!1;for(await this.#T(),this.#g?.refreshIdentity();;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}try{r=await this.#O({title:e})}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let s=parsePromptCommand(r);if(s?.type===`exit`){this.#n.shutdown?.();return}if(s?.type===`new`){this.#D(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(s?.type===`help`){this.#j(formatPromptCommandHelp()),i=void 0,o=!1,r=void 0;continue}if(s?.type===`loglevel`){this.#j(this.#M(s.argument)),i=void 0,o=!1,r=void 0;continue}if(s?.type===`extension`){try{let t=this.#m===void 0?{message:`/${s.name} is not available in this session.`}:await this.#m.handle(s,{renderer:this.#n,title:e});t?.message!==void 0&&this.#j(t.message),t?.vercelEffect!==void 0&&this.#g?.applyEffect(t.vercelEffect)}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let s=await this.#k({prompt:o?void 0:r,inputResponses:i});try{await this.#n.renderStream(s,{title:e,submittedPrompt:r,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=s.turnState?.pendingApprovals??[],n=s.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#y.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#y.delete(t.requestId)}}o=!0,i=a,r=void 0;continue}s.turnState&&s.turnState.boundaryEvent===void 0&&(this.#w=!0)}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0,this.#w&&(this.#w=!1,this.#D(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#D(){for(let e of this.#x.values())e.abort();this.#x.clear(),this.#b.clear(),this.#y.clear(),this.#S.clear(),this.#C.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#O(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#N(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#k(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#N(),session:this.#e})),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#w=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#y,subagentRuns:this.#b,turnState:i,onSubagentCalled:e=>this.#L(e),onSubagentCompleted:e=>this.#z(e),onConnectionAuthRequired:e=>this.#P(e),onConnectionAuthCompleted:e=>this.#F(e),onTerminalFailure:()=>{this.#w=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#A(e){if(this.#p===void 0||this.#n.renderSetupWarning===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e);let n=await detectSetupIssues(t,this.#h);n.length!==0&&this.#n.renderSetupWarning(formatSetupIssuesLine(n))}#j(e){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}#M(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`all`:return`Showing all logs.`}}async#N(){let e=this.#v,t;try{t=await this.#t?.info()}catch{t=void 0}if(t!==void 0&&(this.#v=t,this.#f!==void 0)){let e={info:t,name:this.#r,serverUrl:this.#f};this.#p!==void 0&&(e.tip=this.#_),this.#n.renderAgentHeader?.(e)}(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#P(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#S.set(e.data.name,t),this.#I(t)}#F(e){let t=this.#S.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#S.set(e.data.name,t),this.#C.delete(e.data.name),this.#I(t),this.#n.setConnectionAuthPendingCount?.(this.#C.size)}#I(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#L(e){let t=e.data.callId;if(this.#x.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#x.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#B(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#b.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#x.delete(t)}})()}#R(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#z(e){let t=this.#b.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#B(e,t){let n=this.#b.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#R(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#R(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,input:e.userInput,output:e.screen})}function parseLogDisplayMode(e){return e===`all`||e===`stderr`||e===`none`?e:void 0}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=new Set,v=!1,y=!1,b;for await(let e of t)if(!(y&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;b=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data,n=t.actions.filter(e=>e.kind===`tool-call`);if(n.length===0)break;let r=toolBatchKey(`actions.requested`,t.turnId,t.stepIndex,n);if(g.has(r)){for(let e of n)m.has(e.callId)||h.add(e.callId);break}g.add(r);for(let e of n)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data,r=t.requests.filter(e=>e.action.kind===`tool-call`);if(r.length===0)break;let a=inputRequestBatchKey(t.turnId,t.stepIndex,r);if(g.has(a)){for(let e of r)m.has(e.action.callId)||h.add(e.action.callId);break}g.add(a);for(let e of r){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(h.has(n)||!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,_,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,_,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!0;return;case`turn.completed`:y=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}v||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`action.result`:case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function toolBatchKey(e,t,n,r){return`${e}:${t}:${String(n)}:${stableStringify(r.map(e=>({input:e.input,toolName:e.toolName})))}`}function inputRequestBatchKey(e,t,n){return toolBatchKey(`input.requested`,e,t,n.map(e=>({input:e.action.input,toolName:e.action.toolName})))}function stableStringify(e){return JSON.stringify(toStableJson(e))??`undefined`}function toStableJson(e,t=new WeakSet){if(typeof e!=`object`||!e)return e;if(t.has(e))return`[Circular]`;if(t.add(e),Array.isArray(e))return e.map(e=>toStableJson(e,t));let n=e,r={};for(let e of Object.keys(n).sort())r[e]=toStableJson(n[e],t);return r}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let o=failureKey(e);if(t.has(o))return;t.add(o);let s=n?.(e),c={type:`error`,errorText:s??formatFailureMessage(e)};if(s!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
|
|
1
|
+
import{pickAgentHeaderTip}from"./agent-header.js";import{formatPromptCommandHelp,parsePromptCommand}from"./prompt-commands.js";import{failureKey,formatFailureDetail,formatFailureMessage,formatGatewayAuthFailureNotice,isAbortLikeError,isGatewayAuthFailure,isInterruptedError}from"./errors.js";import{BOOT_DETECTIONS,detectSetupIssues,formatSetupIssuesLine}from"./setup-issues.js";import{TerminalRenderer}from"./terminal-renderer.js";import{createVercelStatusTracker}from"./vercel-status.js";import{toErrorMessage}from"#shared/errors.js";import{isCurrentTurnBoundaryEvent}from"#client/index.js";import{createDevelopmentRuntimeArtifactSessionRefresher}from"#services/dev-client.js";var EveTUIRunner=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_=pickAgentHeaderTip();#v;#y=new Map;#b=new Map;#x=new Map;#S=new Map;#C=new Set;#w=!1;constructor(e){if(this.#e=e.session,e.client!==void 0&&(this.#t=e.client),this.#n=createRenderer(e),this.#r=e.name??`Eve`,this.#i=e.tools??`full`,this.#a=e.reasoning??`full`,this.#o=e.subagents??`full`,this.#s=e.connectionAuth??`full`,this.#c=e.assistantResponseStats??`tokensPerSecond`,this.#l=e.contextSize,this.#u=e.formatTransportError??toErrorMessage,e.appRoot!==void 0){this.#p=e.appRoot;let t={appRoot:e.appRoot,onChange:e=>this.#n.setVercelStatus?.(e)};e.detectProjectIdentity!==void 0&&(t.detectIdentity=e.detectProjectIdentity),this.#g=createVercelStatusTracker(t)}e.promptCommandHandler!==void 0&&(this.#m=e.promptCommandHandler),this.#h=e.bootDetections??BOOT_DETECTIONS,e.serverUrl!==void 0&&(this.#f=e.serverUrl,this.#d=createDevelopmentRuntimeArtifactSessionRefresher({serverUrl:e.serverUrl}))}async#T(){let e=this.#f;if(e===void 0){await this.#A(void 0);return}let t;try{t=await this.#t?.info()}catch{t=void 0}this.#v=t;let n={name:this.#r,serverUrl:e};t!==void 0&&(n.info=t),this.#p!==void 0&&(n.tip=this.#_),this.#n.renderAgentHeader?.(n),await this.#A(t)}async run(){try{await this.#E()}finally{this.#n.shutdown?.(),this.#g?.dispose()}}async#E(){let e=this.#r,r,i,a=!1,o=!1;for(await this.#T(),this.#g?.refreshIdentity();;){if(!o){if(r==null){if(!this.#n.readPrompt){if(a)return;throw Error(`No prompt was provided and the renderer does not support prompt input.`)}try{r=await this.#O({title:e})}catch(e){if(isInterruptedError(e))return;throw e}if(r==null)return}let s=parsePromptCommand(r);if(s?.type===`exit`)return;if(s?.type===`new`){this.#D(),i=void 0,o=!1,r=void 0,this.#n.reset?.();continue}if(s?.type===`help`){this.#j(formatPromptCommandHelp()),i=void 0,o=!1,r=void 0;continue}if(s?.type===`loglevel`){this.#j(this.#M(s.argument)),i=void 0,o=!1,r=void 0;continue}if(s?.type===`extension`){try{let t=this.#m===void 0?{message:`/${s.name} is not available in this session.`}:await this.#m.handle(s,{renderer:this.#n,title:e});t?.message!==void 0&&this.#j(t.message),t?.vercelEffect!==void 0&&this.#g?.applyEffect(t.vercelEffect)}catch(e){if(isInterruptedError(e))return;throw e}i=void 0,r=void 0,o=!1;continue}a=!0}let s=await this.#k({prompt:o?void 0:r,inputResponses:i});try{await this.#n.renderStream(s,{title:e,submittedPrompt:r,continueSession:!!this.#n.readPrompt,tools:this.#i,reasoning:this.#a,subagents:this.#o,connectionAuth:this.#s,assistantResponseStats:this.#c,contextSize:this.#l});let t=s.turnState?.pendingApprovals??[],n=s.turnState?.pendingQuestions??[];if(t.length>0||n.length>0){let a=[];if(t.length>0){if(!this.#n.readToolApproval)throw Error(`Tool approval was requested, but the renderer does not support tool approval input.`);for(let n of t){let t=await this.#n.readToolApproval(n,{title:e});a.push({requestId:n.approvalId,optionId:t.approved?`approve`:`deny`}),this.#y.delete(n.approvalId)}}if(n.length>0){if(!this.#n.readInputQuestion)throw Error(`An interactive question was requested, but the renderer does not support input questions.`);for(let t of n){let n=toAgentTUIInputQuestion(t),r=await this.#n.readInputQuestion(n,{title:e});if(r===void 0)continue;let i={requestId:t.requestId};r.optionId!==void 0&&(i.optionId=r.optionId),r.text!==void 0&&(i.text=r.text),a.push(i),this.#y.delete(t.requestId)}}o=!0,i=a,r=void 0;continue}s.turnState&&s.turnState.boundaryEvent===void 0&&(this.#w=!0)}catch(e){if(isInterruptedError(e))return;throw e}o=!1,i=void 0,r=void 0,this.#w&&(this.#w=!1,this.#D(),this.#n.renderNotice?.(`Session ended — started a new session. Earlier context was cleared.`))}}#D(){for(let e of this.#x.values())e.abort();this.#x.clear(),this.#b.clear(),this.#y.clear(),this.#S.clear(),this.#C.clear(),this.#t&&(this.#e=this.#t.session()),this.#d?.clear()}async#O(e){if(!this.#n.readPrompt)return;let t=this.#n.readPrompt(e),n=this.#t,r=this.#d;if(n===void 0||r===void 0)return await t;let i=!1,a=!1,o,refresh=async()=>{if(!(i||a)){a=!0;try{this.#e=await r.refreshIdle({createSession:()=>n.session(),onRuntimeArtifactsChanged:()=>this.#N(),session:this.#e})}finally{a=!1}}},startRefresh=()=>{if(i||a)return;let e=refresh().finally(()=>{o===e&&(o=void 0)});o=e};startRefresh();let s=setInterval(()=>{startRefresh()},500);s.unref?.();try{return await t}finally{i=!0,clearInterval(s),await o}}async#k(e){let t=new AbortController,n={signal:t.signal};e.prompt!==void 0&&(n.message=e.prompt),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses);let r;try{let e=this.#t;e!==void 0&&this.#d!==void 0&&(this.#e=await this.#d.refresh({createSession:()=>e.session(),inputResponses:n.inputResponses,message:n.message,onRuntimeArtifactsChanged:()=>this.#N(),session:this.#e})),r=await this.#e.send(n)}catch(e){if(isInterruptedError(e))throw e;return this.#w=!0,{events:errorOnlyTUIStream({errorText:this.#u(e)}),turnState:createTurnState()}}let i=createTurnState();return{abort:()=>t.abort(),events:eveEventsToTUIStream({events:r,pendingInputRequests:this.#y,subagentRuns:this.#b,turnState:i,onSubagentCalled:e=>this.#L(e),onSubagentCompleted:e=>this.#z(e),onConnectionAuthRequired:e=>this.#P(e),onConnectionAuthCompleted:e=>this.#F(e),onTerminalFailure:()=>{this.#w=!0},failureOverride:this.#p===void 0?void 0:e=>isGatewayAuthFailure(e)?formatGatewayAuthFailureNotice(e):void 0}),turnState:i}}async#A(e){if(this.#p===void 0||this.#n.renderSetupWarning===void 0)return;let t={appRoot:this.#p,env:process.env};e!==void 0&&(t.info=e);let n=await detectSetupIssues(t,this.#h);n.length!==0&&this.#n.renderSetupWarning(formatSetupIssuesLine(n))}#j(e){if(this.#n.renderCommandResult!==void 0){this.#n.renderCommandResult(e);return}this.#n.renderNotice?.(e)}#M(e){let t=this.#n;if(t.logDisplayMode===void 0||t.setLogDisplayMode===void 0)return`/loglevel is not available in this session.`;if(e===``)return`Logs: ${t.logDisplayMode()}. Use /loglevel all|stderr|none — logs stay buffered, so switching also hides or restores past lines.`;let n=parseLogDisplayMode(e);if(n===void 0)return`Unknown log level "${e}". Use all, stderr, or none.`;if(n===t.logDisplayMode())return`Logs already set to ${n}.`;switch(t.setLogDisplayMode(n),n){case`none`:return`Logs hidden. Output stays buffered — /loglevel all restores it.`;case`stderr`:return`Showing stderr logs only.`;case`all`:return`Showing all logs.`}}async#N(){let e=this.#v,t;try{t=await this.#t?.info()}catch{t=void 0}if(t!==void 0&&(this.#v=t,this.#f!==void 0)){let e={info:t,name:this.#r,serverUrl:this.#f};this.#p!==void 0&&(e.tip=this.#_),this.#n.renderAgentHeader?.(e)}(!this.#n.renderAgentHeader||t===void 0)&&this.#n.renderNotice?.(formatAgentUpdateNotice(e,t))}#P(e){let t={name:e.data.name,description:e.data.description,state:`required`};e.data.authorization!==void 0&&(t.challenge=e.data.authorization),e.data.webhookUrl!==void 0&&(t.webhookUrl=e.data.webhookUrl),this.#S.set(e.data.name,t),this.#I(t)}#F(e){let t=this.#S.get(e.data.name)??{name:e.data.name,description:``,state:e.data.outcome};t.state=e.data.outcome,e.data.reason!==void 0&&(t.reason=e.data.reason),this.#S.set(e.data.name,t),this.#C.delete(e.data.name),this.#I(t),this.#n.setConnectionAuthPendingCount?.(this.#C.size)}#I(e){let t={name:e.name,description:e.description,state:e.state};e.challenge!==void 0&&(t.challenge=e.challenge),e.reason!==void 0&&(t.reason=e.reason),this.#n.upsertConnectionAuth?.(t)}#L(e){let t=e.data.callId;if(this.#x.has(t))return;let n=this.#t;if(!n)return;let r=new AbortController;this.#x.set(t,r),(async()=>{try{let i=n.session({sessionId:e.data.childSessionId,streamIndex:0}).stream({signal:r.signal});for await(let e of i)if(r.signal.aborted||(this.#B(t,e),isCurrentTurnBoundaryEvent(e)))break}catch(e){if(!isAbortLikeError(e)){let n=toErrorMessage(e),r=this.#b.get(t);if(r){let{key:e,step:i}=openCurrentSubagentSection(r);i.message=i.message?`${i.message}\n\nstream error: ${n}`:`stream error: ${n}`,i.finalized=!0,r.currentSectionKey=null,this.#n.upsertSubagentStep?.({callId:t,subagentName:r.name,sectionKey:e,reasoning:i.reasoning,message:i.message,finalized:!0})}}}finally{this.#x.delete(t)}})()}#R(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e={"approval-requested":0,executing:1,done:2,failed:2};e[n.status]>e[r.status]&&(r.status=n.status),r.input=n.input}else t.tools.set(n.childCallId,i);this.#n.markChildToolCallId?.(n.childCallId),this.#n.upsertSubagentTool?.({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#z(e){let t=this.#b.get(e);if(t){for(let[n,r]of t.steps)r.finalized||(r.finalized=!0,this.#n.upsertSubagentStep?.({callId:e,subagentName:t.name,sectionKey:n,reasoning:r.reasoning,message:r.message,finalized:!0}));t.currentSectionKey=null}}#B(e,t){let n=this.#b.get(e);if(!n)return;let r=this.#n,emit=(t,i)=>{r.upsertSubagentStep?.({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent();break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#R(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#R(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;t.data.status===`failed`?(a.status=`failed`,a.errorText=formatActionResultError(t)):(a.status=`done`,a.output=i.output);let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r.upsertSubagentTool?.(o);break}default:break}}};function createRenderer(e){return e.renderer?e.renderer:new TerminalRenderer({tools:e.tools,reasoning:e.reasoning,subagents:e.subagents,connectionAuth:e.connectionAuth,assistantResponseStats:e.assistantResponseStats,contextSize:e.contextSize,logs:e.logs,input:e.userInput,output:e.screen})}function parseLogDisplayMode(e){return e===`all`||e===`stderr`||e===`none`?e:void 0}function formatAgentUpdateNotice(e,t){let n=e?.agent.model.id,r=t?.agent.model.id;return n!==void 0&&r!==void 0&&n!==r?`Agent updated: Model ${n} -> ${r}`:`Agent updated.`}async function*eveEventsToTUIStream(e){let{events:t,pendingInputRequests:n,subagentRuns:r,turnState:i,onSubagentCalled:a,onSubagentCompleted:o,onConnectionAuthRequired:s,onConnectionAuthCompleted:c,onTerminalFailure:l,failureOverride:u}=e,d=new Map,f=new Map,p=0,m=new Set,h=new Set,g=new Set,_=new Set,v=!1,y=!1,b;for await(let e of t)if(!(y&&isPostTurnVisibleEvent(e)))switch(e.type){case`session.started`:case`turn.started`:case`message.received`:break;case`step.started`:p+=1,yield{type:`step-start`};break;case`step.completed`:{let t=e;b=t.data.usage,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`step-finish`,usage:t.data.usage};break}case`message.appended`:{let t=e,n=textPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(d,n),i=t.data.messageSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`assistant-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`message.completed`:{let t=textPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(d,t),r=e.data.message;if(n.completed){if(r===null||r===n.text||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p,yield{type:`assistant-complete`,id:partGenerationId(t,n.generation),text:r};break}let i=partGenerationId(t,n.generation);if(r!==null){if(n.text.length===0)n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i,text:r};else if(r.startsWith(n.text)){let e=r.slice(n.text.length);e.length>0&&(yield{type:`assistant-delta`,id:i,delta:e}),n.text=r,n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i}}}else n.text.length>0&&(n.completed=!0,n.completedEpoch=p,yield{type:`assistant-complete`,id:i});break}case`reasoning.appended`:{let t=e,n=reasoningPartId(t.data.turnId,t.data.stepIndex),r=partStateFor(f,n),i=t.data.reasoningSoFar;if(r.completed){if(r.text.startsWith(i)||p<=r.completedEpoch)break;r.generation+=1,r.text=``,r.completed=!1}if(!i.startsWith(r.text)||i.length<=r.text.length)break;let a=i.slice(r.text.length);r.text=i,yield{type:`reasoning-delta`,id:partGenerationId(n,r.generation),delta:a};break}case`reasoning.completed`:{let t=reasoningPartId(e.data.turnId,e.data.stepIndex),n=partStateFor(f,t),r=e.data.reasoning;if(n.completed){if(r.length===0||r===n.text||n.text.startsWith(r)||p<=n.completedEpoch)break;n.generation+=1,n.text=r,n.completedEpoch=p;let e=partGenerationId(t,n.generation);yield{type:`reasoning-delta`,id:e,delta:r},yield{type:`reasoning-complete`,id:e};break}let i=partGenerationId(t,n.generation);if(n.text.length===0&&r.length>0)n.text=r,yield{type:`reasoning-delta`,id:i,delta:r};else if(r.length>0&&!r.startsWith(n.text))break;n.completed=!0,n.completedEpoch=p,yield{type:`reasoning-complete`,id:i};break}case`actions.requested`:{let t=e.data,n=t.actions.filter(e=>e.kind===`tool-call`);if(n.length===0)break;let r=toolBatchKey(`actions.requested`,t.turnId,t.stepIndex,n);if(g.has(r)){for(let e of n)m.has(e.callId)||h.add(e.callId);break}g.add(r);for(let e of n)m.has(e.callId)||(m.add(e.callId),yield{type:`tool-call`,toolCallId:e.callId,toolName:e.toolName,input:e.input});break}case`input.requested`:{let t=e.data,r=t.requests.filter(e=>e.action.kind===`tool-call`);if(r.length===0)break;let a=inputRequestBatchKey(t.turnId,t.stepIndex,r);if(g.has(a)){for(let e of r)m.has(e.action.callId)||h.add(e.action.callId);break}g.add(a);for(let e of r){let t=e.action.callId;if(m.has(t)||(m.add(t),yield{type:`tool-call`,toolCallId:t,toolName:e.action.toolName,input:e.action.input}),n.set(e.requestId,e),isQuestionRequest(e)){upsertPendingQuestion(i,e);continue}upsertPendingApproval(i,e),yield{type:`tool-approval-request`,approvalId:e.requestId,toolCallId:t}}break}case`action.result`:{let t=e;if(t.data.result.kind!==`tool-result`)break;let n=t.data.result.callId;if(h.has(n)||!m.has(n))break;t.data.status===`failed`?yield{type:`tool-error`,toolCallId:n,errorText:formatActionResultError(t)}:yield{type:`tool-result`,toolCallId:n,output:t.data.result.output};break}case`step.failed`:case`turn.failed`:{let t=toFailureEvent(e,_,u);t&&(yield t);break}case`session.failed`:{i.sawSessionFailure=!0,l?.(e);let t=toFailureEvent(e,_,u);t&&(yield t),i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!0;return}case`session.waiting`:case`session.completed`:i.boundaryEvent=e.type,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b},v=!0;return;case`turn.completed`:y=!0,yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p);break;case`subagent.called`:{let t=e;if(!r.has(t.data.callId))r.set(t.data.callId,{name:t.data.name,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map});else{let e=r.get(t.data.callId);e&&(e.name=t.data.name)}a?.(t);break}case`subagent.started`:case`subagent.event`:break;case`subagent.completed`:o?.(e.data.callId);break;case`authorization.required`:s?.(e);break;case`authorization.completed`:c?.(e);break;default:break}v||(yield*closeOpenParts(d,`assistant-complete`,p),yield*closeOpenParts(f,`reasoning-complete`,p),yield{type:`finish`,usage:b})}async function*errorOnlyTUIStream(e){yield{type:`error`,errorText:e.errorText},yield{type:`finish`}}function createTurnState(){return{pendingApprovals:[],pendingQuestions:[],sawSessionFailure:!1}}function upsertPendingApproval(e,t){let n=toAgentTUIToolApprovalRequest(t),r=e.pendingApprovals.findIndex(e=>e.approvalId===n.approvalId);r===-1?e.pendingApprovals.push(n):e.pendingApprovals[r]=n}function toAgentTUIToolApprovalRequest(e){return{approvalId:e.requestId,toolCallId:e.action.callId,toolName:e.action.toolName,input:e.action.input}}function upsertPendingQuestion(e,t){let n=e.pendingQuestions.findIndex(e=>e.requestId===t.requestId);n===-1?e.pendingQuestions.push(t):e.pendingQuestions[n]=t}function textPartId(e,t){return`text:${e}:${t}`}function reasoningPartId(e,t){return`reasoning:${e}:${t}`}function partStateFor(e,t){let n=e.get(t);return n===void 0&&(n={generation:0,text:``,completed:!1,completedEpoch:0},e.set(t,n)),n}function partGenerationId(e,t){return t===0?e:`${e}#${t}`}function*closeOpenParts(e,t,n){for(let[r,i]of e)i.completed||i.text.length===0||(i.completed=!0,i.completedEpoch=n,yield{type:t,id:partGenerationId(r,i.generation)})}function isPostTurnVisibleEvent(e){switch(e.type){case`action.result`:case`actions.requested`:case`authorization.completed`:case`authorization.required`:case`input.requested`:case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:case`result.completed`:case`step.completed`:case`step.failed`:case`step.started`:case`subagent.called`:case`subagent.completed`:case`subagent.event`:case`subagent.started`:case`turn.completed`:case`turn.failed`:return!0;default:return!1}}function toolBatchKey(e,t,n,r){return`${e}:${t}:${String(n)}:${stableStringify(r.map(e=>({input:e.input,toolName:e.toolName})))}`}function inputRequestBatchKey(e,t,n){return toolBatchKey(`input.requested`,e,t,n.map(e=>({input:e.action.input,toolName:e.action.toolName})))}function stableStringify(e){return JSON.stringify(toStableJson(e))??`undefined`}function toStableJson(e,t=new WeakSet){if(typeof e!=`object`||!e)return e;if(t.has(e))return`[Circular]`;if(t.add(e),Array.isArray(e))return e.map(e=>toStableJson(e,t));let n=e,r={};for(let e of Object.keys(n).sort())r[e]=toStableJson(n[e],t);return r}function formatActionResultError(e){if(e.data.error?.message)return e.data.error.message;let t=e.data.result.output;if(typeof t==`string`)return t;try{return JSON.stringify(t)}catch{return`Tool execution failed.`}}function toFailureEvent(e,t,n){let o=failureKey(e);if(t.has(o))return;t.add(o);let s=n?.(e),c={type:`error`,errorText:s??formatFailureMessage(e)};if(s!==void 0)return c;let l=formatFailureDetail(e);return l!==void 0&&(c.detail=l),c}function isQuestionRequest(e){return e.display===`select`||e.display===`text`?!0:e.display===`confirmation`?!1:e.options!==void 0&&e.options.length>0}function toAgentTUIInputQuestion(e){let t=e.display===`text`?`text`:e.display===`select`||e.options!==void 0&&e.options.length>0?`select`:`text`,n={requestId:e.requestId,prompt:e.prompt,display:t};return e.options!==void 0&&(n.options=e.options.map(e=>{let t={id:e.id,label:e.label};return e.description!==void 0&&(t.description=e.description),e.style!==void 0&&(t.style=e.style),t})),e.allowFreeform!==void 0&&(n.allowFreeform=e.allowFreeform),n}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{EveTUIRunner,parsePromptCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createPromptCommandHandler}from"./prompt-command-handler.js";import{EveTUIRunner}from"./runner.js";import{
|
|
1
|
+
import{createPromptCommandHandler}from"./prompt-command-handler.js";import{EveTUIRunner}from"./runner.js";import{toErrorMessage}from"#shared/errors.js";import{Client}from"#client/index.js";import{resolveDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{formatVercelAuthChallengeMessage,isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";async function runDevelopmentTui(t){let{serverUrl:n,appRoot:r,...i}=t,a=new Client(resolveDevelopmentClientOptions(n)),o={...i,session:a.session(),client:a,serverUrl:n,promptCommandHandler:createPromptCommandHandler({appRoot:r}),formatTransportError:e=>isVercelAuthChallenge(e)?formatVercelAuthChallengeMessage({serverUrl:n}):toErrorMessage(e)};r!==void 0&&(o.appRoot=r),await new EveTUIRunner(o).run()}export{runDevelopmentTui};
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"turndown": "7.2.4",
|
|
23
23
|
"@vercel/oidc": "3.5.0",
|
|
24
24
|
"@vercel/sandbox": "2.1.0",
|
|
25
|
-
"@workflow/core": "5.0.0-beta.
|
|
25
|
+
"@workflow/core": "5.0.0-beta.15",
|
|
26
26
|
"@workflow/errors": "5.0.0-beta.7",
|
|
27
|
-
"@workflow/world": "5.0.0-beta.
|
|
27
|
+
"@workflow/world": "5.0.0-beta.9",
|
|
28
28
|
"zod": "4.4.3",
|
|
29
29
|
"zod-validation-error": "5.0.0"
|
|
30
30
|
},
|
|
@@ -15,11 +15,19 @@
|
|
|
15
15
|
* `@workflow/core` version that supports it
|
|
16
16
|
* 3. The `getRunCapabilities()` function will automatically include it
|
|
17
17
|
*
|
|
18
|
+
* ## Adding a new non-format capability
|
|
19
|
+
*
|
|
20
|
+
* Some capabilities aren't serialization format prefixes — e.g.
|
|
21
|
+
* byte-stream wire framing is an envelope around chunks rather than
|
|
22
|
+
* a content format. For those, add a boolean field to `RunCapabilities`
|
|
23
|
+
* and an entry in `CAPABILITY_VERSION_TABLE` below.
|
|
24
|
+
*
|
|
18
25
|
* ## History
|
|
19
26
|
*
|
|
20
27
|
* - `encr` (AES-256-GCM encryption): added in `4.2.0-beta.64`
|
|
21
28
|
* Commit: 7618ac36 "Wire AES-GCM encryption into serialization layer (#1251)"
|
|
22
29
|
* https://github.com/vercel/workflow/commit/7618ac36
|
|
30
|
+
* - `framedByteStreams` (wire-level chunk framing for byte streams): added in `5.0.0-beta.15`
|
|
23
31
|
*/
|
|
24
32
|
import { type SerializationFormatType } from './serialization.js';
|
|
25
33
|
/**
|
|
@@ -32,6 +40,15 @@ export interface RunCapabilities {
|
|
|
32
40
|
* if encryption is supported, etc.
|
|
33
41
|
*/
|
|
34
42
|
supportedFormats: ReadonlySet<SerializationFormatType>;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the target run can decode wire-framed byte streams. When true,
|
|
45
|
+
* byte streams (`type: 'bytes'` ReadableStreams passed across boundaries)
|
|
46
|
+
* are wrapped in a length-prefixed frame envelope on the wire so the
|
|
47
|
+
* reader can identify chunk boundaries — which enables auto-reconnect
|
|
48
|
+
* on transient stream errors. When false, byte streams are written as
|
|
49
|
+
* raw bytes (the legacy format) for compatibility with older runs.
|
|
50
|
+
*/
|
|
51
|
+
framedByteStreams: boolean;
|
|
35
52
|
}
|
|
36
53
|
/**
|
|
37
54
|
* Look up what serialization capabilities a workflow run supports based on
|
|
@@ -39,7 +56,8 @@ export interface RunCapabilities {
|
|
|
39
56
|
*
|
|
40
57
|
* When the version is `undefined`, not a string, or not a valid semver string
|
|
41
58
|
* (e.g. very old runs that predate the field, or corrupted metadata),
|
|
42
|
-
* we assume the most conservative capabilities (baseline formats only
|
|
59
|
+
* we assume the most conservative capabilities (baseline formats only,
|
|
60
|
+
* non-format capabilities all `false`).
|
|
43
61
|
*/
|
|
44
62
|
export declare function getRunCapabilities(workflowCoreVersion: string | undefined): RunCapabilities;
|
|
45
63
|
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -18,6 +18,38 @@
|
|
|
18
18
|
* when serializing instances (e.g., step return values).
|
|
19
19
|
*/
|
|
20
20
|
export declare function registerSerializationClass(classId: string, cls: Function): void;
|
|
21
|
+
/**
|
|
22
|
+
* Stable, well-known registry id for the SDK's `Run` class.
|
|
23
|
+
*
|
|
24
|
+
* The SWC plugin auto-registers `Run` under a *path-derived* id (e.g.
|
|
25
|
+
* `class//./node_modules/@workflow/core/dist/runtime/run//Run`), which
|
|
26
|
+
* varies with the app's dependency layout and bundler. Host-side code
|
|
27
|
+
* that needs to construct `Run` instances inside the workflow VM (e.g.
|
|
28
|
+
* the hook event consumer resolving `hook.getConflict()`) cannot know
|
|
29
|
+
* that id statically, so the workflow-mode `create-hook` module also
|
|
30
|
+
* aliases the bundle's `Run` under this stable id at evaluation time.
|
|
31
|
+
*
|
|
32
|
+
* The `workflow` pseudo-path cannot collide with plugin-derived ids,
|
|
33
|
+
* which always use real relative module paths (`./…` / `../…`).
|
|
34
|
+
*/
|
|
35
|
+
export declare const RUN_CLASS_ID = "class//workflow//Run";
|
|
36
|
+
/**
|
|
37
|
+
* Register an additional registry id for a class without touching its
|
|
38
|
+
* `classId` property.
|
|
39
|
+
*
|
|
40
|
+
* Unlike {@link registerSerializationClass}, this is safe to call for a
|
|
41
|
+
* class the SWC plugin has already registered: the plugin's inlined IIFE
|
|
42
|
+
* defines `classId` as non-configurable, so a second `defineProperty`
|
|
43
|
+
* would throw. Aliasing only adds a registry entry — the class keeps
|
|
44
|
+
* serializing under its primary (path-derived) id, while lookups succeed
|
|
45
|
+
* under both.
|
|
46
|
+
*
|
|
47
|
+
* Registration is per-global by construction: evaluated inside the
|
|
48
|
+
* workflow VM it registers the VM's compiled class on the VM's registry;
|
|
49
|
+
* evaluated on the host it registers the host class on the host's
|
|
50
|
+
* registry. Each context resolves its own correct variant.
|
|
51
|
+
*/
|
|
52
|
+
export declare function aliasSerializationClass(classId: string, cls: Function, global?: Record<string, any>): void;
|
|
21
53
|
/**
|
|
22
54
|
* Find a registered class constructor by ID (used during deserialization)
|
|
23
55
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Run } from './runtime/run.js';
|
|
1
2
|
import type { Serializable } from './schemas.js';
|
|
2
3
|
/**
|
|
3
4
|
* An object that can be awaited to receive a value.
|
|
@@ -24,6 +25,42 @@ export interface Hook<T = any> extends AsyncIterable<T>, Thenable<T> {
|
|
|
24
25
|
* The token used to identify this hook.
|
|
25
26
|
*/
|
|
26
27
|
token: string;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a promise that resolves with the conflicting {@link Run} if
|
|
30
|
+
* another active hook already owns this hook's token, or `null` once
|
|
31
|
+
* the hook has been registered and is ready to receive payloads.
|
|
32
|
+
*
|
|
33
|
+
* Calling `createHook()` alone does not register the hook — registration
|
|
34
|
+
* only happens when the workflow suspends. Awaiting `getConflict()`
|
|
35
|
+
* suspends the workflow to commit the hook registration, so it can be
|
|
36
|
+
* used to claim the token (and detect token conflicts early) without
|
|
37
|
+
* waiting for payload data.
|
|
38
|
+
*
|
|
39
|
+
* When a conflict is detected, the resolved `Run` is the run that
|
|
40
|
+
* currently owns the token. The workflow can decide how to handle the
|
|
41
|
+
* duplicate in code: return or log `conflict.runId`, inspect
|
|
42
|
+
* `await conflict.status`, await `conflict.returnValue`, or cancel the
|
|
43
|
+
* owner with `await conflict.cancel()` and continue in the current run.
|
|
44
|
+
*
|
|
45
|
+
* Note that awaiting the hook's payload (`await hook`) when the token is
|
|
46
|
+
* already owned by another active hook still rejects with
|
|
47
|
+
* `HookConflictError`. In the rare case where the conflicting run cannot
|
|
48
|
+
* be identified (a `hook_conflict` event persisted by an old world that
|
|
49
|
+
* did not record the owning run's ID), `getConflict()` also rejects with
|
|
50
|
+
* `HookConflictError` rather than resolving with an incomplete value.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* using hook = createHook({ token: `order:${orderId}` });
|
|
55
|
+
* const conflict = await hook.getConflict();
|
|
56
|
+
* if (conflict) {
|
|
57
|
+
* // another run already owns this token
|
|
58
|
+
* return { dedupedTo: conflict.runId };
|
|
59
|
+
* }
|
|
60
|
+
* // token is now claimed, without waiting for payload data
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
getConflict(): Promise<Run<unknown> | null>;
|
|
27
64
|
/**
|
|
28
65
|
* Disposes the hook, releasing its token for reuse by other workflows.
|
|
29
66
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AttributeChange } from '#compiled/@workflow/world/index.js';
|
|
1
2
|
import type { Serializable } from './schemas.js';
|
|
2
3
|
export interface StepInvocationQueueItem {
|
|
3
4
|
type: 'step';
|
|
@@ -14,6 +15,8 @@ export interface HookInvocationQueueItem {
|
|
|
14
15
|
token: string;
|
|
15
16
|
metadata?: Serializable;
|
|
16
17
|
hasCreatedEvent?: boolean;
|
|
18
|
+
/** Whether the workflow is awaiting `hook.getConflict()` for this hook */
|
|
19
|
+
hasConflictAwaiter?: boolean;
|
|
17
20
|
disposed?: boolean;
|
|
18
21
|
isWebhook?: boolean;
|
|
19
22
|
isSystem?: boolean;
|
|
@@ -26,7 +29,13 @@ export interface WaitInvocationQueueItem {
|
|
|
26
29
|
resumeAt: Date;
|
|
27
30
|
hasCreatedEvent?: boolean;
|
|
28
31
|
}
|
|
29
|
-
export
|
|
32
|
+
export interface AttributeInvocationQueueItem {
|
|
33
|
+
type: 'attribute';
|
|
34
|
+
correlationId: string;
|
|
35
|
+
changes: AttributeChange[];
|
|
36
|
+
allowReservedAttributes?: true;
|
|
37
|
+
}
|
|
38
|
+
export type QueueItem = StepInvocationQueueItem | HookInvocationQueueItem | WaitInvocationQueueItem | AttributeInvocationQueueItem;
|
|
30
39
|
/**
|
|
31
40
|
* An error that is thrown when one or more operations (steps/hooks/etc.) are called but do
|
|
32
41
|
* not yet have corresponding entries in the event log. The workflow
|
|
@@ -39,6 +48,7 @@ export declare class WorkflowSuspension extends Error {
|
|
|
39
48
|
stepCount: number;
|
|
40
49
|
hookCount: number;
|
|
41
50
|
waitCount: number;
|
|
51
|
+
attributeCount: number;
|
|
42
52
|
hookDisposedCount: number;
|
|
43
53
|
abortCount: number;
|
|
44
54
|
constructor(stepsInput: Map<string, QueueItem>, global: typeof globalThis);
|