eve 0.81.1 → 0.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/src/channel/channel-address.d.ts +21 -2
- package/dist/src/channel/channel-address.js +1 -1
- package/dist/src/channel/channel-operations.d.ts +32 -1
- package/dist/src/channel/channel-operations.js +1 -1
- package/dist/src/channel/delivery-idempotency.d.ts +4 -0
- package/dist/src/channel/delivery-idempotency.js +1 -0
- package/dist/src/channel/routes.d.ts +6 -0
- package/dist/src/channel/session.d.ts +5 -0
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +14 -11
- package/dist/src/chunks/{use-eve-agent-Bp6nbhfV.js → use-eve-agent-DTu78IAF.js} +36 -0
- package/dist/src/chunks/{use-eve-agent-DLkjJIm3.js → use-eve-agent-DlznYwQk.js} +36 -0
- package/dist/src/cli/dev/command-options.d.ts +1 -0
- package/dist/src/cli/dev/diagnostic-dump.js +1 -1
- package/dist/src/cli/run.d.ts +1 -0
- package/dist/src/cli/run.js +1 -1
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/message-reducer-types.d.ts +7 -3
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/transcript-reducer.d.ts +6 -3
- package/dist/src/client/transcript-reducer.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +19 -18
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/load-binding-namespace.d.ts +2 -0
- package/dist/src/compiler/load-binding-namespace.js +1 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-lifecycle.d.ts +1 -1
- package/dist/src/compiler/module-lifecycle.js +1 -1
- package/dist/src/compiler/module-map.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/project-sources.d.ts +6 -0
- package/dist/src/compiler/project-sources.js +1 -1
- package/dist/src/context/keys.d.ts +2 -0
- package/dist/src/context/keys.js +1 -1
- package/dist/src/evals/cli/eval-state-directory.d.ts +7 -0
- package/dist/src/evals/cli/eval-state-directory.js +1 -0
- package/dist/src/evals/cli/eval.js +2 -2
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/eve-channel/support.d.ts +2 -0
- package/dist/src/eve-channel/support.js +1 -1
- package/dist/src/eve-channel/types.d.ts +7 -0
- package/dist/src/execution/agent-sessions/context.d.ts +2 -13
- package/dist/src/execution/agent-sessions/context.js +1 -1
- package/dist/src/execution/agent-sessions/runtime-overrides.d.ts +5 -0
- package/dist/src/execution/agent-sessions/runtime-overrides.js +1 -0
- package/dist/src/execution/agent-sessions/session.d.ts +2 -2
- package/dist/src/execution/agent-sessions/session.js +1 -1
- package/dist/src/execution/agent-sessions/steps.d.ts +2 -0
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/coordination-dispatch-shared.d.ts +5 -5
- package/dist/src/execution/coordination-dispatch-step.d.ts +17 -2
- package/dist/src/execution/coordination-dispatch-step.js +1 -1
- package/dist/src/execution/create-session-step.d.ts +5 -2
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/deliver-payloads.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +0 -1
- package/dist/src/execution/dynamic-connection-recovery.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/effective-agent-config.d.ts +8 -2
- package/dist/src/execution/effective-agent-config.js +1 -1
- package/dist/src/execution/install-workflow-deployment-id.d.ts +3 -0
- package/dist/src/execution/install-workflow-deployment-id.js +1 -0
- package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
- package/dist/src/execution/node-step.d.ts +1 -0
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/runtime-context.d.ts +2 -0
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/admission.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/entry-input.d.ts +1 -3
- package/dist/src/execution/session/entry.js +1 -1
- package/dist/src/execution/session/finalization.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +6 -9
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/input-queue.d.ts +5 -1
- package/dist/src/execution/session/input-queue.js +1 -1
- package/dist/src/execution/session/pending-history.d.ts +5 -0
- package/dist/src/execution/session/pending-history.js +1 -0
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/program.d.ts +1 -1
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/timeout-control.d.ts +18 -4
- package/dist/src/execution/session/timeout-control.js +1 -1
- package/dist/src/execution/session/timeout.d.ts +1 -2
- package/dist/src/execution/session/timeout.js +1 -1
- package/dist/src/execution/session/turn-event-handler.js +1 -1
- package/dist/src/execution/session/turn-step-result.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn-waiting-step.js +1 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/session-inbox/protocol.js +1 -1
- package/dist/src/execution/session.d.ts +0 -12
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/model-step.js +1 -1
- package/dist/src/execution/tasks/start.d.ts +4 -4
- package/dist/src/execution/tasks/start.js +1 -1
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/terminate-child-sessions-step.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/body.d.ts +2 -2
- package/dist/src/execution/workflow-runtime.d.ts +5 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/budget-request.d.ts +12 -6
- package/dist/src/harness/hitl/budget-request.js +1 -1
- package/dist/src/harness/hitl/budget.d.ts +7 -1
- package/dist/src/harness/hitl/budget.js +1 -1
- package/dist/src/harness/hitl/coordinator.js +1 -1
- package/dist/src/harness/hitl/delivery.d.ts +1 -1
- package/dist/src/harness/hitl/delivery.js +1 -1
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.d.ts +2 -2
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/messages.d.ts +5 -0
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/model-call/call.d.ts +2 -2
- package/dist/src/harness/model-call/request.d.ts +2 -2
- package/dist/src/harness/session-machine/transitions.d.ts +3 -1
- package/dist/src/harness/session-machine/transitions.js +1 -1
- package/dist/src/harness/step/context.d.ts +3 -0
- package/dist/src/harness/step/context.js +1 -1
- package/dist/src/harness/step/intake.d.ts +5 -2
- package/dist/src/harness/step/intake.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/turn-tag-state.d.ts +7 -26
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/harness/types.d.ts +10 -25
- package/dist/src/internal/application/build-profile.d.ts +3 -0
- package/dist/src/internal/application/build-profile.js +1 -1
- package/dist/src/internal/application/compiled-artifacts.js +2 -2
- package/dist/src/internal/application/dev-environment.d.ts +13 -0
- package/dist/src/internal/application/dev-environment.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-module-build-options.d.ts +7 -0
- package/dist/src/internal/authored-module-build-options.js +1 -0
- package/dist/src/internal/authored-module-graph.d.ts +13 -0
- package/dist/src/internal/authored-module-graph.js +1 -0
- package/dist/src/internal/authored-module-loader.d.ts +22 -1
- package/dist/src/internal/authored-module-loader.js +1 -3
- package/dist/src/internal/authored-module.d.ts +7 -0
- package/dist/src/internal/authored-module.js +1 -1
- package/dist/src/internal/authored-package-boundary.js +1 -1
- package/dist/src/internal/bundler/nitro-rolldown.d.ts +5 -1
- package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
- package/dist/src/internal/development-programmatic-source-loader.d.ts +1 -0
- package/dist/src/internal/development-programmatic-source-loader.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-generation-metadata.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/build-deployment-id.d.ts +8 -0
- package/dist/src/internal/nitro/host/build-deployment-id.js +1 -0
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-state.js +1 -1
- package/dist/src/internal/nitro/host/skill-server-assets.js +1 -1
- package/dist/src/internal/nitro/host/stage-build-deployment-id.d.ts +2 -0
- package/dist/src/internal/nitro/host/stage-build-deployment-id.js +1 -0
- package/dist/src/internal/nitro/host/start-production-server.d.ts +1 -0
- package/dist/src/internal/nitro/host/start-production-server.js +3 -3
- package/dist/src/internal/nitro/routes/schedule-task.d.ts +3 -0
- package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
- package/dist/src/internal/programmatic-source-loader.d.ts +1 -0
- package/dist/src/internal/programmatic-source-loader.js +1 -1
- package/dist/src/internal/schedules/disabled.d.ts +2 -0
- package/dist/src/internal/schedules/disabled.js +1 -0
- package/dist/src/internal/workflow/development-world-server.js +1 -1
- package/dist/src/internal/workflow/local-world-data-directory.d.ts +2 -1
- package/dist/src/internal/workflow/local-world-data-directory.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +1 -1
- package/dist/src/protocol/message.d.ts +27 -1
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +13 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/chat-sdk/fetch-message.d.ts +10 -0
- package/dist/src/public/channels/chat-sdk/fetch-message.js +1 -0
- package/dist/src/public/channels/chat-sdk/index.d.ts +1 -1
- package/dist/src/public/channels/chat-sdk/reply-context.d.ts +15 -0
- package/dist/src/public/channels/chat-sdk/reply-context.js +2 -0
- package/dist/src/public/channels/discord/discordChannel.d.ts +3 -0
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +3 -0
- package/dist/src/public/channels/imessage-tapbacks.d.ts +74 -0
- package/dist/src/public/channels/imessage-tapbacks.js +1 -0
- package/dist/src/public/channels/index.d.ts +2 -1
- package/dist/src/public/channels/index.js +1 -1
- package/dist/src/public/channels/linear/linearChannel.d.ts +3 -0
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/linq/inboundContent.d.ts +7 -0
- package/dist/src/public/channels/linq/inboundContent.js +1 -1
- package/dist/src/public/channels/linq/index.d.ts +1 -0
- package/dist/src/public/channels/linq/index.js +1 -1
- package/dist/src/public/channels/linq/linqChannel.d.ts +17 -1
- package/dist/src/public/channels/linq/linqChannel.js +1 -1
- package/dist/src/public/channels/photon/inboundContent.d.ts +7 -0
- package/dist/src/public/channels/photon/inboundContent.js +2 -1
- package/dist/src/public/channels/photon/index.d.ts +1 -0
- package/dist/src/public/channels/photon/index.js +1 -1
- package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +17 -1
- package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
- package/dist/src/public/channels/slack/api.d.ts +6 -0
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/model-context.d.ts +7 -0
- package/dist/src/public/channels/slack/model-context.js +1 -1
- package/dist/src/public/channels/slack/reply-delivery.d.ts +5 -0
- package/dist/src/public/channels/slack/reply-delivery.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +17 -3
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -0
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -0
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +1 -1
- package/dist/src/public/definitions/channel.d.ts +2 -2
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +1 -0
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/runtime/agent/resolve-model.d.ts +4 -0
- package/dist/src/runtime/agent/resolve-model.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +2 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
- package/dist/src/runtime/types.d.ts +3 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +31 -42
- package/dist/src/shared/session-history.d.ts +22 -0
- package/dist/src/shared/session-history.js +1 -0
- package/dist/src/subagents/tool.d.ts +1 -3
- package/dist/src/subagents/tool.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/workflow-definition.d.ts +14 -1
- package/dist/src/tracing/eve/conversation-context.d.ts +4 -1
- package/dist/src/tracing/eve/conversation-context.js +1 -1
- package/dist/src/tracing/eve/invoke-tool-span.js +1 -1
- package/dist/src/tracing/eve/operation-input.d.ts +0 -5
- package/dist/src/tracing/eve/operation-input.js +1 -1
- package/dist/src/tracing/eve/otel-registration.js +1 -1
- package/dist/src/tracing/eve/session.d.ts +3 -2
- package/dist/src/tracing/eve/session.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +86 -65
- package/docs/channels/chat-sdk.mdx +6 -1
- package/docs/channels/custom.mdx +38 -6
- package/docs/channels/eve.mdx +46 -0
- package/docs/channels/linq.mdx +51 -0
- package/docs/channels/photon.mdx +64 -0
- package/docs/channels/slack.mdx +4 -2
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/concepts/execution-model-and-durability.mdx +12 -5
- package/docs/concepts/sessions-runs-and-streaming.md +9 -8
- package/docs/connections/overview.mdx +1 -1
- package/docs/experimental/dynamic-schedules.mdx +186 -0
- package/docs/experimental/meta.json +4 -0
- package/docs/guides/client/streaming.mdx +1 -0
- package/docs/guides/deployment/self-hosting.md +3 -0
- package/docs/guides/hooks.md +21 -1
- package/docs/memory/overview.mdx +2 -1
- package/docs/patterns/dynamic-scheduling.md +3 -1
- package/docs/reference/cli.md +14 -7
- package/docs/schedules.mdx +2 -0
- package/docs/subagents/index.mdx +2 -0
- package/docs/tools/overview.mdx +2 -1
- package/docs/tools/tasks-upgrade.md +12 -7
- package/docs/tools/tasks.md +10 -6
- package/docs/tools/workflows.mdx +36 -5
- package/docs/tutorial/connect-a-warehouse.mdx +1 -1
- package/docs/tutorial/run-analysis.mdx +1 -1
- package/package.json +1 -1
- package/dist/src/execution/run-session-limits.d.ts +0 -12
- package/dist/src/execution/run-session-limits.js +0 -1
- package/dist/src/harness/session-usage-limits.d.ts +0 -49
- package/dist/src/harness/session-usage-limits.js +0 -1
- package/dist/src/subagents/token-budget.d.ts +0 -15
- package/dist/src/subagents/token-budget.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.82.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c543585: Breaking: replace `limits.maxInputTokensPerSession`, `limits.maxOutputTokensPerSession` and `limits.maxTokenCostUsdPerSession` with one `limits.sessionUsage` function. It receives the session's `total` usage and its `window` since the last approved continuation, and returns `true` when the limit is reached; Continue starts a new window. The default is 40M new input tokens (input minus cache reads) per window. Subagents now check their own window with their own `sessionUsage` or the root agent's instead of receiving a share of the parent's remaining quota. Sessions that can't ask now fail with `SESSION_USAGE_LIMIT_REACHED`, replacing `SESSION_TOKEN_LIMIT_REACHED` and `SESSION_TOKEN_COST_LIMIT_REACHED`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- baf3030: Attach the agent trace session ID to auto-instrumented child spans on Vercel so Agent Runs can include network and other third-party spans in a session trace.
|
|
12
|
+
- 91b3183: The session input-token limit now counts only new input (uncached input plus cache writes). Cache reads no longer count toward the limit, the grant after Continue, or the quota shared with subagents, so long cache-heavy sessions stop hitting continuation prompts for replaying their own history. Usage telemetry still reports raw input and cache totals. Providers that report no cache details count exactly as before.
|
|
13
|
+
- 8aba0f6: Allow authored workflow tools to select an AI Gateway model when they open a local session with `ctx.agent()`. The child keeps the target agent's other configuration, and the selected model applies for the session's lifetime.
|
|
14
|
+
- 0aea7fc: `eve eval` now runs while an `eve dev` session for the same agent is open, instead of failing with "A dev server is already running for this eve agent." The eval server keeps its runtime generations, local Workflow data, and server record in a per-run directory under `.eve/eval-servers/`, so it never swaps or prunes the dev session's state.
|
|
15
|
+
- a9f5065: Channel and session sends and responses now accept `idempotencyKey` to ignore retries across replay and owner handoffs. Photon supplies message IDs automatically; deduplication requires a shared Workflow World and only covers keys in the session's recent-key window.
|
|
16
|
+
- 6752c95: Fix a workflow tool task running twice when the session was interrupted while publishing `task.started`, for example during a slow `task.started` hook. The session now records each task's run before it publishes the event, so a retry only publishes `task.started` again and never starts a second run.
|
|
17
|
+
- 964a41f: `limits.sessionTimeoutMs` is now an idle timeout: the window restarts each time a turn settles, so a session in active use no longer ends 30 days after it was created. Idle sessions still complete when the window elapses, and the next channel message at their address starts a fresh session as before.
|
|
18
|
+
- dd8c231: Linq and Photon iMessage channels now tell the model when a message is a reply, and include the text of the message it quotes.
|
|
19
|
+
- cf824a8: The Photon and Linq channels can now pass tapbacks to the agent with a new `onTapback` hook, which can also answer the approval or question posted in the message the tapback is on, for example approving with a like. `channel.tapbackTool()` gives the model a tool that reacts to the latest message with a standard tapback or any emoji. Tapbacks stay ignored unless you opt in.
|
|
20
|
+
- 743b498: `eve start --no-schedules` and `EVE_SCHEDULES_DISABLED=1` start a server that does not fire authored cron schedules, so only one process runs them when you scale out.
|
|
21
|
+
- b34844b: Channel `send()`, channel message hooks, and a new `create()` on channel addresses accept `history` to add prior user and assistant messages, such as a stored transcript, as real turns. `create()` starts a session that waits for its first message and reports with `created` whether it did. A new `history.imported` stream event publishes added messages; the default client reducer renders them, and `transcriptReducer()` includes them. Slack `threadContext` now adds earlier replies as history when a message starts the thread's session; later messages keep the existing transcript.
|
|
22
|
+
- e40d7d7: `eve build` and `eve dev` now evaluate a module shared by several tools, channels, or other authored files once per compile instead of once per importing file. Compile memory now grows with the code an agent actually has, not with the number of files that import it, so agents with many tools over a shared SDK or workspace package no longer run out of memory on smaller build machines. Authored modules transpiled to CommonJS with an `__esModule` marker, such as a `tools/*.cjs` file with `exports.default = …`, now also compile and run correctly instead of resolving to the whole `exports` object. On Windows, CommonJS authored modules can now `require()` eve and other external packages.
|
|
23
|
+
- 62d3227: Skip the final Slack reply when the message that started the turn was deleted, instead of letting Slack post it as a top-level channel message.
|
|
24
|
+
- ee5e8e9: Self-hosted `eve build` output now carries a build identity derived from its contents. eve exposes it to Workflow Worlds as `WORKFLOW_DEPLOYMENT_ID` unless that variable is already set, and records it in `eve build --profile` reports.
|
|
25
|
+
- 7b8a520: Fix unnecessary `eve dev` runtime-generation changes when Nitro installs newer Rolldown versions. No-op rebuilds and environment-only reloads now keep the active runtime snapshot unchanged instead of treating bundler debug comments as runtime changes.
|
|
26
|
+
|
|
3
27
|
## 0.81.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -4,27 +4,46 @@ import { type ChannelDeliverySource } from "#channel/delivery-metadata.js";
|
|
|
4
4
|
import type { SendPayload } from "#channel/routes.js";
|
|
5
5
|
import { type Session } from "#channel/session.js";
|
|
6
6
|
import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
|
|
7
|
+
interface BaseChannelAddressCreateOptions {
|
|
8
|
+
readonly auth: SessionAuthContext | null;
|
|
9
|
+
readonly history?: SendPayload["history"];
|
|
10
|
+
readonly initiatorAuth?: SessionAuthContext | null;
|
|
11
|
+
readonly title?: string;
|
|
12
|
+
}
|
|
13
|
+
type ChannelAddressCreateOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelAddressCreateOptions : BaseChannelAddressCreateOptions & {
|
|
14
|
+
readonly state?: Partial<TState>;
|
|
15
|
+
};
|
|
7
16
|
interface BaseChannelAddressDeliveryOptions {
|
|
17
|
+
readonly idempotencyKey?: string;
|
|
8
18
|
readonly auth: SessionAuthContext | null;
|
|
9
19
|
readonly callback?: SessionCallback;
|
|
10
20
|
readonly initiatorAuth?: SessionAuthContext | null;
|
|
11
21
|
readonly title?: string;
|
|
12
22
|
readonly turnPolicy?: TurnPolicy;
|
|
13
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Result of `create()`. `created` is `false` when another session already owned the address, or
|
|
26
|
+
* won it concurrently; that session is returned unchanged and any `history` was not added.
|
|
27
|
+
*/
|
|
28
|
+
export interface ChannelCreateResult {
|
|
29
|
+
readonly created: boolean;
|
|
30
|
+
readonly session: Session;
|
|
31
|
+
}
|
|
14
32
|
/** Delivery options for a channel address whose continuation token is already bound. */
|
|
15
33
|
export type ChannelAddressDeliveryOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelAddressDeliveryOptions : BaseChannelAddressDeliveryOptions & {
|
|
16
34
|
readonly state?: Partial<TState>;
|
|
17
35
|
};
|
|
18
36
|
/**
|
|
19
37
|
* Dynamic handle for whichever durable session currently owns one channel-local address.
|
|
20
|
-
* Only {@link send} may create a session: when the address is unowned,
|
|
21
|
-
* place of a stranded session that another eve version built. Sends to a session whose
|
|
38
|
+
* Only {@link create} and {@link send} may create a session: when the address is unowned, and
|
|
39
|
+
* `send` also in place of a stranded session that another eve version built. Sends to a session whose
|
|
22
40
|
* owner is only unavailable throw `SessionStrandedError` and deliver nothing.
|
|
23
41
|
* Responses to an address no session holds throw `SessionNotActiveError`.
|
|
24
42
|
*/
|
|
25
43
|
interface ChannelAddress<TState = undefined> {
|
|
26
44
|
readonly continuationToken: string;
|
|
27
45
|
deliver(input: SendPayload, options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
|
|
46
|
+
create(options: ChannelAddressCreateOptions<TState>): Promise<ChannelCreateResult>;
|
|
28
47
|
send(message: string | UserContent, options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
|
|
29
48
|
respond(inputResponses: SendPayload["inputResponses"], options: ChannelAddressDeliveryOptions<TState>): Promise<Session>;
|
|
30
49
|
cancel(options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{normalizeSendInput,serializeFilePartsInMessage}from"#channel/send-input.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{isReservedSessionCommandToken}from"#execution/session-inbox/address.js";function createChannelAddress(e){let t=e.metadata??{},n=`${e.channelName}:${e.continuationToken}`;if(isReservedSessionCommandToken(n))throw Error(`Channel address "${n}" uses eve's reserved session namespace.`);return{continuationToken:e.continuationToken,async deliver(r,i){let a=t.channelKind!==void 0&&t.channelName!==void 0?createChannelDeliveryMetadata(t):void 0,o=normalizeSendInput(r),s=sessionCallbackToTurnCaller(i.callback),c={auth:i.auth,delivery:a,kind:`send`,payload:{...o,message:serializeFilePartsInMessage(o.message)},requestId:t.requestId,turnPolicy:o.message===void 0?void 0:i.turnPolicy??e.turnPolicy??DEFAULT_TURN_POLICY},l=s===void 0?c:{...c,caller:s},u=i.state,d=
|
|
1
|
+
import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{normalizeSendInput,serializeFilePartsInMessage}from"#channel/send-input.js";import{SessionNotActiveError}from"#channel/session-not-active-error.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{isReservedSessionCommandToken}from"#execution/session-inbox/address.js";import{validateSessionHistory}from"#shared/session-history.js";function createChannelAddress(e){let t=e.metadata??{},n=`${e.channelName}:${e.continuationToken}`;if(isReservedSessionCommandToken(n))throw Error(`Channel address "${n}" uses eve's reserved session namespace.`);return{continuationToken:e.continuationToken,async deliver(r,i){validateDeliveryIdempotencyKey(i.idempotencyKey);let a=t.channelKind!==void 0&&t.channelName!==void 0?createChannelDeliveryMetadata(t):void 0,o=withValidatedHistory(normalizeSendInput(r)),s=sessionCallbackToTurnCaller(i.callback),c={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:a,kind:`send`,payload:{...o,message:serializeFilePartsInMessage(o.message)},requestId:t.requestId,turnPolicy:o.message===void 0?void 0:i.turnPolicy??e.turnPolicy??DEFAULT_TURN_POLICY},l=s===void 0?c:{...c,caller:s},u=i.state,d=u===void 0?e.adapter:{...e.adapter,state:{...e.adapter.state,...u}},f={idempotencyKey:i.idempotencyKey,adapter:d,auth:i.auth,capabilities:{requestInput:!0},callback:i.callback,channelName:e.channelName,continuationConflictCommand:l,continuationToken:n,delivery:a,initiatorAuth:i.initiatorAuth,input:{context:o.context,history:o.history,message:serializeFilePartsInMessage(o.message)??``,outputSchema:o.outputSchema,state:o.state},requestId:t.requestId,title:i.title},toSession=n=>createSession(n,e.runtime,{...t,turnPolicy:e.turnPolicy}),p=await e.runtime.dispatchContinuation({command:l,continuationToken:n,successor:f});if(p.status===`accepted`)return toSession(p.sessionId);if(o.inputResponses&&o.inputResponses.length>0)throw new SessionNotActiveError;return toSession((await e.runtime.createSession(f)).sessionId)},async create(r){let i=validateSessionHistory(r.history),toSession=n=>createSession(n,e.runtime,{...t,turnPolicy:e.turnPolicy}),a;try{a=await e.runtime.resolveContinuation(n,{runnable:!0})}catch(e){throw SessionStrandedError.is(e)?new SessionStrandedError(e.owner,describeStrandedSession(e.owner,`Call reset() on the address, then create() again to start a session from your history.`)):e}if(a!==void 0)return{created:!1,session:toSession(a.sessionId)};let o=r.state,s=await e.runtime.createSession({adapter:o===void 0?e.adapter:{...e.adapter,state:{...e.adapter.state,...o}},auth:r.auth,capabilities:{requestInput:!0},channelName:e.channelName,continuationToken:n,initiatorAuth:r.initiatorAuth,input:i===void 0?{}:{history:i},requestId:t.requestId,title:r.title}),c=await waitForContinuationOwner(e.runtime,n,s.sessionId);return{created:c.sessionId===s.sessionId,session:toSession(c.sessionId)}},async send(e,t){return await this.deliver({message:e},t)},async respond(e,t){if(e===void 0||e.length===0)throw Error(`respond() requires at least one input response.`);return await this.deliver({inputResponses:e},t)},async cancel(t){return await e.runtime.dispatchContinuation({command:{kind:`cancel`,turnId:t?.turnId},continuationToken:n})},async compact(){return await e.runtime.dispatchContinuation({command:{kind:`compact`},continuationToken:n})},async clear(){return await e.runtime.dispatchContinuation({command:{kind:`clear`},continuationToken:n})},async reset(t){return await e.runtime.dispatchContinuation({command:{kind:`reset`,reason:t?.reason},continuationToken:n})},async resolveSession(){let r=await e.runtime.resolveContinuation(n);return r===void 0?void 0:createSession(r.sessionId,e.runtime,{...t,turnPolicy:e.turnPolicy})}}}function createChannelAddressFn(e){return t=>createChannelAddress({...e,continuationToken:t})}function withValidatedHistory(e){let{history:t,...n}=e,r=validateSessionHistory(t);return r===void 0?n:{...n,history:r}}const CREATE_CLAIM_TIMEOUT_MS=15e3;async function waitForContinuationOwner(e,t,n){let r=Date.now()+CREATE_CLAIM_TIMEOUT_MS;for(let i=25;;i=Math.min(i*2,500)){let a=await e.resolveContinuation(t);if(a!==void 0)return a;if(Date.now()+i>r)throw Error(`create() started session "${n}" for "${t}", but no session claimed the address within ${CREATE_CLAIM_TIMEOUT_MS/1e3}s. Call resolveSession() on the address to find its owner once one does.`);await new Promise(e=>setTimeout(e,i))}}export{createChannelAddress,createChannelAddressFn};
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import type { UserContent } from "ai";
|
|
2
2
|
import type { ChannelAdapter } from "#channel/adapter.js";
|
|
3
3
|
import type { ChannelDeliverySource } from "#channel/delivery-metadata.js";
|
|
4
|
+
import { type ChannelCreateResult } from "#channel/channel-address.js";
|
|
5
|
+
export type { ChannelCreateResult } from "#channel/channel-address.js";
|
|
4
6
|
import type { Session } from "#channel/session.js";
|
|
5
7
|
import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
|
|
6
8
|
import { type InputResponse, type StrictInputResponses } from "#shared/input.js";
|
|
7
9
|
import type { JsonObject } from "#shared/json.js";
|
|
10
|
+
import type { SessionHistoryMessage } from "#shared/session-history.js";
|
|
8
11
|
interface BaseChannelSendOptions {
|
|
12
|
+
/** Stable delivery identity, deduplicated within this session's recent-key window. */
|
|
13
|
+
readonly idempotencyKey?: string;
|
|
9
14
|
readonly auth: SessionAuthContext | null;
|
|
10
15
|
readonly callback?: SessionCallback;
|
|
11
16
|
readonly context?: readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* Prior conversation added as user and assistant turns before this
|
|
19
|
+
* message and its `context`. Seeds a session this send creates, or
|
|
20
|
+
* extends the history of the session that owns the address.
|
|
21
|
+
*/
|
|
22
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
12
23
|
readonly initiatorAuth?: SessionAuthContext | null;
|
|
13
24
|
/** JSON Schema for a structured final answer, as on `Session.send()`. */
|
|
14
25
|
readonly outputSchema?: JsonObject;
|
|
@@ -20,16 +31,37 @@ export type ChannelSendOptions<TState = undefined> = [TState] extends [undefined
|
|
|
20
31
|
readonly state: TState;
|
|
21
32
|
};
|
|
22
33
|
interface BaseChannelRespondOptions<TState = undefined> {
|
|
34
|
+
/** Stable delivery identity, with the same scope and retention as `send()`. */
|
|
35
|
+
readonly idempotencyKey?: string;
|
|
23
36
|
readonly auth: SessionAuthContext | null;
|
|
24
37
|
readonly context?: readonly string[];
|
|
25
38
|
readonly state?: Partial<TState>;
|
|
26
39
|
}
|
|
27
40
|
/** Options for answering pending input requests at an existing continuation address. */
|
|
28
41
|
export type ChannelRespondOptions<TState = undefined> = BaseChannelRespondOptions<TState>;
|
|
42
|
+
interface BaseChannelCreateOptions {
|
|
43
|
+
readonly auth: SessionAuthContext | null;
|
|
44
|
+
/** Prior conversation the session starts with; it joins history with the first message. */
|
|
45
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
46
|
+
readonly initiatorAuth?: SessionAuthContext | null;
|
|
47
|
+
readonly title?: string;
|
|
48
|
+
}
|
|
49
|
+
/** Options for creating a session at a channel-local address without running a turn. */
|
|
50
|
+
export type ChannelCreateOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelCreateOptions : BaseChannelCreateOptions & {
|
|
51
|
+
readonly state: TState;
|
|
52
|
+
};
|
|
29
53
|
/** Dynamic handle for whichever session currently owns one channel-local address. */
|
|
30
54
|
export interface ChannelSource<TState = undefined> {
|
|
31
55
|
/** Starts or resumes a turn with a user message. May create a session. */
|
|
32
56
|
send(message: string | UserContent, options: ChannelSendOptions<TState>): Promise<Session>;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a session that waits for its first message, without running a
|
|
59
|
+
* turn. When another session owns the address, or claims it concurrently,
|
|
60
|
+
* returns that session unchanged with `created: false`; its `history` was not
|
|
61
|
+
* added. Throws `SessionStrandedError` when the owner is stranded; reset the
|
|
62
|
+
* address, then create again.
|
|
63
|
+
*/
|
|
64
|
+
create(options: ChannelCreateOptions<TState>): Promise<ChannelCreateResult>;
|
|
33
65
|
/** Answers pending input requests. Never creates a session. */
|
|
34
66
|
respond<const TResponses extends readonly InputResponse[]>(inputResponses: StrictInputResponses<TResponses>, options: ChannelRespondOptions<TState>): Promise<Session>;
|
|
35
67
|
/** Cooperatively cancels the active turn without creating a session. */
|
|
@@ -62,4 +94,3 @@ export declare function createChannelOperations<TState = undefined>(input: {
|
|
|
62
94
|
readonly runtime: Runtime;
|
|
63
95
|
readonly turnPolicy?: TurnPolicy;
|
|
64
96
|
}): ChannelReceiveContext<TState>;
|
|
65
|
-
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{attachInputText,readInputText}from"#internal/input-text.js";import{createChannelAddressFn}from"#channel/channel-address.js";import{parseInputResponses}from"#shared/input.js";function createChannelOperations(e){let t=createChannelAddressFn(e);return{from(e){let n=t(e);return{async send(e,t){return await n.deliver(attachInputText({context:t.context,message:e,outputSchema:t.outputSchema,state:t.state},readInputText(t)),t)},async respond(e,t){if(e.length===0)throw Error(`respond() requires at least one input response.`);let r=parseInputResponses(e);return await n.deliver({context:t.context,inputResponses:r,state:t.state},t)},async cancel(e){return await n.cancel(e)},async compact(){return await n.compact()},async clear(){return await n.clear()},async reset(e){return await n.reset(e)}}},async resolveSession(e){return await t(e).resolveSession()}}}export{createChannelOperations};
|
|
1
|
+
import{attachInputText,readInputText}from"#internal/input-text.js";import{createChannelAddressFn}from"#channel/channel-address.js";import{parseInputResponses}from"#shared/input.js";function createChannelOperations(e){let t=createChannelAddressFn(e);return{from(e){let n=t(e);return{async send(e,t){return await n.deliver(attachInputText({context:t.context,history:t.history,message:e,outputSchema:t.outputSchema,state:t.state},readInputText(t)),t)},async create(e){return await n.create(e)},async respond(e,t){if(e.length===0)throw Error(`respond() requires at least one input response.`);let r=parseInputResponses(e);return await n.deliver({context:t.context,inputResponses:r,state:t.state},t)},async cancel(e){return await n.cancel(e)},async compact(){return await n.compact()},async clear(){return await n.clear()},async reset(e){return await n.reset(e)}}},async resolveSession(e){return await t(e).resolveSession()}}}export{createChannelOperations};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Maximum number of distinct delivery keys remembered by one logical session. */
|
|
2
|
+
export declare const DELIVERY_IDEMPOTENCY_WINDOW = 1024;
|
|
3
|
+
export declare const MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH = 256;
|
|
4
|
+
export declare function validateDeliveryIdempotencyKey(key: unknown): asserts key is string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const DELIVERY_IDEMPOTENCY_WINDOW=1024,MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH=256;function validateDeliveryIdempotencyKey(e){if(e!==void 0&&(typeof e!=`string`||e.length===0||e.length>256))throw Error(`idempotencyKey must be a nonempty string of at most 256 characters.`)}export{DELIVERY_IDEMPOTENCY_WINDOW,MAX_DELIVERY_IDEMPOTENCY_KEY_LENGTH,validateDeliveryIdempotencyKey};
|
|
@@ -5,6 +5,7 @@ import type { InvokeToolFn } from "#channel/invoke-tool.js";
|
|
|
5
5
|
import type { InputResponse } from "#shared/input.js";
|
|
6
6
|
import type { Session } from "#channel/session.js";
|
|
7
7
|
import type { JsonObject } from "#shared/json.js";
|
|
8
|
+
import type { SessionHistoryMessage } from "#shared/session-history.js";
|
|
8
9
|
import type { ChannelMethod } from "#public/definitions/channel.js";
|
|
9
10
|
import type { AgentDescription, AgentSkillFileDescription } from "#channel/agent-description.js";
|
|
10
11
|
type WebSocketHeaders = Headers | readonly (readonly [string, string])[] | Record<string, string>;
|
|
@@ -65,6 +66,11 @@ export interface SendPayload {
|
|
|
65
66
|
* message and persists it across the session.
|
|
66
67
|
*/
|
|
67
68
|
readonly context?: readonly string[];
|
|
69
|
+
/**
|
|
70
|
+
* Prior conversation added as user and assistant turns before this
|
|
71
|
+
* delivery's `context` and message.
|
|
72
|
+
*/
|
|
73
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
68
74
|
/**
|
|
69
75
|
* Run-scoped JSON schema the turn's result must match.
|
|
70
76
|
*/
|
|
@@ -6,6 +6,7 @@ import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, GetEve
|
|
|
6
6
|
import type { SessionAuth } from "#context/keys.js";
|
|
7
7
|
import { type InputResponse, type StrictInputResponses } from "#shared/input.js";
|
|
8
8
|
import type { JsonObject } from "#shared/json.js";
|
|
9
|
+
import { type SessionHistoryMessage } from "#shared/session-history.js";
|
|
9
10
|
/** Immutable-ID handle for one exact durable session. */
|
|
10
11
|
export interface Session {
|
|
11
12
|
readonly id: string;
|
|
@@ -38,6 +39,8 @@ export interface Session {
|
|
|
38
39
|
getStreamTailIndex(): Promise<number>;
|
|
39
40
|
}
|
|
40
41
|
interface SessionDeliveryOptions {
|
|
42
|
+
/** Stable delivery identity, deduplicated within this session's recent-key window. */
|
|
43
|
+
readonly idempotencyKey?: string;
|
|
41
44
|
readonly auth: SessionAuthContext | null;
|
|
42
45
|
/** Public callback destination for a delegated continuation turn. */
|
|
43
46
|
readonly callback?: SessionCallback;
|
|
@@ -46,6 +49,8 @@ interface SessionDeliveryOptions {
|
|
|
46
49
|
}
|
|
47
50
|
/** Options for sending a message through a fixed session handle. */
|
|
48
51
|
export type SessionSendOptions = SessionDeliveryOptions & {
|
|
52
|
+
/** Prior conversation added as user and assistant turns before this message and its `context`. */
|
|
53
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
49
54
|
/** Initial workflow title for a prewarmed session. */
|
|
50
55
|
readonly title?: string;
|
|
51
56
|
readonly turnPolicy?: TurnPolicy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{serializeFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{parseInputResponses}from"#shared/input.js";import{AuthKey,ContinuationHookTokensKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(e,t,n={}){return{id:e,async send(r,i){let a=createDelivery(n),o=sessionCallbackToTurnCaller(i.callback),s=attachClientContext({message:serializeFilePartsInMessage(r)},readClientContext(i));i.context!==void 0&&(
|
|
1
|
+
import{attachClientContext,readClientContext}from"#internal/client-context.js";import{validateDeliveryIdempotencyKey}from"#channel/delivery-idempotency.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{serializeFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{validateSessionHistory}from"#shared/session-history.js";import{parseInputResponses}from"#shared/input.js";import{AuthKey,ContinuationHookTokensKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(e,t,n={}){return{id:e,async send(r,i){validateDeliveryIdempotencyKey(i.idempotencyKey);let a=createDelivery(n),o=sessionCallbackToTurnCaller(i.callback),s=validateSessionHistory(i.history),c=attachClientContext({message:serializeFilePartsInMessage(r)},readClientContext(i));i.context!==void 0&&(c.context=i.context),s!==void 0&&(c.history=s),i.outputSchema!==void 0&&(c.outputSchema=i.outputSchema);let l={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:a,kind:`send`,payload:c,requestId:n.requestId,turnPolicy:i.turnPolicy??n.turnPolicy??DEFAULT_TURN_POLICY,title:i.title};return await t.dispatchSession({command:o===void 0?l:{...l,caller:o},sessionId:e})},async respond(r,i){if(validateDeliveryIdempotencyKey(i.idempotencyKey),r.length===0)throw Error(`respond() requires at least one input response.`);let a=parseInputResponses(r),o=sessionCallbackToTurnCaller(i.callback),s=createDelivery(n),c=attachClientContext({inputResponses:a},readClientContext(i));i.context!==void 0&&(c.context=i.context),i.outputSchema!==void 0&&(c.outputSchema=i.outputSchema);let l={idempotencyKey:i.idempotencyKey,auth:i.auth,delivery:s,kind:`send`,payload:c,requestId:n.requestId};return await t.dispatchSession({command:o===void 0?l:{...l,caller:o},sessionId:e})},async cancel(n){let r={kind:`cancel`};return n?.turnId!==void 0&&(r.turnId=n.turnId),await t.dispatchSession({command:r,sessionId:e})},async compact(){return await t.dispatchSession({command:{kind:`compact`},sessionId:e})},async clear(){return await t.dispatchSession({command:{kind:`clear`},sessionId:e})},async reset(n){return await t.dispatchSession({command:{kind:`reset`,reason:n?.reason},sessionId:e})},async getEventStream(n){return t.getEventStream(e,n)},async getStreamTailIndex(){return t.getStreamTailIndex(e)}}}function createAttachSessionFn(e,t={}){return n=>createSession(n,e,t)}function createDelivery(e){return e.channelKind!==void 0&&e.channelName!==void 0?createChannelDeliveryMetadata(e):void 0}function buildSessionHandle(e){return{get id(){return e.get(SessionIdKey)??``},get auth(){return{current:e.get(AuthKey)??null,initiator:e.get(InitiatorAuthKey)??null}},get continuation(){let t=e.get(ContinuationTokenKey);if(t!==void 0&&t.length!==0)return{token:toChannelLocalContinuationToken(t),alias(n){if(n.length===0)throw Error(`A session alias requires a nonempty token.`);let r=namespaceContinuationToken(t,n);t!==r&&(e.set(ContinuationHookTokensKey,e=>{let n=e??[t];return n.includes(r)?n:[...n,r]}),e.set(ContinuationTokenKey,r))}}}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}function sessionCallbackToTurnCaller(e){return e===void 0?void 0:{callId:e.callId,replyTo:{kind:`callback`,token:e.token,url:e.url},subagentName:e.subagentName}}export{buildSessionHandle,createAttachSessionFn,createSession,sessionCallbackToTurnCaller};
|
|
@@ -6,8 +6,8 @@ import type { CancelTurnResult as ProtocolCancelTurnResult } from "#protocol/can
|
|
|
6
6
|
import type { RuntimeSubagentChildResult, RuntimeSubagentDispatchFailure, RuntimeToolResultActionResult } from "#shared/action-types.js";
|
|
7
7
|
import type { InputRequest, InputResponse } from "#shared/input.js";
|
|
8
8
|
import type { ChannelAdapter } from "#channel/adapter.js";
|
|
9
|
-
import type { AgentLimitsDefinition } from "#shared/agent-definition.js";
|
|
10
9
|
import type { JsonObject } from "#shared/json.js";
|
|
10
|
+
import type { SessionHistoryMessage } from "#shared/session-history.js";
|
|
11
11
|
import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
|
|
12
12
|
import type { ForwardedTraceAssertion } from "#shared/forwarded-trace-policy.js";
|
|
13
13
|
import type { ConversationContext } from "#shared/conversation-context.js";
|
|
@@ -15,7 +15,6 @@ import type { StubScope } from "#tool-stubs/types.js";
|
|
|
15
15
|
export type { ContextAccessor } from "#context/key.js";
|
|
16
16
|
export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
|
|
17
17
|
import type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
|
|
18
|
-
export type RunSessionLimits = Pick<AgentLimitsDefinition, "maxInputTokensPerSession" | "maxOutputTokensPerSession" | "maxTokenCostUsdPerSession">;
|
|
19
18
|
/** Identifies the session turn to cancel. */
|
|
20
19
|
export interface CancelTurnInput {
|
|
21
20
|
readonly sessionId: string;
|
|
@@ -155,6 +154,8 @@ export interface DeliverPayload {
|
|
|
155
154
|
readonly inputResponses?: readonly InputResponse[];
|
|
156
155
|
readonly message?: string | UserContent;
|
|
157
156
|
readonly context?: readonly string[];
|
|
157
|
+
/** Prior conversation added as user and assistant turns before this delivery's input. */
|
|
158
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
158
159
|
readonly outputSchema?: JsonObject;
|
|
159
160
|
readonly [key: string]: unknown;
|
|
160
161
|
}
|
|
@@ -164,6 +165,7 @@ export type TurnPolicy = "steer" | "queue";
|
|
|
164
165
|
export declare const DEFAULT_TURN_POLICY: TurnPolicy;
|
|
165
166
|
/** One command accepted by a durable session inbox. */
|
|
166
167
|
export type SessionCommand = {
|
|
168
|
+
readonly idempotencyKey?: string;
|
|
167
169
|
readonly auth?: SessionAuthContext | null;
|
|
168
170
|
readonly caller?: TurnCaller;
|
|
169
171
|
/** Initial workflow title when delivering to a prewarmed session. */
|
|
@@ -230,6 +232,7 @@ export interface DispatchSessionInput<TCommand extends SessionCommand = SessionC
|
|
|
230
232
|
* metadata so both cross the durable hook boundary outside adapter-owned data.
|
|
231
233
|
*/
|
|
232
234
|
export interface DeliverHookPayload {
|
|
235
|
+
readonly idempotencyKey?: string;
|
|
233
236
|
readonly schedule?: import("#context/session-schedule.js").SessionSchedule;
|
|
234
237
|
/** Initial workflow title; ignored once session initialization has run. */
|
|
235
238
|
readonly title?: string;
|
|
@@ -371,6 +374,8 @@ export interface SessionCapabilities {
|
|
|
371
374
|
* subagent tool wrapper).
|
|
372
375
|
*/
|
|
373
376
|
export interface RunInput {
|
|
377
|
+
/** Optional stable identity of the initial delivery, scoped to this logical session. */
|
|
378
|
+
readonly idempotencyKey?: string;
|
|
374
379
|
/**
|
|
375
380
|
* @internal Set by the server after it authorizes tool stubs.
|
|
376
381
|
* Local subagents match rules qualified by their full path, such as researcher/list_tasks.
|
|
@@ -456,6 +461,8 @@ export interface RunInput {
|
|
|
456
461
|
/** Omitted only when creating a conversation session before its first turn. */
|
|
457
462
|
readonly message?: string | UserContent;
|
|
458
463
|
readonly context?: readonly string[];
|
|
464
|
+
/** Prior conversation; with no message, it waits for the first message's turn. */
|
|
465
|
+
readonly history?: readonly SessionHistoryMessage[];
|
|
459
466
|
readonly outputSchema?: JsonObject;
|
|
460
467
|
/** Channel payload state for the first delivery, as later deliveries carry it. */
|
|
461
468
|
readonly state?: unknown;
|
|
@@ -470,13 +477,6 @@ export interface RunInput {
|
|
|
470
477
|
* because trace state is scoped to one session's context.
|
|
471
478
|
*/
|
|
472
479
|
readonly parentTraceContext?: SessionTraceContext;
|
|
473
|
-
/**
|
|
474
|
-
* Runtime-supplied session limits. Delegated local subagents use this to
|
|
475
|
-
* carry the parent's remaining quota and delegation caps with the same limit
|
|
476
|
-
* fields authors configure on agents; `false` means no inherited token cap
|
|
477
|
-
* for that axis.
|
|
478
|
-
*/
|
|
479
|
-
readonly limits?: RunSessionLimits;
|
|
480
480
|
/** Framework-owned metadata for a protocol-neutral external invocation. */
|
|
481
481
|
readonly externalInvocation?: {
|
|
482
482
|
readonly continuationToken: string;
|
|
@@ -551,9 +551,12 @@ export interface Runtime {
|
|
|
551
551
|
/**
|
|
552
552
|
* Resolves the session that currently owns a continuation token without
|
|
553
553
|
* delivering input or starting a run. Returns `undefined` when no session
|
|
554
|
-
* owns the token.
|
|
554
|
+
* owns the token. With `runnable`, throws `SessionStrandedError` when the
|
|
555
|
+
* owner is stranded and can run nothing.
|
|
555
556
|
*/
|
|
556
|
-
resolveContinuation(continuationToken: string
|
|
557
|
+
resolveContinuation(continuationToken: string, options?: {
|
|
558
|
+
readonly runnable?: boolean;
|
|
559
|
+
}): Promise<{
|
|
557
560
|
sessionId: string;
|
|
558
561
|
} | undefined>;
|
|
559
562
|
/**
|
|
@@ -3506,6 +3506,7 @@ function reduceContent(data, event) {
|
|
|
3506
3506
|
parts: projectReceivedParts(event.data.parts, event.data.message),
|
|
3507
3507
|
role: "user"
|
|
3508
3508
|
}, event.data.turnId);
|
|
3509
|
+
case "history.imported": return importHistory(data, event);
|
|
3509
3510
|
case "step.started": return updateAssistantMessage(data, event.data.turnId, (message) => ensureStepStartPart(message, event.data.stepIndex));
|
|
3510
3511
|
case "step.completed":
|
|
3511
3512
|
if (data.messages.find((message) => message.role === "assistant" && message.metadata?.turnId === event.data.turnId) === void 0) return data;
|
|
@@ -3698,6 +3699,41 @@ function reduceContent(data, event) {
|
|
|
3698
3699
|
default: return data;
|
|
3699
3700
|
}
|
|
3700
3701
|
}
|
|
3702
|
+
function importHistory(data, event) {
|
|
3703
|
+
const eventId = event.meta.id ?? `${event.data.turnId}:${event.data.sequence}`;
|
|
3704
|
+
const imported = event.data.messages.map((message, index) => ({
|
|
3705
|
+
id: `${eventId}:imported:${index}`,
|
|
3706
|
+
metadata: message.id === void 0 ? {
|
|
3707
|
+
imported: true,
|
|
3708
|
+
status: "complete"
|
|
3709
|
+
} : {
|
|
3710
|
+
historyId: message.id,
|
|
3711
|
+
imported: true,
|
|
3712
|
+
status: "complete"
|
|
3713
|
+
},
|
|
3714
|
+
parts: [message.role === "assistant" ? {
|
|
3715
|
+
state: "done",
|
|
3716
|
+
text: message.text,
|
|
3717
|
+
type: "text"
|
|
3718
|
+
} : {
|
|
3719
|
+
text: message.text,
|
|
3720
|
+
type: "text"
|
|
3721
|
+
}],
|
|
3722
|
+
role: message.role
|
|
3723
|
+
}));
|
|
3724
|
+
const ids = new Set(imported.map((message) => message.id));
|
|
3725
|
+
const messages = data.messages.filter((message) => !ids.has(message.id));
|
|
3726
|
+
const before = messages.findIndex((message) => message.metadata?.optimistic === true || message.role === "assistant" && message.metadata?.turnId === event.data.turnId);
|
|
3727
|
+
const at = before === -1 ? messages.length : before;
|
|
3728
|
+
return {
|
|
3729
|
+
...data,
|
|
3730
|
+
messages: [
|
|
3731
|
+
...messages.slice(0, at),
|
|
3732
|
+
...imported,
|
|
3733
|
+
...messages.slice(at)
|
|
3734
|
+
]
|
|
3735
|
+
};
|
|
3736
|
+
}
|
|
3701
3737
|
function toolCallIds(data, event) {
|
|
3702
3738
|
const byRequest = (requestId) => findToolPartByApprovalId(data, requestId)?.toolCallId ?? [];
|
|
3703
3739
|
switch (event.type) {
|
|
@@ -3507,6 +3507,7 @@ function reduceContent(data, event) {
|
|
|
3507
3507
|
parts: projectReceivedParts(event.data.parts, event.data.message),
|
|
3508
3508
|
role: "user"
|
|
3509
3509
|
}, event.data.turnId);
|
|
3510
|
+
case "history.imported": return importHistory(data, event);
|
|
3510
3511
|
case "step.started": return updateAssistantMessage(data, event.data.turnId, (message) => ensureStepStartPart(message, event.data.stepIndex));
|
|
3511
3512
|
case "step.completed":
|
|
3512
3513
|
if (data.messages.find((message) => message.role === "assistant" && message.metadata?.turnId === event.data.turnId) === void 0) return data;
|
|
@@ -3699,6 +3700,41 @@ function reduceContent(data, event) {
|
|
|
3699
3700
|
default: return data;
|
|
3700
3701
|
}
|
|
3701
3702
|
}
|
|
3703
|
+
function importHistory(data, event) {
|
|
3704
|
+
const eventId = event.meta.id ?? `${event.data.turnId}:${event.data.sequence}`;
|
|
3705
|
+
const imported = event.data.messages.map((message, index) => ({
|
|
3706
|
+
id: `${eventId}:imported:${index}`,
|
|
3707
|
+
metadata: message.id === void 0 ? {
|
|
3708
|
+
imported: true,
|
|
3709
|
+
status: "complete"
|
|
3710
|
+
} : {
|
|
3711
|
+
historyId: message.id,
|
|
3712
|
+
imported: true,
|
|
3713
|
+
status: "complete"
|
|
3714
|
+
},
|
|
3715
|
+
parts: [message.role === "assistant" ? {
|
|
3716
|
+
state: "done",
|
|
3717
|
+
text: message.text,
|
|
3718
|
+
type: "text"
|
|
3719
|
+
} : {
|
|
3720
|
+
text: message.text,
|
|
3721
|
+
type: "text"
|
|
3722
|
+
}],
|
|
3723
|
+
role: message.role
|
|
3724
|
+
}));
|
|
3725
|
+
const ids = new Set(imported.map((message) => message.id));
|
|
3726
|
+
const messages = data.messages.filter((message) => !ids.has(message.id));
|
|
3727
|
+
const before = messages.findIndex((message) => message.metadata?.optimistic === true || message.role === "assistant" && message.metadata?.turnId === event.data.turnId);
|
|
3728
|
+
const at = before === -1 ? messages.length : before;
|
|
3729
|
+
return {
|
|
3730
|
+
...data,
|
|
3731
|
+
messages: [
|
|
3732
|
+
...messages.slice(0, at),
|
|
3733
|
+
...imported,
|
|
3734
|
+
...messages.slice(at)
|
|
3735
|
+
]
|
|
3736
|
+
};
|
|
3737
|
+
}
|
|
3702
3738
|
function toolCallIds(data, event) {
|
|
3703
3739
|
const byRequest = (requestId) => findToolPartByApprovalId(data, requestId)?.toolCallId ?? [];
|
|
3704
3740
|
switch (event.type) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{access,readdir,stat,writeFile}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,join,relative,sep}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{
|
|
1
|
+
import{access,readdir,stat,writeFile}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,join,relative,sep}from"node:path";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{displayLocalWorkflowWorldDataDirectory,resolveLocalWorkflowWorldDataDirectory}from"#internal/workflow/local-world-data-directory.js";import{captureVercel,resolveVercelInvocation}from"#setup/primitives/run-vercel.js";function createDevDiagnosticDump(e,t,n={}){let r=t.replace(/\.log$/,`.dump`),i=n.now??(()=>new Date),a=i().getTime(),o,s,c=Promise.resolve(),l=!1,u=!1,write=()=>{if(u||l)return;let e=formatDump({at:i(),durationMs:i().getTime()-a,environment:o,stats:s});c=c.then(()=>writeFile(r,e,{encoding:`utf8`,mode:384})).catch(()=>{l=!0})};return write(),(n.environment??(()=>collectDevEnvironmentInfo(e)))().then(e=>{o=e,write()}).catch(()=>{}),{path:r,displayPath:relative(e,r).split(sep).join(`/`),updateSessionStats(e){s=e,write()},async close(){u||(write(),u=!0,await c)}}}function formatDump(e){let t={updatedAt:e.at.toISOString(),durationMs:e.durationMs,environment:e.environment??null,session:e.stats??null};return`${JSON.stringify(t,null,2)}\n`}async function collectDevEnvironmentInfo(e){let[t,n]=await Promise.all([detectVercelCli(e),measureSessionsDirectory(e)]),r={eveVersion:resolveInstalledPackageInfo().version,nodeVersion:process.version,platform:`${process.platform} ${process.arch}`,...t};return n!==void 0&&(r.sessionsDirectory=n),r}async function detectVercelCli(e){let t=resolveVercelInvocation(e),[n,r]=await Promise.all([captureVercel([`--version`],{cwd:e,nonInteractive:!0,timeoutMs:5e3}),t.command===`vercel`?findOnPath(`vercel`):Promise.resolve(t.command)]),i=n.ok?n.stdout:`${n.failure.stdout}\n${n.failure.stderr}`,a=/(\d+\.\d+\.\d+\S*)/.exec(i)?.[1],o={};return a!==void 0&&(o.vercelCliVersion=a),r!==void 0&&(o.vercelCliPath=r),o}async function findOnPath(e){let t=(process.env.PATH??``).split(delimiter).filter(e=>e.length>0);for(let n of t){let t=join(n,e);try{return await access(t,constants.X_OK),t}catch{}}}async function measureSessionsDirectory(e){let t=resolveLocalWorkflowWorldDataDirectory(e),n;try{n=await readdir(t,{recursive:!0,withFileTypes:!0})}catch{return}let r=0,i=0;for(let e of n)if(e.isFile()){r+=1;try{i+=(await stat(join(e.parentPath,e.name))).size}catch{}}return{path:displayLocalWorkflowWorldDataDirectory(e),files:r,bytes:i}}export{createDevDiagnosticDump,measureSessionsDirectory};
|
package/dist/src/cli/run.d.ts
CHANGED
package/dist/src/cli/run.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Command,CommanderError}from"#compiled/commander/index.js";import{agentCommand}from"#cli/agent-command.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{findEveProjectContext,resolveEveProjectContext}from"#internal/project-context.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{registerDevelopmentCommand,registerRemoteCommands}from"#cli/dev/command.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseAgentNamesOption,parsePortOption,parseReasoningOption}from"#cli/option-parsers.js";import{registerEveTelemetryCommands}from"#cli/telemetry/command.js";import{canonicalCommand,createEveCliTelemetry}from"#cli/telemetry/index.js";async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function createCliProgram(e,t,n,r){let i=resolveInstalledPackageInfo().version,a=new Command,o=createCliTheme();a.name(`eve`).description(`Build and run an eve application.`).version(i).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();!r&&(n.name()===`info`||n.name()===`init`&&n.parent!==a)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),registerEveTelemetryCommands(a,e),registerIntegrationCommands({program:a,logger:e,applicationContext:n});let s=a.command(`extension`).description(`Create and build reusable eve extension packages.`);s.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:a}=await import(`#cli/commands/extension-init.js`);await a(e,n.root,t,void 0,e=>{r.trackSetupStep({flow:`extension_init`,step:e})})}),s.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);await t(n.root);let{runExtensionBuildCommand:r}=await import(`#cli/commands/extension-build.js`);await r(e,n.root)}),registerRegistryCommands({program:a,logger:e,applicationContext:n}),a.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--agents <names>`,`Create an agents/ workspace with comma-separated agent names`,parseAgentNamesOption).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`-n, --non-interactive`,`Scaffold the agent without starting development`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:a}=await import(`#cli/commands/init.js`);await a(e,n.root,t,{agents:i.agents,channelWebNextjs:i.channelWebNextjs,model:i.model,reasoning:i.reasoning,nonInteractive:i.nonInteractive},void 0,e=>{r.trackSetupStep({flow:`init`,step:e})},(e,t,n)=>{r.trackSetupTerminal({flow:`init`,step:e,result:t,failureCode:n})})});let c=a.command(`set`).description(`Change root agent model settings.`);agentCommand(c.command(`model [model]`),n).description(`Set the agent model and reasoning effort.`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async(t,r)=>{let{runSetCommand:i}=await import(`#cli/commands/set.js`);await i(e,n.root,{model:t,reasoning:r.reasoning})}),registerProjectCommands({program:a,logger:e,applicationContext:n}),registerBuildCommand({applicationContext:n,buildHost:t.buildHost,logger:e,program:a}),agentCommand(a.command(`start`),n).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async r=>{let{loadDevelopmentEnvironmentFiles:i}=await import(`#cli/dev/environment.js`);await i(n.root);let a=await(t.startProductionHost??await loadStartProductionHost())(n.root,{host:r.host,port:r.port});e.log(renderCliTaggedLine(o,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForShutdownSignal({close:()=>a.close(),wait:()=>a.wait()})});let l=a.command(`remote`).description(`Connect to an existing eve agent.`);registerRemoteCommands({applicationContext:n,logger:e,program:l,runtime:t,telemetry:r}),registerRuntimeInvokeCommand({applicationContext:n,logger:e,program:l,runtime:t}),registerAcpCommand({applicationContext:n,eveVersion:i,program:a,resolveVerifiedRemoteDevelopmentClient:t.resolveVerifiedRemoteDevelopmentClient,runAcpServer:t.runAcpServer,startHost:t.startHost}),registerDevelopmentCommand({applicationContext:n,logger:e,program:a,runtime:t,telemetry:r});let u=a.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");agentCommand(u.command(`show [logid]`,{isDefault:!0}),n).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,r)=>{let{runLogsShowCommand:i}=await import(`#cli/commands/logs.js`);await i(e,n.root,t,r)}),agentCommand(u.command(`list`).alias(`ls`),n).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:r}=await import(`#cli/commands/logs.js`);await r(e,n.root,t)});let d=a.command(`traces`).usage(`[options] [trace]
|
|
1
|
+
import{Command,CommanderError}from"#compiled/commander/index.js";import{agentCommand}from"#cli/agent-command.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";import{waitForShutdownSignal}from"#cli/shutdown.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{findEveProjectContext,resolveEveProjectContext}from"#internal/project-context.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{areSchedulesDisabled}from"#internal/schedules/disabled.js";import{findCliApplicationRoot,resolveCliApplicationProject}from"#cli/application-root.js";import{registerIntegrationCommands}from"#cli/commands/register-integration-commands.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{registerRegistryCommands}from"#cli/commands/register-registry-commands.js";import{registerDevelopmentCommand,registerRemoteCommands}from"#cli/dev/command.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{registerAcpCommand}from"#cli/acp/command.js";import{registerRuntimeInvokeCommand}from"#cli/invoke/command.js";import{parseAgentNamesOption,parsePortOption,parseReasoningOption}from"#cli/option-parsers.js";import{registerEveTelemetryCommands}from"#cli/telemetry/command.js";import{canonicalCommand,createEveCliTelemetry}from"#cli/telemetry/index.js";async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function createCliProgram(e,t,n,r){let i=resolveInstalledPackageInfo().version,a=new Command,o=createCliTheme();a.name(`eve`).description(`Build and run an eve application.`).version(i).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{let{json:r}=n.opts();!r&&(n.name()===`info`||n.name()===`init`&&n.parent!==a)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}}),registerEveTelemetryCommands(a,e),registerIntegrationCommands({program:a,logger:e,applicationContext:n});let s=a.command(`extension`).description(`Create and build reusable eve extension packages.`);s.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:a}=await import(`#cli/commands/extension-init.js`);await a(e,n.root,t,void 0,e=>{r.trackSetupStep({flow:`extension_init`,step:e})})}),s.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);await t(n.root);let{runExtensionBuildCommand:r}=await import(`#cli/commands/extension-build.js`);await r(e,n.root)}),registerRegistryCommands({program:a,logger:e,applicationContext:n}),a.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`--agents <names>`,`Create an agents/ workspace with comma-separated agent names`,parseAgentNamesOption).option(`--model <model>`,`Set the agent model (provider/model-id)`).option(`-n, --non-interactive`,`Scaffold the agent without starting development`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,i)=>{i.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:a}=await import(`#cli/commands/init.js`);await a(e,n.root,t,{agents:i.agents,channelWebNextjs:i.channelWebNextjs,model:i.model,reasoning:i.reasoning,nonInteractive:i.nonInteractive},void 0,e=>{r.trackSetupStep({flow:`init`,step:e})},(e,t,n)=>{r.trackSetupTerminal({flow:`init`,step:e,result:t,failureCode:n})})});let c=a.command(`set`).description(`Change root agent model settings.`);agentCommand(c.command(`model [model]`),n).description(`Set the agent model and reasoning effort.`).option(`--reasoning <effort>`,`Set reasoning (provider-default|none|minimal|low|medium|high|xhigh)`,parseReasoningOption).action(async(t,r)=>{let{runSetCommand:i}=await import(`#cli/commands/set.js`);await i(e,n.root,{model:t,reasoning:r.reasoning})}),registerProjectCommands({program:a,logger:e,applicationContext:n}),registerBuildCommand({applicationContext:n,buildHost:t.buildHost,logger:e,program:a}),agentCommand(a.command(`start`),n).description(`Start a built eve application.`).option(`--no-schedules`,`Start without running authored cron schedules`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async r=>{let{loadDevelopmentEnvironmentFiles:i}=await import(`#cli/dev/environment.js`);await i(n.root);let a=await(t.startProductionHost??await loadStartProductionHost())(n.root,{host:r.host,port:r.port,schedules:r.schedules});e.log(renderCliTaggedLine(o,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),(r.schedules===!1||areSchedulesDisabled())&&e.log(renderCliTaggedLine(o,{message:`schedules disabled`,tag:`start`,tone:`info`})),await waitForShutdownSignal({close:()=>a.close(),wait:()=>a.wait()})});let l=a.command(`remote`).description(`Connect to an existing eve agent.`);registerRemoteCommands({applicationContext:n,logger:e,program:l,runtime:t,telemetry:r}),registerRuntimeInvokeCommand({applicationContext:n,logger:e,program:l,runtime:t}),registerAcpCommand({applicationContext:n,eveVersion:i,program:a,resolveVerifiedRemoteDevelopmentClient:t.resolveVerifiedRemoteDevelopmentClient,runAcpServer:t.runAcpServer,startHost:t.startHost}),registerDevelopmentCommand({applicationContext:n,logger:e,program:a,runtime:t,telemetry:r});let u=a.command(`logs`).description("Inspect local `eve dev` diagnostic logs (.eve/logs).");agentCommand(u.command(`show [logid]`,{isDefault:!0}),n).description(`Print a diagnostic log (the most recent when logid is omitted).`).option(`--dump`,`Prepend the log's environment dump (.dump sibling)`).option(`--events`,`Interleave session events from the local workflow store`).action(async(t,r)=>{let{runLogsShowCommand:i}=await import(`#cli/commands/logs.js`);await i(e,n.root,t,r)}),agentCommand(u.command(`list`).alias(`ls`),n).description(`List diagnostic logs, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runLogsListCommand:r}=await import(`#cli/commands/logs.js`);await r(e,n.root,t)});let d=a.command(`traces`).usage(`[options] [trace]
|
|
2
2
|
eve traces list [options]`).description("Inspect local `eve dev` traces.");return agentCommand(d.command(`show [trace]`,{isDefault:!0}),n).description(`Show a local trace (the most recent when trace is omitted).`).option(`--verbose`,`Expand every span with all attributes and events`).option(`--json`,`Output as JSON`).action(async(t,r)=>{let{runTraceShowCommand:i}=await import(`#cli/commands/trace.js`);await i(e,n.root,t,r)}),agentCommand(d.command(`list`).alias(`ls`),n).description(`List local traces, most recent first.`).option(`--json`,`Output as JSON`).action(async t=>{let{runTraceListCommand:r}=await import(`#cli/commands/trace.js`);await r(e,n.root,t)}),agentCommand(a.command(`info`),n).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async r=>{await(t.printApplicationInfo??await loadPrintApplicationInfo())(e,n.root,r)}),agentCommand(a.command(`eval`),n,e=>e.opts().url===void 0).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--exclude-tag <tag...>`,`Skip evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval logs and workflow run IDs to stdout`).action(async(r,i)=>{await(t.runEvalCommand??await loadRunEvalCommand())(r,i,e,n.root)}),a}async function runCli(e=process.argv.slice(2),t=console,n={}){let r={root:resolveApplicationRoot(),async resolve(){let e=await(n.resolveApplicationProject??resolveCliApplicationProject)(r.root);r.project=e,r.root=e.appRoot},async resolveAgent(){return resolveEveProjectContext(r.root)}},i=createEveCliTelemetry(resolveInstalledPackageInfo().version),a=createCliProgram(t,n,r,i),o=e;if(o.length===0){let e=await(n.findApplicationRoot??findCliApplicationRoot)(r.root);e===void 0?o=(await findEveProjectContext(r.root))?.kind===`workspace`?[`dev`]:[`init`]:(r.root=e,o=[`dev`])}let s=canonicalCommand(o);i.trackCommand(s),s!==`telemetry`&&await i.notify(t);try{await a.parseAsync(o,{from:`user`}),i.trackOutcome(`success`)}catch(e){if(e instanceof CommanderError&&e.exitCode===0){i.trackOutcome(`success`);return}if(i.trackOutcome(e instanceof CommanderError?`usage_error`:`error`),e instanceof CommanderError){let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(o[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}finally{await i.flush()}}export{createCliProgram,resolveDevUiMode,resolveTuiDisplayOptions,runCli};
|
|
@@ -18,7 +18,7 @@ export type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot,
|
|
|
18
18
|
export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoRemoteAgentEntry, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, CancelSessionResult, ClearResult, CompactResult, ClientAuth, ClientOptions, ClientRedirectPolicy, CreateSessionOptions, HeadersValue, HealthResult, MessageResult, RespondTurnOptions, ResetResult, ResolvedStreamReconnectPolicy, SendTurnInput, SendTurnOptions, SessionSnapshot, ClientSessionState, StreamOptions, StreamReconnectPolicy, StreamReconnectRetryPolicy, TokenValue, } from "#client/types.js";
|
|
19
19
|
export type { EveAgentReducer, EveAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
|
|
20
20
|
export type { EveAuthorizationChallenge, EveAuthorizationOutcome, EveAuthorizationPart, EveMessageData, EveDynamicToolPart, EveMessageInputRequest, EveMessage, EveMessageMetadata, EveMessagePart, EveMessageToolMetadata, } from "#client/message-reducer.js";
|
|
21
|
-
export type { ActionPartialStreamEvent, ActionResultStreamEvent, ActionsRequestedStreamEvent, AgentStartedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, MessageStreamEventMeta, InputResolution, InputResolutionOutcome, InputResolvedStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, RuntimeTraceContext, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionPredecessor, SessionStartedStreamEvent, SessionWaitingStreamEvent, MessageStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, TaskSettledStreamEvent, TaskStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, TurnWaitingOn, TurnWaitingStreamEvent, } from "#protocol/message.js";
|
|
21
|
+
export type { ActionPartialStreamEvent, ActionResultStreamEvent, ActionsRequestedStreamEvent, AgentStartedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, HistoryImportedMessage, HistoryImportedStreamEvent, MessageStreamEventMeta, InputResolution, InputResolutionOutcome, InputResolvedStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, RuntimeTraceContext, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionPredecessor, SessionStartedStreamEvent, SessionWaitingStreamEvent, MessageStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, TaskSettledStreamEvent, TaskStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, TurnWaitingOn, TurnWaitingStreamEvent, } from "#protocol/message.js";
|
|
22
22
|
export { isCurrentTurnBoundaryEvent, isTurnFailureEvent } from "#protocol/message.js";
|
|
23
23
|
export type { InputOption, InputRequest, InputRequestKind, InputResponse } from "#shared/input.js";
|
|
24
24
|
export { isInputRequest, isInputResponse, parseInputResponse, parseInputResponses, } from "#shared/input.js";
|
|
@@ -21,11 +21,15 @@ export interface EveMessage {
|
|
|
21
21
|
* `status` tracks this message's own lifecycle (distinct from session-level
|
|
22
22
|
* status): user messages use `"submitted"` or `"failed"`, assistant messages
|
|
23
23
|
* use `"streaming"` or `"complete"`. `optimistic` is set only while a
|
|
24
|
-
* client-projected user message awaits server confirmation. `
|
|
25
|
-
* message
|
|
26
|
-
*
|
|
24
|
+
* client-projected user message awaits server confirmation. `imported` marks a
|
|
25
|
+
* message added through `history`, ahead of its turn's message, and carries no
|
|
26
|
+
* `turnId`; `historyId` is the app-owned `id` that history entry carried.
|
|
27
|
+
* `turnId` links the message to its runtime turn; `result` holds the harness
|
|
28
|
+
* structured result once the turn finalizes.
|
|
27
29
|
*/
|
|
28
30
|
export interface EveMessageMetadata {
|
|
31
|
+
readonly historyId?: string;
|
|
32
|
+
readonly imported?: true;
|
|
29
33
|
readonly optimistic?: true;
|
|
30
34
|
readonly result?: unknown;
|
|
31
35
|
readonly status?: "complete" | "failed" | "streaming" | "submitted";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{foldSession,initialSessionProjection,reportedCallStatus}from"#protocol/session-projection.js";import{actionLabel}from"#shared/action-label.js";import{createToolMetadata,mergeToolMetadata,normalizeActionRequest,normalizeActionResult,settledLabel,stringifyUnknown,toMessageInputRequest}from"#client/message-action-parts.js";import{conversationProjection,withConversationProjection}from"#client/conversation-projection.js";import{createAuthorizationCompletedPart,createAuthorizationRequiredPart}from"#client/authorization-message-parts.js";import{optimisticUserMessageId,partKey,projectReceivedParts,upsertMessage}from"#client/message-reducer-primitives.js";import{messageRun}from"#client/message-run-parts.js";import{toolPartState}from"#client/tool-part-state.js";function receivedMessageEventId(e){return e.meta.id??`${e.data.turnId}:${e.data.sequence}`}function defaultMessageReducer(){return{initial(){return withConversationProjection({messages:[]},initialSessionProjection())},reduce(e,t){return reduceMessageData(e,t)}}}function reduceMessageData(e,t){let n=foldSession(conversationProjection(e),t),r=withConversationProjection(reduceContent(e,t),n),i=toolCallIds(r,t);return withConversationProjection(i.length===0?r:withToolPartStates(r,i),n)}function reduceContent(e,t){switch(t.type){case`client.message.submitted`:case`client.message.failed`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:t.type===`client.message.failed`?`failed`:`submitted`},parts:[{type:`text`,text:t.data.message}],role:`user`},t.data.turnId);case`message.received`:return upsertMessage(e,{id:`${receivedMessageEventId(t)}:user`,metadata:{status:`complete`,turnId:t.data.turnId},parts:projectReceivedParts(t.data.parts,t.data.message),role:`user`},t.data.turnId);case`step.started`:return updateAssistantMessage(e,t.data.turnId,e=>ensureStepStartPart(e,t.data.stepIndex));case`step.completed`:return e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t.data.turnId)===void 0?e:updateAssistantMessage(e,t.data.turnId,e=>({...e,parts:closeStreamingRuns(e.parts,t.data.stepIndex)}));case`reasoning.appended`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`append`,delta:t.data.reasoningDelta,id:t.meta?.id,stepIndex:t.data.stepIndex,type:`reasoning`}));case`reasoning.completed`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`complete`,stepIndex:t.data.stepIndex,text:t.data.reasoning,id:t.meta?.id,type:`reasoning`}));case`action.input.appended`:{let n=findToolPart(e,t.data.callId);if(n!==void 0&&n.state!==`input-streaming`)return e;let r=(n?.state===`input-streaming`?n.inputText:``)+t.data.inputTextDelta;return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{input:void 0,inputText:r,state:`input-streaming`,stepIndex:t.data.stepIndex,toolCallId:t.data.callId,toolMetadata:n?.toolMetadata??{eve:{kind:`unknown`,name:t.data.toolName}},toolName:t.data.toolName,type:`dynamic-tool`})}case`actions.requested`:{let n=e;for(let e of t.data.actions){let r=findToolPart(n,e.callId);if(r!==void 0&&r.state!==`input-streaming`)continue;let i=normalizeActionRequest(e);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{input:`input`in e?e.input:void 0,state:`input-available`,stepIndex:t.data.stepIndex,toolCallId:e.callId,toolMetadata:createToolMetadata(i,{label:actionLabel(e,t.data.presentation)}),toolName:i.toolName,type:`dynamic-tool`}))}return n}case`input.requested`:{let n=e;for(let e of t.data.requests){let r=findToolPart(n,e.action.callId);if(r?.approval?.id===e.requestId||r!==void 0&&isSettledToolPart(r))continue;let i=normalizeActionRequest(e.action);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{...r,approval:{id:e.requestId},input:e.action.input,state:`approval-requested`,stepIndex:r?.stepIndex??t.data.stepIndex,toolCallId:e.action.callId,toolMetadata:createToolMetadata(i,{inputRequest:toMessageInputRequest(e),label:r?.toolMetadata?.eve?.label??actionLabel(e.action,void 0)}),toolName:i.toolName,type:`dynamic-tool`}))}return n}case`action.result`:{if(conversationProjection(e).calls[t.data.result.callId]?.taskId!==void 0)return e;if(t.data.error?.code===`MODEL_CALL_ATTEMPT_RETRIED`)return updateAssistantMessage(e,t.data.turnId,e=>({...e,parts:e.parts.filter(e=>e.type!==`dynamic-tool`||e.toolCallId!==t.data.result.callId)}));let n=findToolPart(e,t.data.result.callId),r=normalizeActionResult(t.data.result),i=t.data.status===void 0||t.data.status===`completed`?t.data.result.isError!==!0&&t.data.error===void 0:!1,a={...n,input:n?.input,stepIndex:n?.stepIndex??t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:mergeToolMetadata(n?.toolMetadata,createToolMetadata(r,{label:settledLabel(n?.toolMetadata,t.data.presentation?.[t.data.result.callId]?.label,r)})),toolName:n?.toolName??r.toolName,type:`dynamic-tool`},o=i?{errorText:void 0,output:t.data.result.output}:{errorText:t.data.error?.message??stringifyUnknown(t.data.result.output),output:void 0};return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{...a,...o,partial:void 0})}case`action.partial`:{let n=findToolPart(e,t.data.result.callId);if(n!==void 0&&isSettledToolPart(n))return e;let r=normalizeActionResult(t.data.result);return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{...n,input:n?.input,output:t.data.result.output,partial:!0,state:`output-available`,stepIndex:n?.stepIndex??t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:mergeToolMetadata(n?.toolMetadata,createToolMetadata(r,{label:settledLabel(n?.toolMetadata,t.data.presentation?.[t.data.result.callId]?.label,r)})),toolName:n?.toolName??r.toolName,type:`dynamic-tool`})}case`input.resolved`:{let n=e;for(let{requestId:e,response:r}of t.data.resolutions){let t=r===void 0?void 0:findToolPartByApprovalId(n,e);t!==void 0&&(n=replaceToolPart(n,{...t,toolMetadata:mergeToolMetadata(t.toolMetadata,{eve:{inputResponse:r,kind:t.toolMetadata?.eve?.kind??`unknown`,name:t.toolMetadata?.eve?.name??t.toolName}})}))}return n}case`task.settled`:{let n=findToolPart(e,t.data.callId);if(n===void 0)return e;let{error:r,output:i,status:a}=t.data,o=a===`completed`?{output:i}:{errorText:r?.message};return replaceToolPart(e,{...n,...o})}case`authorization.required`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),createAuthorizationRequiredPart(t)));case`authorization.completed`:return completeAuthorization(e,t);case`message.appended`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`append`,delta:t.data.messageDelta,id:t.meta?.id,stepIndex:t.data.stepIndex,type:`text`}));case`message.completed`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`complete`,stepIndex:t.data.stepIndex,text:t.data.message,id:t.meta?.id,type:`text`}));case`result.completed`:return updateAssistantMessage(e,t.data.turnId,e=>({...e,metadata:{...e.metadata,result:t.data.result}}));case`turn.completed`:case`turn.cancelled`:case`turn.failed`:return t.type===`turn.failed`&&!e.messages.some(e=>e.role===`assistant`&&e.metadata?.turnId===t.data.turnId)?e:updateAssistantMessage(e,t.data.turnId,t=>({...t,metadata:{...t.metadata,status:`complete`},parts:removeUnsettledToolParts(closeStreamingRuns(t.parts),conversationProjection(e))}));default:return e}}function toolCallIds(e,t){let byRequest=t=>findToolPartByApprovalId(e,t)?.toolCallId??[];switch(t.type){case`actions.requested`:return t.data.actions.map(e=>e.callId);case`input.requested`:return t.data.requests.map(e=>e.action.callId);case`action.result`:case`action.partial`:return[t.data.result.callId];case`task.started`:case`task.settled`:return[t.data.callId];case`input.resolved`:return t.data.resolutions.flatMap(e=>byRequest(e.requestId));case`approval.settled`:return[byRequest(t.data.requestId)].flat();default:return[]}}function withToolPartStates(e,t){let n=e;for(let r of new Set(t)){let t=findToolPart(n,r);if(t===void 0)continue;let i=toolPartState(n,t);i!==t&&(n=withConversationProjection(replaceToolPart(n,i),conversationProjection(e)))}return n}function closeStreamingRuns(e,t){return e.map(e=>(e.type===`text`||e.type===`reasoning`)&&e.state===`streaming`&&(t===void 0||e.stepIndex===t)?{...e,state:`done`}:e)}function removeUnsettledToolParts(e,t){return e.filter(e=>{if(e.type!==`dynamic-tool`)return!0;if(e.state===`input-streaming`)return!1;if(e.state!==`input-available`)return!0;let n=t.calls[e.toolCallId];return n===void 0||n.taskId!==void 0||reportedCallStatus(t,n)!==`running`})}function updateAssistantMessage(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t)??createAssistantMessage(t);return upsertMessage(e,n(r))}function createAssistantMessage(e){return{id:`${e}:assistant`,metadata:{status:`streaming`,turnId:e},parts:[],role:`assistant`}}function ensureStepStartPart(e,t){let n=e.parts.filter(e=>e.type===`step-start`).length;if(n>t)return e;let r=t-n+1;return{...e,parts:[...e.parts,...Array.from({length:r},()=>({type:`step-start`}))]}}function upsertPart(e,t){let n=e.parts.findIndex(e=>partKey(e)===partKey(t)),r=n===-1?[...e.parts,t]:[...e.parts.slice(0,n),t,...e.parts.slice(n+1)];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function upsertToolPart(e,t,n,r){let i=updateToolPart(e,r.toolCallId,r);return i===e?updateAssistantMessage(e,t,e=>upsertPart(ensureStepStartPart(e,n),r)):i}function updateToolPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t));return r?upsertMessage(e,upsertPart(r,n)):e}function replaceToolPart(e,t){let n=e.messages.find(e=>e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t.toolCallId));return n===void 0?e:upsertMessage(e,{...n,parts:n.parts.map(e=>partKey(e)===partKey(t)?t:e)})}function completeAuthorization(e,t){let n=findPendingAuthorizationPart(e,t.data.name,t.data.attemptId),r=createAuthorizationCompletedPart(t,n);return updateAssistantMessage(e,n?.turnId??t.data.turnId,e=>upsertPart(ensureStepStartPart(e,r.stepIndex),r))}function findToolPart(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.toolCallId===t)return e}function isSettledToolPart(e){return e.state===`output-denied`||e.state===`output-error`||e.state===`output-available`&&e.partial!==!0}function findPendingAuthorizationPart(e,t,n){for(let r=e.messages.length-1;r>=0;--r){let i=e.messages[r];if(i?.role===`assistant`)for(let e=i.parts.length-1;e>=0;--e){let r=i.parts[e];if(r?.type===`authorization`&&r.state===`required`&&(n===void 0?r.attemptId===void 0&&r.name===t:r.attemptId===n))return r}}}function findToolPartByApprovalId(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.approval?.id===t)return e}export{defaultMessageReducer};
|
|
1
|
+
import{foldSession,initialSessionProjection,reportedCallStatus}from"#protocol/session-projection.js";import{actionLabel}from"#shared/action-label.js";import{createToolMetadata,mergeToolMetadata,normalizeActionRequest,normalizeActionResult,settledLabel,stringifyUnknown,toMessageInputRequest}from"#client/message-action-parts.js";import{conversationProjection,withConversationProjection}from"#client/conversation-projection.js";import{createAuthorizationCompletedPart,createAuthorizationRequiredPart}from"#client/authorization-message-parts.js";import{optimisticUserMessageId,partKey,projectReceivedParts,upsertMessage}from"#client/message-reducer-primitives.js";import{messageRun}from"#client/message-run-parts.js";import{toolPartState}from"#client/tool-part-state.js";function receivedMessageEventId(e){return e.meta.id??`${e.data.turnId}:${e.data.sequence}`}function defaultMessageReducer(){return{initial(){return withConversationProjection({messages:[]},initialSessionProjection())},reduce(e,t){return reduceMessageData(e,t)}}}function reduceMessageData(e,t){let n=foldSession(conversationProjection(e),t),r=withConversationProjection(reduceContent(e,t),n),i=toolCallIds(r,t);return withConversationProjection(i.length===0?r:withToolPartStates(r,i),n)}function reduceContent(e,t){switch(t.type){case`client.message.submitted`:case`client.message.failed`:return upsertMessage(e,{id:optimisticUserMessageId(t.data.submissionId),metadata:{optimistic:!0,status:t.type===`client.message.failed`?`failed`:`submitted`},parts:[{type:`text`,text:t.data.message}],role:`user`},t.data.turnId);case`message.received`:return upsertMessage(e,{id:`${receivedMessageEventId(t)}:user`,metadata:{status:`complete`,turnId:t.data.turnId},parts:projectReceivedParts(t.data.parts,t.data.message),role:`user`},t.data.turnId);case`history.imported`:return importHistory(e,t);case`step.started`:return updateAssistantMessage(e,t.data.turnId,e=>ensureStepStartPart(e,t.data.stepIndex));case`step.completed`:return e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t.data.turnId)===void 0?e:updateAssistantMessage(e,t.data.turnId,e=>({...e,parts:closeStreamingRuns(e.parts,t.data.stepIndex)}));case`reasoning.appended`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`append`,delta:t.data.reasoningDelta,id:t.meta?.id,stepIndex:t.data.stepIndex,type:`reasoning`}));case`reasoning.completed`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`complete`,stepIndex:t.data.stepIndex,text:t.data.reasoning,id:t.meta?.id,type:`reasoning`}));case`action.input.appended`:{let n=findToolPart(e,t.data.callId);if(n!==void 0&&n.state!==`input-streaming`)return e;let r=(n?.state===`input-streaming`?n.inputText:``)+t.data.inputTextDelta;return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{input:void 0,inputText:r,state:`input-streaming`,stepIndex:t.data.stepIndex,toolCallId:t.data.callId,toolMetadata:n?.toolMetadata??{eve:{kind:`unknown`,name:t.data.toolName}},toolName:t.data.toolName,type:`dynamic-tool`})}case`actions.requested`:{let n=e;for(let e of t.data.actions){let r=findToolPart(n,e.callId);if(r!==void 0&&r.state!==`input-streaming`)continue;let i=normalizeActionRequest(e);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{input:`input`in e?e.input:void 0,state:`input-available`,stepIndex:t.data.stepIndex,toolCallId:e.callId,toolMetadata:createToolMetadata(i,{label:actionLabel(e,t.data.presentation)}),toolName:i.toolName,type:`dynamic-tool`}))}return n}case`input.requested`:{let n=e;for(let e of t.data.requests){let r=findToolPart(n,e.action.callId);if(r?.approval?.id===e.requestId||r!==void 0&&isSettledToolPart(r))continue;let i=normalizeActionRequest(e.action);n=updateAssistantMessage(n,t.data.turnId,n=>upsertPart(ensureStepStartPart(n,t.data.stepIndex),{...r,approval:{id:e.requestId},input:e.action.input,state:`approval-requested`,stepIndex:r?.stepIndex??t.data.stepIndex,toolCallId:e.action.callId,toolMetadata:createToolMetadata(i,{inputRequest:toMessageInputRequest(e),label:r?.toolMetadata?.eve?.label??actionLabel(e.action,void 0)}),toolName:i.toolName,type:`dynamic-tool`}))}return n}case`action.result`:{if(conversationProjection(e).calls[t.data.result.callId]?.taskId!==void 0)return e;if(t.data.error?.code===`MODEL_CALL_ATTEMPT_RETRIED`)return updateAssistantMessage(e,t.data.turnId,e=>({...e,parts:e.parts.filter(e=>e.type!==`dynamic-tool`||e.toolCallId!==t.data.result.callId)}));let n=findToolPart(e,t.data.result.callId),r=normalizeActionResult(t.data.result),i=t.data.status===void 0||t.data.status===`completed`?t.data.result.isError!==!0&&t.data.error===void 0:!1,a={...n,input:n?.input,stepIndex:n?.stepIndex??t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:mergeToolMetadata(n?.toolMetadata,createToolMetadata(r,{label:settledLabel(n?.toolMetadata,t.data.presentation?.[t.data.result.callId]?.label,r)})),toolName:n?.toolName??r.toolName,type:`dynamic-tool`},o=i?{errorText:void 0,output:t.data.result.output}:{errorText:t.data.error?.message??stringifyUnknown(t.data.result.output),output:void 0};return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{...a,...o,partial:void 0})}case`action.partial`:{let n=findToolPart(e,t.data.result.callId);if(n!==void 0&&isSettledToolPart(n))return e;let r=normalizeActionResult(t.data.result);return upsertToolPart(e,t.data.turnId,t.data.stepIndex,{...n,input:n?.input,output:t.data.result.output,partial:!0,state:`output-available`,stepIndex:n?.stepIndex??t.data.stepIndex,toolCallId:t.data.result.callId,toolMetadata:mergeToolMetadata(n?.toolMetadata,createToolMetadata(r,{label:settledLabel(n?.toolMetadata,t.data.presentation?.[t.data.result.callId]?.label,r)})),toolName:n?.toolName??r.toolName,type:`dynamic-tool`})}case`input.resolved`:{let n=e;for(let{requestId:e,response:r}of t.data.resolutions){let t=r===void 0?void 0:findToolPartByApprovalId(n,e);t!==void 0&&(n=replaceToolPart(n,{...t,toolMetadata:mergeToolMetadata(t.toolMetadata,{eve:{inputResponse:r,kind:t.toolMetadata?.eve?.kind??`unknown`,name:t.toolMetadata?.eve?.name??t.toolName}})}))}return n}case`task.settled`:{let n=findToolPart(e,t.data.callId);if(n===void 0)return e;let{error:r,output:i,status:a}=t.data,o=a===`completed`?{output:i}:{errorText:r?.message};return replaceToolPart(e,{...n,...o})}case`authorization.required`:return updateAssistantMessage(e,t.data.turnId,e=>upsertPart(ensureStepStartPart(e,t.data.stepIndex),createAuthorizationRequiredPart(t)));case`authorization.completed`:return completeAuthorization(e,t);case`message.appended`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`append`,delta:t.data.messageDelta,id:t.meta?.id,stepIndex:t.data.stepIndex,type:`text`}));case`message.completed`:return updateAssistantMessage(e,t.data.turnId,e=>messageRun.transition(ensureStepStartPart(e,t.data.stepIndex),{kind:`complete`,stepIndex:t.data.stepIndex,text:t.data.message,id:t.meta?.id,type:`text`}));case`result.completed`:return updateAssistantMessage(e,t.data.turnId,e=>({...e,metadata:{...e.metadata,result:t.data.result}}));case`turn.completed`:case`turn.cancelled`:case`turn.failed`:return t.type===`turn.failed`&&!e.messages.some(e=>e.role===`assistant`&&e.metadata?.turnId===t.data.turnId)?e:updateAssistantMessage(e,t.data.turnId,t=>({...t,metadata:{...t.metadata,status:`complete`},parts:removeUnsettledToolParts(closeStreamingRuns(t.parts),conversationProjection(e))}));default:return e}}function importHistory(e,t){let n=t.meta.id??`${t.data.turnId}:${t.data.sequence}`,r=t.data.messages.map((e,t)=>({id:`${n}:imported:${t}`,metadata:e.id===void 0?{imported:!0,status:`complete`}:{historyId:e.id,imported:!0,status:`complete`},parts:[e.role===`assistant`?{state:`done`,text:e.text,type:`text`}:{text:e.text,type:`text`}],role:e.role})),i=new Set(r.map(e=>e.id)),a=e.messages.filter(e=>!i.has(e.id)),o=a.findIndex(e=>e.metadata?.optimistic===!0||e.role===`assistant`&&e.metadata?.turnId===t.data.turnId),s=o===-1?a.length:o;return{...e,messages:[...a.slice(0,s),...r,...a.slice(s)]}}function toolCallIds(e,t){let byRequest=t=>findToolPartByApprovalId(e,t)?.toolCallId??[];switch(t.type){case`actions.requested`:return t.data.actions.map(e=>e.callId);case`input.requested`:return t.data.requests.map(e=>e.action.callId);case`action.result`:case`action.partial`:return[t.data.result.callId];case`task.started`:case`task.settled`:return[t.data.callId];case`input.resolved`:return t.data.resolutions.flatMap(e=>byRequest(e.requestId));case`approval.settled`:return[byRequest(t.data.requestId)].flat();default:return[]}}function withToolPartStates(e,t){let n=e;for(let r of new Set(t)){let t=findToolPart(n,r);if(t===void 0)continue;let i=toolPartState(n,t);i!==t&&(n=withConversationProjection(replaceToolPart(n,i),conversationProjection(e)))}return n}function closeStreamingRuns(e,t){return e.map(e=>(e.type===`text`||e.type===`reasoning`)&&e.state===`streaming`&&(t===void 0||e.stepIndex===t)?{...e,state:`done`}:e)}function removeUnsettledToolParts(e,t){return e.filter(e=>{if(e.type!==`dynamic-tool`)return!0;if(e.state===`input-streaming`)return!1;if(e.state!==`input-available`)return!0;let n=t.calls[e.toolCallId];return n===void 0||n.taskId!==void 0||reportedCallStatus(t,n)!==`running`})}function updateAssistantMessage(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t)??createAssistantMessage(t);return upsertMessage(e,n(r))}function createAssistantMessage(e){return{id:`${e}:assistant`,metadata:{status:`streaming`,turnId:e},parts:[],role:`assistant`}}function ensureStepStartPart(e,t){let n=e.parts.filter(e=>e.type===`step-start`).length;if(n>t)return e;let r=t-n+1;return{...e,parts:[...e.parts,...Array.from({length:r},()=>({type:`step-start`}))]}}function upsertPart(e,t){let n=e.parts.findIndex(e=>partKey(e)===partKey(t)),r=n===-1?[...e.parts,t]:[...e.parts.slice(0,n),t,...e.parts.slice(n+1)];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function upsertToolPart(e,t,n,r){let i=updateToolPart(e,r.toolCallId,r);return i===e?updateAssistantMessage(e,t,e=>upsertPart(ensureStepStartPart(e,n),r)):i}function updateToolPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t));return r?upsertMessage(e,upsertPart(r,n)):e}function replaceToolPart(e,t){let n=e.messages.find(e=>e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t.toolCallId));return n===void 0?e:upsertMessage(e,{...n,parts:n.parts.map(e=>partKey(e)===partKey(t)?t:e)})}function completeAuthorization(e,t){let n=findPendingAuthorizationPart(e,t.data.name,t.data.attemptId),r=createAuthorizationCompletedPart(t,n);return updateAssistantMessage(e,n?.turnId??t.data.turnId,e=>upsertPart(ensureStepStartPart(e,r.stepIndex),r))}function findToolPart(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.toolCallId===t)return e}function isSettledToolPart(e){return e.state===`output-denied`||e.state===`output-error`||e.state===`output-available`&&e.partial!==!0}function findPendingAuthorizationPart(e,t,n){for(let r=e.messages.length-1;r>=0;--r){let i=e.messages[r];if(i?.role===`assistant`)for(let e=i.parts.length-1;e>=0;--e){let r=i.parts[e];if(r?.type===`authorization`&&r.state===`required`&&(n===void 0?r.attemptId===void 0&&r.name===t:r.attemptId===n))return r}}}function findToolPartByApprovalId(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.approval?.id===t)return e}export{defaultMessageReducer};
|