eve 0.62.0 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/src/cli/dev/tui/model-picker.d.ts +48 -0
  3. package/dist/src/cli/dev/tui/model-picker.js +1 -0
  4. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  5. package/dist/src/cli/dev/tui/runner.js +2 -2
  6. package/dist/src/cli/dev/tui/setup-commands.d.ts +1 -1
  7. package/dist/src/cli/dev/tui/setup-commands.js +1 -1
  8. package/dist/src/cli/dev/tui/setup-flow.d.ts +2 -2
  9. package/dist/src/cli/dev/tui/setup-panel.d.ts +1 -26
  10. package/dist/src/cli/dev/tui/setup-panel.js +3 -3
  11. package/dist/src/cli/dev/tui/stream-format.d.ts +0 -7
  12. package/dist/src/cli/dev/tui/stream-format.js +1 -1
  13. package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
  14. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  15. package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -1
  16. package/dist/src/cli/dev/tui/test/mock-terminal.js +1 -1
  17. package/dist/src/cli/dev/tui/theme.d.ts +0 -8
  18. package/dist/src/cli/dev/tui/theme.js +1 -1
  19. package/dist/src/compiled/.vendor-stamp.json +1 -1
  20. package/dist/src/compiler/extension-compatibility.d.ts +25 -6
  21. package/dist/src/compiler/extension-compatibility.js +1 -1
  22. package/dist/src/compiler/normalize-agent-config.js +1 -1
  23. package/dist/src/compiler/normalize-tool.js +1 -1
  24. package/dist/src/context/build-dynamic-tools.js +1 -1
  25. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  26. package/dist/src/evals/runner/derive-run-facts.js +1 -1
  27. package/dist/src/evals/types.d.ts +4 -3
  28. package/dist/src/eve-channel/request.js +1 -1
  29. package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
  30. package/dist/src/execution/cancel-indexed-session-tasks-step.d.ts +2 -1
  31. package/dist/src/execution/cancel-indexed-session-tasks-step.js +1 -1
  32. package/dist/src/execution/coordination-dispatch-shared.d.ts +1 -6
  33. package/dist/src/execution/coordination-dispatch-shared.js +1 -1
  34. package/dist/src/execution/coordination-dispatch-step.js +1 -1
  35. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  36. package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
  37. package/dist/src/execution/node-step.js +1 -1
  38. package/dist/src/execution/proxied-deliver-step.js +1 -1
  39. package/dist/src/execution/route-child-delivery.js +3 -1
  40. package/dist/src/execution/session/admission.js +1 -1
  41. package/dist/src/execution/session/handoff-steps.js +1 -1
  42. package/dist/src/execution/session/handoff.d.ts +2 -1
  43. package/dist/src/execution/session/handoff.js +1 -1
  44. package/dist/src/execution/session/input-queue.d.ts +2 -0
  45. package/dist/src/execution/session/input-queue.js +1 -1
  46. package/dist/src/execution/session/next-input.js +1 -1
  47. package/dist/src/execution/session/turn.js +1 -1
  48. package/dist/src/execution/session-workflow-tool-run.js +1 -1
  49. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  50. package/dist/src/execution/stable-workflow-names.d.ts +0 -1
  51. package/dist/src/execution/stable-workflow-names.js +1 -1
  52. package/dist/src/execution/tasks/child/notify.d.ts +44 -0
  53. package/dist/src/execution/tasks/child/notify.js +1 -0
  54. package/dist/src/execution/tasks/parent/control-shared.d.ts +2 -5
  55. package/dist/src/execution/tasks/parent/control-shared.js +1 -1
  56. package/dist/src/execution/tasks/parent/delegate.d.ts +8 -36
  57. package/dist/src/execution/tasks/parent/delegate.js +1 -1
  58. package/dist/src/execution/tasks/parent/dispatch.d.ts +3 -5
  59. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  60. package/dist/src/execution/tasks/parent/hitl-proxy-steps.d.ts +4 -1
  61. package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
  62. package/dist/src/execution/tasks/parent/run-parent.d.ts +5 -19
  63. package/dist/src/execution/tasks/parent/run-parent.js +1 -1
  64. package/dist/src/execution/tasks/parent/task-cancel.d.ts +6 -5
  65. package/dist/src/execution/tasks/parent/task-cancel.js +1 -1
  66. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  67. package/dist/src/execution/tool-auth.d.ts +3 -9
  68. package/dist/src/execution/tool-auth.js +1 -1
  69. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  70. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  71. package/dist/src/execution/tools/subagent/accept-event-step.js +1 -1
  72. package/dist/src/execution/tools/subagent/emit-event-step.d.ts +11 -0
  73. package/dist/src/execution/tools/subagent/emit-event-step.js +1 -0
  74. package/dist/src/execution/tools/subagent/invoke-agent.d.ts +5 -7
  75. package/dist/src/execution/tools/subagent/invoke-agent.js +1 -1
  76. package/dist/src/execution/tools/subagent/invoke-preparation.js +1 -1
  77. package/dist/src/execution/tools/subagent/invoke-step.d.ts +3 -2
  78. package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
  79. package/dist/src/execution/tools/subagent/task-agent-requests.d.ts +0 -1
  80. package/dist/src/execution/tools/subagent/task-agent-requests.js +1 -1
  81. package/dist/src/execution/tools/subagent/task-cancel.d.ts +1 -1
  82. package/dist/src/execution/tools/subagent/task-cancel.js +1 -1
  83. package/dist/src/execution/tools/workflow/background.d.ts +1 -1
  84. package/dist/src/execution/tools/workflow/background.js +1 -1
  85. package/dist/src/execution/tools/workflow/body.d.ts +0 -2
  86. package/dist/src/execution/tools/workflow/body.js +1 -1
  87. package/dist/src/execution/tools/workflow/cancel.d.ts +4 -3
  88. package/dist/src/execution/tools/workflow/cancel.js +1 -1
  89. package/dist/src/execution/tools/workflow/cancellation-policy.d.ts +2 -0
  90. package/dist/src/execution/tools/workflow/cancellation-policy.js +1 -0
  91. package/dist/src/execution/tools/workflow/messages.d.ts +0 -1
  92. package/dist/src/execution/tools/workflow/owner-channels.d.ts +6 -6
  93. package/dist/src/execution/tools/workflow/owner-inbox.d.ts +5 -9
  94. package/dist/src/execution/tools/workflow/owner-inbox.js +1 -1
  95. package/dist/src/execution/tools/workflow/owner.d.ts +6 -2
  96. package/dist/src/execution/tools/workflow/owner.js +1 -1
  97. package/dist/src/execution/tools/workflow/start.js +1 -1
  98. package/dist/src/execution/tools/workflow/types.d.ts +11 -19
  99. package/dist/src/execution/tools/workflow/types.js +1 -1
  100. package/dist/src/execution/tools/workflow/workflow-owner-background.d.ts +13 -0
  101. package/dist/src/execution/tools/workflow/workflow-owner-background.js +1 -0
  102. package/dist/src/execution/tools/workflow/workflow-owner-blocking.d.ts +12 -0
  103. package/dist/src/execution/tools/workflow/workflow-owner-blocking.js +1 -0
  104. package/dist/src/execution/tools/workflow/workflow.d.ts +3 -3
  105. package/dist/src/execution/tools/workflow/workflow.js +1 -1
  106. package/dist/src/execution/workflow-runtime.d.ts +0 -4
  107. package/dist/src/execution/workflow-runtime.js +1 -1
  108. package/dist/src/harness/background-tools.d.ts +3 -5
  109. package/dist/src/harness/coordination.js +1 -1
  110. package/dist/src/harness/emission.js +1 -1
  111. package/dist/src/harness/execute-tool.d.ts +2 -29
  112. package/dist/src/harness/tool-loop.js +1 -1
  113. package/dist/src/harness/tool-model-output.js +1 -1
  114. package/dist/src/harness/tools.js +1 -1
  115. package/dist/src/harness/workflow-tool-runs.d.ts +53 -18
  116. package/dist/src/harness/workflow-tool-runs.js +1 -1
  117. package/dist/src/internal/application/package.js +1 -1
  118. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  119. package/dist/src/protocol/message.d.ts +4 -4
  120. package/dist/src/public/tools/index.d.ts +2 -2
  121. package/dist/src/runtime/agent/resolve-model.js +1 -1
  122. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  123. package/dist/src/runtime/sessions/turn.d.ts +10 -8
  124. package/dist/src/runtime/subagents/registry.js +1 -1
  125. package/dist/src/runtime/subagents/workflow.js +1 -1
  126. package/dist/src/runtime/tools/registry.js +1 -1
  127. package/dist/src/setup/flows/model.d.ts +5 -5
  128. package/dist/src/setup/scaffold/create/project.js +1 -1
  129. package/dist/src/shared/action-types.d.ts +0 -4
  130. package/dist/src/shared/action-types.js +1 -1
  131. package/dist/src/tasks/delivery-context.js +2 -2
  132. package/dist/src/tasks/notification.d.ts +4 -0
  133. package/dist/src/tasks/notification.js +1 -0
  134. package/dist/src/tasks/session-task-cohorts.d.ts +1 -12
  135. package/dist/src/tasks/session-task-cohorts.js +1 -1
  136. package/dist/src/tasks/transitions.d.ts +5 -2
  137. package/dist/src/tasks/transitions.js +1 -1
  138. package/dist/src/tasks/types.d.ts +2 -52
  139. package/dist/src/tasks/types.js +1 -1
  140. package/dist/src/tools/definition.d.ts +1 -25
  141. package/dist/src/tools/definition.js +1 -1
  142. package/dist/src/tools/dynamic.d.ts +1 -3
  143. package/dist/src/tools/framework/agent.d.ts +16 -22
  144. package/dist/src/tools/framework/agent.js +1 -1
  145. package/dist/src/tools/workflow-definition.d.ts +16 -5
  146. package/dist/src/tracing/agent-invocation-coordinator.js +1 -1
  147. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  148. package/docs/concepts/execution-model-and-durability.mdx +4 -5
  149. package/docs/concepts/sessions-runs-and-streaming.md +2 -2
  150. package/docs/evals/assertions.mdx +5 -1
  151. package/docs/guides/dev-tui.md +21 -9
  152. package/docs/guides/frontend/overview.mdx +1 -1
  153. package/docs/subagents/index.mdx +12 -9
  154. package/docs/tools/overview.mdx +26 -34
  155. package/docs/tools/workflows.mdx +31 -24
  156. package/package.json +1 -1
  157. package/dist/src/cli/dev/tui/model-editor.d.ts +0 -103
  158. package/dist/src/cli/dev/tui/model-editor.js +0 -1
  159. package/dist/src/execution/tasks/child/steps.d.ts +0 -81
  160. package/dist/src/execution/tasks/child/steps.js +0 -1
  161. package/dist/src/execution/tasks/child/workflow.d.ts +0 -28
  162. package/dist/src/execution/tasks/child/workflow.js +0 -1
  163. package/dist/src/execution/tools/subagent/emit-called-step.d.ts +0 -9
  164. package/dist/src/execution/tools/subagent/emit-called-step.js +0 -1
  165. package/dist/src/execution/tools/workflow/run-control.d.ts +0 -14
  166. package/dist/src/execution/tools/workflow/run-control.js +0 -1
  167. package/dist/src/tasks/session-index.d.ts +0 -65
  168. package/dist/src/tasks/session-index.js +0 -1
  169. package/dist/src/tools/task.d.ts +0 -55
  170. package/dist/src/tools/task.js +0 -1
