eve 0.30.7 → 0.31.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/README.md +5 -6
- package/dist/src/acp/adapter.d.ts +10 -4
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/adapter-context.d.ts +1 -1
- package/dist/src/channel/adapter.d.ts +2 -4
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-address.d.ts +58 -0
- package/dist/src/channel/channel-address.js +1 -0
- package/dist/src/channel/channel-operations.d.ts +72 -0
- package/dist/src/channel/channel-operations.js +1 -0
- package/dist/src/channel/compiled-channel.d.ts +10 -6
- package/dist/src/channel/cross-channel-receive.d.ts +13 -25
- package/dist/src/channel/cross-channel-receive.js +2 -2
- package/dist/src/channel/receive-target.d.ts +1 -2
- package/dist/src/channel/routes.d.ts +21 -149
- package/dist/src/channel/schedule.d.ts +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/send-input.d.ts +6 -0
- package/dist/src/channel/send-input.js +1 -0
- package/dist/src/channel/session.d.ts +44 -30
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +8 -35
- package/dist/src/chunks/{use-eve-agent-k-XHfrJT.js → use-eve-agent-CF5D6jSV.js} +361 -367
- package/dist/src/chunks/{use-eve-agent-BXMIf5fR.js → use-eve-agent-DbYZLG0h.js} +364 -368
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
- package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
- package/dist/src/cli/commands/info.d.ts +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/commands/registry-metadata.d.ts +15 -0
- package/dist/src/cli/commands/registry-metadata.js +1 -0
- package/dist/src/cli/commands/registry-package.d.ts +46 -0
- package/dist/src/cli/commands/registry-package.js +1 -0
- package/dist/src/cli/commands/registry.d.ts +1 -1
- package/dist/src/cli/commands/registry.js +4 -4
- package/dist/src/cli/dev/tui/runner.d.ts +1 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/invoke/invoke.d.ts +1 -1
- package/dist/src/cli/invoke/invoke.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +0 -11
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/client/client-error.d.ts +2 -0
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/client.d.ts +7 -14
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +4 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +3 -2
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +3 -0
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/message-response.d.ts +2 -7
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-controls.d.ts +29 -0
- package/dist/src/client/session-controls.js +1 -0
- package/dist/src/client/session-utils.d.ts +0 -20
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +26 -90
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +20 -0
- package/dist/src/client/sessions.js +1 -0
- package/dist/src/client/types.d.ts +26 -47
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/session.d.ts +7 -6
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +9 -9
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/runtime-errors.d.ts +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/tool-auth.d.ts +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/turn-control-receiver.d.ts +2 -2
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
- package/dist/src/harness/cancelled-turn-emission.js +1 -1
- package/dist/src/harness/emission-state.d.ts +25 -0
- package/dist/src/harness/emission-state.js +1 -0
- package/dist/src/harness/emission.d.ts +5 -37
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/handles/prompt.d.ts +22 -3
- package/dist/src/harness/handles/prompt.js +1 -1
- package/dist/src/harness/handles/store.d.ts +0 -5
- package/dist/src/harness/handles/store.js +1 -1
- package/dist/src/harness/ordered-stream-emitter.d.ts +3 -2
- package/dist/src/harness/ordered-stream-emitter.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +1 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/cancel-turn.d.ts +9 -4
- package/dist/src/protocol/cancel-turn.js +1 -1
- package/dist/src/protocol/message.d.ts +27 -17
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/reset-session.d.ts +1 -1
- package/dist/src/protocol/routes.d.ts +27 -47
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +5 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/eve.d.ts +11 -10
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/github/dispatch.d.ts +8 -8
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +4 -3
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/github/pr-context.d.ts +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/linear/linearChannel.d.ts +4 -3
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/interactions.d.ts +3 -4
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
- package/dist/src/public/channels/slack/session-operations.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +56 -74
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -3
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/callback-context.d.ts +1 -2
- package/dist/src/public/definitions/channel.d.ts +22 -86
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +1 -0
- package/dist/src/public/definitions/remote-agent.js +1 -1
- package/dist/src/public/definitions/schedule.d.ts +16 -16
- package/dist/src/public/definitions/tool.d.ts +5 -5
- package/dist/src/public/schedules/index.d.ts +1 -1
- package/dist/src/react/use-eve-agent.d.ts +7 -4
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/services/inspect-application.d.ts +1 -1
- package/dist/src/services/inspect-application.js +1 -1
- package/dist/src/setup/channel-add-conflicts.js +1 -1
- package/dist/src/setup/integrations/linear/setup.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +29 -17
- package/dist/src/shared/async-iterable.d.ts +2 -0
- package/dist/src/shared/async-iterable.js +1 -0
- package/dist/src/shared/channel-definition.d.ts +7 -7
- package/dist/src/shared/schedule-definition.d.ts +2 -2
- package/dist/src/shared/tool-definition.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -5
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -5
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/README.md +6 -6
- package/docs/channels/chat-sdk.mdx +5 -6
- package/docs/channels/custom.mdx +116 -144
- package/docs/channels/discord.mdx +1 -1
- package/docs/channels/eve.mdx +76 -30
- package/docs/channels/github.mdx +1 -1
- package/docs/channels/linear.mdx +10 -10
- package/docs/channels/overview.mdx +2 -2
- package/docs/channels/slack.mdx +46 -15
- package/docs/channels/telegram.mdx +1 -1
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/default-harness.md +11 -3
- package/docs/concepts/execution-model-and-durability.mdx +17 -5
- package/docs/concepts/sessions-runs-and-streaming.md +45 -16
- package/docs/evals/cases.mdx +3 -3
- package/docs/evals/targets.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +2 -1
- package/docs/guides/client/continuations.mdx +50 -77
- package/docs/guides/client/messages.mdx +29 -33
- package/docs/guides/client/output-schema.mdx +7 -14
- package/docs/guides/client/overview.mdx +40 -11
- package/docs/guides/client/streaming.mdx +18 -23
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +40 -36
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
- package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
- package/docs/guides/hooks.md +1 -1
- package/docs/guides/instrumentation.md +1 -1
- package/docs/install-integrations.mdx +4 -2
- package/docs/patterns/dynamic-scheduling.md +16 -15
- package/docs/reference/cli.md +4 -1
- package/docs/schedules.mdx +10 -11
- package/docs/subagents.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tools/overview.mdx +26 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/dist/src/channel/cancel.d.ts +0 -6
- package/dist/src/channel/cancel.js +0 -1
- package/dist/src/channel/clear-session.d.ts +0 -4
- package/dist/src/channel/clear-session.js +0 -1
- package/dist/src/channel/compact-session.d.ts +0 -4
- package/dist/src/channel/compact-session.js +0 -1
- package/dist/src/channel/reset-session.d.ts +0 -6
- package/dist/src/channel/reset-session.js +0 -1
- package/dist/src/channel/resolve-active-session.d.ts +0 -4
- package/dist/src/channel/resolve-active-session.js +0 -1
- package/dist/src/channel/send.d.ts +0 -6
- package/dist/src/channel/send.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const WEB_APP_TEMPLATE_FILES: {
|
|
2
2
|
readonly "agent/channels/eve.ts": 'import { eveChannel } from "eve/channels/eve";\nimport { localDev, placeholderAuth, vercelOidc } from "eve/channels/auth";\n\nexport default eveChannel({\n auth: [\n // Lets the eve TUI and your Vercel deployments reach the deployed agent.\n vercelOidc(),\n // Open on localhost for `eve dev` and the REPL; ignored in production.\n localDev(),\n // This placeholder will not allow browser requests in production.\n // Replace it with your app\'s auth provider, like Auth.js or Clerk,\n // or use none() for a public demo.\n placeholderAuth(),\n ],\n});\n';
|
|
3
|
-
readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport type { UserContent } from "ai";\nimport { Client, type MessageStreamEvent } from "eve/client";\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon } from "lucide-react";\nimport { useCallback, useRef, useState } from "react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n} from "@/components/ai-elements/conversation";\nimport {\n PromptInput,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n} from "@/components/ai-elements/prompt-input";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\ntype AgentStatus = ReturnType<typeof useEveAgent>["status"];\ntype CancellationState = "idle" | "requested" | "cancelling";\n\ntype Cancellation = {\n requested: boolean;\n sentTurnId?: string;\n turnId?: string;\n};\n\nexport function AgentChat() {\n const [
|
|
3
|
+
readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport type { UserContent } from "ai";\nimport { Client, type MessageStreamEvent } from "eve/client";\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon } from "lucide-react";\nimport { useCallback, useRef, useState } from "react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n} from "@/components/ai-elements/conversation";\nimport {\n PromptInput,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n} from "@/components/ai-elements/prompt-input";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\n\nconst AGENT_NAME = "__EVE_INIT_APP_NAME__";\n\ntype AgentStatus = ReturnType<typeof useEveAgent>["status"];\ntype CancellationState = "idle" | "requested" | "cancelling";\n\ntype Cancellation = {\n requested: boolean;\n sentTurnId?: string;\n turnId?: string;\n};\n\nexport function AgentChat() {\n const [client] = useState(() => new Client({ host: "" }));\n const sessionIdRef = useRef<string | undefined>(undefined);\n const cancellationRef = useRef<Cancellation>({ requested: false });\n const [cancellationError, setCancellationError] = useState<string>();\n const [cancellationState, setCancellationState] = useState<CancellationState>("idle");\n\n const cancelTurn = useCallback(\n (turnId: string) => {\n const cancellation = cancellationRef.current;\n if (!cancellation.requested || cancellation.sentTurnId === turnId) {\n return;\n }\n\n cancellation.sentTurnId = turnId;\n setCancellationState("cancelling");\n\n const sessionId = sessionIdRef.current;\n if (sessionId === undefined) {\n return;\n }\n\n void client.sessions\n .attach(sessionId)\n .cancel({ turnId })\n .catch((error: unknown) => {\n if (cancellationRef.current !== cancellation) {\n return;\n }\n\n cancellation.requested = false;\n cancellation.sentTurnId = undefined;\n setCancellationError(toErrorMessage(error));\n setCancellationState("idle");\n });\n },\n [client],\n );\n\n const handleEvent = useCallback(\n (event: MessageStreamEvent) => {\n if (event.type !== "turn.started") {\n return;\n }\n\n const cancellation = cancellationRef.current;\n cancellation.turnId = event.data.turnId;\n cancelTurn(event.data.turnId);\n },\n [cancelTurn],\n );\n\n const agent = useEveAgent({\n onEvent: handleEvent,\n onSessionChange(session) {\n sessionIdRef.current = session?.sessionId;\n },\n });\n const isBusy = agent.status === "submitted" || agent.status === "streaming";\n const isEmpty = agent.data.messages.length === 0;\n const errorMessage = cancellationError ?? agent.error?.message;\n const submitStatus = isBusy && cancellationState !== "idle" ? "submitted" : agent.status;\n\n const prepareTurn = () => {\n cancellationRef.current = { requested: false };\n setCancellationError(undefined);\n setCancellationState("idle");\n };\n\n const requestCancellation = () => {\n if (!isBusy || cancellationState !== "idle") {\n return;\n }\n\n const cancellation = cancellationRef.current;\n cancellation.requested = true;\n setCancellationError(undefined);\n setCancellationState("requested");\n\n if (cancellation.turnId !== undefined) {\n cancelTurn(cancellation.turnId);\n }\n };\n\n const handleSubmit = async (message: PromptInputMessage) => {\n const text = message.text.trim();\n if ((text.length === 0 && message.files.length === 0) || isBusy) return;\n\n prepareTurn();\n\n if (message.files.length === 0) {\n await agent.send(text);\n return;\n }\n\n const parts: UserContent = [];\n if (text.length > 0) {\n parts.push({ text, type: "text" });\n }\n for (const file of message.files) {\n parts.push({\n data: file.url,\n filename: file.filename,\n mediaType: file.mediaType,\n type: "file",\n });\n }\n\n await agent.send(parts);\n };\n\n const composer = (\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputTextarea placeholder="Send a message…" />\n <PromptInputSubmit onStop={requestCancellation} status={submitStatus} />\n </PromptInput>\n );\n\n return (\n <main className="flex h-dvh flex-col overflow-hidden bg-background text-foreground">\n {isEmpty ? null : (\n <header className="flex h-14 shrink-0 items-center justify-center gap-3 pl-4 pr-2">\n <span className="flex min-w-0 items-center gap-2">\n <span className="truncate text-muted-foreground text-sm">{AGENT_NAME}</span>\n <StatusDot status={agent.status} />\n </span>\n </header>\n )}\n\n {errorMessage ? (\n <div className="mx-auto w-full max-w-3xl shrink-0 px-4 pt-2 sm:px-6">\n <div className="flex items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm">\n <AlertCircleIcon className="mt-0.5 size-4 shrink-0 text-destructive" />\n <div>\n <p className="font-medium">Request failed</p>\n <p className="mt-0.5 text-muted-foreground">{errorMessage}</p>\n </div>\n </div>\n </div>\n ) : null}\n\n {isEmpty ? null : (\n <Conversation className="min-h-0 flex-1">\n <ConversationContent className="mx-auto w-full max-w-3xl gap-6 px-4 py-6 sm:px-6">\n {agent.data.messages.map((message, index) => (\n <AgentMessage\n canRespond={!isBusy}\n isStreaming={\n agent.status === "streaming" && index === agent.data.messages.length - 1\n }\n key={message.id}\n message={message}\n onInputResponses={(inputResponses) => {\n prepareTurn();\n return agent.respond(inputResponses);\n }}\n />\n ))}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n )}\n\n <div\n className={cn(\n "mx-auto w-full px-4 sm:px-6",\n isEmpty\n ? "flex max-w-xl flex-1 flex-col items-center justify-center gap-8 pb-[10vh]"\n : "max-w-3xl shrink-0 pb-6",\n )}\n >\n {isEmpty ? (\n <div className="flex flex-col items-center gap-3 text-center">\n <h1 className="font-medium text-5xl tracking-tighter">{AGENT_NAME}</h1>\n </div>\n ) : null}\n <div className="w-full">{composer}</div>\n </div>\n </main>\n );\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : "Unable to cancel the response.";\n}\n\nfunction StatusDot({ status }: { readonly status: AgentStatus }) {\n const isLive = status === "submitted" || status === "streaming";\n const tone =\n status === "error"\n ? "bg-destructive"\n : isLive\n ? "bg-emerald-500"\n : status === "ready"\n ? "bg-muted-foreground"\n : "bg-muted-foreground/50";\n\n return (\n <span className="relative flex size-1">\n {isLive ? (\n <span\n className={cn(\n "absolute inline-flex size-full animate-ping rounded-full opacity-75",\n tone,\n )}\n />\n ) : null}\n <span className={cn("relative inline-flex size-1 rounded-full transition-colors", tone)} />\n </span>\n );\n}\n';
|
|
4
4
|
readonly "app/_components/agent-message.tsx": '"use client";\n\nimport type {\n EveAuthorizationPart,\n EveDynamicToolPart,\n EveMessage,\n EveMessagePart,\n} from "eve/react";\nimport {\n CheckCircleIcon,\n ExternalLinkIcon,\n FileIcon,\n ImageIcon,\n KeyRoundIcon,\n XCircleIcon,\n} from "lucide-react";\nimport { Message, MessageContent, MessageResponse } from "@/components/ai-elements/message";\nimport { Reasoning, ReasoningContent, ReasoningTrigger } from "@/components/ai-elements/reasoning";\nimport {\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n} from "@/components/ai-elements/tool";\nimport { Button } from "@/components/ui/button";\nimport { cn } from "@/lib/utils";\n\nexport type AgentInputResponse = {\n readonly optionId?: string;\n readonly requestId: string;\n readonly text?: string;\n};\n\ntype EveFilePart = Extract<EveMessagePart, { type: "file" }>;\n\nexport function AgentMessage({\n canRespond,\n isStreaming,\n message,\n onInputResponses,\n}: {\n readonly canRespond: boolean;\n readonly isStreaming: boolean;\n readonly message: EveMessage;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n}) {\n const lastTextIndex = message.parts.reduce(\n (last, part, index) => (part.type === "text" ? index : last),\n -1,\n );\n\n return (\n <Message\n data-optimistic={message.metadata?.optimistic ? "true" : undefined}\n from={message.role}\n >\n <MessageContent>\n {message.parts.map((part, index) => (\n <AgentMessagePart\n canRespond={canRespond}\n key={partKey(part, index)}\n onInputResponses={onInputResponses}\n part={part}\n showCaret={isStreaming && message.role === "assistant" && index === lastTextIndex}\n />\n ))}\n </MessageContent>\n </Message>\n );\n}\n\nfunction AgentMessagePart({\n canRespond,\n onInputResponses,\n part,\n showCaret,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveMessagePart;\n readonly showCaret: boolean;\n}) {\n switch (part.type) {\n case "step-start":\n return null;\n case "text":\n return (\n <MessageResponse caret="block" isAnimating={showCaret}>\n {part.text}\n </MessageResponse>\n );\n case "reasoning":\n return (\n <Reasoning defaultOpen isStreaming={part.state === "streaming"}>\n <ReasoningTrigger />\n <ReasoningContent>{part.text}</ReasoningContent>\n </Reasoning>\n );\n case "file":\n return <AttachmentPart part={part} />;\n case "authorization":\n return <AuthorizationPrompt part={part} />;\n case "dynamic-tool":\n return (\n <Tool\n defaultOpen={part.state === "approval-requested" || part.state === "approval-responded"}\n >\n <ToolHeader\n state={part.state}\n title={part.toolName}\n toolName={part.toolName}\n type="dynamic-tool"\n />\n <ToolContent>\n <ToolInput input={part.input} />\n <InputRequestActions\n canRespond={canRespond}\n part={part}\n onInputResponses={onInputResponses}\n />\n <ToolOutput errorText={part.errorText} output={part.output} />\n </ToolContent>\n </Tool>\n );\n }\n}\n\nfunction AttachmentPart({ part }: { readonly part: EveFilePart }) {\n const label = part.filename ?? "Attachment";\n const detail = [part.mediaType, formatBytes(part.size)].filter(Boolean).join(" - ");\n const isImage = part.mediaType.startsWith("image/") && part.url !== undefined;\n const Icon = isImage ? ImageIcon : FileIcon;\n const body = (\n <span className="flex max-w-sm items-center gap-3 rounded-md border bg-background/60 p-2 text-sm">\n {isImage ? (\n <img alt={label} className="size-12 shrink-0 rounded-sm object-cover" src={part.url} />\n ) : (\n <span className="flex size-10 shrink-0 items-center justify-center rounded-sm bg-muted text-muted-foreground">\n <Icon className="size-4" />\n </span>\n )}\n <span className="min-w-0 flex-1">\n <span className="block truncate font-medium">{label}</span>\n {detail ? <span className="block truncate text-muted-foreground">{detail}</span> : null}\n </span>\n {part.url ? <ExternalLinkIcon className="size-4 shrink-0 text-muted-foreground" /> : null}\n </span>\n );\n\n return part.url ? (\n <a href={part.url} rel="noreferrer" target="_blank">\n {body}\n </a>\n ) : (\n body\n );\n}\n\nfunction AuthorizationPrompt({ part }: { readonly part: EveAuthorizationPart }) {\n const isAuthorized = part.state === "completed" && part.outcome === "authorized";\n const isCompleted = part.state === "completed";\n const Icon = isAuthorized ? CheckCircleIcon : isCompleted ? XCircleIcon : KeyRoundIcon;\n const instructions = part.authorization?.instructions;\n const shouldShowInstructions = instructions !== undefined && instructions !== part.description;\n\n return (\n <div\n className={cn(\n "space-y-3 rounded-md border p-3",\n isAuthorized\n ? "border-emerald-500/30 bg-emerald-500/5"\n : isCompleted\n ? "border-destructive/30 bg-destructive/5"\n : "border-blue-500/30 bg-blue-500/5",\n )}\n >\n <div className="flex items-start gap-3">\n <span\n className={cn(\n "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full",\n isAuthorized\n ? "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"\n : isCompleted\n ? "bg-destructive/10 text-destructive"\n : "bg-blue-500/10 text-blue-700 dark:text-blue-300",\n )}\n >\n <Icon className="size-4" />\n </span>\n <div className="min-w-0 flex-1 space-y-2">\n <p className="font-medium text-sm">{authorizationTitle(part)}</p>\n <p className="text-muted-foreground text-sm">{authorizationDescription(part)}</p>\n {shouldShowInstructions ? (\n <p className="text-muted-foreground text-sm">{instructions}</p>\n ) : null}\n {part.state === "required" && part.authorization?.userCode ? (\n <div className="flex flex-wrap items-center gap-2 text-sm">\n <span className="text-muted-foreground">Code</span>\n <code className="rounded-md bg-background px-2 py-1 font-mono">\n {part.authorization.userCode}\n </code>\n </div>\n ) : null}\n {part.state === "required" && part.authorization?.url ? (\n <Button asChild size="sm">\n <a href={part.authorization.url} rel="noreferrer" target="_blank">\n <ExternalLinkIcon className="size-4" />\n Sign in with {part.displayName}\n </a>\n </Button>\n ) : null}\n </div>\n </div>\n </div>\n );\n}\n\nfunction authorizationTitle(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return `Connect ${part.displayName}`;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected`;\n }\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}`;\n}\n\nfunction authorizationDescription(part: EveAuthorizationPart): string {\n if (part.state === "required") {\n return part.description;\n }\n if (part.outcome === "authorized") {\n return `${part.displayName} connected.`;\n }\n const tail = part.reason !== undefined ? ` (${part.reason})` : "";\n return `${part.displayName} authorization ${formatAuthorizationOutcome(part.outcome)}${tail}.`;\n}\n\nfunction formatAuthorizationOutcome(outcome: NonNullable<EveAuthorizationPart["outcome"]>): string {\n switch (outcome) {\n case "authorized":\n return "authorized";\n case "declined":\n return "declined";\n case "failed":\n return "failed";\n case "timed-out":\n return "timed out";\n }\n}\n\nfunction formatBytes(size: number | undefined): string | undefined {\n if (size === undefined) {\n return undefined;\n }\n if (size < 1024) {\n return `${size} B`;\n }\n if (size < 1024 * 1024) {\n return `${(size / 1024).toFixed(1)} KB`;\n }\n return `${(size / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction InputRequestActions({\n canRespond,\n onInputResponses,\n part,\n}: {\n readonly canRespond: boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveDynamicToolPart;\n}) {\n const inputRequest = part.toolMetadata?.eve?.inputRequest;\n if (!inputRequest) {\n return null;\n }\n\n const inputResponse = part.toolMetadata?.eve?.inputResponse;\n const selectedOption = inputRequest.options?.find(\n (option) => option.id === inputResponse?.optionId,\n );\n\n return (\n <div className="space-y-3 rounded-md border border-yellow-500/30 bg-yellow-500/5 p-3">\n <p className="text-muted-foreground text-sm">{inputRequest.prompt}</p>\n {inputResponse ? (\n <p className="font-medium text-sm">\n Responded: {selectedOption?.label ?? inputResponse.text ?? inputResponse.optionId}\n </p>\n ) : (\n <div className="flex flex-wrap gap-2">\n {inputRequest.options?.map((option) => (\n <Button\n disabled={!canRespond}\n key={option.id}\n onClick={() => {\n void onInputResponses([\n {\n optionId: option.id,\n requestId: inputRequest.requestId,\n },\n ]);\n }}\n size="sm"\n type="button"\n variant={option.style === "danger" ? "destructive" : "default"}\n >\n {option.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction partKey(part: EveMessagePart, index: number): string {\n switch (part.type) {\n case "authorization":\n return `authorization:${part.turnId}:${part.stepIndex}:${part.name}`;\n case "dynamic-tool":\n return part.toolCallId;\n default:\n return `${part.type}:${index}`;\n }\n}\n';
|
|
5
5
|
readonly "app/globals.css": '@import "tailwindcss";\n@source "../node_modules/streamdown/dist/*.js";\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n --font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;\n --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;\n}\n\n:root {\n color-scheme: light;\n /* Soft neutral page with white elevated surfaces so cards/composer pop. */\n --background: oklch(0.971 0 0);\n --foreground: oklch(0.16 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.16 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.16 0 0);\n --primary: oklch(0.19 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.94 0 0);\n --secondary-foreground: oklch(0.19 0 0);\n --muted: oklch(0.94 0 0);\n --muted-foreground: oklch(0.6 0 0);\n --accent: oklch(0.94 0 0);\n --accent-foreground: oklch(0.19 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.916 0 0);\n --input: oklch(0.916 0 0);\n --ring: oklch(0.708 0 0);\n --radius: 0.625rem;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n color-scheme: dark;\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n }\n}\n\n* {\n border-color: var(--border);\n}\n\nhtml {\n height: 100%;\n}\n\nbody {\n min-height: 100%;\n margin: 0;\n background: var(--background);\n font-family: var(--font-sans);\n}\n\nbutton,\ninput,\ntextarea {\n font: inherit;\n}\n';
|
|
6
6
|
readonly "app/layout.tsx": 'import type { Metadata } from "next";\nimport { Geist, Geist_Mono } from "next/font/google";\nimport type { ReactNode } from "react";\nimport { TooltipProvider } from "@/components/ui/tooltip";\nimport { cn } from "@/lib/utils";\nimport "./globals.css";\n\nconst sans = Geist({\n variable: "--font-sans",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nconst mono = Geist_Mono({\n variable: "--font-mono",\n subsets: ["latin"],\n weight: "variable",\n display: "swap",\n});\n\nexport const metadata: Metadata = {\n title: "__EVE_INIT_APP_NAME__",\n description: "A Next.js starter for eve agents with AI Elements.",\n};\n\nexport default function RootLayout({ children }: { readonly children: ReactNode }) {\n return (\n <html className={cn(sans.variable, mono.variable)} lang="en">\n <body>\n <TooltipProvider>{children}</TooltipProvider>\n </body>\n </html>\n );\n}\n';
|
|
@@ -46,9 +46,8 @@ type Cancellation = {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export function AgentChat() {
|
|
49
|
-
const [
|
|
50
|
-
|
|
51
|
-
);
|
|
49
|
+
const [client] = useState(() => new Client({ host: "" }));
|
|
50
|
+
const sessionIdRef = useRef<string | undefined>(undefined);
|
|
52
51
|
const cancellationRef = useRef<Cancellation>({ requested: false });
|
|
53
52
|
const [cancellationError, setCancellationError] = useState<string>();
|
|
54
53
|
const [cancellationState, setCancellationState] = useState<CancellationState>("idle");
|
|
@@ -63,18 +62,26 @@ export function AgentChat() {
|
|
|
63
62
|
cancellation.sentTurnId = turnId;
|
|
64
63
|
setCancellationState("cancelling");
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
const sessionId = sessionIdRef.current;
|
|
66
|
+
if (sessionId === undefined) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
void client.sessions
|
|
71
|
+
.attach(sessionId)
|
|
72
|
+
.cancel({ turnId })
|
|
73
|
+
.catch((error: unknown) => {
|
|
74
|
+
if (cancellationRef.current !== cancellation) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
cancellation.requested = false;
|
|
79
|
+
cancellation.sentTurnId = undefined;
|
|
80
|
+
setCancellationError(toErrorMessage(error));
|
|
81
|
+
setCancellationState("idle");
|
|
82
|
+
});
|
|
76
83
|
},
|
|
77
|
-
[
|
|
84
|
+
[client],
|
|
78
85
|
);
|
|
79
86
|
|
|
80
87
|
const handleEvent = useCallback(
|
|
@@ -90,7 +97,12 @@ export function AgentChat() {
|
|
|
90
97
|
[cancelTurn],
|
|
91
98
|
);
|
|
92
99
|
|
|
93
|
-
const agent = useEveAgent({
|
|
100
|
+
const agent = useEveAgent({
|
|
101
|
+
onEvent: handleEvent,
|
|
102
|
+
onSessionChange(session) {
|
|
103
|
+
sessionIdRef.current = session?.sessionId;
|
|
104
|
+
},
|
|
105
|
+
});
|
|
94
106
|
const isBusy = agent.status === "submitted" || agent.status === "streaming";
|
|
95
107
|
const isEmpty = agent.data.messages.length === 0;
|
|
96
108
|
const errorMessage = cancellationError ?? agent.error?.message;
|
|
@@ -124,7 +136,7 @@ export function AgentChat() {
|
|
|
124
136
|
prepareTurn();
|
|
125
137
|
|
|
126
138
|
if (message.files.length === 0) {
|
|
127
|
-
await agent.send(
|
|
139
|
+
await agent.send(text);
|
|
128
140
|
return;
|
|
129
141
|
}
|
|
130
142
|
|
|
@@ -141,7 +153,7 @@ export function AgentChat() {
|
|
|
141
153
|
});
|
|
142
154
|
}
|
|
143
155
|
|
|
144
|
-
await agent.send(
|
|
156
|
+
await agent.send(parts);
|
|
145
157
|
};
|
|
146
158
|
|
|
147
159
|
const composer = (
|
|
@@ -187,7 +199,7 @@ export function AgentChat() {
|
|
|
187
199
|
message={message}
|
|
188
200
|
onInputResponses={(inputResponses) => {
|
|
189
201
|
prepareTurn();
|
|
190
|
-
return agent.
|
|
202
|
+
return agent.respond(inputResponses);
|
|
191
203
|
}}
|
|
192
204
|
/>
|
|
193
205
|
))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function isAsyncIterable(e){return typeof e==`object`&&!!e&&Symbol.asyncIterator in e&&typeof e[Symbol.asyncIterator]==`function`}export{isAsyncIterable};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type ChannelCors } from "#channel/cors.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { UserContent } from "ai";
|
|
3
|
+
import type { ChannelReceiveContext } from "#channel/channel-operations.js";
|
|
4
|
+
import type { RouteDefinition } from "#channel/routes.js";
|
|
3
5
|
import type { Session, SessionHandle } from "#channel/session.js";
|
|
4
6
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
5
7
|
/**
|
|
@@ -22,7 +24,7 @@ export type FetchFileFunction = (url: string) => Promise<Buffer | FetchFileResul
|
|
|
22
24
|
* schedule proactively routes a message to it.
|
|
23
25
|
*/
|
|
24
26
|
export interface GenericReceiveInput<TReceiveTarget = Record<string, unknown>> {
|
|
25
|
-
readonly message: string;
|
|
27
|
+
readonly message: string | UserContent;
|
|
26
28
|
readonly target: Readonly<TReceiveTarget>;
|
|
27
29
|
readonly auth: SessionAuthContext | null;
|
|
28
30
|
}
|
|
@@ -54,14 +56,12 @@ export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = vo
|
|
|
54
56
|
*
|
|
55
57
|
* Return the channel-owned context (thread handles, API clients, etc.). The
|
|
56
58
|
* framework passes it as the `channel` argument to event handlers (with
|
|
57
|
-
* {@link
|
|
58
|
-
* separate `ctx` argument.
|
|
59
|
+
* {@link ChannelContinuationOps} injected) and passes {@link SessionContext}
|
|
60
|
+
* as a separate `ctx` argument.
|
|
59
61
|
*/
|
|
60
62
|
context?(state: NonNullable<TState>, session: SessionHandle): TCtx;
|
|
61
63
|
readonly routes: readonly RouteDefinition<TState>[];
|
|
62
|
-
receive?(input: GenericReceiveInput<TReceiveTarget>,
|
|
63
|
-
send: SendFn<TState>;
|
|
64
|
-
}): Promise<Session>;
|
|
64
|
+
receive?(input: GenericReceiveInput<TReceiveTarget>, ctx: ChannelReceiveContext<TState>): Promise<Session>;
|
|
65
65
|
readonly events?: TEvents;
|
|
66
66
|
/**
|
|
67
67
|
* Fetches bytes for a `URL` object encountered on a `FilePart.data` by the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The `run` form of {@link ScheduleDefinition} invokes this handler when a
|
|
3
|
-
* schedule's cron fires. It receives {@link ScheduleHandlerArgs} (`
|
|
3
|
+
* schedule's cron fires. It receives {@link ScheduleHandlerArgs} (`to`,
|
|
4
4
|
* `waitUntil`, `appAuth`) and may return synchronously or as a promise.
|
|
5
5
|
*/
|
|
6
6
|
export type GenericScheduleRunHandler<TArgs> = (args: TArgs) => Promise<void> | void;
|
|
@@ -18,7 +18,7 @@ export interface GenericScheduleDefinitionFields<TArgs> {
|
|
|
18
18
|
* on the prompt and discards the output (equivalent to the `<name>.md`
|
|
19
19
|
* markdown form).
|
|
20
20
|
* - `run`: full handler ({@link GenericScheduleRunHandler}). Receives
|
|
21
|
-
* `{
|
|
21
|
+
* `{ to, waitUntil, appAuth }` and decides what to do.
|
|
22
22
|
*
|
|
23
23
|
* Identity is derived from the file path under `agent/schedules/`; authored
|
|
24
24
|
* definitions do not carry a `name` field.
|
|
@@ -6,7 +6,7 @@ import type { JsonObject } from "#shared/json.js";
|
|
|
6
6
|
* function. These are the same options the SDK passes to every tool call.
|
|
7
7
|
*/
|
|
8
8
|
export type ToolExecuteOptions = Omit<ToolExecutionOptions<unknown>, "context">;
|
|
9
|
-
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput
|
|
9
|
+
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
|
|
10
10
|
interface ToolDefinitionBase {
|
|
11
11
|
readonly description: string;
|
|
12
12
|
}
|
package/dist/src/svelte/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { UserContent } from "ai";
|
|
1
2
|
import { type EveAgentStoreCallbacks, type EveAgentStoreSnapshot, type EveAgentStoreStatus, type PrepareSend } from "#client/eve-agent-store.js";
|
|
2
3
|
import { type EveMessageData } from "#client/message-reducer.js";
|
|
3
4
|
import type { EveAgentReducer } from "#client/reducer.js";
|
|
4
5
|
import type { ClientSession } from "#client/session.js";
|
|
5
|
-
import type { ClientAuth, HeadersValue,
|
|
6
|
+
import type { ClientAuth, HeadersValue, RespondTurnOptions, SendTurnOptions, ClientSessionState } from "#client/types.js";
|
|
6
7
|
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
7
8
|
export type { PrepareSend };
|
|
8
9
|
/**
|
|
@@ -33,10 +34,12 @@ export interface UseEveAgentReturn<TData> {
|
|
|
33
34
|
readonly events: readonly MessageStreamEvent[];
|
|
34
35
|
/** Clear all state and start a new session. */
|
|
35
36
|
readonly reset: () => void;
|
|
36
|
-
/** Send a
|
|
37
|
-
readonly send: <TOutput = unknown>(
|
|
37
|
+
/** Send a message with optional turn settings. */
|
|
38
|
+
readonly send: <TOutput = unknown>(message: string | UserContent, options?: SendTurnOptions<TOutput>) => Promise<void>;
|
|
39
|
+
/** Answer pending HITL input requests. */
|
|
40
|
+
readonly respond: <TOutput = unknown>(inputResponses: Parameters<ClientSession["respond"]>[0], options?: RespondTurnOptions<TOutput>) => Promise<void>;
|
|
38
41
|
/** Current session identity and stream cursor. */
|
|
39
|
-
readonly session:
|
|
42
|
+
readonly session: ClientSessionState | undefined;
|
|
40
43
|
/** Lifecycle phase: `"ready"` (idle), `"submitted"` (request sent, awaiting first event), `"streaming"` (events arriving), or `"error"`. */
|
|
41
44
|
readonly status: UseEveAgentStatus;
|
|
42
45
|
/** Abort the in-flight request. */
|
|
@@ -79,7 +82,7 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
|
|
|
79
82
|
/** Ordered prefix of the session stream used to rehydrate projected state. */
|
|
80
83
|
readonly initialEvents?: readonly MessageStreamEvent[];
|
|
81
84
|
/** Seed session identity and stream cursor for resuming a prior conversation. */
|
|
82
|
-
readonly initialSession?:
|
|
85
|
+
readonly initialSession?: ClientSessionState;
|
|
83
86
|
/**
|
|
84
87
|
* Project submitted user messages before eve confirms them with a
|
|
85
88
|
* `message.received` stream event. Optimistic events are reducer-facing
|
package/dist/src/vue/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type ComputedRef } from "vue";
|
|
2
|
+
import type { UserContent } from "ai";
|
|
2
3
|
import { type EveAgentStoreCallbacks, type EveAgentStoreSnapshot, type EveAgentStoreStatus, type PrepareSend } from "#client/eve-agent-store.js";
|
|
3
4
|
import type { EveAgentReducer } from "#client/reducer.js";
|
|
4
5
|
import type { ClientSession } from "#client/session.js";
|
|
5
6
|
import { type EveMessageData } from "#client/message-reducer.js";
|
|
6
7
|
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
7
|
-
import type { ClientAuth, HeadersValue,
|
|
8
|
+
import type { ClientAuth, HeadersValue, RespondTurnOptions, SendTurnOptions, ClientSessionState } from "#client/types.js";
|
|
8
9
|
export type { PrepareSend };
|
|
9
10
|
/**
|
|
10
11
|
* Lifecycle phase of a `useEveAgent` session: `"ready"` (idle), `"submitted"`
|
|
@@ -32,10 +33,12 @@ export interface UseEveAgentReturn<TData> {
|
|
|
32
33
|
readonly events: ComputedRef<readonly MessageStreamEvent[]>;
|
|
33
34
|
/** Clear all state and start a new session. */
|
|
34
35
|
readonly reset: () => void;
|
|
35
|
-
/** Send a
|
|
36
|
-
readonly send: <TOutput = unknown>(
|
|
36
|
+
/** Send a message with optional turn settings. */
|
|
37
|
+
readonly send: <TOutput = unknown>(message: string | UserContent, options?: SendTurnOptions<TOutput>) => Promise<void>;
|
|
38
|
+
/** Answer pending HITL input requests. */
|
|
39
|
+
readonly respond: <TOutput = unknown>(inputResponses: Parameters<ClientSession["respond"]>[0], options?: RespondTurnOptions<TOutput>) => Promise<void>;
|
|
37
40
|
/** Current session identity and stream cursor. */
|
|
38
|
-
readonly session: ComputedRef<
|
|
41
|
+
readonly session: ComputedRef<ClientSessionState | undefined>;
|
|
39
42
|
/** Lifecycle phase: `"ready"` (idle), `"submitted"` (request sent, awaiting first event), `"streaming"` (events arriving), or `"error"`. */
|
|
40
43
|
readonly status: ComputedRef<UseEveAgentStatus>;
|
|
41
44
|
/** Abort the in-flight request. */
|
|
@@ -78,7 +81,7 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
|
|
|
78
81
|
/** Ordered prefix of the session stream used to rehydrate projected state. */
|
|
79
82
|
readonly initialEvents?: readonly MessageStreamEvent[];
|
|
80
83
|
/** Prior session cursor to resume from on mount. */
|
|
81
|
-
readonly initialSession?:
|
|
84
|
+
readonly initialSession?: ClientSessionState;
|
|
82
85
|
/**
|
|
83
86
|
* Project submitted user messages before eve confirms them with a
|
|
84
87
|
* `message.received` stream event.
|
package/docs/README.md
CHANGED
|
@@ -86,21 +86,21 @@ eve then gives you:
|
|
|
86
86
|
The public surface stays filesystem-first, but the implementation model underneath is still useful to
|
|
87
87
|
know:
|
|
88
88
|
|
|
89
|
-
- channels normalize inbound transport input and
|
|
89
|
+
- channels normalize inbound transport input and map platform addresses to sessions
|
|
90
90
|
- the harness does one unit of AI work and decides whether to continue, wait, or finish
|
|
91
91
|
- the runtime persists session state, streams events, and owns workflow orchestration
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
The default HTTP API exposes one durable `sessionId` for messages, controls, and
|
|
94
|
+
streaming. Platform channels additionally own channel-local continuation
|
|
95
|
+
addresses so a Slack thread or custom conversation ID can point at its current
|
|
96
|
+
session without leaking that routing identity into the HTTP client contract.
|
|
97
97
|
|
|
98
98
|
## How to use these docs
|
|
99
99
|
|
|
100
100
|
- Start with the authored filesystem shape and `agent.ts`.
|
|
101
101
|
- Then add runtime surfaces in this order: skills, tools, workspace, sandbox, channels.
|
|
102
102
|
- Then learn the durable runtime model: HITL, session context, sessions, streaming, and
|
|
103
|
-
|
|
103
|
+
ID-addressed follow-ups and channel address routing.
|
|
104
104
|
- Then add advanced features: subagents, schedules, route protection, deployment.
|
|
105
105
|
|
|
106
106
|
## Good companions in this repo
|
|
@@ -177,14 +177,13 @@ chatSdkChannel({
|
|
|
177
177
|
|
|
178
178
|
### Proactive sessions
|
|
179
179
|
|
|
180
|
-
Start a session without an inbound webhook through `channel.
|
|
180
|
+
Start a session without an inbound webhook through `to(channel, target).send(message, { auth })` from a schedule `run` handler, or `ctx.to(channel, target).send(message, { auth })` from another channel. The target is a serialized Chat SDK thread, or `{ threadId, adapterName }` when you only have a provider-native thread id:
|
|
181
181
|
|
|
182
182
|
```ts
|
|
183
|
-
await channel.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
});
|
|
183
|
+
await to(channel, { adapterName: "resend", threadId: "resend:user@example.com" }).send(
|
|
184
|
+
"Your weekly digest is ready.",
|
|
185
|
+
{ auth: null },
|
|
186
|
+
);
|
|
188
187
|
```
|
|
189
188
|
|
|
190
189
|
### Attachments
|