eve 0.69.0 → 0.70.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 +36 -0
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/task-card.d.ts +3 -3
- package/dist/src/channel/task-card.js +1 -1
- package/dist/src/channel/types.d.ts +18 -0
- package/dist/src/chunks/{use-eve-agent-Dab2MnT2.js → use-eve-agent-CJQeE7-t.js} +1873 -1236
- package/dist/src/chunks/{use-eve-agent-D_5129A9.js → use-eve-agent-DdemtY6C.js} +1874 -1234
- package/dist/src/cli/dev/command.js +1 -1
- package/dist/src/cli/dev/console-records-preload.d.ts +1 -0
- package/dist/src/cli/dev/console-records-preload.js +1 -0
- package/dist/src/cli/dev/console-records.d.ts +17 -0
- package/dist/src/cli/dev/console-records.js +3 -0
- package/dist/src/cli/dev/diagnostic-sink.d.ts +1 -0
- package/dist/src/cli/dev/local-server-process.js +1 -1
- package/dist/src/cli/dev/tui/blocks.d.ts +2 -1
- package/dist/src/cli/dev/tui/blocks.js +3 -3
- package/dist/src/cli/dev/tui/conversation-view.d.ts +54 -0
- package/dist/src/cli/dev/tui/conversation-view.js +1 -0
- package/dist/src/cli/dev/tui/flow-drawer.d.ts +5 -2
- package/dist/src/cli/dev/tui/flow-drawer.js +1 -1
- package/dist/src/cli/dev/tui/log-display-mode.d.ts +4 -10
- package/dist/src/cli/dev/tui/log-display-mode.js +1 -1
- package/dist/src/cli/dev/tui/message-queue.d.ts +7 -63
- package/dist/src/cli/dev/tui/message-queue.js +3 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/question-panel.d.ts +3 -1
- package/dist/src/cli/dev/tui/question-panel.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +56 -193
- package/dist/src/cli/dev/tui/runner.js +3 -3
- package/dist/src/cli/dev/tui/task-activity.d.ts +11 -7
- package/dist/src/cli/dev/tui/task-activity.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +15 -37
- package/dist/src/cli/dev/tui/terminal-renderer.js +10 -13
- package/dist/src/cli/dev/tui/terminal-tool-part.d.ts +2 -0
- package/dist/src/cli/dev/tui/terminal-tool-part.js +1 -0
- package/dist/src/cli/dev/tui/test/fake-eve-server.d.ts +34 -0
- package/dist/src/cli/dev/tui/test/fake-eve-server.js +1 -0
- package/dist/src/cli/dev/tui/test/index.d.ts +1 -0
- package/dist/src/cli/dev/tui/test/index.js +1 -1
- package/dist/src/cli/dev/tui/tool-block-groups.js +1 -1
- package/dist/src/cli/dev/tui/tool-presentation.d.ts +1 -0
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
- package/dist/src/cli/dev/tui/tool-rows.d.ts +1 -0
- package/dist/src/cli/dev/tui/tool-rows.js +2 -2
- package/dist/src/cli/dev/tui/transcript-parts.d.ts +73 -0
- package/dist/src/cli/dev/tui/transcript-parts.js +3 -0
- package/dist/src/cli/dev/tui/transcript.d.ts +47 -0
- package/dist/src/cli/dev/tui/transcript.js +1 -0
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/tui/turn-clock.d.ts +11 -26
- package/dist/src/cli/dev/tui/turn-clock.js +1 -1
- package/dist/src/cli/dev/tui/types.d.ts +2 -4
- package/dist/src/cli/dev/ui-options.js +1 -1
- package/dist/src/client/agent-stream-follower.d.ts +26 -0
- package/dist/src/client/agent-stream-follower.js +1 -0
- package/dist/src/client/authorization-message-parts.js +1 -1
- package/dist/src/client/conversation-client.d.ts +40 -0
- package/dist/src/client/conversation-client.js +1 -0
- package/dist/src/client/conversation-reducer.d.ts +29 -0
- package/dist/src/client/conversation-reducer.js +1 -0
- package/dist/src/client/conversation-state.d.ts +110 -0
- package/dist/src/client/conversation-state.js +1 -0
- package/dist/src/client/eve-agent-projection.d.ts +24 -7
- package/dist/src/client/eve-agent-projection.js +1 -1
- package/dist/src/client/eve-agent-store-helpers.d.ts +21 -2
- package/dist/src/client/eve-agent-store-helpers.js +2 -2
- package/dist/src/client/eve-agent-store-state.d.ts +15 -3
- package/dist/src/client/eve-agent-store.d.ts +10 -1
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +4 -1
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-reducer-primitives.d.ts +1 -2
- package/dist/src/client/message-reducer-primitives.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +9 -2
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/message-run-parts.d.ts +10 -6
- package/dist/src/client/message-run-parts.js +1 -1
- package/dist/src/client/optimistic-message-submissions.d.ts +6 -4
- package/dist/src/client/optimistic-message-submissions.js +1 -1
- package/dist/src/client/reducer.d.ts +5 -1
- package/dist/src/client/session-turn-dispatch.d.ts +15 -0
- package/dist/src/client/session-turn-dispatch.js +1 -0
- package/dist/src/client/session-utils.d.ts +27 -10
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +2 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +18 -18
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/load-binding-namespace.js +1 -1
- package/dist/src/context/keys.d.ts +5 -2
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/provider.d.ts +5 -9
- package/dist/src/context/run-step.d.ts +4 -4
- package/dist/src/context/run-step.js +1 -1
- package/dist/src/evals/runner/derive-run-facts.js +1 -1
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/session.js +2 -2
- package/dist/src/evals/types.d.ts +16 -0
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/execution/agent-sessions/context.d.ts +4 -2
- package/dist/src/execution/agent-sessions/context.js +1 -1
- package/dist/src/execution/agent-sessions/steps.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/coordination-dispatch-shared.d.ts +6 -4
- package/dist/src/execution/coordination-dispatch-shared.js +1 -1
- package/dist/src/execution/create-session-step.d.ts +4 -2
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +10 -4
- package/dist/src/execution/durable-session-store.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/legacy-session/completion-step.d.ts +2 -0
- package/dist/src/execution/legacy-session/completion-step.js +1 -1
- package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
- package/dist/src/execution/legacy-session/prepare-step.d.ts +1 -0
- package/dist/src/execution/legacy-session/prepare-step.js +1 -1
- package/dist/src/execution/legacy-session/snapshot.d.ts +8 -4
- package/dist/src/execution/legacy-session/snapshot.js +1 -1
- package/dist/src/execution/legacy-session/turn-workflow.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/publish-session-events.d.ts +27 -7
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/reconcile-session-continuation-token.d.ts +2 -2
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/session/active-turn.d.ts +97 -0
- package/dist/src/execution/session/active-turn.js +1 -0
- 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 +5 -3
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/input-queue.d.ts +19 -13
- package/dist/src/execution/session/input-queue.js +1 -1
- package/dist/src/execution/session/next-input.d.ts +2 -10
- package/dist/src/execution/session/next-input.js +1 -1
- package/dist/src/execution/session/program.d.ts +2 -0
- package/dist/src/execution/session/program.js +1 -1
- package/dist/src/execution/session/state-cursor.d.ts +22 -16
- package/dist/src/execution/session/state-cursor.js +1 -1
- package/dist/src/execution/session/state-delta.d.ts +8 -1
- package/dist/src/execution/session/state-delta.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-types.d.ts +13 -4
- 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.d.ts +8 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/session.d.ts +5 -5
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/settle-cancelled-turn-step.d.ts +5 -4
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/start.d.ts +2 -2
- package/dist/src/execution/tasks/task-id-input.d.ts +1 -1
- package/dist/src/execution/tasks/task-id-input.js +1 -1
- package/dist/src/execution/terminal-session-completion-step.d.ts +2 -0
- package/dist/src/execution/terminal-session-completion-step.js +1 -1
- package/dist/src/execution/terminal-session-failure-step.d.ts +2 -0
- package/dist/src/execution/terminal-session-failure-step.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/connection-target.d.ts +5 -0
- package/dist/src/execution/tools/connection-target.js +1 -1
- package/dist/src/execution/tools/connection-tools.js +2 -2
- package/dist/src/execution/tools/workflow/start.d.ts +3 -3
- package/dist/src/harness/authorization.d.ts +15 -2
- package/dist/src/harness/authorization.js +1 -1
- package/dist/src/harness/cancelled-turn-emission.d.ts +2 -1
- package/dist/src/harness/cancelled-turn-emission.js +1 -1
- package/dist/src/harness/coordination.d.ts +5 -3
- package/dist/src/harness/emission.d.ts +5 -2
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/held-requests.d.ts +18 -0
- package/dist/src/harness/held-requests.js +1 -0
- package/dist/src/harness/hitl/approval-input-requests.d.ts +16 -0
- package/dist/src/harness/hitl/approval-input-requests.js +1 -1
- package/dist/src/harness/input-extraction.js +1 -1
- package/dist/src/harness/input-requests.d.ts +0 -4
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/model-call-error.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +4 -4
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/stale-input-responses.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/turn-tag-state.d.ts +2 -0
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/harness/types.d.ts +23 -11
- package/dist/src/instrumentation/channel-delivery.d.ts +1 -0
- package/dist/src/instrumentation/channel-delivery.js +1 -1
- package/dist/src/instrumentation/lifecycle.d.ts +4 -0
- package/dist/src/instrumentation/memory.d.ts +2 -0
- package/dist/src/instrumentation/memory.js +1 -1
- package/dist/src/instrumentation/native-events.d.ts +1 -0
- package/dist/src/instrumentation/native-events.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +4 -3
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/instrumentation/session-init.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-module-loader.d.ts +14 -6
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/authored-package-boundary.d.ts +1 -1
- package/dist/src/internal/authored-package-boundary.js +1 -1
- package/dist/src/internal/bundler/extension-mount-plugin.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-remote-agent-transform.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +27 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +2 -2
- package/dist/src/protocol/message.d.ts +41 -3
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/slack/action-status.d.ts +2 -2
- package/dist/src/public/channels/slack/action-status.js +1 -1
- package/dist/src/public/channels/slack/approval-cards.d.ts +15 -0
- package/dist/src/public/channels/slack/approval-cards.js +2 -0
- package/dist/src/public/channels/slack/auth.d.ts +2 -0
- package/dist/src/public/channels/slack/auth.js +1 -1
- package/dist/src/public/channels/slack/connections.d.ts +15 -11
- package/dist/src/public/channels/slack/connections.js +1 -1
- package/dist/src/public/channels/slack/defaults.d.ts +1 -15
- package/dist/src/public/channels/slack/defaults.js +3 -4
- package/dist/src/public/channels/slack/hitl.js +1 -1
- package/dist/src/public/channels/slack/inbound.d.ts +10 -2
- package/dist/src/public/channels/slack/inbound.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +2 -0
- package/dist/src/public/channels/slack/index.js +1 -1
- package/dist/src/public/channels/slack/input-response.js +1 -1
- package/dist/src/public/channels/slack/interaction-cards.js +1 -1
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/limits.d.ts +5 -3
- package/dist/src/public/channels/slack/private-approval-delivery.js +1 -1
- package/dist/src/public/channels/slack/renderers.d.ts +1 -1
- package/dist/src/public/channels/slack/renderers.js +1 -1
- package/dist/src/public/channels/slack/reply-delivery.d.ts +72 -0
- package/dist/src/public/channels/slack/reply-delivery.js +1 -0
- package/dist/src/public/channels/slack/sign-in-cancel.d.ts +20 -0
- package/dist/src/public/channels/slack/sign-in-cancel.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +15 -0
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/slack/task-card.js +1 -1
- package/dist/src/public/channels/teams/defaults.d.ts +1 -1
- package/dist/src/public/channels/teams/defaults.js +2 -2
- package/dist/src/public/definitions/channel.d.ts +1 -0
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +2 -0
- package/dist/src/public/next/server.js +1 -2
- package/dist/src/public/nuxt/module.d.ts +6 -0
- package/dist/src/public/nuxt/module.js +1 -1
- package/dist/src/react/index.d.ts +3 -0
- package/dist/src/react/index.js +1 -1
- package/dist/src/react/use-eve-agent.d.ts +7 -5
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/connections/scoped-authorization.d.ts +2 -0
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/setup/boxes/deploy-project.js +1 -1
- package/dist/src/setup/integrations/web/setup.js +6 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
- package/dist/src/setup/scaffold/create/web-template.js +28 -9
- package/dist/src/setup/vercel-project-framework.js +1 -1
- package/dist/src/shared/display-name.d.ts +15 -0
- package/dist/src/shared/display-name.js +1 -0
- package/dist/src/shared/framework-eve-server.d.ts +43 -0
- package/dist/src/shared/framework-eve-server.js +2 -0
- package/dist/src/shared/token-usage.d.ts +2 -0
- package/dist/src/shared/token-usage.js +1 -1
- package/dist/src/shared/trace-root.d.ts +8 -0
- package/dist/src/shared/trace-root.js +1 -0
- package/dist/src/subagents/hitl-proxy.d.ts +3 -3
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/subagents/invocation.d.ts +3 -1
- package/dist/src/subagents/tool.js +1 -1
- package/dist/src/svelte/index.d.ts +3 -0
- package/dist/src/svelte/index.js +2 -2
- package/dist/src/svelte/use-eve-agent.d.ts +7 -4
- 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/load-skill.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tracing/agent-action-instrumentation.js +1 -1
- package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
- package/dist/src/tracing/agent-memory-instrumentation.js +1 -1
- package/dist/src/tracing/agent-otel-attributes.d.ts +6 -0
- package/dist/src/tracing/agent-otel-attributes.js +1 -1
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-runtime-context.d.ts +1 -1
- package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
- package/dist/src/tracing/agent-otel-session-context.js +1 -1
- package/dist/src/tracing/agent-span-contract.js +1 -1
- package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
- package/dist/src/tracing/agent-trace-context-codec.d.ts +4 -0
- package/dist/src/tracing/agent-trace-context-codec.js +1 -1
- package/dist/src/tracing/agent-trace-span-processor.js +1 -1
- package/dist/src/tracing/agent-trace-state.d.ts +3 -0
- package/dist/src/tracing/conversation-context.d.ts +10 -0
- package/dist/src/tracing/conversation-context.js +1 -1
- package/dist/src/tracing/otel-registration.js +1 -1
- package/dist/src/vue/index.d.ts +3 -0
- package/dist/src/vue/index.js +2 -2
- package/dist/src/vue/use-eve-agent.d.ts +7 -3
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/slack.mdx +60 -13
- package/docs/concepts/built-in-tools.md +3 -2
- package/docs/concepts/sessions-runs-and-streaming.md +4 -4
- package/docs/connections/overview.mdx +9 -3
- package/docs/evals/reporters.mdx +4 -0
- package/docs/extensions.md +11 -0
- package/docs/guides/client/streaming.mdx +7 -6
- package/docs/guides/deployment/vercel.mdx +2 -1
- package/docs/guides/dev-tui.md +15 -15
- package/docs/guides/dynamic-capabilities.md +1 -1
- package/docs/guides/frontend/nuxt.mdx +24 -4
- package/docs/guides/frontend/overview.mdx +44 -38
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +4 -10
- package/docs/guides/frontend/use-eve-agent-vue.mdx +4 -10
- package/docs/guides/instrumentation/otel.mdx +24 -6
- package/docs/guides/remote-agents.md +26 -8
- package/docs/reference/cli.md +4 -4
- package/docs/tools/human-in-the-loop.md +4 -4
- package/docs/tools/overview.mdx +1 -1
- package/docs/tools/tasks.md +8 -8
- package/package.json +1 -1
- package/dist/src/cli/dev/tui/steering-stream.d.ts +0 -15
- package/dist/src/cli/dev/tui/steering-stream.js +0 -1
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +0 -134
- package/dist/src/cli/dev/tui/subagent-pump.js +0 -1
- package/dist/src/public/nuxt/dev-server.d.ts +0 -25
- package/dist/src/public/nuxt/dev-server.js +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type ConversationState } from "#client/conversation-state.js";
|
|
2
|
+
import type { Block } from "./blocks.js";
|
|
3
|
+
import type { AgentTUIConversationView } from "./conversation-view.js";
|
|
4
|
+
import { type TaskEntry } from "./task-activity.js";
|
|
5
|
+
import type { SubagentDisplayMode, TerminalPartDisplayMode } from "./types.js";
|
|
6
|
+
export interface TranscriptOptions {
|
|
7
|
+
readonly tools: TerminalPartDisplayMode;
|
|
8
|
+
readonly reasoning: TerminalPartDisplayMode;
|
|
9
|
+
readonly subagents: SubagentDisplayMode;
|
|
10
|
+
readonly connectionAuth: TerminalPartDisplayMode;
|
|
11
|
+
/** Names of the agent's local subagents, whose tools read as delegations. */
|
|
12
|
+
readonly subagentNames?: readonly string[];
|
|
13
|
+
/** Where full failure detail is recorded, shown instead of the raw dump. */
|
|
14
|
+
readonly diagnosticsPath?: string;
|
|
15
|
+
/** Separates a task end line's facts; the theme's `·`. */
|
|
16
|
+
readonly dot?: string;
|
|
17
|
+
}
|
|
18
|
+
/** How long a settled agent task waits for its own last events before writing its end line. */
|
|
19
|
+
export declare const TASK_END_GRACE_MS = 2000;
|
|
20
|
+
/**
|
|
21
|
+
* Projects one session's conversation into transcript blocks. Each block's
|
|
22
|
+
* `live` flag says whether its part can still change; the renderer commits a
|
|
23
|
+
* settled prefix to scrollback. Built blocks are reused while their inputs are
|
|
24
|
+
* unchanged, so file-diff bases observe each tool call once, in order.
|
|
25
|
+
*
|
|
26
|
+
* A task writes one line when it starts, at its call, and one when it ends, where the transcript
|
|
27
|
+
* had reached by then; what it does in between is {@link ConversationTranscript.tasks}, which the
|
|
28
|
+
* renderer shows in the task panel above the prompt.
|
|
29
|
+
*/
|
|
30
|
+
export declare class ConversationTranscript {
|
|
31
|
+
#private;
|
|
32
|
+
reset(): void;
|
|
33
|
+
/** The tasks between their start and end lines as of the last projection, in start order. */
|
|
34
|
+
get tasks(): readonly TaskEntry[];
|
|
35
|
+
/** Whether a settled agent task is waiting for its own last events. */
|
|
36
|
+
get finishing(): boolean;
|
|
37
|
+
/** How input requests name the task that asked: as its task lines do. */
|
|
38
|
+
taskLabel(conversation: ConversationState, taskId: string): string | undefined;
|
|
39
|
+
/** End lines for the tasks still working when their session ends; they read as stopped. */
|
|
40
|
+
stopWorking(options: TranscriptOptions): Block[];
|
|
41
|
+
project(view: AgentTUIConversationView, options: TranscriptOptions): Block[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Running tools and the live turn's model activity, for the turn bar. A session parked on a
|
|
45
|
+
* sign-in names its connections, and a turn parked on its tasks names them.
|
|
46
|
+
*/
|
|
47
|
+
export declare function turnActivity(view: AgentTUIConversationView, tasks: readonly TaskEntry[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FileContentCache}from"./file-content-cache.js";import{agentDisplayName,agentTaskLabel,isPanelRoutedTool,presentTool,readWriteFileInput,toolBaseName}from"./tool-presentation.js";import{isTerminalToolCallPart}from"./terminal-tool-part.js";import{activeToolSteps,agentTaskSummary,authorizationTerminalMessage,childToolCallIds,endLine,firstLine,formatAuthorization,isActive,isToolCallRow,labelContext,nestedTaskRecord,startLine,subagentSteps,taskCallsById,taskNeedsApproval,toolBlock,toolState,uniqueTaskName,userText,writeExistedFlag}from"./transcript-parts.js";import{signInLabel,waitingLabel}from"./task-activity.js";import{isTaskControlTool}from"#protocol/task-tools.js";import{stripTerminalControls}from"#cli/ui/terminal-text.js";import{agentCallTurns,agentToolSession,conversationAuthorizations,isAgentCallContentPending}from"#client/conversation-state.js";import{authorizationKey}from"#client/session-utils.js";const TASK_END_GRACE_MS=2e3;var ConversationTranscript=class{#e=new Map;#t=new FileContentCache;#n=new Map;#r=new Map;#i=new Set;#a=new Map;#o=new Map;#s=[];#c=new Set;#l=[];reset(){this.#e=new Map,this.#t.clear(),this.#n.clear(),this.#r=new Map,this.#i.clear(),this.#a.clear(),this.#o.clear(),this.#s=[],this.#c.clear(),this.#l=[]}get tasks(){return this.#l}get finishing(){return this.#l.some(e=>e.finishing===!0)}taskLabel(e,t){let n=e.tasks[t];if(n===void 0)return;let r=Object.values(n.calls),i=r.findLast(e=>e.status===`working`)??r.at(-1),a=i===void 0?void 0:this.#a.get(i.callId);return a===void 0?n.kind===`agent`?agentTaskLabel(agentDisplayName(stripTerminalControls(n.name))):stripTerminalControls(n.name):a.kind===`agent`?agentTaskLabel(a.name):a.name}stopWorking(e){let t=[];for(let n of this.#a.values())n.ended||(n.ended=!0,t.push(endLine(n,{status:`cancelled`},void 0,e.dot??`·`)));return this.#l=[],t}project(e,t){let{conversation:n,working:r}=e,i=Date.now(),a=[];this.#h(n.messages);let o=childToolCallIds(n),s=taskCallsById(n),c=new Set(e.data.withdrawnCallIds),l=e.data.toolLabels;for(let e of n.messages){if(e.role===`user`){let t=this.#g(e);t!==void 0&&a.push(t);continue}let u=e.parts.filter(e=>isToolCallRow(e)&&(e.state!==`input-streaming`||r)&&!isTaskControlTool(e.toolName)&&!c.has(e.toolCallId)&&e.toolMetadata?.eve?.inputRequest?.kind!==`session-limit`&&!s.has(e.toolCallId)&&!o.has(e.toolCallId)&&!isPanelRoutedTool(e.toolName)),d=new Map(u.map(e=>[e,toolState(e,n,r,!1)])),f=activeToolSteps(d);for(let[n,o]of e.parts.entries())if(o.type===`text`||o.type===`reasoning`){let i=this.#_(e,n,t,r);i!==void 0&&a.push(i)}else if(o.type===`authorization`)t.connectionAuth!==`hidden`&&a.push(this.#v(o));else if(o.type===`dynamic-tool`){let e=s.get(o.toolCallId);if(e!==void 0){let n=this.#d(o,e.task,l,t,i);n!==void 0&&a.push(n);continue}let n=d.get(o);if(n===void 0||t.tools===`hidden`)continue;let r=l[o.toolCallId];a.push(this.#y(o,n,f.has(o.stepIndex),r,t))}let p=e.metadata?.turnId;p!==void 0&&n.turns[p]?.status===`cancelled`&&a.push(this.#m(`cancelled:${p}`,[],()=>({kind:`notice`,body:`Cancelled.`,live:!1})))}for(let[n,r]of e.failures.entries())a.push(this.#b(n,r,t));let u=this.#u(a),d=this.#f(e,s,t,i);for(let e of d){let t=u.slice(-8).map(e=>e.id);this.#s.push({block:e,after:t}),this.#c.add(e.id),u.push(e)}return u}#u(e){let t=[...e];for(let{block:e,after:n}of this.#s){let r=t.length;for(let e=n.length-1;e>=0;--e){let i=t.findIndex(t=>t.id===n[e]);if(i!==-1){r=i+1;break}}t.splice(r,0,e)}return t}#d(e,t,n,r,i){if(!(t.kind===`agent`?r.subagents!==`hidden`:r.tools!==`hidden`))return;let a=e.toolCallId,o=n[a]?.start,s=this.#a.get(a),c=agentTaskSummary(e.input),l=agentDisplayName(stripTerminalControls(e.toolName));if(t.kind===`tool`){let t=presentTool(e.toolName,e.input,labelContext(o));l=stripTerminalControls(t.title),c=stripTerminalControls(t.subtitle)}return s===void 0&&(s={callId:a,kind:t.kind,name:uniqueTaskName(l,this.#a.values()),toolName:e.toolName,input:e.input,label:o,purpose:c||o,startedAtMs:i,ended:!1},this.#a.set(a,s)),this.#m(`task:${a}:start`,[s],()=>startLine(s))}#f(e,t,n,r){let{conversation:i,working:a}=e,o=Object.values(i.turns).at(-1),s=!a&&(e.data.sessionFailed||o?.status===`cancelled`||o?.status===`failed`),c=[],l=[],u={remaining:128};for(let e of this.#a.values()){if(e.ended)continue;let o=t.get(e.callId);if(o===void 0)continue;let{task:d,call:f}=o,p=this.#p(e,d,f,i,n,u);if(n.subagents===`full`)for(let e of p.rows)this.#c.has(e.id)||c.push(e);let m=f.status!==`working`;m&&(e.settledAtMs??=r);let h=m&&p.pending&&a&&r-(e.settledAtMs??r)<2e3;if(m&&!h||!m&&s){e.ended=!0,c.push(endLine(e,m?f:{status:`cancelled`},p.tools,n.dot??`·`));continue}let g={callId:e.callId,kind:e.kind,name:e.name,toolName:e.toolName,input:e.input,label:e.label,purpose:e.purpose,children:p.children,omittedTasks:p.omittedTasks,omittedAttention:p.omittedAttention,startedAtMs:e.startedAtMs,childTools:new Map(p.tools.map(e=>[e.id,e]))};p.step!==void 0&&(g.step=p.step),h&&(g.finishing=!0),l.push(g)}return this.#l=l,c}#p(e,t,n,r,i,a,o=0){let s=t.kind===`agent`?agentToolSession(r,t):void 0,c=s===void 0||s.observation.status===`not-followed`?void 0:s.observation.conversation;if(s===void 0||c===void 0)return{tools:[],rows:[],pending:!1};let l=s.observation.status===`following`&&isAgentCallContentPending(t,n,c),u=new Set(agentCallTurns(t,c).get(n.callId)??[]),d=c.messages.filter(e=>e.role===`assistant`&&e.metadata?.turnId!==void 0&&u.has(e.metadata.turnId)),f=n.status===`working`||l,p=taskCallsById(c),m=[],h=[],g=[],_=0,v=!1,y=0;for(let t of d)for(let n of t.parts){if(y+=1,!isToolCallRow(n)||isTaskControlTool(n.toolName))continue;let t=p.get(n.toolCallId),r=toolState(n,c,f,t?.call.status===`working`),s=`subagent:${e.callId}:tool:${n.toolCallId}`,l=this.#m(s,[n,r.status,e.name],()=>{let a=this.#x(n.toolCallId,n,r,i,{isSubagent:t?.task.kind===`agent`});return{...toolBlock(n,r,a),kind:`subagent-tool`,subagentCallId:e.callId,agentName:e.name,depth:1,live:!1}}),u=t?.task.kind===`agent`?i.subagents!==`hidden`:i.tools!==`hidden`;if(t?.call.status===`working`&&u){if(o>=8||a.remaining<=0){_+=1,v||=r.status===`approval`||taskNeedsApproval(c,t.task);continue}--a.remaining;let s=`${e.callId}/${n.toolCallId}`,u=this.#o.get(s);u===void 0&&(u=nestedTaskRecord(s,n,t.task,l),this.#o.set(s,u));let d=this.#p(u,t.task,t.call,c,i,a,o+1);g.push({...u,step:d.step,children:d.children,omittedTasks:d.omittedTasks,omittedAttention:d.omittedAttention,childTools:new Map(d.tools.map(e=>[e.id,e]))})}else h.push(l);m.push({order:y,block:l,settled:!isActive(r.status)})}let b=subagentSteps(d);for(let t of b){if(!t.finalized)continue;let n=`subagent:${e.callId}:step:${t.key}`,r=this.#m(n,[t.reasoning,t.message,e.name],()=>{let n={kind:`subagent-step`,subagentCallId:e.callId,agentName:e.name,depth:1,body:t.message,live:!1};return t.reasoning.length>0&&(n.reasoning=t.reasoning),n});m.push({order:t.order,block:r,settled:!0})}let x=m.filter(e=>e.settled).sort((e,t)=>e.order-t.order).map(e=>e.block),S=b.at(-1),C={tools:h,rows:x,children:g,omittedTasks:_,omittedAttention:v,pending:l};return S!==void 0&&(C.step=firstLine(S.message)??`Thinking`),C}#m(e,t,n){let r=this.#e.get(e);if(r!==void 0&&sameKey(r.key,t))return r.block;let i={...n(),id:e};return this.#e.set(e,{key:t,block:i}),i}#h(e){let t=new Map;for(let n of e)n.role===`user`&&n.metadata?.optimistic===!0&&t.set(n.id,userText(n));let n=[...this.#r].filter(([e])=>!t.has(e)),r=new Set(t.values());for(let t of e){if(t.role!==`user`||t.metadata?.optimistic===!0||this.#i.has(t.id))continue;let e=userText(t),i=n.findIndex(([,t])=>t===e);i===-1&&r.has(e)||(this.#i.add(t.id),i!==-1&&(this.#n.set(t.id,n[i][0]),n.splice(i,1)))}this.#r=t}#g(e){if(e.metadata?.optimistic!==!0&&!this.#i.has(e.id))return;let t=stripTerminalControls(userText(e));if(t.trim().length===0)return;let n=`user:${this.#n.get(e.id)??e.id}`;return this.#m(n,[t],()=>({kind:`user`,body:t,live:!1}))}#_(e,t,n,r){let i=e.parts[t];if(i?.type!==`text`&&i?.type!==`reasoning`||i.type===`reasoning`&&n.reasoning!==`full`)return;let a=stripTerminalControls(i.text).trim();if(a.length===0)return;let o=i.state===`streaming`&&r,s=`${i.type}:${i.id??`${e.id}:${t}`}`;return this.#m(s,[a,o],()=>i.type===`text`?{kind:`assistant`,body:a,live:o}:{kind:`reasoning`,body:a,collapsed:!1,live:o})}#v(e){return this.#m(`connection-auth:${authorizationKey(e)}`,[e],()=>{let t=e.state===`completed`?e.outcome:e.state,n=authorizationTerminalMessage(t);return{kind:`connection-auth`,title:`${stripTerminalControls(e.name)} · authorization · ${t}`,body:formatAuthorization(e,n),preformatted:!0,live:n===void 0}})}#y(e,t,n,r,i){let a=n||isActive(t.status);return this.#m(`tool:${e.toolCallId}`,[e,t.status,a,i.tools,i.subagentNames,r],()=>{let n=this.#x(e.toolCallId,e,t,i,{label:r?.start,completeLabel:r?.complete});return{...toolBlock(e,t,n),kind:`tool`,live:a,expanded:i.tools===`full`}})}#b(e,t,n){let{message:r,hint:i,detail:a}=t;return this.#m(`failure:${e}`,[r,i,a],()=>{let e={kind:`error`,title:`Error`,body:stripTerminalControls(r),live:!1};return i!==void 0&&(e.hint=stripTerminalControls(i)),a!==void 0&&(e.detail=n.diagnosticsPath===void 0?stripTerminalControls(a):`details: ${n.diagnosticsPath}`),e})}#x(e,t,n,r,i={}){n.output!==void 0&&this.#t.observeRead(n.output);let a={};(i.isSubagent===!0||r.subagentNames?.includes(toolBaseName(t.toolName))===!0)&&(a.isSubagent=!0),i.label!==void 0&&(a.label=i.label),i.completeLabel!==void 0&&(a.completeLabel=i.completeLabel);let o=readWriteFileInput(t.toolName,t.input);if(o!==void 0){let t=this.#t.observeWrite({...o,callId:e});t!==void 0&&(a.previousContent=t);let r=writeExistedFlag(n.output);r!==void 0&&(a.existed=r)}return Object.keys(a).length>0?a:void 0}};function turnActivity(e,t){let{conversation:n}=e,r=n.activeTurnId===void 0?void 0:n.turns[n.activeTurnId],i=e.conversation.messages.findLast(e=>e.role===`assistant`),a=taskCallsById(n);if(i?.parts.some(e=>isTerminalToolCallPart(e)&&!isTaskControlTool(e.toolName)&&!a.has(e.toolCallId)&&(e.state===`input-available`||e.state===`approval-responded`))===!0)return`Running`;if(r===void 0||r.waiting===!0){let e=conversationAuthorizations(n).filter(e=>e.state===`required`&&e.awaitsCallback===!0);if(e.length>0)return signInLabel(e.map(e=>e.displayName))}if(r?.waiting===!0&&t.length>0)return waitingLabel(t);if(i===void 0)return`Thinking`;let o=i.parts.findLast(e=>e.type!==`step-start`);return o?.type===`text`&&o.state===`streaming`||o?.type===`dynamic-tool`&&o.state===`input-streaming`?`Generating`:`Thinking`}function sameKey(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}export{ConversationTranscript,TASK_END_GRACE_MS,turnActivity};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{remoteHost}from"./target.js";import{createDevDiagnostics}from"../diagnostics.js";import{promptCommandsFor}from"./prompt-commands.js";import{probeMcpConnection}from"./mcp-connection-status.js";import{createPromptCommandHandler}from"./prompt-command-handler.js";import{formatRemoteAuthChallengeMessage}from"./remote-auth-result.js";import{TerminalRenderer}from"./terminal-renderer.js";import{EveTUIRunner}from"./runner.js";import{Client}from"#client/index.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{LOGIN_CONNECTION_COMMAND_OPTIONS}from"#setup/flows/model-login-options.js";import{toErrorMessage}from"#shared/errors.js";import{resolveDevelopmentOidcToken,resolveLinkedDevelopmentOidcToken}from"#services/dev-client/request-headers.js";import{isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";import{resolveVercelDeployment}from"#setup/vercel-deployment.js";import{appendUserAgentProduct}from"#internal/user-agent.js";import{resolveLocalDevelopmentClientOptions,resolveRemoteDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{createDevelopmentCredentialGate}from"#services/dev-client/credential-gate.js";function inlineArgumentSuggestions(e){return async t=>{if(t===`loglevel`)return[{value:`
|
|
1
|
+
import{remoteHost}from"./target.js";import{createDevDiagnostics}from"../diagnostics.js";import{promptCommandsFor}from"./prompt-commands.js";import{probeMcpConnection}from"./mcp-connection-status.js";import{createPromptCommandHandler}from"./prompt-command-handler.js";import{formatRemoteAuthChallengeMessage}from"./remote-auth-result.js";import{TerminalRenderer}from"./terminal-renderer.js";import{EveTUIRunner}from"./runner.js";import{Client}from"#client/index.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{LOGIN_CONNECTION_COMMAND_OPTIONS}from"#setup/flows/model-login-options.js";import{toErrorMessage}from"#shared/errors.js";import{resolveDevelopmentOidcToken,resolveLinkedDevelopmentOidcToken}from"#services/dev-client/request-headers.js";import{isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";import{resolveVercelDeployment}from"#setup/vercel-deployment.js";import{appendUserAgentProduct}from"#internal/user-agent.js";import{resolveLocalDevelopmentClientOptions,resolveRemoteDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{createDevelopmentCredentialGate}from"#services/dev-client/credential-gate.js";function inlineArgumentSuggestions(e){return async t=>{if(t===`loglevel`)return[{value:`none`,label:`none`,hint:`Hide logs`},{value:`error`,label:`error`,hint:`Errors only (default)`},{value:`warn`,label:`warn`,hint:`Warnings and errors`},{value:`debug`,label:`debug`,hint:`All severity-tagged logs`},{value:`all`,label:`all`,hint:`Include raw stdout and sandbox output`}];if(t===`login`)return LOGIN_CONNECTION_COMMAND_OPTIONS.map(e=>({value:e.command,label:e.label}));if(t===`model`){let{gatewayModelCapabilities:e}=await import(`#setup/boxes/model-capabilities.js`),{fetchGatewayCatalog:t,modelOptionsFromCatalog:n}=await import(`#setup/boxes/select-model.js`),r=await t().catch(()=>void 0);return n(r).map(t=>{let n=e(r,t.value);return{value:t.value,label:t.value,hint:t.hint,...n?.reasoning?{next:[{value:`default`,label:`default`},...n.reasoningLevels.map(e=>({value:e,label:e}))]}:{}}})}let{browseRegistryCatalog:n}=await import(`#cli/commands/registry.js`);return(await n(e)).items.map(e=>({value:e.address,label:e.name,hint:e.description??e.address}))}}async function startDevelopmentTuiStartup(e){let t=await createDevDiagnostics(e.appRoot).catch(()=>void 0),n=new TerminalRenderer({...e,diagnostics:t,argumentSuggestions:inlineArgumentSuggestions(e.appRoot),onExitRequest:e.onExitRequest});return n.beginStartupDraft({initialDraft:e.initialInput,title:e.name??`eve`}),{diagnostics:t,renderer:n,finish:()=>n.finishStartupDraft(),async shutdown(){n.shutdown(),await t?.close()}}}function prepareRemoteTarget(e){return{target:e,credentials:createDevelopmentCredentialGate(e.serverUrl),resolveOidcToken:resolveDevelopmentOidcToken,resolveDeployment:t=>resolveVercelDeployment({workspaceRoot:e.workspaceRoot,host:remoteHost(e),signal:t})}}function prepareDevelopmentTarget(e){return e.kind===`local`?{kind:`local`,target:e}:{kind:`remote`,target:e,remote:prepareRemoteTarget(e)}}function withTuiUserAgent(e){let t=new Headers(e);return appendUserAgentProduct(t,`eve-tui/${resolveInstalledPackageInfo().version}`),Object.fromEntries(t.entries())}async function runDevelopmentTui(e){let{target:t,headers:n,initialInput:r,onboard:i,onOnboardingStep:a,onOnboardingTerminal:o,onBootProgress:s,lifecycle:c,startup:l,withExclusiveTerminal:u,...d}=e,f=prepareDevelopmentTarget(t),{serverUrl:p}=t,m={headers:withTuiUserAgent(n)},h=new Client(f.kind===`local`?resolveLocalDevelopmentClientOptions({...m,interactiveClient:!0,serverUrl:p,token:()=>resolveLinkedDevelopmentOidcToken(f.target.workspaceRoot)}):resolveRemoteDevelopmentClientOptions({...m,serverUrl:p,credentials:f.remote.credentials})),g={...d,client:h,serverUrl:p,promptCommandHandler:createPromptCommandHandler({target:t}),availablePromptCommands:promptCommandsFor(t.kind),...t.kind===`local`?{argumentSuggestions:inlineArgumentSuggestions(t.workspaceRoot)}:{},formatTransportError:e=>isVercelAuthChallenge(e)?formatRemoteAuthChallengeMessage(p):toErrorMessage(e)};f.kind===`local`?(g.appRoot=f.target.workspaceRoot,g.probeMcpConnection=probeMcpConnection):g.remote=f.remote,r!==void 0&&(g.initialInput=r),l!==void 0&&(g.renderer=l.renderer,g.startup=l),i!==void 0&&(g.onboard=i),a!==void 0&&(g.onOnboardingStep=a),o!==void 0&&(g.onOnboardingTerminal=o),s!==void 0&&(g.onBootProgress=s),c!==void 0&&(g.lifecycle=c),u!==void 0&&(g.withExclusiveTerminal=u);let _=l?.diagnostics??(f.kind===`local`?await createDevDiagnostics(f.target.workspaceRoot).catch(()=>void 0):void 0);_!==void 0&&(g.diagnostics=_);try{await new EveTUIRunner(g).run()}finally{await _?.close()}}export{runDevelopmentTui,startDevelopmentTuiStartup};
|
|
@@ -1,36 +1,21 @@
|
|
|
1
|
+
import type { TokenUsage } from "./conversation-view.js";
|
|
1
2
|
/**
|
|
2
|
-
* One turn's wall clock and
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Multi-pass turns (question answers, connection authorizations) re-stream
|
|
7
|
-
* without re-arming, so one turn gets one coda.
|
|
3
|
+
* One turn's wall clock and token flow, measured against the session's summed
|
|
4
|
+
* step usage when work started. Armed when work starts and consumed once by
|
|
5
|
+
* the end-of-turn coda, so answering an approval or question mid-turn does
|
|
6
|
+
* not split the turn.
|
|
8
7
|
*/
|
|
9
8
|
export declare class TurnClock {
|
|
10
9
|
#private;
|
|
11
|
-
|
|
12
|
-
arm(): void;
|
|
10
|
+
arm(usage: TokenUsage): void;
|
|
13
11
|
get armed(): boolean;
|
|
14
12
|
get startedAtMs(): number | undefined;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
addUsage(usage: {
|
|
20
|
-
inputTokens?: number;
|
|
21
|
-
outputTokens?: number;
|
|
22
|
-
}): void;
|
|
23
|
-
/**
|
|
24
|
-
* Consumes the armed clock, returning the turn's elapsed time and summed
|
|
25
|
-
* flow — or `undefined` when no turn was armed (the coda's "already
|
|
26
|
-
* settled" signal). The flow survives the settle so a repaint between the
|
|
27
|
-
* coda and the next arm still reads the last turn's numbers.
|
|
28
|
-
*/
|
|
29
|
-
settle(): {
|
|
13
|
+
/** Token flow since the clock was armed. */
|
|
14
|
+
usage(current: TokenUsage): TokenUsage;
|
|
15
|
+
/** Consumes the armed clock, or returns `undefined` when no turn was armed. */
|
|
16
|
+
settle(current: TokenUsage): ({
|
|
30
17
|
elapsedMs: number;
|
|
31
|
-
|
|
32
|
-
outputTokens: number;
|
|
33
|
-
} | undefined;
|
|
18
|
+
} & TokenUsage) | undefined;
|
|
34
19
|
/** Drops the clock without a coda (conversation boundaries). */
|
|
35
20
|
reset(): void;
|
|
36
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var TurnClock=class{#e;#t={inputTokens:0,outputTokens:0};arm(){this.#e=Date.now(),this.#t=
|
|
1
|
+
var TurnClock=class{#e;#t={inputTokens:0,outputTokens:0};arm(e){this.#e=Date.now(),this.#t=e}get armed(){return this.#e!==void 0}get startedAtMs(){return this.#e}usage(e){return{inputTokens:Math.max(0,e.inputTokens-this.#t.inputTokens),outputTokens:Math.max(0,e.outputTokens-this.#t.outputTokens)}}settle(e){let t=this.#e;if(t!==void 0)return this.#e=void 0,{elapsedMs:Date.now()-t,...this.usage(e)}}reset(){this.#e=void 0,this.#t={inputTokens:0,outputTokens:0}}};export{TurnClock};
|
|
@@ -61,12 +61,10 @@ export type TuiDisplayOptions = {
|
|
|
61
61
|
*/
|
|
62
62
|
contextSize?: number;
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
65
|
-
* surface as inline regions. Output is always captured and buffered so it
|
|
64
|
+
* Minimum log severity to surface as inline regions. Output is always captured and buffered so it
|
|
66
65
|
* cannot corrupt the frame; this only controls what is rendered. The
|
|
67
66
|
* `/loglevel` command switches the mode at runtime, retroactively hiding or
|
|
68
|
-
* restoring buffered lines. `
|
|
69
|
-
* `eve dev` CLI defaults to `stderr`.
|
|
67
|
+
* restoring buffered lines. Defaults to `error`. Only `all` includes unclassified raw output.
|
|
70
68
|
*/
|
|
71
69
|
logs?: LogDisplayMode;
|
|
72
70
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function resolveDevUiMode(e){return e.options.ui===!1||!e.interactive?`headless`:`tui`}function resolveTuiDisplayOptions(e){let t={logs:e.logs??`
|
|
1
|
+
function resolveDevUiMode(e){return e.options.ui===!1||!e.interactive?`headless`:`tui`}function resolveTuiDisplayOptions(e){let t={logs:e.logs??`error`,reasoning:e.reasoning??`auto-collapsed`,tools:e.tools??`auto-collapsed`};return e.subagents!==void 0&&(t.subagents=e.subagents),e.connectionAuth!==void 0&&(t.connectionAuth=e.connectionAuth),e.assistantResponseStats!==void 0&&(t.assistantResponseStats=e.assistantResponseStats),e.contextSize!==void 0&&(t.contextSize=e.contextSize),t}export{resolveDevUiMode,resolveTuiDisplayOptions};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ConversationState } from "#client/conversation-state.js";
|
|
2
|
+
import type { ClientSession } from "#client/session.js";
|
|
3
|
+
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
4
|
+
export interface AgentStreamFollowerOptions {
|
|
5
|
+
/** The session whose stream announced the agents; reads use its host and credentials. */
|
|
6
|
+
readonly session: ClientSession;
|
|
7
|
+
readonly getState: () => ConversationState;
|
|
8
|
+
readonly onFollowing: (sessionId: string) => void;
|
|
9
|
+
readonly onEvent: (sessionId: string, event: MessageStreamEvent) => void;
|
|
10
|
+
readonly onIdle: (sessionId: string) => void;
|
|
11
|
+
readonly onUnavailable: (sessionId: string) => void;
|
|
12
|
+
/** Retained by the transport owner across detach and reattach. */
|
|
13
|
+
readonly cursors: Map<string, number>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Follows each agent tool's session while its task has content the conversation has not shown.
|
|
17
|
+
* The conversation decides when a session is caught up; this class only owns transport.
|
|
18
|
+
*/
|
|
19
|
+
export declare class AgentStreamFollower {
|
|
20
|
+
#private;
|
|
21
|
+
constructor(options: AgentStreamFollowerOptions);
|
|
22
|
+
acceptParentEvent(event: MessageStreamEvent): void;
|
|
23
|
+
/** Starts, resumes, or pauses subscriptions to match the conversation. */
|
|
24
|
+
reconcile(): void;
|
|
25
|
+
abortAll(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{agentToolTask,isAgentSessionCaughtUp}from"#client/conversation-state.js";const agentStreamReconnectPolicy={streamIdleReconnectPolicy:{maxAttempts:1/0},streamOpenReconnectPolicy:{maxAttempts:1/0}};var AgentStreamFollower=class{#e;#t=new Map;#n=new Map;#r=new Set;#i=!1;constructor(e){this.#e=e}acceptParentEvent(e){e.type===`agent.started`&&this.#t.set(e.data.sessionId,e)}reconcile(){if(this.#i)return;let e=this.#e.getState();for(let t of Object.values(e.agents)){if(agentToolTask(e,t)===void 0)continue;let n=this.#n.get(t.sessionId),r=isAgentSessionCaughtUp(e,t);n!==void 0&&r?(this.#n.delete(t.sessionId),n.abort(),this.#e.onIdle(t.sessionId)):n===void 0&&!r&&!this.#r.has(t.sessionId)&&this.#a(t.sessionId)}}abortAll(){this.#i=!0;for(let e of this.#n.values())e.abort();this.#n.clear()}#a(e){let t=this.#t.get(e);if(t===void 0)return;let n=new AbortController;this.#n.set(e,n),this.#e.onFollowing(e);let{cursors:r}=this.#e;(async()=>{let i=r.get(e)??0;try{for await(let a of this.#e.session.agent(t).stream({signal:n.signal,startIndex:i,streamReconnectPolicy:agentStreamReconnectPolicy})){if(n.signal.aborted)return;r.set(e,++i),this.#e.onEvent(e,a),this.reconcile()}}catch{}n.signal.aborted||this.#n.get(e)!==n||(this.#n.delete(e),this.#r.add(e),this.#e.onUnavailable(e))})()}};export{AgentStreamFollower};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function createAuthorizationRequiredPart(e){let t=e.data.authorization?.displayName??formatAuthorizationDisplayName(e.data.name)
|
|
1
|
+
function createAuthorizationRequiredPart(e){let t=e.data.authorization?.displayName??formatAuthorizationDisplayName(e.data.name),n={authorization:e.data.authorization,description:normalizeAuthorizationDescription(e.data.description,e.data.name,t),displayName:t,name:e.data.name,state:`required`,stepIndex:e.data.stepIndex,turnId:e.data.turnId,type:`authorization`};return e.data.attemptId!==void 0&&(n.attemptId=e.data.attemptId),e.data.webhookUrl!==void 0&&(n.awaitsCallback=!0),n}function createAuthorizationCompletedPart(e,t){let n=e.data.authorization?.displayName??t?.displayName??formatAuthorizationDisplayName(e.data.name),r={authorization:t?.authorization||e.data.authorization?{...t?.authorization,...e.data.authorization}:void 0,description:t?.description??buildCompletedAuthorizationDescription(n,e.data.outcome,e.data.reason),displayName:n,name:e.data.name,outcome:e.data.outcome,state:`completed`,stepIndex:t?.stepIndex??e.data.stepIndex,turnId:t?.turnId??e.data.turnId,type:`authorization`},i=e.data.attemptId??t?.attemptId;return i!==void 0&&(r.attemptId=i),t?.awaitsCallback&&(r.awaitsCallback=!0),e.data.reason!==void 0&&(r.reason=e.data.reason),r}function buildCompletedAuthorizationDescription(e,t,n){return t===`authorized`?`${e} connected.`:`${e} authorization ${t}${n===void 0?``:` (${n})`}.`}function normalizeAuthorizationDescription(e,t,n){return e===`Authorization required for ${t}`?`Authorization required for ${n}`:e}function formatAuthorizationDisplayName(e){return e.length===0?e:`${e.charAt(0).toUpperCase()}${e.slice(1)}`}export{createAuthorizationCompletedPart,createAuthorizationRequiredPart};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ConversationState } from "#client/conversation-state.js";
|
|
2
|
+
import { EveAgentProjection, type EveAgentEventLog } from "#client/eve-agent-projection.js";
|
|
3
|
+
import type { SendTurnPayload } from "#client/types.js";
|
|
4
|
+
import type { EveAgentReducerEvent } from "#client/reducer.js";
|
|
5
|
+
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
6
|
+
import type { InputResponse } from "#shared/input.js";
|
|
7
|
+
import { SessionEventStream, type SessionEventStreamOptions } from "#client/session-event-stream.js";
|
|
8
|
+
import type { ClientSession } from "#client/session.js";
|
|
9
|
+
/** Owns the canonical conversation and its root and agent-session transports for one client session. */
|
|
10
|
+
export declare class ConversationClient<TData = ConversationState> {
|
|
11
|
+
#private;
|
|
12
|
+
readonly projection: EveAgentProjection<TData>;
|
|
13
|
+
constructor(projection: EveAgentProjection<TData>, onChange: (data: TData, previous: TData) => void, onConversationChange?: (state: ConversationState, previous: ConversationState) => void);
|
|
14
|
+
get data(): TData;
|
|
15
|
+
get conversation(): ConversationState;
|
|
16
|
+
get projections(): readonly EveAgentEventLog[];
|
|
17
|
+
get following(): boolean;
|
|
18
|
+
append(event: EveAgentReducerEvent): void;
|
|
19
|
+
/** Projects submitted answers; the returned callback withdraws them if the server never accepts. */
|
|
20
|
+
projectResponses(responses: readonly InputResponse[] | undefined): (() => void) | undefined;
|
|
21
|
+
/** Swaps projected answers for a prepared payload's, which must still be answerable. */
|
|
22
|
+
replaceResponses(retract: (() => void) | undefined, input: SendTurnPayload): (() => void) | undefined;
|
|
23
|
+
/** Admit and project a root event before the agent sessions it announces are followed. */
|
|
24
|
+
observe(event: MessageStreamEvent, options?: {
|
|
25
|
+
/** The store reconciles optimistic messages instead of directly appending the event. */
|
|
26
|
+
project?: (event: MessageStreamEvent) => void;
|
|
27
|
+
/** Record the accepted event before projection or child notifications. */
|
|
28
|
+
onAccepted?: (event: MessageStreamEvent) => void;
|
|
29
|
+
/** The store publishes after updating its event log and status. */
|
|
30
|
+
notify?: boolean;
|
|
31
|
+
}): boolean;
|
|
32
|
+
/** Admit and project a hydrated root event without notifying subscribers. */
|
|
33
|
+
hydrate(event: MessageStreamEvent): boolean;
|
|
34
|
+
/** Start following the agent sessions the root stream has announced so far. */
|
|
35
|
+
follow(session: ClientSession, events?: readonly MessageStreamEvent[]): void;
|
|
36
|
+
/** Follows the root session continuously; operation readers subscribe to this one stream. */
|
|
37
|
+
stream(session: ClientSession, options: SessionEventStreamOptions): SessionEventStream;
|
|
38
|
+
stop(): void;
|
|
39
|
+
reset(): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertAnswerable}from"#client/eve-agent-store-helpers.js";import{AgentStreamFollower}from"#client/agent-stream-follower.js";import{canonicalConversationReducer,conversationReducer}from"#client/conversation-reducer.js";import{EveAgentProjection}from"#client/eve-agent-projection.js";import{createEventDeduper}from"#protocol/event-dedupe.js";import{SessionEventStream}from"#client/session-event-stream.js";var ConversationClient=class{projection;#e;#t=new Map;#n=createEventDeduper();#r;#i;#a;#o;constructor(e,t,n){this.projection=e,this.#e=e.reducer===conversationReducer?e:new EveAgentProjection(canonicalConversationReducer,[]),this.#a=t,this.#o=n}get data(){return this.projection.data}get conversation(){return this.#e.data}get projections(){return this.#e===this.projection?[this.projection]:[this.#e,this.projection]}get following(){return this.#r!==void 0}append(e){let t=this.data,n=this.conversation;this.#c(e),t===this.data?n!==this.conversation&&this.#o?.(this.conversation,n):this.#a(this.data,t)}projectResponses(e){if(!e?.length)return;let t={data:{createdAt:Date.now(),responses:e},type:`client.input.responded`};return this.append(t),()=>this.#s(t)}replaceResponses(e,t){return e?.(),assertAnswerable(t,this.conversation),this.projectResponses(t.inputResponses)}#s(e){let t=this.data,n=this.conversation;for(let t of this.projections)t.remove(t=>t===e);t===this.data?n!==this.conversation&&this.#o?.(this.conversation,n):this.#a(this.data,t)}observe(e,t={}){if(!this.#n.admit(e))return!1;t.onAccepted?.(e);let n=this.data,r=this.conversation;return t.project?t.project(e):this.#c(e),t.notify!==!1&&(n===this.data?r!==this.conversation&&this.#o?.(this.conversation,r):this.#a(this.data,n)),this.#r?.acceptParentEvent(e),this.#r?.reconcile(),!0}hydrate(e){return this.#n.admit(e)?(this.#c(e),!0):!1}follow(e,t=[]){this.#r?.abortAll();let n=new AgentStreamFollower({session:e,cursors:this.#t,getState:()=>this.conversation,onFollowing:e=>this.#l({type:`client.agent.following`,data:{sessionId:e}}),onEvent:(e,t)=>this.#l({type:`client.agent.observed`,data:{sessionId:e,event:t}}),onIdle:e=>this.#l({type:`client.agent.idle`,data:{sessionId:e}}),onUnavailable:e=>this.#l({type:`client.agent.unavailable`,data:{sessionId:e}})});this.#r=n;for(let e of t)n.acceptParentEvent(e);n.reconcile()}#c(e){for(let t of this.projections)t.append(e)}#l(e){let t=this.data,n=this.conversation;this.#e.append(e),t===this.data?n!==this.conversation&&this.#o?.(this.conversation,n):this.#a(this.data,t)}stream(e,t){return this.#i!==void 0&&!this.#i.ended?(this.#i.setOptions(t),this.#i):(this.#i=new SessionEventStream(e,t),this.#i)}stop(){this.#r?.abortAll(),this.#r=void 0,this.#i?.close(),this.#i=void 0}reset(){this.stop(),this.#t.clear(),this.#n=createEventDeduper();for(let e of this.projections)e.reset()}};export{ConversationClient};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ConversationState } from "#client/conversation-state.js";
|
|
2
|
+
import type { EveAgentReducer, EveAgentReducerEvent } from "#client/reducer.js";
|
|
3
|
+
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
4
|
+
/**
|
|
5
|
+
* Transport facts about followed agent sessions. Only the canonical conversation receives them;
|
|
6
|
+
* custom reducers see their results in `conversation.agents`.
|
|
7
|
+
*/
|
|
8
|
+
export type ClientAgentEvent = {
|
|
9
|
+
readonly data: {
|
|
10
|
+
readonly sessionId: string;
|
|
11
|
+
};
|
|
12
|
+
readonly type: "client.agent.following" | "client.agent.idle" | "client.agent.unavailable";
|
|
13
|
+
} | {
|
|
14
|
+
readonly data: {
|
|
15
|
+
readonly event: MessageStreamEvent;
|
|
16
|
+
readonly sessionId: string;
|
|
17
|
+
};
|
|
18
|
+
readonly type: "client.agent.observed";
|
|
19
|
+
};
|
|
20
|
+
export type ConversationEvent = EveAgentReducerEvent | ClientAgentEvent;
|
|
21
|
+
export declare function initialConversationState(): ConversationState;
|
|
22
|
+
/** Pure reduction of accepted root and agent-session observations; followers own transport. */
|
|
23
|
+
export declare function reduceConversation(state: ConversationState, event: ConversationEvent): ConversationState;
|
|
24
|
+
/** The canonical conversation's reducer, which also folds in followed agent sessions. */
|
|
25
|
+
export declare const canonicalConversationReducer: {
|
|
26
|
+
initial: typeof initialConversationState;
|
|
27
|
+
reduce: typeof reduceConversation;
|
|
28
|
+
};
|
|
29
|
+
export declare const conversationReducer: EveAgentReducer<ConversationState>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defaultMessageReducer}from"#client/message-reducer.js";function initialConversationState(){return{messages:[],turns:{},inputs:{},tasks:{},agents:{}}}function updateTurn(e,t,n){let r=e.turns[t];if(r===void 0)return e;let i=n(r);return i===r?e:{...e,turns:{...e.turns,[t]:i}}}function updateTask(e,t,n){let r=e.tasks[t];if(r===void 0)return e;let i=n(r);return i===r?e:{...e,tasks:{...e.tasks,[t]:i}}}function updateObservation(e,t,n){let r=e.agents[t];if(r===void 0)return e;let i=n(r.observation);return i===r.observation?e:{...e,agents:{...e.agents,[t]:{...r,observation:i}}}}function observedConversation(e){return e.status===`not-followed`?void 0:e.conversation}function reduceConversationLifecycle(e,t){switch(t.type){case`turn.started`:return{...e,activeTurnId:t.data.turnId,turns:{...e.turns,[t.data.turnId]:{turnId:t.data.turnId,status:`active`}}};case`turn.waiting`:return updateTurn(e,t.data.turnId,e=>e.status===`active`&&!e.waiting?{...e,waiting:!0}:e);case`step.started`:return updateTurn(e,t.data.turnId,e=>e.waiting?{turnId:e.turnId,status:e.status}:e);case`turn.completed`:case`turn.cancelled`:case`turn.failed`:{let{turnId:n}=t.data;return{...e,activeTurnId:e.activeTurnId===n?void 0:e.activeTurnId,turns:{...e.turns,[n]:{turnId:n,status:t.type===`turn.completed`?`completed`:t.type===`turn.failed`?`failed`:`cancelled`}}}}case`session.waiting`:case`session.completed`:case`session.failed`:return e.activeTurnId===void 0?e:{...e,activeTurnId:void 0};case`task.started`:{let{callId:n,kind:r,name:i,taskId:a,turnId:o}=t.data,s=e.tasks[a]??{taskId:a,name:i,kind:r,calls:{}};return s.calls[n]===void 0?{...e,tasks:{...e.tasks,[a]:{...s,calls:{...s.calls,[n]:{callId:n,turnId:o,status:`working`}}}}}:e}case`task.settled`:{let{callId:n,error:r,output:i,status:a,taskId:o}=t.data;return updateTask(e,o,e=>{let t=e.calls[n];if(t===void 0||t.status!==`working`)return e;let o={callId:n,turnId:t.turnId,status:a};return{...e,calls:{...e.calls,[n]:a===`completed`&&i!==void 0?{...o,output:i}:a===`failed`&&r!==void 0?{...o,error:r}:o}}})}case`agent.started`:{let{callId:n,name:r,sessionId:i,taskId:a,turnId:o}=t.data;if(e.agents[i]!==void 0)return e;let s={sessionId:i,name:r,callId:n,turnId:o,observation:{status:`not-followed`}};return a!==void 0&&(s.taskId=a),{...e,agents:{...e.agents,[i]:s}}}case`input.requested`:{let n={...e.inputs};for(let e of t.data.requests){if(n[e.requestId]!==void 0)continue;let r={request:e,turnId:t.data.turnId,stepIndex:t.data.stepIndex,status:`open`};t.data.taskId!==void 0&&(r.taskId=t.data.taskId),n[e.requestId]=r}return{...e,inputs:n}}case`client.input.responded`:{let n={...e.inputs};for(let e of t.data.responses){let t=n[e.requestId];t?.status===`open`&&(n[e.requestId]={...t,response:e,status:`responded`})}return{...e,inputs:n}}case`approval.candidate`:{let n=e.inputs[t.data.requestId];return n===void 0||n.status===`settled`||t.data.outcome===`pending`?e:{...e,inputs:{...e.inputs,[t.data.requestId]:{...n,status:`open`,response:void 0}}}}case`approval.settled`:{let n=e.inputs[t.data.requestId];return n===void 0||n.status===`settled`?e:{...e,inputs:{...e.inputs,[t.data.requestId]:{...n,status:`settled`,outcome:t.data.outcome}}}}case`input.resolved`:{let n={...e.inputs};for(let e of t.data.resolutions){let t=n[e.requestId];t!==void 0&&t.status!==`settled`&&(n[e.requestId]={...t,status:`settled`,outcome:e.outcome,response:e.response??t.response})}return{...e,inputs:n}}default:return e}}const messageReducer=defaultMessageReducer();function reduceConversation(e,t){switch(t.type){case`client.agent.following`:return updateObservation(e,t.data.sessionId,e=>e.status===`following`?e:{status:`following`,conversation:observedConversation(e)??initialConversationState()});case`client.agent.observed`:return updateObservation(e,t.data.sessionId,e=>e.status===`following`?{status:`following`,conversation:reduceConversation(e.conversation,t.data.event)}:e);case`client.agent.idle`:return updateObservation(e,t.data.sessionId,e=>e.status===`following`?{status:`idle`,conversation:e.conversation}:e);case`client.agent.unavailable`:return updateObservation(e,t.data.sessionId,e=>{let t=observedConversation(e);return t===void 0?{status:`unavailable`}:{status:`unavailable`,conversation:t}});default:{let n=messageReducer.reduce(e,t);return reduceConversationLifecycle({...e,...n},t)}}}const canonicalConversationReducer={initial:initialConversationState,reduce:reduceConversation},conversationReducer=canonicalConversationReducer;export{canonicalConversationReducer,conversationReducer,initialConversationState,reduceConversation};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { EveAuthorizationPart, EveMessageData } from "#client/message-reducer-types.js";
|
|
2
|
+
import type { InputRequest, InputResponse } from "#shared/input.js";
|
|
3
|
+
import type { JsonValue } from "#shared/json.js";
|
|
4
|
+
export interface ConversationTurn {
|
|
5
|
+
readonly turnId: string;
|
|
6
|
+
readonly status: "active" | "completed" | "cancelled" | "failed";
|
|
7
|
+
/** The open turn is parked, holding on its tasks or on a question one of its calls asked. */
|
|
8
|
+
readonly waiting?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ConversationInput {
|
|
11
|
+
readonly request: InputRequest;
|
|
12
|
+
readonly turnId: string;
|
|
13
|
+
readonly stepIndex: number;
|
|
14
|
+
/** The task whose run asks, when a task asks. */
|
|
15
|
+
readonly taskId?: string;
|
|
16
|
+
readonly status: "open" | "responded" | "settled";
|
|
17
|
+
readonly response?: InputResponse;
|
|
18
|
+
readonly outcome?: string;
|
|
19
|
+
}
|
|
20
|
+
/** One call that started or reached a task, settled by its `task.settled`. */
|
|
21
|
+
export interface ConversationTaskCall {
|
|
22
|
+
readonly callId: string;
|
|
23
|
+
readonly turnId: string;
|
|
24
|
+
readonly status: "working" | "completed" | "failed" | "cancelled";
|
|
25
|
+
/** The call's result; present only when `status` is `"completed"`. */
|
|
26
|
+
readonly output?: JsonValue;
|
|
27
|
+
/** Why the call failed; present only when `status` is `"failed"`. */
|
|
28
|
+
readonly error?: {
|
|
29
|
+
readonly message: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface ConversationTask {
|
|
33
|
+
readonly taskId: string;
|
|
34
|
+
/** The tool whose call started the task. */
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/**
|
|
37
|
+
* `"agent"` when a subagent's tool, local or remote, started the task; `"tool"` for an authored
|
|
38
|
+
* tool, including one that opens sessions with `ctx.agent`.
|
|
39
|
+
*/
|
|
40
|
+
readonly kind: "agent" | "tool";
|
|
41
|
+
/** Calls in the order they started or reached the task. */
|
|
42
|
+
readonly calls: Readonly<Record<string, ConversationTaskCall>>;
|
|
43
|
+
}
|
|
44
|
+
export type AgentObservation = {
|
|
45
|
+
readonly status: "not-followed";
|
|
46
|
+
} | {
|
|
47
|
+
readonly status: "following";
|
|
48
|
+
readonly conversation: ConversationState;
|
|
49
|
+
}
|
|
50
|
+
/** Every call so far has shown its content; a later call to the task resumes following. */
|
|
51
|
+
| {
|
|
52
|
+
readonly status: "idle";
|
|
53
|
+
readonly conversation: ConversationState;
|
|
54
|
+
} | {
|
|
55
|
+
/** The stream failed; this does not mean the agent failed. */
|
|
56
|
+
readonly status: "unavailable";
|
|
57
|
+
readonly conversation?: ConversationState;
|
|
58
|
+
};
|
|
59
|
+
/** A session a run opened with `ctx.agent`, as its `agent.started` announced it. */
|
|
60
|
+
export interface ConversationAgentSession {
|
|
61
|
+
readonly sessionId: string;
|
|
62
|
+
readonly name: string;
|
|
63
|
+
/** The call whose invocation opened the session. */
|
|
64
|
+
readonly callId: string;
|
|
65
|
+
readonly turnId: string;
|
|
66
|
+
/** The task whose run opened the session; absent when an `execute` call opened it. */
|
|
67
|
+
readonly taskId?: string;
|
|
68
|
+
readonly observation: AgentObservation;
|
|
69
|
+
}
|
|
70
|
+
/** Renderable conversation state. Root and agent-session input IDs occupy separate scopes. */
|
|
71
|
+
export interface ConversationState extends EveMessageData {
|
|
72
|
+
readonly activeTurnId?: string;
|
|
73
|
+
readonly turns: Readonly<Record<string, ConversationTurn>>;
|
|
74
|
+
readonly inputs: Readonly<Record<string, ConversationInput>>;
|
|
75
|
+
readonly tasks: Readonly<Record<string, ConversationTask>>;
|
|
76
|
+
/** Sessions opened by this session's runs, by session ID. */
|
|
77
|
+
readonly agents: Readonly<Record<string, ConversationAgentSession>>;
|
|
78
|
+
}
|
|
79
|
+
/** Inputs awaiting an answer, including requests introduced in earlier turns. */
|
|
80
|
+
export declare function openConversationInputs(state: ConversationState): readonly ConversationInput[];
|
|
81
|
+
/** Authorization attempts remain visible across turns, including parked callbacks. */
|
|
82
|
+
export declare function conversationAuthorizations(state: ConversationState): readonly EveAuthorizationPart[];
|
|
83
|
+
/** A sign-in the session still waits on, which resumes its work when the callback arrives. */
|
|
84
|
+
export declare function hasPendingAuthorizations(state: ConversationState): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* The agent task whose calls a session receives, when the session is that agent's own. eve's agent
|
|
87
|
+
* tools send each call as one message, in call order, which is what lets a client attribute the
|
|
88
|
+
* session's turns to calls. A session an authored tool opens with `ctx.agent` has no such task.
|
|
89
|
+
*/
|
|
90
|
+
export declare function agentToolTask(state: ConversationState, agent: ConversationAgentSession): ConversationTask | undefined;
|
|
91
|
+
/** The session an agent tool forwards its task's calls to. */
|
|
92
|
+
export declare function agentToolSession(state: ConversationState, task: ConversationTask): ConversationAgentSession | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Whether a followed agent tool session has shown everything its task's calls produced so far:
|
|
95
|
+
* no call is working, the session has no open turn, question, or sign-in, and every completed call's
|
|
96
|
+
* message has arrived. The last check covers a child stream that lags the root stream.
|
|
97
|
+
*/
|
|
98
|
+
export declare function isAgentSessionCaughtUp(state: ConversationState, agent: ConversationAgentSession): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Attributes an agent tool session's turns to the calls that produced them. The k-th message the
|
|
101
|
+
* session received came from the task's k-th call; a turn without a message of its own, such as
|
|
102
|
+
* one resumed after an approval, continues the previous call. A call whose message joined a
|
|
103
|
+
* running turn owns no turn.
|
|
104
|
+
*/
|
|
105
|
+
export declare function agentCallTurns(task: ConversationTask, conversation: ConversationState): ReadonlyMap<string, readonly string[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Whether a call's content may still arrive on its agent tool session: one of the call's turns is
|
|
108
|
+
* still open there, or the call completed before its message reached the session.
|
|
109
|
+
*/
|
|
110
|
+
export declare function isAgentCallContentPending(task: ConversationTask, call: ConversationTaskCall, conversation: ConversationState): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function openConversationInputs(e){return Object.values(e.inputs).filter(e=>e.status===`open`)}function conversationAuthorizations(e){return e.messages.flatMap(e=>e.role===`assistant`?e.parts.filter(e=>e.type===`authorization`):[])}function hasPendingAuthorizations(e){return conversationAuthorizations(e).some(e=>e.state===`required`&&e.awaitsCallback===!0)}function agentToolTask(e,t){let n=t.taskId===void 0?void 0:e.tasks[t.taskId];return n?.kind===`agent`?n:void 0}function agentToolSession(e,t){return Object.values(e.agents).find(n=>agentToolTask(e,n)?.taskId===t.taskId)}function isAgentSessionCaughtUp(e,t){if(t.observation.status!==`following`&&t.observation.status!==`idle`)return!1;let n=agentToolTask(e,t);if(n===void 0)return!1;let r=Object.values(n.calls);if(r.some(e=>e.status===`working`))return!1;let i=t.observation.conversation;return i.activeTurnId!==void 0||Object.values(i.inputs).some(e=>e.status!==`settled`)||hasPendingAuthorizations(i)?!1:i.messages.filter(e=>e.role===`user`).length>=r.filter(e=>e.status===`completed`).length}function agentCallTurns(e,t){let n=Object.keys(e.calls),r=new Map,i=0;for(let e of t.messages){if(e.role!==`user`)continue;let t=n[i++],a=e.metadata?.turnId;t!==void 0&&a!==void 0&&!r.has(a)&&r.set(a,t)}let a=new Map(n.map(e=>[e,[]])),o;for(let e of Object.keys(t.turns))o=r.get(e)??o,o!==void 0&&a.get(o)?.push(e);return a}function isAgentCallContentPending(e,t,n){let r=agentCallTurns(e,n).get(t.callId)??[],{activeTurnId:i}=n;return i!==void 0&&r.includes(i)?!0:t.status===`completed`&&n.messages.filter(e=>e.role===`user`).length<=Object.keys(e.calls).indexOf(t.callId)}export{agentCallTurns,agentToolSession,agentToolTask,conversationAuthorizations,hasPendingAuthorizations,isAgentCallContentPending,isAgentSessionCaughtUp,openConversationInputs};
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { ConversationEvent } from "#client/conversation-reducer.js";
|
|
2
|
+
import type { EveAgentReducerEvent } from "#client/reducer.js";
|
|
3
|
+
interface ProjectionReducer<TData, TEvent> {
|
|
4
|
+
initial(): TData;
|
|
5
|
+
reduce(data: TData, event: TEvent): TData;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The part of a projection that root-stream bookkeeping writes. Its entries can include the
|
|
9
|
+
* canonical conversation's agent-session events, so predicates see the wider event type.
|
|
10
|
+
*/
|
|
11
|
+
export interface EveAgentEventLog {
|
|
12
|
+
append(event: EveAgentReducerEvent): void;
|
|
13
|
+
remove(predicate: (event: ConversationEvent) => boolean): void;
|
|
14
|
+
replace(predicate: (event: ConversationEvent) => boolean, replacement: EveAgentReducerEvent): void;
|
|
15
|
+
reset(): void;
|
|
16
|
+
}
|
|
17
|
+
/** Owns chronological reducer replay when optimistic events are replaced by server events. */
|
|
18
|
+
export declare class EveAgentProjection<TData, TEvent = EveAgentReducerEvent> {
|
|
4
19
|
#private;
|
|
5
|
-
constructor(reducer:
|
|
20
|
+
constructor(reducer: ProjectionReducer<TData, TEvent>, events: readonly TEvent[]);
|
|
6
21
|
get data(): TData;
|
|
22
|
+
get reducer(): ProjectionReducer<TData, TEvent>;
|
|
7
23
|
reset(): void;
|
|
8
|
-
append(event:
|
|
9
|
-
remove(predicate: (event:
|
|
10
|
-
replace(predicate: (event:
|
|
24
|
+
append(event: TEvent): void;
|
|
25
|
+
remove(predicate: (event: TEvent) => boolean): void;
|
|
26
|
+
replace(predicate: (event: TEvent) => boolean, replacement: TEvent): void;
|
|
11
27
|
}
|
|
28
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var EveAgentProjection=class{#e;#t;#n;constructor(e,t){this.#e=e,this.#t=t,this.#n=this.#r()}get data(){return this.#n}reset(){this.#t=[],this.#n=this.#e.initial()}append(e){this.#t
|
|
1
|
+
var EveAgentProjection=class{#e;#t;#n;constructor(e,t){this.#e=e,this.#t=[...t],this.#n=this.#r()}get data(){return this.#n}get reducer(){return this.#e}reset(){this.#t=[],this.#n=this.#e.initial()}append(e){this.#t.push(e),this.#n=this.#e.reduce(this.#n,e)}remove(e){this.#t=this.#t.filter(t=>!e(t)),this.#n=this.#r()}replace(e,t){let n=this.#t.findIndex(e);n===-1?this.#t.push(t):this.#t[n]=t,this.#n=this.#r()}#r(){let e=this.#e.initial();for(let t of this.#t)e=this.#e.reduce(e,t);return e}};export{EveAgentProjection};
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
import { type ConversationState } from "#client/conversation-state.js";
|
|
1
2
|
import type { ActiveTurn } from "#client/eve-agent-store-state.js";
|
|
2
3
|
import type { CancelSessionResult, SendTurnPayload } from "#client/types.js";
|
|
3
|
-
import type
|
|
4
|
+
import { type MessageStreamEvent } from "#protocol/message.js";
|
|
4
5
|
import type { UserContent } from "ai";
|
|
5
|
-
export declare function
|
|
6
|
+
export declare function activeTurnForOptimisticFollowUp(events: readonly MessageStreamEvent[]): string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Where catch-up stops following and when an idle session counts as settled. These reads have no
|
|
9
|
+
* response to scope them, so the {@link endsTurnSegment} rule reads the whole conversation.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isResponseBoundary(event: MessageStreamEvent, conversation: ConversationState): boolean;
|
|
12
|
+
/** A turn parked on a question stays open, so its session is still streaming. */
|
|
13
|
+
export declare function settledStatus(error: Error | undefined, conversation: ConversationState): "error" | "ready" | "streaming";
|
|
14
|
+
export declare function isSettledSessionTail(events: readonly MessageStreamEvent[], conversation: ConversationState): boolean;
|
|
15
|
+
/** A server ignores answers to requests it already settled, so the store never sends them. */
|
|
16
|
+
export declare function assertAnswerable(input: SendTurnPayload, conversation: ConversationState): void;
|
|
17
|
+
export declare function assertInFlightFollowUp(input: SendTurnPayload): void;
|
|
18
|
+
export declare function validateFollowUp<T extends SendTurnPayload>(input: T): T;
|
|
6
19
|
export declare function assertExclusiveTurnInput(input: SendTurnPayload): void;
|
|
7
20
|
export declare function createSubmissionId(): string;
|
|
8
21
|
export declare function createAbortSignal(first: AbortSignal | undefined, second: AbortSignal): AbortSignal;
|
|
@@ -10,6 +23,12 @@ export declare function summarizeUserContent(message: string | UserContent): str
|
|
|
10
23
|
export declare function isAbortError(error: unknown): boolean;
|
|
11
24
|
export declare function toTerminalStreamFailureError(event: MessageStreamEvent): Error | undefined;
|
|
12
25
|
export declare function createActiveTurn(cancel: (turn: ActiveTurn) => Promise<CancelSessionResult>): ActiveTurn;
|
|
26
|
+
/** Counts confirmed steered messages toward the active turn's accepted follow-ups. */
|
|
27
|
+
export declare function countFollowUpDeliveries(turn: ActiveTurn, reconciliation: {
|
|
28
|
+
readonly alreadyProjected: boolean;
|
|
29
|
+
readonly event: MessageStreamEvent;
|
|
30
|
+
readonly ids: readonly string[];
|
|
31
|
+
}): void;
|
|
13
32
|
export declare function followSteeredTurns(turn: ActiveTurn, events: AsyncIterable<MessageStreamEvent>, isActive: () => boolean): Promise<void>;
|
|
14
33
|
/** Aborts a caller's wait without cancelling shared work owned by the store. */
|
|
15
34
|
export declare function waitWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function isAbortError(e){return e instanceof Error&&e.name===`AbortError`}function toTerminalStreamFailureError(e){if(e.type!==`session.failed`)return;let t=Error(e.data.message);return t.name=e.data.code,t}function createActiveTurn(e){let t=Promise.withResolvers(),n=Promise.withResolvers(),r={abortController:new AbortController,acceptedFollowUps:0,cancel:()=>e(r),completion:n.promise,followUpDispatches:new Set,receivedFollowUps:0,receivedFollowUpEvents:new Map,followUpSubmissionIds:new Set,resolveCompletion:n.resolve,response:t.promise,resolveResponse:t.resolve};return r}async function followSteeredTurns(e,t,n){for(;e.followUpDispatches.size>0;)await Promise.allSettled(e.followUpDispatches);if(e.receivedFollowUps>=e.acceptedFollowUps)return;let r=new
|
|
1
|
+
import{hasPendingAuthorizations}from"#client/conversation-state.js";import{TurnSegment,endsTurnSegment}from"#client/session-utils.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";function activeTurnForOptimisticFollowUp(e){let t=e.findLast(e=>e.type===`turn.started`||e.type===`turn.completed`||e.type===`turn.failed`||e.type===`turn.cancelled`||isCurrentTurnBoundaryEvent(e));return t?.type===`turn.started`?t.data.turnId:void 0}function isResponseBoundary(e,t){return endsTurnSegment(e,{callbacks:hasPendingAuthorizations(t),requests:Object.values(t.inputs).some(e=>e.status!==`settled`)})}function settledStatus(e,t){return e===void 0?t.activeTurnId===void 0?`ready`:`streaming`:`error`}function isSettledSessionTail(e,t){let n=e.at(-1);return n!==void 0&&isResponseBoundary(n,t)}function assertAnswerable(e,t){for(let{requestId:n}of e.inputResponses??[]){let e=t.inputs[n]?.status;if(e!==void 0&&e!==`open`)throw Error(`Input request ${n} was already answered.`)}}function assertInFlightFollowUp(e){if(e.inputResponses===void 0&&(e.message===void 0||e.turnPolicy!==`steer`))throw Error(`eve session is already processing a turn. Send a message with turnPolicy: "steer" to guide it at the next boundary, or answer an open input request.`)}function validateFollowUp(e){return assertExclusiveTurnInput(e),assertInFlightFollowUp(e),e}function assertExclusiveTurnInput(e){if(e.message!==void 0==(e.inputResponses!==void 0))throw Error(`A turn requires exactly one of message or inputResponses.`)}let submissionSequence=0;function createSubmissionId(){let e=globalThis.crypto?.randomUUID;return e===void 0?(submissionSequence+=1,`submission_${submissionSequence.toString()}`):e.call(globalThis.crypto)}function createAbortSignal(e,t){return e?AbortSignal.any([e,t]):t}function summarizeUserContent(e){if(typeof e==`string`)return e;let t=[];for(let n of e)n.type===`text`?t.push(n.text):n.type===`file`&&t.push(n.filename?`[file: ${n.filename}]`:`[file]`);return t.join(`
|
|
2
|
+
`)}function isAbortError(e){return e instanceof Error&&e.name===`AbortError`}function toTerminalStreamFailureError(e){if(e.type!==`session.failed`)return;let t=Error(e.data.message);return t.name=e.data.code,t}function createActiveTurn(e){let t=Promise.withResolvers(),n=Promise.withResolvers(),r={abortController:new AbortController,acceptedFollowUps:0,cancel:()=>e(r),completion:n.promise,followUpDispatches:new Set,receivedFollowUps:0,receivedFollowUpEvents:new Map,followUpSubmissionIds:new Set,resolveCompletion:n.resolve,response:t.promise,resolveResponse:t.resolve};return r}function countFollowUpDeliveries(e,t){let n=0;for(let r of t.ids)e.followUpSubmissionIds.delete(r)&&(n+=1);if(n!==0){if(t.alreadyProjected)e.receivedFollowUps+=n;else{let r=e.receivedFollowUpEvents.get(t.event)??0;e.receivedFollowUpEvents.set(t.event,r+n)}}}async function followSteeredTurns(e,t,n){for(;e.followUpDispatches.size>0;)await Promise.allSettled(e.followUpDispatches);if(e.receivedFollowUps>=e.acceptedFollowUps)return;let r=new TurnSegment({followCallbacks:!0});for await(let i of t){if(!n())return;if(e.receivedFollowUps+=e.receivedFollowUpEvents.get(i)??0,e.receivedFollowUpEvents.delete(i),r.observe(i)){for(;e.followUpDispatches.size>0;)await Promise.allSettled(e.followUpDispatches);if(e.receivedFollowUps>=e.acceptedFollowUps)return}}}async function waitWithSignal(e,t){if(t===void 0)return await e;let n=Promise.withResolvers(),onAbort=()=>n.reject(t.reason);t.addEventListener(`abort`,onAbort,{once:!0}),t.aborted&&onAbort();try{return await Promise.race([n.promise,e])}finally{t.removeEventListener(`abort`,onAbort)}}export{activeTurnForOptimisticFollowUp,assertAnswerable,assertExclusiveTurnInput,assertInFlightFollowUp,countFollowUpDeliveries,createAbortSignal,createActiveTurn,createSubmissionId,followSteeredTurns,isAbortError,isResponseBoundary,isSettledSessionTail,settledStatus,summarizeUserContent,toTerminalStreamFailureError,validateFollowUp,waitWithSignal};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { Client } from "#client/client.js";
|
|
1
2
|
import type { MessageResponse } from "#client/message-response.js";
|
|
2
3
|
import type { EveAgentReducer } from "#client/reducer.js";
|
|
4
|
+
import type { ConversationState } from "#client/conversation-state.js";
|
|
3
5
|
import type { ClientSession } from "#client/session.js";
|
|
4
6
|
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
5
7
|
import type { CancelSessionResult, ClientAuth, ClientSessionState, HeadersValue, SendTurnPayload } from "#client/types.js";
|
|
@@ -18,6 +20,8 @@ export type PrepareSend = (input: SendTurnPayload) => SendTurnPayload | Promise<
|
|
|
18
20
|
/** Immutable projected state of an eve frontend session store. */
|
|
19
21
|
export interface EveAgentStoreSnapshot<TData> {
|
|
20
22
|
readonly data: TData;
|
|
23
|
+
/** Canonical session facts, independent of the caller's data projection. */
|
|
24
|
+
readonly conversation: ConversationState;
|
|
21
25
|
/** The latest session creation, stream, resume, or turn failure. */
|
|
22
26
|
readonly error: Error | undefined;
|
|
23
27
|
readonly events: readonly MessageStreamEvent[];
|
|
@@ -36,12 +40,14 @@ export interface EveAgentStoreCallbacks<TData> {
|
|
|
36
40
|
readonly prepareSend?: PrepareSend;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
|
-
* Configuration for constructing an eve frontend session store. Pass
|
|
40
|
-
*
|
|
41
|
-
* Saved events must be an ordered prefix of the same session stream.
|
|
43
|
+
* Configuration for constructing an eve frontend session store. Pass connection
|
|
44
|
+
* options or a configured `Client` for store-owned sessions, or an existing
|
|
45
|
+
* `ClientSession`. Saved events must be an ordered prefix of the same session stream.
|
|
42
46
|
*/
|
|
43
47
|
export interface EveAgentStoreInit<TData> {
|
|
44
48
|
readonly prewarm?: boolean;
|
|
49
|
+
/** Configured client for store-owned sessions; replaces `host`, `auth`, and `headers`. */
|
|
50
|
+
readonly client?: Client;
|
|
45
51
|
readonly auth?: ClientAuth;
|
|
46
52
|
readonly headers?: HeadersValue;
|
|
47
53
|
readonly host?: string;
|
|
@@ -49,6 +55,11 @@ export interface EveAgentStoreInit<TData> {
|
|
|
49
55
|
readonly initialEvents?: readonly MessageStreamEvent[];
|
|
50
56
|
readonly initialSession?: ClientSessionState;
|
|
51
57
|
readonly optimistic?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Follow each agent tool's session into `conversation.agents`, regardless of the data reducer,
|
|
60
|
+
* while the store streams its session or a framework binding has it mounted.
|
|
61
|
+
*/
|
|
62
|
+
readonly followSubagents?: boolean;
|
|
52
63
|
readonly reducer: EveAgentReducer<TData>;
|
|
53
64
|
readonly session?: ClientSession;
|
|
54
65
|
}
|
|
@@ -57,6 +68,7 @@ export interface PendingMessageSubmission {
|
|
|
57
68
|
readonly eventStartIndex: number;
|
|
58
69
|
readonly id: string;
|
|
59
70
|
readonly message: string;
|
|
71
|
+
readonly turnId?: string;
|
|
60
72
|
readonly requiresDeliveryId: boolean;
|
|
61
73
|
readonly deliveryId?: string;
|
|
62
74
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot } from "#client/eve-agent-store-state.js";
|
|
2
|
-
import type { CancelSessionResult, SendTurnPayload } from "#client/types.js";
|
|
2
|
+
import type { CancelSessionResult, ClearResult, CompactResult, ResetResult, SendTurnPayload } from "#client/types.js";
|
|
3
3
|
export type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot, EveAgentStoreStatus, PrepareSend, } from "#client/eve-agent-store-state.js";
|
|
4
4
|
declare const detachStore: unique symbol;
|
|
5
5
|
declare const attachStore: unique symbol;
|
|
@@ -26,6 +26,15 @@ export declare class EveAgentStore<TData> {
|
|
|
26
26
|
* that turn ID. The event stream stays attached until the turn settles.
|
|
27
27
|
*/
|
|
28
28
|
cancel(): Promise<CancelSessionResult>;
|
|
29
|
+
/** Queues server-side compaction of the current session's context. */
|
|
30
|
+
compact(): Promise<CompactResult>;
|
|
31
|
+
/** Clears the current session's model-message history on the server. */
|
|
32
|
+
clear(): Promise<ClearResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Terminally retires the store-owned server session, then resets local state so the next
|
|
35
|
+
* send starts a fresh session. A failed request leaves both intact.
|
|
36
|
+
*/
|
|
37
|
+
retire(): Promise<ResetResult>;
|
|
29
38
|
[attachStore](): void;
|
|
30
39
|
[detachStore](): void;
|
|
31
40
|
reset(): void;
|