@@ -118,12 +118,11 @@ Some work has to wait, including a human approving a [tool](../tools) or an inte
118
118
  Background execution is a separate choice about result delivery. A background workflow tool
119
119
  returns a task receipt so the parent turn can continue; the tool's workflow may then run or
120
120
  suspend independently. A default workflow tool can suspend too, with its original tool call
121
- still pending. Ordinary background tools run their executor inside the initiating step and do
122
- not gain durable waits by setting `execution: "background"`.
121
+ still pending. Declare background work with `defineWorkflowTool`; `defineTool` always executes
122
+ inside its initiating step.
123
123
 
124
- A generator's `yield` reports progress; an awaited workflow operation provides the durable wait.
125
- For background tools, ordinary yields are stream-only, while `yield task.postMessage(...)`
126
- requests a parent-agent turn. See [background execution](../tools#background-execution) and
124
+ An awaited workflow operation provides the durable wait. A generator's `yield` reports progress
125
+ in default execution; background workflow tools consume yields without publishing progress. See [background execution](../tools#background-execution) and
127
126
  [workflow suspension](../tools/workflows#how-suspension-works) for the execution and result rules.
128
127
 
129
128
  ## Message delivery and steering
@@ -80,7 +80,7 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
80
80
  | `input.requested` | The run paused for human input ([HITL](/docs/human-in-the-loop) approval or `ask_question`); carries `requests`. |
81
81
  | `input.resolved` | The server accepted terminal human-input outcomes; carries `resolutions` with responses when provided. |
82
82
  | `subagent.called` | A subagent was delegated; carries `childSessionId` to attach to. |
83
- | `subagent.completed` | A background subagent was admitted and returned its task receipt. |
83
+ | `subagent.completed` | The parent recorded a successful subagent invocation result; carries the actual output. |
84
84
  | `reasoning.appended` | A reasoning text delta. |
85
85
  | `reasoning.completed` | The finalized reasoning block. |
86
86
  | `message.appended` | An assistant text delta. |
@@ -119,7 +119,7 @@ Note: consider the privacy, confidentiality, and user-experience implications fo
119
119
 
120
120
  When a task explicitly requires conditional delivery and there is nothing new to report, the agent can finish with exactly `<eve-empty-delivery/>`. eve emits `message.completed` with `message: null` for that intentional silence. The marker must be the entire response, apart from surrounding whitespace; the HTML-escaped form `&lt;eve-empty-delivery/&gt;` is also accepted. A response that quotes the marker in prose or code is delivered normally.
121
121
 
122
- A delegated subagent publishes progress on its own child-session stream. The parent emits `subagent.called` with a `childSessionId`, which a client uses to attach. `subagent.completed` carries a working task receipt after admission; terminal outcomes arrive as task-triggered `message.received` notifications with `data.kind: "execution.background_task"`. The default frontend reducer retains these events in `events` but does not project their runtime-authored text as participant messages.
122
+ A delegated subagent publishes progress on its own child-session stream. The parent emits `subagent.called` with a `childSessionId`, which a client uses to attach. Both blocking and background calls emit `subagent.completed` with the actual output after the parent records a successful outcome. A background working receipt is an `action.result` tool output; it does not emit completion. Older streams can contain receipt-bearing completion events marked by `data.backgroundTask`; those are admission only. Completion does not mean that the reusable child session has ended. Background task terminal outcomes also arrive as task-triggered `message.received` notifications with `data.kind: "execution.background_task"`. The default frontend reducer retains these events in `events` but does not project their runtime-authored text as participant messages.
123
123
 
124
124
  `step.failed` and `turn.failed` carry `{ code, message, details? }` for the failed fragment or turn, and `session.failed` is the terminal session-level variant. `turn.cancelled` is not a failure: the cancelled turn ends without any failure event, `session.waiting` follows, and the session accepts the next message normally. Whatever the turn streamed before cancellation stays on the stream. Durable history keeps the accepted user input and previously settled work, but discards incomplete assistant output and unfinished tool state. When a turn requested an output schema, the finalized payload lands on `result.completed` as `data.result` before the turn boundary. `authorization.required` carries the sign-in challenge (`data.authorization` may include `url`, `userCode`, `expiresAt`, `instructions`), and `authorization.completed` carries `data.outcome` (`"authorized" | "declined" | "failed" | "timed-out"`).
125
125
 
@@ -83,7 +83,11 @@ Pick the cheapest builder that captures what "correct" means. When exact match i
83
83
 
84
84
  ## The matcher mini-language
85
85
 
86
- `t.calledTool` and `t.calledSubagent` take matcher objects. Tools accept `{ input, output, status, count }`; subagents accept `{ callId, childSessionId, remoteUrl, output, status, count }`. Calls match `status: "completed"` by default; use `"pending"`, `"failed"`, or `"rejected"` explicitly for lifecycle checks. A numeric `count` requires an exact number of calls matching every supplied constraint. Use a predicate for ranges or other custom count requirements; it receives the observed number of matching calls.
86
+ `t.calledTool` and `t.calledSubagent` take matcher objects. Tools accept `{ input, output, status, count }`; subagents accept `{ callId, childSessionId, remoteUrl, output, status, count }`. Calls match `status: "completed"` by default. Tool lifecycle checks also accept `"pending"`, `"failed"`, and `"rejected"`. Subagent checks use the shared task status values: `"working"`, `"input_required"`, `"completed"`, `"failed"`, and `"cancelled"`. A numeric `count` requires an exact number of calls matching every supplied constraint. Use a predicate for ranges or other custom count requirements; it receives the observed number of matching calls.
87
+
88
+ A background subagent that has only returned a working task receipt remains `working`; use `t.calledSubagent(name, { status: "working" })` to assert that delegation. Both blocking and background calls become `completed` when their actual successful result is observed through `subagent.completed`, even when the child session stays available for another call. A rejected dispatch is `failed`; an explicit cancelled child outcome is `cancelled`.
89
+
90
+ The runner derives these values from captured events. It does not read stored task state, and the current stream does not expose every task transition. A proxied input request alone does not update the subagent call to `input_required`; assert that request with `requireInputRequest`. Check task notifications for background failure and cancellation when no child outcome event is present.
87
91
 
88
92
  Matcher values accept a literal (objects partial-deep-match), a RegExp, or a predicate function that returns a boolean:
89
93
 
@@ -17,19 +17,19 @@ The transcript remains in your terminal scrollback after you exit. Run `/help` i
17
17
 
18
18
  | Command | Description |
19
19
  | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
20
+ | `/model` | Choose the model, speed, and reasoning. Pass a model ID to set it directly: `/model provider/model-id`. |
21
+ | `/reset` | Start a fresh session. |
22
+ | `/clear` | Clear the session's model-message history. `/new` is an alias. |
23
+ | `/compact` | Compact the current session's context. |
24
+ | `/cancel` | Cancel the current turn without discarding settled context. |
20
25
  | `/login` | Connect a ChatGPT subscription, Vercel account, or provider API key. |
21
- | `/model` | Choose the model and its settings. Pass a model ID to set it directly: `/model provider/model-id`. |
22
26
  | `/add` | Select and install channels, MCP connections, extensions, and observability integrations. Pass an item address to install it directly: `/add channel/slack`. |
23
27
  | `/deploy` | Deploy the agent to Vercel production. Installs the Vercel CLI, signs in, and links the directory if needed. |
24
- | `/info` | Show the resolved application, compiled artifacts, discovery diagnostics, and messaging routes. |
25
- | `/loglevel` | Choose which server and agent logs appear in the transcript. |
26
28
  | `/traces` | Open the local trace viewer. Pass a trace ID prefix to open a specific trace. |
27
- | `/reset` | Start a fresh session. |
28
- | `/cancel` | Cancel the current turn without discarding settled context. |
29
- | `/clear` | Clear the session's model-message history. `/new` is an alias. |
30
- | `/compact` | Compact the current session's context. |
31
- | `/exit` | Quit the UI. |
29
+ | `/loglevel` | Choose which server and agent logs appear in the transcript. |
30
+ | `/info` | Show the resolved application, compiled artifacts, discovery diagnostics, and messaging routes. |
32
31
  | `/help` | List available commands. |
32
+ | `/exit` | Quit the UI. |
33
33
 
34
34
  `/login`, `/model`, `/add`, `/deploy`, `/info`, and `/traces` are available when `eve dev` runs locally. They are unavailable when the UI connects to a server with `--url`.
35
35
 
@@ -59,7 +59,17 @@ Local discovery runs only in development. Deployments need explicitly provisione
59
59
 
60
60
  ### Models and settings
61
61
 
62
- `/model` opens the model picker and settings. Each completed selection applies immediately and returns to chat; there is no final Done step. A successful login or model change takes effect on the next prompt.
62
+ `/model` walks through model, speed, and reasoning in order:
63
+
64
+ 1. Choose a model. Type to filter the list.
65
+ 2. Choose **Standard** or **Fast** speed, when supported.
66
+ 3. Choose a reasoning level, when the model supports reasoning settings. **Provider default** leaves the reasoning level to the provider.
67
+
68
+ The picker highlights your current settings when they are compatible with the selected model and skips settings that cannot be changed. Use `↑` and `↓` to move, then `Enter` to advance or apply the final choice. `Esc` or `←` returns to the previous step; at the model list, either key cancels. `Ctrl+C` cancels from any step.
69
+
70
+ Changes apply together after the final choice, then the picker returns to chat. Cancelling leaves your model and settings unchanged.
71
+
72
+ A successful login or model change takes effect on the next prompt.
63
73
 
64
74
  OpenAI, ChatGPT, and Gateway connections default to `gpt-5.6-luna-fast`; Anthropic defaults to `claude-sonnet-5`. An explicitly authored compatible model stays selected. If a new default is unavailable, eve offers the connection's available models. Dynamic or custom model expressions must be edited in `agent.ts`.
65
75
 
@@ -82,6 +92,8 @@ Required authorization or deployment setup still runs for the selected item. Pre
82
92
 
83
93
  Type a message and press `Enter` to send it. When the agent asks a question or requests tool approval, respond in the prompt shown by the UI. Connection authorization can open a browser; keep local `eve dev` running until the browser returns to it.
84
94
 
95
+ The activity line shows **Thinking** while the model reasons or waits to respond, **Generating** while it writes a response or tool input, and **Running** while tools execute. A blinking dot and elapsed time indicate progress, with token counts shown when available. The activity line disappears when the turn finishes or needs your input.
96
+
85
97
  While a turn is running, `Enter` sends your message immediately as steering. Before assistant output begins, the runtime interrupts pending model generation and continues the same turn with your correction. Executing tools finish safely. After output begins, steering applies at the next workflow boundary and preserves streamed text.
86
98
 
87
99
  Slash commands wait until the turn ends, except `/cancel`, which cancels directly. If the session does not support steering, messages queue for the next turn. Press `Esc` or `Ctrl+C` to cancel a turn with no queued messages. With queued messages, these keys select the oldest message for steering, or for the next turn if steering is unavailable. If a direct cancellation requested with `/cancel` or `Ctrl+C` does not settle, press `Ctrl+C` to stop waiting. The UI then returns to the prompt and asks you to press `Ctrl+C` again to exit. At an idle prompt, press `Ctrl+C` twice to exit.
@@ -172,7 +172,7 @@ supplied `session` remains externally owned and is never replaced by prewarming
172
172
 
173
173
  `data.messages` are eve-owned `EveMessage[]`. Common text, reasoning, file, and dynamic-tool parts follow the [AI SDK `UIMessage`](https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message) rendering convention, but the types are not interchangeable. eve also exposes authorization and HITL metadata, and a file part's URL can be absent. Adapt those parts before passing messages to an API typed as `UIMessage[]`.
174
174
 
175
- When the root agent delegates, its stream emits `subagent.called` with the child's `childSessionId`, then `subagent.completed` after admission with a working task receipt. Later task notifications wake the parent with completion, failure, or cancellation. Detailed child progress lives on the child session's stream instead of being flattened into the root `data.messages`. Use the lower-level [TypeScript client](../client/overview#sessions) to attach to that ID when your UI needs live subagent activity. See [What the parent sees](../../subagents#what-the-parent-sees) for the complete contract.
175
+ When the root agent delegates, its stream emits `subagent.called` with the child's `childSessionId`, then `subagent.completed` when the parent records a successful result, for both blocking and background invocations. A background working receipt appears in `action.result`, without a completion event. The child session can remain available for reuse. Task notifications wake the parent with completion, failure, or cancellation. Detailed child progress lives on the child session's stream instead of being flattened into the root `data.messages`. Use the lower-level [TypeScript client](../client/overview#sessions) to attach to that ID when your UI needs live subagent activity. See [What the parent sees](../../subagents#what-the-parent-sees) for the complete contract.
176
176
 
177
177
  ## Sending and streaming
178
178
 
@@ -9,15 +9,16 @@ eve supports two ways to delegate work: the root-only built-in `agent` tool, whi
9
9
 
10
10
  Overlapping background work owned by a session forms a cohort. Tasks launched in
11
11
  later user turns join the open cohort while earlier work is still pending or its
12
- successful results await delivery. eve holds successful completion notifications
13
- until every task in that cohort has completed, failed, or been cancelled, then
14
- delivers the successful results together in one parent turn. Partial completions
15
- do not invoke the parent model. Work started after the cohort settles forms a new
16
- cohort. No configuration or debounce timer is required.
17
-
18
- User messages, input requests, authorization events, failures, and cancellation
19
- are handled without waiting for the cohort. Child lifecycle events are processed
20
- before completion delivery so usage accounting and handle cleanup stay ordered.
12
+ terminal results await delivery. eve holds completion, failure, and cancellation
13
+ notifications until every task in that cohort is terminal, then delivers all outcomes
14
+ together in one parent turn. This includes cohorts where every task failed or was
15
+ cancelled. Partial settlements do not invoke the parent model. Work started after the
16
+ cohort settles forms a new cohort. No configuration or debounce timer is required.
17
+
18
+ User messages, input requests, and authorization events are handled without waiting
19
+ for the cohort. Failure and cancellation update task lifecycle state immediately;
20
+ their automatic conversational report waits for the cohort. Child lifecycle events
21
+ are processed before terminal delivery so usage accounting and handle cleanup stay ordered.
21
22
  To follow work in progress, subscribe to the child session streams.
22
23
 
23
24
  ## The built-in `agent` tool
@@ -234,6 +235,8 @@ Do not rely on subagent delegation by itself as an approval boundary. Put sensit
234
235
 
235
236
  Each delegated subagent spins up its own child session and stream. The parent stream carries the control-plane events `subagent.called` and `subagent.completed`, plus interactive `input.requested`, `authorization.required`, and `authorization.completed` events proxied from descendants so the root channel can prompt the user. To follow the child's other progress, read `subagent.called.data.childSessionId` and subscribe at `GET /eve/v1/session/:childSessionId/stream`.
236
237
 
238
+ Both blocking and background invocations emit `subagent.called` after dispatch and `subagent.completed` after the parent records successful completion. Completion carries the actual output and identifies the same invocation by `callId`; the child session can remain available for reuse. A background working receipt is returned as an `action.result` tool output and does not emit completion. Background completion events do not wait for the cohort report. Failure and cancellation are not successful completion; task notifications retain those outcomes.
239
+
237
240
  Channels with activity reporting attribute the backing agent's tool activity to its background task. Local and remote subagents share the task's progress item rather than adding a separate agent item. Continuing or steering a child with `agentId` attaches its new activity to the new task; the previous task keeps its completed or cancelled status. This applies to the built-in `agent` and declared subagent tools, not to child invocations inside custom workflow tools. Activity reporting is best-effort and does not change task execution or result delivery.
238
241
 
239
242
  A background task that was already admitted survives cancellation of the turn that started it; background work that has not yet been admitted is rejected with the cancelled step. Use `task_cancel` to stop an admitted task. Cancellation delivers the task's final notification to an active parent even if the task must be stopped forcibly. Parent-session finalization cancels remaining live tasks.
@@ -121,33 +121,25 @@ receive only the projected text.
121
121
 
122
122
  ### Background execution
123
123
 
124
- Background execution controls how a tool delivers its result to the parent agent. Durable
125
- suspension controls whether the executor can pause at a workflow wait and release compute.
126
- These are independent choices: `execution: "background"` selects the task lifecycle;
127
- `defineWorkflowTool` with a leading `"use workflow"` directive enables durable suspension.
128
-
129
- | Definition | Durable waits inside `execute` | Result delivered to the model |
130
- | ------------------------------------------------ | --------------------------------------------------------------- | ---------------------------------------------------------------------- |
131
- | `defineTool` | No; the executor runs inside the initiating step. | Executor output after it finishes. |
132
- | `defineTool` + `execution: "background"` | No; the initiating step still waits for the executor to finish. | Task receipt, followed by task notifications. |
133
- | `defineWorkflowTool` | Yes; the tool call waits while the workflow can suspend. | Workflow output after it finishes. |
134
- | `defineWorkflowTool` + `execution: "background"` | Yes; the workflow body can outlive the initiating step. | Task receipt before the body finishes, followed by task notifications. |
135
-
136
- A background tool receives a third `task` argument. Its tool result is the receipt
137
- `{ status: "working", taskId }`; its eventual output belongs to the task. Use a background
138
- workflow tool when the conversation should continue while the body waits for a person,
139
- webhook, or timer. Setting `execution: "background"` on an ordinary tool does not move its
140
- executor into a separate workflow or make an ordinary Promise a durable wait.
124
+ Background execution controls how a workflow tool delivers its result to the parent agent.
125
+ Set `execution: "background"` on `defineWorkflowTool`; ordinary `defineTool` calls always finish
126
+ inside the initiating step.
127
+
128
+ | Definition | Durable waits inside `execute` | Result delivered to the model |
129
+ | ------------------------------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
130
+ | `defineTool` | No; the executor runs inside the initiating step. | Executor output after it finishes. |
131
+ | `defineWorkflowTool` | Yes; the tool call waits while the workflow can suspend. | Workflow output after it finishes. |
132
+ | `defineWorkflowTool` + `execution: "background"` | Yes; the workflow body can outlive the initiating step. | Task receipt before the body finishes; one combined report after all tasks in its cohort are terminal. |
133
+
134
+ A background workflow tool's result is the receipt `{ status: "working", taskId }`; its eventual
135
+ output belongs to the task. Use this mode when the conversation should continue while the body
136
+ waits for a person, webhook, or timer.
141
137
 
142
138
  For background tools, `outputSchema` and `toModelOutput` describe the fixed receipt. The body's
143
139
  return value is available through the completed task's output.
144
140
 
145
- `task.delegated()` has been removed. Move external work into a `defineWorkflowTool` executor and
146
- return its result when it finishes. Rebuild extensions using the removed API after migrating.
147
-
148
- `yield task.postMessage(message)` is the only yield that requests a parent-agent turn. Calling
149
- `task.postMessage` only constructs the message descriptor; you must yield it to send it.
150
- In a workflow body, keep values needed after a wait in local variables; workflow replay
141
+ The `TaskExec` argument and `task.postMessage` have been removed. Return the terminal result;
142
+ background yields are consumed without publishing progress or retaining a task-progress stream. In a workflow body, keep values needed after a wait in local variables; workflow replay
151
143
  reconstructs them across durable waits.
152
144
  Use [`ctx.ask`](/docs/tools/workflows#ask-a-human-ctxask) when the body needs an answer from the human.
153
145
  Background tools are a normal execution mode and need no root-agent flag. Built-in, declared local,
@@ -158,10 +150,11 @@ cohort and instructs the model to acknowledge that the work started without wait
158
150
  [Schedule](/docs/schedules)-initiated turns are the exception: no user prompted them, so their
159
151
  launches keep conditional delivery and send no acknowledgement.
160
152
  Later task-triggered parent turns receive fresh state for the same cohort. Once every related
161
- task is terminal, the state includes their outputs so the model can combine the useful results.
153
+ task is terminal, one automatic parent turn receives the cohort's completed, failed, and cancelled
154
+ outcomes so the model can combine the useful results.
162
155
  eve does not instruct the model to stay silent while sibling tasks are pending; a new user
163
156
  question can receive an answer while background work continues. [Completion batching](/docs/subagents#completion-batching)
164
- combines successful results already queued for the parent.
157
+ combines terminal results already queued for the parent.
165
158
 
166
159
  ### Yield and return
167
160
 
@@ -169,19 +162,18 @@ combines successful results already queued for the parent.
169
162
  It does not by itself create a durable wait for a person, timer, or external event. The value's
170
163
  meaning depends on the tool's execution mode:
171
164
 
172
- | Executor | Ordinary `yield value` | Final output |
173
- | ------------------------------------------------ | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
174
- | `defineTool`, default execution | Earlier values are `action.partial` snapshots; the final yield becomes the tool result. | Last yielded value; a generator `return` value is ignored. |
175
- | `defineWorkflowTool`, default execution | Every yield is an `action.partial` snapshot. | Explicit return value; falls back to the last yield if the return is `null` or `undefined`, then to `null`. |
176
- | Either definition with `execution: "background"` | Stream-only task progress; does not request a parent-agent turn. | Explicit return value becomes the task output; no return completes with `null`. The last yield is not a fallback. |
165
+ | Executor | Ordinary `yield value` | Final output |
166
+ | --------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
167
+ | `defineTool`, default execution | Earlier values are `action.partial` snapshots; the final yield becomes the tool result. | Last yielded value; a generator `return` value is ignored. |
168
+ | `defineWorkflowTool`, default execution | Every yield is an `action.partial` snapshot. | Explicit return value; falls back to the last yield if the return is `null` or `undefined`, then to `null`. |
169
+ | `defineWorkflowTool` with `execution: "background"` | Consumed without publishing progress or requesting a parent-agent turn. | Explicit return value becomes the task output; no return completes with `null`. The last yield is not a fallback. |
177
170
 
178
- For either kind of background tool, `yield task.postMessage(message)` sends a message to the
179
- parent agent while the task remains open. Return completes the task; throw fails it. These
180
- notifications are separate from the original tool call's receipt.
171
+ For a background workflow tool, return completes the task and throw fails it. The automatic
172
+ cohort report is separate from the original tool call's receipt.
181
173
 
182
174
  Progress snapshots do not enter model history as intermediate tool results. For a default
183
175
  executor, the final output selected by the rules above becomes the tool result. For a background
184
- executor, task messages and completion notifications provide input to later parent-agent turns.
176
+ executor, the terminal cohort report provides input to a later parent-agent turn.
185
177
 
186
178
  ### Workflows as tools
187
179
 
@@ -178,8 +178,7 @@ agent should receive a tool result:
178
178
 
179
179
  Use default execution when the model needs the answer to continue. Use background execution when
180
180
  the conversation should continue while the task is pending. Background tools need no root-agent
181
- flag. Ordinary `defineTool` also accepts `execution: "background"`, but its executor still runs
182
- inside the initiating step and cannot suspend at workflow waits. See the
181
+ flag. `defineTool` does not accept background execution. See the
183
182
  [tool execution comparison](/docs/tools#background-execution).
184
183
 
185
184
  ### How suspension works
@@ -429,23 +428,23 @@ This pattern controls specialist selection, not whether the parent model delegat
429
428
 
430
429
  ## Report progress: `yield`
431
430
 
432
- A workflow body may be an async generator. Ordinary yields report progress in both execution
433
- modes. After processing a yield, eve advances the generator; use an awaited workflow operation
431
+ A workflow body may be an async generator. In default execution, yields report progress.
432
+ Background execution consumes yielded values without publishing them or retaining a task-progress
433
+ stream. After processing a yield, eve advances the generator; use an awaited workflow operation
434
434
  when the body needs to suspend.
435
435
 
436
- | Operation | Default execution | `execution: "background"` |
437
- | --------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------- |
438
- | `yield value` | Emits an `action.partial` snapshot for the pending tool call. | Emits stream-only task progress; does not request a parent-agent turn. |
439
- | `yield task.postMessage(message)` | Unavailable; there is no `task` argument. | Sends a message requesting a parent-agent turn; the task stays open. |
440
- | `return value` | Settles the tool call with its output. | Completes the task and delivers its output in a later notification. |
441
- | No return value | Uses the last yield as output, or `null` if there were no yields. | Completes with `null`; yielded progress is not the task output. |
436
+ | Operation | Default execution | `execution: "background"` |
437
+ | --------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------- |
438
+ | `yield value` | Emits an `action.partial` snapshot for the pending tool call. | Consumes the value without publishing progress or requesting a parent-agent turn. |
439
+ | `return value` | Settles the tool call with its output. | Completes the task and contributes to its cohort's terminal report. |
440
+ | No return value | Uses the last yield as output, or `null` if there were no yields. | Completes with `null`; yielded progress is not the task output. |
442
441
 
443
442
  For default execution, an explicit `return null` also falls back to the last yield. Prefer an
444
443
  explicit object return when progress snapshots and the final result have different shapes.
445
444
  Progress snapshots are last-write-wins by tool call id and do not enter model history as
446
445
  intermediate tool results. A snapshot used as the final output does enter history as the tool result.
447
446
 
448
- This background workflow reports progress, sends the parent one message, and then suspends:
447
+ This background workflow consumes an intermediate yield, then suspends until its timer expires:
449
448
 
450
449
  ```ts title="agent/tools/remind_with_progress.ts"
451
450
  import { defineWorkflowTool } from "eve/tools";
@@ -453,25 +452,22 @@ import { sleep } from "workflow";
453
452
  import { z } from "zod";
454
453
 
455
454
  export default defineWorkflowTool({
456
- description: "Schedule a reminder and report progress before waiting.",
455
+ description: "Schedule a reminder.",
457
456
  inputSchema: z.object({ note: z.string(), delay: z.string() }),
458
457
  execution: "background",
459
- async *execute({ note, delay }, ctx, task) {
458
+ async *execute({ note, delay }) {
460
459
  "use workflow";
461
- yield { status: "preparing reminder" }; // Stream-only progress.
462
- yield task.postMessage(`Reminder scheduled for ${delay}.`); // Parent-agent message.
460
+ yield { status: "preparing reminder" }; // Consumed without publishing progress in background mode.
463
461
  await sleep(delay); // Durable suspension while the timer is pending.
464
462
  return { reminder: note }; // Task completion notification.
465
463
  },
466
464
  });
467
465
  ```
468
466
 
469
- Calling `task.postMessage` constructs a descriptor; yielding it sends the message. It does not
470
- wait for a reply. Use [`ctx.ask`](#ask-a-human-ctxask) when the workflow needs a human answer.
471
- Removing `execution: "background"` requires removing the `task` argument and message yield; the
472
- ordinary progress yield and `await sleep(delay)` still work, but the model waits for the final
473
- reminder as the tool result. See [yield and return](/docs/tools#yield-and-return) for the different
474
- final-output rules of ordinary `defineTool` generators.
467
+ Use [`ctx.ask`](#ask-a-human-ctxask) when the workflow needs a human answer. Removing
468
+ `execution: "background"` makes the yield visible as progress and keeps the durable sleep; the model
469
+ waits for the final reminder as the tool result. See [yield and return](/docs/tools#yield-and-return) for the
470
+ final-output rules.
475
471
 
476
472
  ## Cancel and clean up: `ctx.abortSignal`
477
473
 
@@ -497,6 +493,11 @@ as cancelled whether or not it did. A body parked on a hook or a `sleep` does no
497
493
  it is abandoned when the grace period ends. Steps that received the signal are how you clean up
498
494
  first.
499
495
 
496
+ The caller waits up to 35 seconds for a cooperatively cancelled run to settle before forcing it
497
+ to stop. This includes time for the run to publish its outcome after body cleanup. A background
498
+ task records its cancelled status before cleanup finishes, so that status alone does not mean
499
+ its work has stopped.
500
+
500
501
  ## Workflow tool examples
501
502
 
502
503
  ### Approve with a deadline and an escalation
@@ -607,8 +608,10 @@ it.
607
608
  ## Semantics
608
609
 
609
610
  One call, one result. A waiting tool's call resolves once, with the return value, the error, or a
610
- cancellation. A background tool's call resolves once, with the receipt; everything after arrives as
611
- separate session input.
611
+ cancellation. A background tool's call resolves once, with the receipt. Its terminal outcome arrives
612
+ in one automatic report after every task in its cohort is terminal. A cohort includes overlapping
613
+ background work in the same session, including tasks launched in later user turns while earlier
614
+ work remains open.
612
615
 
613
616
  While a waiting tool runs, the turn is parked. A `queue` message waits for it. A `steer` message
614
617
  cancels the turn, which cancels the run, which withdraws its requests. Input responses never steer.
@@ -616,8 +619,12 @@ cancels the turn, which cancels the run, which withdraws its requests. Input res
616
619
  Background runs belong to the session. They survive turn completion and cancellation, appear in the
617
620
  session's task index, can be cancelled with `task_cancel`, and are cancelled when the session ends.
618
621
 
622
+ The parent session records each background task's outcome when it processes the child's notification.
623
+ The first terminal outcome it records is final: a late child result cannot replace a recorded
624
+ cancellation. Task completion does not require the wrapper workflow to have exited.
625
+
619
626
  Errors follow the SDK. A thrown error in a step retries per the step's policy; `FatalError` does
620
- not. An error that escapes the body fails the run.
627
+ not. An error that escapes the body fails the tool invocation.
621
628
 
622
629
  Starting a waiting workflow tool can also be retried. If dispatch is interrupted after starting a
623
630
  run, its retry starts another run, and both may execute. The parent tracks the run returned by the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.62.0",
3
+ "version": "0.63.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -1,103 +0,0 @@
1
- import { type ReasoningLevel } from "#setup/boxes/model-capabilities.js";
2
- import type { GatewayModelCapabilities } from "#setup/boxes/model-capabilities.js";
3
- import { type SelectState } from "#setup/cli/select-state.js";
4
- import type { ModelSettingsRequest, ModelSettingsResult } from "#setup/flows/model.js";
5
- import type { SelectOption } from "#setup/prompter.js";
6
- /** The Change-model menu's rows, in visual order. */
7
- export type ModelEditorRowId = "model" | "reasoning" | "tier" | "done";
8
- /**
9
- * The screen stack, depth two: the value menu, or the model list it opens.
10
- * Reasoning and tier adjust inline on their menu rows — only the catalog pick
11
- * warrants its own screen. The list carries scratch select state seeded when
12
- * opened; Esc drops it, so "returns unchanged" is structural.
13
- */
14
- export type ModelEditorScreen = {
15
- kind: "menu";
16
- cursor: ModelEditorRowId;
17
- } | {
18
- kind: "model";
19
- select: SelectState;
20
- };
21
- /** The in-progress values; a completed selection is applied immediately. */
22
- export interface ModelEditorDraft {
23
- modelId: string | null;
24
- reasoning: "default" | ReasoningLevel;
25
- tier: "standard" | "priority";
26
- }
27
- /** One Change-model interaction, advanced by {@link transitionModelEditor}. */
28
- export interface ModelEditorState {
29
- screen: ModelEditorScreen;
30
- draft: ModelEditorDraft;
31
- /** Catalog capabilities for `draft.modelId`; recomputed on every pick. */
32
- capabilities: GatewayModelCapabilities | undefined;
33
- }
34
- /** Semantic input after terminal-key decoding. */
35
- export type ModelEditorEvent = {
36
- type: "move";
37
- direction: "up" | "down";
38
- } | {
39
- type: "adjust";
40
- direction: "left" | "right";
41
- } | {
42
- type: "char";
43
- char: string;
44
- } | {
45
- type: "backspace";
46
- } | {
47
- type: "cancel";
48
- } | {
49
- type: "submit";
50
- };
51
- export type ModelEditorTransition = {
52
- kind: "ignore";
53
- state: ModelEditorState;
54
- } | {
55
- kind: "render";
56
- state: ModelEditorState;
57
- } | {
58
- kind: "cancel";
59
- } | {
60
- kind: "settle";
61
- result: ModelSettingsResult;
62
- };
63
- /**
64
- * How a value row presents: an adjustable control, a dim explanatory line the
65
- * cursor skips, or nothing at all — a control that cannot apply to the
66
- * drafted model (no priority tier) is noise, while an authored-but-unowned
67
- * state (custom tier, external provider) still explains itself.
68
- */
69
- export type ModelEditorSectionView = {
70
- kind: "interactive";
71
- } | {
72
- kind: "static";
73
- text: string;
74
- } | {
75
- kind: "hidden";
76
- };
77
- /**
78
- * The reasoning row stays interactive while a level is drafted even when the
79
- * catalog disowns reasoning, so the authored value at least stays visible.
80
- */
81
- export declare function reasoningSectionView(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
82
- /** The tier row's presentation; static or hidden for every state it cannot own. */
83
- export declare function tierSectionView(request: ModelSettingsRequest, capabilities: GatewayModelCapabilities | undefined): ModelEditorSectionView;
84
- /**
85
- * The track's notch positions: the levels the catalog supports (every level
86
- * when capabilities are unknown). The provider default is not a notch — an
87
- * unset draft renders an empty track and the first right-adjust enters the
88
- * scale at the lowest level. A drafted level the catalog does not list is
89
- * inserted in canonical level order, so the track never hides the value it
90
- * is about to replace.
91
- */
92
- export declare function reasoningPositions(capabilities: GatewayModelCapabilities | undefined, drafted: "default" | ReasoningLevel): readonly ReasoningLevel[];
93
- /**
94
- * The value menu's rows, derived fresh from the draft on every transition and
95
- * paint: interactive sections are pickable rows, static sections are disabled
96
- * rows carrying their explanation, and a hidden tier is omitted entirely.
97
- * Value hints are the painter's job — it styles them with theme glyphs.
98
- */
99
- export declare function modelEditorMenuRows(request: ModelSettingsRequest, draft: ModelEditorDraft, capabilities: GatewayModelCapabilities | undefined): SelectOption<ModelEditorRowId>[];
100
- /** Creates the screen's state; the cursor opens on the first pickable row. */
101
- export declare function initialModelEditorState(request: ModelSettingsRequest): ModelEditorState;
102
- /** Applies one keypress worth of semantics; terminal resources stay in the renderer. */
103
- export declare function transitionModelEditor(state: ModelEditorState, event: ModelEditorEvent, request: ModelSettingsRequest): ModelEditorTransition;
@@ -1 +0,0 @@
1
- import{ALL_REASONING_LEVELS}from"#setup/boxes/model-capabilities.js";import{filterOptions,initialSelectState,reduceSelect,selectValueAtCursor}from"#setup/cli/select-state.js";const NOT_EDITABLE_TEXT=`No editable agent.ts config object is available`;function reasoningSectionView(e,t,n){return e.settingsEditable?n?.reasoning===!1&&t.reasoning==="default"?{kind:`static`,text:`Not supported by the selected model`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function tierSectionView(e,t){return e.settingsEditable?e.externalRouting?{kind:`static`,text:`Disabled for a direct external provider`}:e.serviceTier.kind===`custom`?{kind:`static`,text:`Custom (${e.serviceTier.value}) — authored in agent.ts`}:t!==void 0&&!t.fastMode?{kind:`hidden`}:{kind:`interactive`}:{kind:`static`,text:NOT_EDITABLE_TEXT}}function reasoningPositions(e,t){let n=[...e===void 0?ALL_REASONING_LEVELS:e.reasoningLevels];if(t!=="default"&&!n.includes(t)){let e=ALL_REASONING_LEVELS.indexOf(t),r=n.findIndex(t=>ALL_REASONING_LEVELS.indexOf(t)>e);r===-1?n.push(t):n.splice(r,0,t)}return n}function snapReasoningToCapabilities(e,t){if(e==="default"||t===void 0)return e;let n=t.reasoningLevels;if(!t.reasoning||n.length===0)return`default`;if(n.includes(e))return e;let r=ALL_REASONING_LEVELS.indexOf(e),i=n[0];for(let e of n)Math.abs(ALL_REASONING_LEVELS.indexOf(e)-r)<Math.abs(ALL_REASONING_LEVELS.indexOf(i)-r)&&(i=e);return i}function modelEditorMenuRows(e,t,n){let r=[];e.model.kind===`pick`?r.push({value:`model`,label:`Model`}):r.push({value:`model`,label:`Model`,disabled:!0,description:e.model.reason});let i=reasoningSectionView(e,t,n);i.kind===`static`?r.push({value:`reasoning`,label:`Reasoning effort`,disabled:!0,description:i.text}):r.push({value:`reasoning`,label:`Reasoning effort`});let a=tierSectionView(e,n);return a.kind===`interactive`?r.push({value:`tier`,label:`Service tier`}):a.kind===`static`&&r.push({value:`tier`,label:`Service tier`,disabled:!0,description:a.text}),r}function initialModelEditorState(e){let t={modelId:e.model.current,reasoning:e.reasoning??`default`,tier:e.serviceTier.kind===`priority`?`priority`:`standard`},n=e.capabilitiesFor(t.modelId);return{screen:{kind:`menu`,cursor:modelEditorMenuRows(e,t,n).find(e=>e.disabled!==!0)?.value??`done`},draft:t,capabilities:n}}function expandedModelSelect(e,t){let n={options:e.model.kind===`pick`?e.model.options:[]};return t!==null&&(n.defaultValue=t),initialSelectState(n)}function ignore(e){return{kind:`ignore`,state:e}}function toMenu(e,t){return{kind:`render`,state:{...e,screen:{kind:`menu`,cursor:t}}}}function settleResult(e,t){let n={};if(e.model.kind===`pick`&&t.modelId!==null&&t.modelId!==e.model.current&&(n.model=t.modelId),!e.settingsEditable)return n;t.reasoning!==(e.reasoning??`default`)&&(n.reasoning=t.reasoning);let r=!e.externalRouting&&e.serviceTier.kind!==`custom`,i=e.serviceTier.kind===`priority`?`priority`:`standard`;return r&&t.tier!==i&&(n.serviceTier=t.tier),n}function adjustMenuValue(e,t,n,r){let i=r===`left`?-1:1;if(n===`reasoning`){if(reasoningSectionView(t,e.draft,e.capabilities).kind!==`interactive`)return ignore(e);let n=reasoningPositions(e.capabilities,e.draft.reasoning);if(n.length===0)return ignore(e);let r=e.draft.reasoning==="default"?-1:n.indexOf(e.draft.reasoning),a=r===-1?n[i===1?0:n.length-1]:n[(r+i+n.length)%n.length];return a===e.draft.reasoning?ignore(e):{kind:`render`,state:{...e,draft:{...e.draft,reasoning:a}}}}if(n===`tier`){if(tierSectionView(t,e.capabilities).kind!==`interactive`)return ignore(e);let n=e.draft.tier===`priority`?`standard`:`priority`;return{kind:`render`,state:{...e,draft:{...e.draft,tier:n}}}}return ignore(e)}function transitionMenu(e,t,n,r){let i=modelEditorMenuRows(n,e.draft,e.capabilities);switch(t.type){case`cancel`:return{kind:`cancel`};case`move`:{let n=Math.max(0,i.findIndex(e=>e.value===r)),a=i[reduceSelect({filter:``,cursor:n,selected:new Set},{type:t.direction},{options:i}).cursor]?.value;return a===void 0||a===r?ignore(e):toMenu(e,a)}case`adjust`:return adjustMenuValue(e,n,r,t.direction);case`submit`:{let t=i.find(e=>e.value===r);return t===void 0||t.disabled===!0?ignore(e):r===`model`?{kind:`render`,state:{...e,screen:{kind:`model`,select:expandedModelSelect(n,e.draft.modelId)}}}:{kind:`settle`,result:settleResult(n,e.draft)}}case`char`:case`backspace`:return ignore(e)}}function transitionModelScreen(e,t,n,r){let i=n.model.kind===`pick`?n.model.options:[],renderSelect=t=>t===r?ignore(e):{kind:`render`,state:{...e,screen:{kind:`model`,select:t}}};switch(t.type){case`cancel`:return r.filter.length>0?renderSelect(reduceSelect(r,{type:`clear`},{options:i})):toMenu(e,`model`);case`move`:return renderSelect(reduceSelect(r,{type:t.direction},{options:i}));case`char`:return renderSelect(reduceSelect(r,{type:`char`,char:t.char},{options:i}));case`backspace`:return renderSelect(reduceSelect(r,{type:`backspace`},{options:i}));case`submit`:{let t=filterOptions(i,r.filter),a=selectValueAtCursor(t,r.cursor);if(a===void 0)return ignore(e);let o=n.capabilitiesFor(a);return{kind:`settle`,result:settleResult(n,{...e.draft,modelId:a,reasoning:snapReasoningToCapabilities(e.draft.reasoning,o),tier:o!==void 0&&!o.fastMode?`standard`:e.draft.tier})}}case`adjust`:return ignore(e)}}function transitionModelEditor(e,t,n){switch(e.screen.kind){case`menu`:return transitionMenu(e,t,n,e.screen.cursor);case`model`:return transitionModelScreen(e,t,n,e.screen.select)}}export{initialModelEditorState,modelEditorMenuRows,reasoningPositions,reasoningSectionView,tierSectionView,transitionModelEditor};
@@ -1,81 +0,0 @@
1
- import type { ActivityObserverConfig } from "#channel/types.js";
2
- import type { WorkflowToolAuthorizationRequest, WorkflowToolRunRequestMessage } from "#execution/tools/workflow/messages.js";
3
- import type { WorkflowToolRunTaskInputRequest } from "./workflow.js";
4
- import type { AnswerHookRoute } from "#harness/proxy-input-requests.js";
5
- import type { ActivityEventV1 } from "#protocol/activity.js";
6
- import { type TaskInboundAnswerInput, type TaskInboundMessage, type TaskInboundUpdate, type TaskProgress, type TaskView } from "#tasks/types.js";
7
- /**
8
- * Appends one full task view to the owning task run's `eve.task`
9
- * stream. Only the task run workflow calls this, which is what makes
10
- * the run the single writer readers can trust without re-validating.
11
- */
12
- export declare function appendTaskViewStep(input: {
13
- readonly activityObserver?: ActivityObserverConfig;
14
- readonly view: TaskView;
15
- }): Promise<void>;
16
- export declare function projectTaskActivity(input: {
17
- readonly activityObserver: ActivityObserverConfig | undefined;
18
- readonly settledAt: string;
19
- readonly view: TaskView;
20
- }): readonly ActivityEventV1[];
21
- /** Appends task progress without starting a parent turn. */
22
- export declare function appendTaskProgressStep(input: {
23
- readonly progress: TaskProgress;
24
- }): Promise<void>;
25
- /**
26
- * Wakes the parent session with a framework task notification.
27
- *
28
- * Rides the ordinary session delivery path: a parked parent starts a
29
- * turn carrying this message, while an active turn observes it at the
30
- * next safe boundary through the owner's normal delivery routing. A
31
- * parent whose session already ended is a tolerated no-op.
32
- */
33
- export declare function wakeTaskParentStep(input: {
34
- readonly token: string;
35
- readonly view: TaskView;
36
- }): Promise<void>;
37
- /** Forwards a running child's intermediate update to its parent session. */
38
- export declare function wakeTaskUpdateParentStep(input: {
39
- readonly token: string;
40
- readonly update: TaskInboundUpdate;
41
- readonly view: TaskView;
42
- }): Promise<void>;
43
- /** Delivers one task-authored message to the parent as a new turn. */
44
- export declare function wakeTaskMessageParentStep(input: {
45
- readonly message: TaskInboundMessage;
46
- readonly taskId: string;
47
- readonly token: string;
48
- }): Promise<void>;
49
- /** Forwards one agent spawn or settlement request to the parent session. */
50
- export declare function wakeTaskAgentRequestParentStep(input: {
51
- readonly request: WorkflowToolRunRequestMessage;
52
- readonly taskId: string;
53
- readonly token: string;
54
- }): Promise<void>;
55
- /** Re-emits a task child's authorization event through the parent channel. */
56
- export declare function wakeTaskAuthorizationParentStep(input: {
57
- readonly request: WorkflowToolAuthorizationRequest;
58
- readonly taskId: string;
59
- readonly token: string;
60
- }): Promise<void>;
61
- /** Sends a workflow-body question to the owning parent's pre-model router. */
62
- export declare function wakeWorkflowTaskInputRequestParentStep(input: {
63
- readonly request: WorkflowToolRunTaskInputRequest;
64
- readonly taskId: string;
65
- readonly token: string;
66
- }): Promise<void>;
67
- /**
68
- * Forwards answered input to the blocked child.
69
- *
70
- * The task run performs this itself so the child unblocks and the
71
- * view leaves `input_required` under one durable decision. Returns
72
- * `unreachable` when the child hook is already gone, which leaves the
73
- * outstanding batch untouched rather than reporting a task as working
74
- * when nothing received the answer.
75
- */
76
- export declare function deliverTaskInputResponsesStep(input: {
77
- readonly answer: TaskInboundAnswerInput;
78
- readonly answerHook?: AnswerHookRoute;
79
- readonly requestIds: readonly string[];
80
- }): Promise<"delivered" | "unreachable">;
81
- export declare function formatTaskNotification(view: TaskView): string;