eve 0.79.0 → 0.79.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/dist/src/channel/pending-authorization.d.ts +10 -0
- package/dist/src/channel/pending-authorization.js +1 -0
- package/dist/src/chunks/{use-eve-agent-BSYe_Re7.js → use-eve-agent-Ch-Q-s12.js} +43 -13
- package/dist/src/chunks/{use-eve-agent-B8brxCk-.js → use-eve-agent-Vsl-S0yI.js} +43 -13
- package/dist/src/client/abort-signal.d.ts +2 -0
- package/dist/src/client/abort-signal.js +1 -0
- package/dist/src/client/conversation-client.d.ts +2 -0
- package/dist/src/client/conversation-client.js +1 -1
- package/dist/src/client/eve-agent-store-state.d.ts +9 -0
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/ndjson.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-turn-dispatch.js +1 -1
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@eve/tracing/adapters/serialization.d.ts +2 -2
- package/dist/src/compiled/@eve/tracing/core/types.d.ts +6 -1
- package/dist/src/compiled/@eve/tracing/index.js +1 -1
- package/dist/src/compiled/@eve/tracing/otel.js +1 -1
- package/dist/src/compiled/_chunks/workflow/mcp-Bwx_LQ4q.js +5 -0
- package/dist/src/compiler/extension-compatibility.d.ts +18 -18
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/project-sources.js +1 -1
- package/dist/src/context/memory-tools.js +1 -1
- package/dist/src/evals/runner/reporters/assertion-scores.d.ts +6 -4
- package/dist/src/evals/runner/reporters/assertion-scores.js +1 -1
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/execution/authorization-callback-match.d.ts +2 -2
- package/dist/src/execution/authorization-callback-match.js +1 -1
- package/dist/src/execution/durable-session-store.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/forward-session-input.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/publish-session-events.d.ts +26 -5
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-create-sdk.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +2 -0
- package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lookup.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +3 -6
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session/active-turn.d.ts +2 -1
- package/dist/src/execution/session/active-turn.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -1
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/input-queue.d.ts +13 -6
- package/dist/src/execution/session/input-queue.js +1 -1
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +5 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/tasks/steps.d.ts +1 -1
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/tasks/task-id-input.js +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/answer.d.ts +1 -1
- package/dist/src/execution/tools/workflow/apply-run-messages-step.d.ts +6 -2
- package/dist/src/execution/tools/workflow/apply-run-messages-step.js +1 -1
- package/dist/src/execution/tools/workflow/body.d.ts +10 -1
- package/dist/src/execution/tools/workflow/body.js +1 -1
- package/dist/src/execution/tools/workflow/owner-inbox.js +1 -1
- package/dist/src/execution/tools/workflow/serve.js +1 -1
- package/dist/src/execution/tools/workflow/withdraw-step.d.ts +2 -2
- package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
- package/dist/src/execution/workflow-callback-url.d.ts +10 -1
- package/dist/src/execution/workflow-callback-url.js +1 -1
- package/dist/src/harness/action-result-helpers.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/authorization.d.ts +3 -13
- package/dist/src/harness/authorization.js +1 -1
- package/dist/src/harness/compaction/engine.js +3 -1
- package/dist/src/harness/compaction/prompt.d.ts +7 -0
- package/dist/src/harness/compaction/prompt.js +1 -1
- package/dist/src/harness/compaction/step.d.ts +1 -0
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/coordination.js +1 -1
- package/dist/src/harness/hitl/approvals.d.ts +1 -1
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +3 -0
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/candidates.d.ts +13 -0
- package/dist/src/harness/hitl/candidates.js +1 -1
- package/dist/src/harness/hitl/coordinator.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +2 -5
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/{proxy-input-requests.d.ts → hitl/relays.d.ts} +3 -39
- package/dist/src/harness/hitl/relays.js +1 -0
- package/dist/src/harness/hitl/requests.d.ts +64 -0
- package/dist/src/harness/hitl/requests.js +1 -0
- package/dist/src/harness/hitl/sign-ins.d.ts +9 -0
- package/dist/src/harness/hitl/sign-ins.js +1 -0
- package/dist/src/harness/inline-tool-authorization.js +1 -1
- package/dist/src/harness/input-request-resolution.d.ts +2 -1
- package/dist/src/harness/input-request-resolution.js +1 -1
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/model.d.ts +3 -1
- package/dist/src/harness/model-call/model.js +1 -1
- package/dist/src/harness/session-machine/commit.d.ts +14 -3
- package/dist/src/harness/session-machine/commit.js +1 -1
- package/dist/src/harness/session-machine/transitions.d.ts +16 -0
- package/dist/src/harness/session-machine/transitions.js +1 -1
- package/dist/src/instrumentation/native-events.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +1 -0
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/internal/application/optional-package-import.d.ts +5 -0
- package/dist/src/internal/application/optional-package-import.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/authored-definition/source-identity.d.ts +6 -0
- package/dist/src/internal/authored-definition/source-identity.js +1 -1
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/helpers/markdown.js +1 -1
- package/dist/src/internal/nitro/host/start-production-server.js +2 -2
- package/dist/src/internal/workflow/is-inactive-workflow-run-error.d.ts +2 -0
- package/dist/src/internal/workflow/is-inactive-workflow-run-error.js +1 -1
- package/dist/src/protocol/baggage.d.ts +1 -0
- package/dist/src/protocol/baggage.js +1 -1
- package/dist/src/protocol/message.d.ts +2 -0
- package/dist/src/protocol/message.js +1 -1
- package/dist/src/public/channels/teams/authorization.d.ts +53 -0
- package/dist/src/public/channels/teams/authorization.js +1 -0
- package/dist/src/public/channels/teams/defaults.js +2 -2
- package/dist/src/public/channels/teams/hitl.d.ts +2 -1
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/authorization-callback.js +1 -1
- package/dist/src/public/definitions/connections/mcp.js +1 -1
- package/dist/src/public/definitions/connections/openapi.js +1 -1
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +11 -2
- package/dist/src/public/next/server.js +1 -1
- package/dist/src/public/sandbox/vercel.d.ts +2 -0
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/public/tools/result.d.ts +10 -7
- package/dist/src/react/use-eve-agent.d.ts +6 -0
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/authorization-context.d.ts +5 -0
- package/dist/src/runtime/authorization-context.js +1 -1
- package/dist/src/runtime/connections/mcp-tracing.js +1 -1
- package/dist/src/runtime/connections/openapi-operations.js +1 -1
- package/dist/src/runtime/connections/scoped-authorization.d.ts +6 -0
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/runtime/resolve-connection.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 +18 -10
- package/dist/src/shared/action-types.d.ts +1 -0
- package/dist/src/shared/action-types.js +1 -1
- package/dist/src/shared/git.js +1 -1
- package/dist/src/shared/instrumentation-content.d.ts +1 -1
- package/dist/src/shared/instrumentation-content.js +1 -1
- package/dist/src/shared/instrumentation-decision.d.ts +3 -0
- package/dist/src/shared/instrumentation-decision.js +1 -1
- package/dist/src/shared/skill-package.js +1 -1
- package/dist/src/shared/trace-policy.js +1 -1
- package/dist/src/subagents/adapter.js +1 -1
- package/dist/src/subagents/event-proxy-step.d.ts +1 -1
- package/dist/src/subagents/event-proxy-step.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +1 -1
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +6 -0
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/definition.d.ts +38 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tools/signature.d.ts +4 -2
- package/dist/src/tools/signature.js +1 -1
- package/dist/src/tracing/eve/agent-otel-provider.js +1 -1
- package/dist/src/tracing/eve/gateway.d.ts +2 -1
- package/dist/src/tracing/eve/gateway.js +1 -1
- package/dist/src/tracing/eve/invoke-tool-span.js +1 -1
- package/dist/src/tracing/eve/otel-declaration.d.ts +9 -8
- package/dist/src/tracing/eve/policy.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +6 -0
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +48 -0
- package/docs/channels/eve.mdx +2 -0
- package/docs/channels/teams.mdx +6 -0
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/connections/overview.mdx +9 -6
- package/docs/guides/frontend/overview.mdx +10 -1
- package/docs/guides/hooks.md +6 -2
- package/docs/guides/instrumentation/instrumentation.mdx +2 -0
- package/docs/guides/instrumentation/otel.mdx +3 -0
- package/docs/reference/cli.md +1 -1
- package/docs/reference/typescript-api.md +7 -6
- package/docs/sandbox/vercel.mdx +9 -0
- package/docs/skills.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +21 -0
- package/package.json +1 -1
- package/dist/src/compiled/_chunks/workflow/mcp-CrGp4EC8.js +0 -5
- package/dist/src/harness/proxy-input-requests.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const WEB_APP_TEMPLATE_FILES: {
|
|
2
|
-
readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport type { UserContent } from "ai";\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon, BrainIcon, PlusIcon, SquareIcon } from "lucide-react";\nimport { useState } from "react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n ConversationTopFade,\n} from "@/components/ai-elements/conversation";\nimport { Message, MessageContent } from "@/components/ai-elements/message";\nimport {\n PromptInput,\n PromptInputButton,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n usePromptInputAttachments,\n} from "@/components/ai-elements/prompt-input";\nimport { Shimmer } from "@/components/ai-elements/shimmer";\nimport { Button } from "@/components/ui/button";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\nimport { WEB_CHAT_AGENT } from "@/app/eve-agent";\n\nconst DEFAULT_AGENT_NAME = "__EVE_INIT_APP_NAME__";\nconst AGENT_NAME = WEB_CHAT_AGENT ?? DEFAULT_AGENT_NAME;\n\nexport function AgentChat({\n sessionId,\n sessionless = false,\n}: {\n readonly sessionId?: string;\n readonly sessionless?: boolean;\n}) {\n const [cancellationError, setCancellationError] = useState<string>();\n const [hasInputText, setHasInputText] = useState(false);\n const agent = useEveAgent({\n agent: WEB_CHAT_AGENT,\n initialSession:\n sessionId === undefined\n ? undefined\n : {\n sessionId,\n streamIndex: 0,\n },\n resume: sessionId !== undefined,\n onSessionChange(session) {\n if (sessionId === undefined && session !== undefined) {\n // Framework routers (Next.js, TanStack Router) patch window.history; navigating\n // through them would remount this route and detach the active stream.\n History.prototype.replaceState.call(\n window.history,\n window.history.state,\n "",\n `/s/${encodeURIComponent(session.sessionId)}`,\n );\n }\n },\n });\n\n const isBusy = agent.status === "submitted" || agent.status === "streaming";\n const isResuming = agent.status === "resuming";\n const isEmpty = agent.data.messages.length === 0;\n const lastMessage = agent.data.messages.at(-1);\n const isPendingAssistantShell =\n lastMessage?.role === "assistant" &&\n lastMessage.parts.every((part) => part.type === "step-start");\n const showPendingThinking =\n isBusy &&\n (agent.status === "submitted" || lastMessage?.role !== "assistant" || isPendingAssistantShell);\n const turnFailure = isBusy || isResuming ? undefined : getLatestTurnFailure(agent.events);\n const errorMessage = cancellationError ?? agent.error?.message ?? turnFailure;\n const hasConversationContent = sessionless || !isEmpty || errorMessage !== undefined;\n const showConversationLayout = isResuming || hasConversationContent;\n const activeSessionId = sessionId ?? agent.session?.sessionId;\n // Answers are accepted while work runs; the server\'s settlement closes each request.\n const canRespond = (requestId: string) =>\n !isResuming && agent.data.inputs[requestId]?.status === "open";\n // A tool call can ask several questions at once, and its message part holds only the latest.\n const questionsFor = (callId: string) =>\n Object.values(agent.data.inputs).filter(\n (input) => input.request.kind === "question" && input.request.action.callId === callId,\n );\n\n const requestCancellation = () => {\n setCancellationError(undefined);\n void agent.cancel().catch((error: unknown) => {\n setCancellationError(toErrorMessage(error));\n });\n };\n\n const handleSubmit = async (message: PromptInputMessage) => {\n const text = message.text.trim();\n if ((text.length === 0 && message.files.length === 0) || isResuming) return;\n\n setHasInputText(false);\n setCancellationError(undefined);\n const options = isBusy ? { turnPolicy: "steer" as const } : undefined;\n\n if (message.files.length === 0) {\n await agent.send(text, options);\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, options);\n };\n\n const composer = (\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputTextarea\n disabled={isResuming}\n onChange={(event) => setHasInputText(event.currentTarget.value.trim().length > 0)}\n placeholder="Send a message…"\n />\n <ComposerAction\n hasInputText={hasInputText}\n isBusy={isBusy}\n isResuming={isResuming}\n onCancel={requestCancellation}\n />\n </PromptInput>\n );\n\n return (\n <main className="flex h-dvh flex-col overflow-hidden bg-background text-foreground">\n {showConversationLayout ? (\n <ChatHeader canStartNewChat={activeSessionId !== undefined} />\n ) : null}\n\n {showConversationLayout ? (\n <Conversation\n className="min-h-0 flex-1"\n initial={sessionId === undefined ? undefined : false}\n resize={activeSessionId === undefined ? "smooth" : "instant"}\n scrollRestorationKey={\n isEmpty || activeSessionId === undefined\n ? undefined\n : `eve:web-chat-scroll:${activeSessionId}`\n }\n >\n <ConversationTopFade className="top-14" />\n <ConversationContent className="mx-auto w-full max-w-3xl gap-6 px-4 pt-20 pb-36 sm:px-6">\n {agent.data.messages.map((message, index) =>\n showPendingThinking &&\n isPendingAssistantShell &&\n message.id === lastMessage.id ? null : (\n <AgentMessage\n canRespond={canRespond}\n isStreaming={\n agent.status === "streaming" && index === agent.data.messages.length - 1\n }\n key={message.id}\n message={message}\n questionsFor={questionsFor}\n onInputResponses={(inputResponses) => {\n setCancellationError(undefined);\n return agent.respond(inputResponses);\n }}\n />\n ),\n )}\n {showPendingThinking ? <PendingThinking /> : null}\n {errorMessage ? <ErrorMessage message={errorMessage} /> : null}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n ) : null}\n\n <div\n className={cn(\n "mx-auto w-full px-4 sm:px-6",\n showConversationLayout\n ? "fixed bottom-0 left-1/2 z-20 max-w-3xl -translate-x-1/2 bg-gradient-to-t from-background via-background to-transparent pt-4 pb-6"\n : "flex max-w-xl flex-1 flex-col items-center justify-center gap-8 pb-[10vh]",\n )}\n >\n {showConversationLayout ? null : (\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 )}\n <div className="w-full">{composer}</div>\n </div>\n </main>\n );\n}\n\nfunction ComposerAction({\n hasInputText,\n isBusy,\n isResuming,\n onCancel,\n}: {\n readonly hasInputText: boolean;\n readonly isBusy: boolean;\n readonly isResuming: boolean;\n readonly onCancel: () => void;\n}) {\n const attachments = usePromptInputAttachments();\n const canSubmit = hasInputText || attachments.files.length > 0;\n\n if (!isBusy || canSubmit) {\n return <PromptInputSubmit disabled={isResuming} />;\n }\n\n return (\n <PromptInputButton\n aria-label="Stop"\n className="absolute right-2.5 bottom-2.5"\n onClick={onCancel}\n variant="outline"\n >\n <SquareIcon className="size-3 fill-current" />\n </PromptInputButton>\n );\n}\n\nfunction ErrorMessage({ message }: { readonly message: string }) {\n return (\n <Message className="max-w-full" from="assistant">\n <MessageContent>\n <div\n className="flex w-full items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm"\n role="alert"\n >\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">{message}</p>\n </div>\n </div>\n </MessageContent>\n </Message>\n );\n}\n\nfunction ChatHeader({ canStartNewChat }: { readonly canStartNewChat: boolean }) {\n return (\n <header className="pointer-events-none fixed top-0 right-0 left-0 z-20 h-14">\n <div className="relative mx-auto flex h-full w-full max-w-3xl items-center justify-center bg-background px-24">\n <span className="truncate text-muted-foreground text-sm">{AGENT_NAME}</span>\n {canStartNewChat ? (\n <Button\n aria-label="Start a new chat"\n className="pointer-events-auto fixed top-3 right-6 pr-4"\n onClick={() => window.location.assign("/s")}\n size="sm"\n type="button"\n variant="ghost"\n >\n <PlusIcon className="size-4" />\n <span className="hidden font-normal text-sm sm:inline">New chat</span>\n </Button>\n ) : null}\n </div>\n </header>\n );\n}\n\nfunction PendingThinking() {\n return (\n <Message aria-live="polite" from="assistant">\n <MessageContent>\n <div className="mb-4 flex w-full items-center gap-2 text-muted-foreground text-sm">\n <BrainIcon className="size-4" />\n <Shimmer duration={1}>Thinking</Shimmer>\n </div>\n </MessageContent>\n </Message>\n );\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : "Unable to cancel the response.";\n}\n\nfunction getLatestTurnFailure(\n events: ReturnType<typeof useEveAgent>["events"],\n): string | undefined {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n\n if (event.type === "turn.failed") {\n return event.data.code === "MODEL_CALL_FAILED"\n ? "The model is temporarily unavailable. Please try again."\n : event.data.message;\n }\n\n if (event.type === "turn.completed" || event.type === "turn.cancelled") {\n return undefined;\n }\n\n if (event.type === "message.received") {\n return undefined;\n }\n }\n\n return undefined;\n}\n';
|
|
2
|
+
readonly "app/_components/agent-chat.tsx": '"use client";\n\nimport type { UserContent } from "ai";\nimport { useEveAgent } from "eve/react";\nimport { AlertCircleIcon, BrainIcon, PlusIcon, SquareIcon } from "lucide-react";\nimport { useRef, useState } from "react";\nimport {\n Conversation,\n ConversationContent,\n ConversationScrollButton,\n ConversationTopFade,\n} from "@/components/ai-elements/conversation";\nimport { Message, MessageContent } from "@/components/ai-elements/message";\nimport {\n PromptInput,\n PromptInputButton,\n type PromptInputMessage,\n PromptInputSubmit,\n PromptInputTextarea,\n usePromptInputAttachments,\n} from "@/components/ai-elements/prompt-input";\nimport { Shimmer } from "@/components/ai-elements/shimmer";\nimport { Button } from "@/components/ui/button";\nimport { cn } from "@/lib/utils";\nimport { AgentMessage } from "./agent-message";\nimport { WEB_CHAT_AGENT } from "@/app/eve-agent";\n\nconst DEFAULT_AGENT_NAME = "__EVE_INIT_APP_NAME__";\nconst AGENT_NAME = WEB_CHAT_AGENT ?? DEFAULT_AGENT_NAME;\n\nexport function AgentChat({\n sessionId,\n sessionless = false,\n}: {\n readonly sessionId?: string;\n readonly sessionless?: boolean;\n}) {\n const [cancellationError, setCancellationError] = useState<string>();\n const [hasInputText, setHasInputText] = useState(false);\n const hasSubmittedMessage = useRef(false);\n const replaceSessionRoute = (nextSessionId: string) => {\n if (sessionId !== undefined) return;\n // Framework routers (Next.js, TanStack Router) patch window.history; navigating\n // through them would remount this route and detach the active stream.\n History.prototype.replaceState.call(\n window.history,\n window.history.state,\n "",\n `/s/${encodeURIComponent(nextSessionId)}`,\n );\n };\n const agent = useEveAgent({\n agent: WEB_CHAT_AGENT,\n prewarm: hasInputText,\n initialSession:\n sessionId === undefined\n ? undefined\n : {\n sessionId,\n streamIndex: 0,\n },\n resume: sessionId !== undefined,\n onSessionChange(session) {\n if (hasSubmittedMessage.current && session !== undefined) {\n replaceSessionRoute(session.sessionId);\n }\n },\n });\n\n const isBusy = agent.status === "submitted" || agent.status === "streaming";\n const isResuming = agent.status === "resuming";\n const isEmpty = agent.data.messages.length === 0;\n const lastMessage = agent.data.messages.at(-1);\n const isPendingAssistantShell =\n lastMessage?.role === "assistant" &&\n lastMessage.parts.every((part) => part.type === "step-start");\n const showPendingThinking =\n isBusy &&\n (agent.status === "submitted" || lastMessage?.role !== "assistant" || isPendingAssistantShell);\n const turnFailure = isBusy || isResuming ? undefined : getLatestTurnFailure(agent.events);\n const errorMessage = cancellationError ?? agent.error?.message ?? turnFailure;\n const hasConversationContent = sessionless || !isEmpty || errorMessage !== undefined;\n const showConversationLayout = isResuming || hasConversationContent;\n const activeSessionId = sessionId ?? agent.session?.sessionId;\n // Answers are accepted while work runs; the server\'s settlement closes each request.\n const canRespond = (requestId: string) =>\n !isResuming && agent.data.inputs[requestId]?.status === "open";\n // A tool call can ask several questions at once, and its message part holds only the latest.\n const questionsFor = (callId: string) =>\n Object.values(agent.data.inputs).filter(\n (input) => input.request.kind === "question" && input.request.action.callId === callId,\n );\n\n const requestCancellation = () => {\n setCancellationError(undefined);\n void agent.cancel().catch((error: unknown) => {\n setCancellationError(toErrorMessage(error));\n });\n };\n\n const handleSubmit = async (message: PromptInputMessage) => {\n const text = message.text.trim();\n if ((text.length === 0 && message.files.length === 0) || isResuming) return;\n\n setHasInputText(false);\n setCancellationError(undefined);\n hasSubmittedMessage.current = true;\n if (agent.session !== undefined) replaceSessionRoute(agent.session.sessionId);\n const options = isBusy ? { turnPolicy: "steer" as const } : undefined;\n\n if (message.files.length === 0) {\n await agent.send(text, options);\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, options);\n };\n\n const composer = (\n <PromptInput onSubmit={handleSubmit}>\n <PromptInputTextarea\n disabled={isResuming}\n onChange={(event) => setHasInputText(event.currentTarget.value.trim().length > 0)}\n placeholder="Send a message…"\n />\n <ComposerAction\n hasInputText={hasInputText}\n isBusy={isBusy}\n isResuming={isResuming}\n onCancel={requestCancellation}\n />\n </PromptInput>\n );\n\n return (\n <main className="flex h-dvh flex-col overflow-hidden bg-background text-foreground">\n {showConversationLayout ? (\n <ChatHeader canStartNewChat={activeSessionId !== undefined} />\n ) : null}\n\n {showConversationLayout ? (\n <Conversation\n className="min-h-0 flex-1"\n initial={sessionId === undefined ? undefined : false}\n resize={activeSessionId === undefined ? "smooth" : "instant"}\n scrollRestorationKey={\n isEmpty || activeSessionId === undefined\n ? undefined\n : `eve:web-chat-scroll:${activeSessionId}`\n }\n >\n <ConversationTopFade className="top-14" />\n <ConversationContent className="mx-auto w-full max-w-3xl gap-6 px-4 pt-20 pb-36 sm:px-6">\n {agent.data.messages.map((message, index) =>\n showPendingThinking &&\n isPendingAssistantShell &&\n message.id === lastMessage.id ? null : (\n <AgentMessage\n canRespond={canRespond}\n isStreaming={\n agent.status === "streaming" && index === agent.data.messages.length - 1\n }\n key={message.id}\n message={message}\n questionsFor={questionsFor}\n onInputResponses={(inputResponses) => {\n setCancellationError(undefined);\n return agent.respond(inputResponses);\n }}\n />\n ),\n )}\n {showPendingThinking ? <PendingThinking /> : null}\n {errorMessage ? <ErrorMessage message={errorMessage} /> : null}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n ) : null}\n\n <div\n className={cn(\n "mx-auto w-full px-4 sm:px-6",\n showConversationLayout\n ? "fixed bottom-0 left-1/2 z-20 max-w-3xl -translate-x-1/2 bg-gradient-to-t from-background via-background to-transparent pt-4 pb-6"\n : "flex max-w-xl flex-1 flex-col items-center justify-center gap-8 pb-[10vh]",\n )}\n >\n {showConversationLayout ? null : (\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 )}\n <div className="w-full">{composer}</div>\n </div>\n </main>\n );\n}\n\nfunction ComposerAction({\n hasInputText,\n isBusy,\n isResuming,\n onCancel,\n}: {\n readonly hasInputText: boolean;\n readonly isBusy: boolean;\n readonly isResuming: boolean;\n readonly onCancel: () => void;\n}) {\n const attachments = usePromptInputAttachments();\n const canSubmit = hasInputText || attachments.files.length > 0;\n\n if (!isBusy || canSubmit) {\n return <PromptInputSubmit disabled={isResuming} />;\n }\n\n return (\n <PromptInputButton\n aria-label="Stop"\n className="absolute right-2.5 bottom-2.5"\n onClick={onCancel}\n variant="outline"\n >\n <SquareIcon className="size-3 fill-current" />\n </PromptInputButton>\n );\n}\n\nfunction ErrorMessage({ message }: { readonly message: string }) {\n return (\n <Message className="max-w-full" from="assistant">\n <MessageContent>\n <div\n className="flex w-full items-start gap-3 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm"\n role="alert"\n >\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">{message}</p>\n </div>\n </div>\n </MessageContent>\n </Message>\n );\n}\n\nfunction ChatHeader({ canStartNewChat }: { readonly canStartNewChat: boolean }) {\n return (\n <header className="pointer-events-none fixed top-0 right-0 left-0 z-20 h-14">\n <div className="relative mx-auto flex h-full w-full max-w-3xl items-center justify-center bg-background px-24">\n <span className="truncate text-muted-foreground text-sm">{AGENT_NAME}</span>\n {canStartNewChat ? (\n <Button\n aria-label="Start a new chat"\n className="pointer-events-auto fixed top-3 right-6 pr-4"\n onClick={() => window.location.assign("/s")}\n size="sm"\n type="button"\n variant="ghost"\n >\n <PlusIcon className="size-4" />\n <span className="hidden font-normal text-sm sm:inline">New chat</span>\n </Button>\n ) : null}\n </div>\n </header>\n );\n}\n\nfunction PendingThinking() {\n return (\n <Message aria-live="polite" from="assistant">\n <MessageContent>\n <div className="mb-4 flex w-full items-center gap-2 text-muted-foreground text-sm">\n <BrainIcon className="size-4" />\n <Shimmer duration={1}>Thinking</Shimmer>\n </div>\n </MessageContent>\n </Message>\n );\n}\n\nfunction toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : "Unable to cancel the response.";\n}\n\nfunction getLatestTurnFailure(\n events: ReturnType<typeof useEveAgent>["events"],\n): string | undefined {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index];\n\n if (event.type === "turn.failed") {\n return event.data.code === "MODEL_CALL_FAILED"\n ? "The model is temporarily unavailable. Please try again."\n : event.data.message;\n }\n\n if (event.type === "turn.completed" || event.type === "turn.cancelled") {\n return undefined;\n }\n\n if (event.type === "message.received") {\n return undefined;\n }\n }\n\n return undefined;\n}\n';
|
|
3
3
|
readonly "app/_components/agent-message.tsx": '"use client";\n\nimport type {\n ConversationInput,\n EveAuthorizationPart,\n EveDynamicToolPart,\n EveMessage,\n EveMessageInputRequest,\n EveMessagePart,\n} from "eve/react";\nimport type { FormEvent } from "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 BashToolContent,\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n} from "@/components/ai-elements/tool";\nimport { Button } from "@/components/ui/button";\nimport {\n Questionnaire,\n QuestionnaireActions,\n QuestionnaireChoice,\n QuestionnaireChoiceDescription,\n QuestionnaireChoices,\n QuestionnaireError,\n QuestionnaireInput,\n QuestionnaireItem,\n QuestionnaireSubmit,\n QuestionnaireTitle,\n} from "@/components/ui/questionnaire";\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 questionsFor,\n}: {\n readonly canRespond: (requestId: string) => boolean;\n readonly isStreaming: boolean;\n readonly message: EveMessage;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly questionsFor: (callId: string) => readonly ConversationInput[];\n}) {\n const lastTextIndex = message.parts.reduce(\n (last, part, index) => (part.type === "text" ? index : last),\n -1,\n );\n const hasAssistantText =\n message.role === "assistant" &&\n message.parts.some((part) => part.type === "text" && part.text.length > 0);\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 hasAssistantText && part.type === "reasoning" ? null : (\n <AgentMessagePart\n canRespond={canRespond}\n key={partKey(part, index)}\n onInputResponses={onInputResponses}\n part={part}\n questionsFor={questionsFor}\n showCaret={isStreaming && message.role === "assistant" && index === lastTextIndex}\n />\n ),\n )}\n </MessageContent>\n </Message>\n );\n}\n\nfunction AgentMessagePart({\n canRespond,\n onInputResponses,\n part,\n questionsFor,\n showCaret,\n}: {\n readonly canRespond: (requestId: string) => boolean;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n readonly part: EveMessagePart;\n readonly questionsFor: (callId: string) => readonly ConversationInput[];\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 const questions = questionsFor(part.toolCallId);\n if (questions.length > 0) {\n return (\n <div className="space-y-4">\n {questions.map(({ request, response }) => (\n <QuestionRequest\n canRespond={canRespond(request.requestId)}\n inputRequest={request}\n inputResponse={response}\n key={request.requestId}\n onInputResponses={onInputResponses}\n />\n ))}\n </div>\n );\n }\n\n return (\n <>\n <Tool>\n <ToolHeader\n state={part.state}\n title={part.toolMetadata?.eve?.label ?? part.toolName}\n toolName={part.toolName}\n type="dynamic-tool"\n />\n <ToolContent>\n {part.toolName === "bash" ? (\n <BashToolContent\n errorText={part.errorText}\n input={part.input}\n output={part.output}\n />\n ) : (\n <>\n <ToolInput input={part.input} />\n <ToolOutput errorText={part.errorText} output={part.output} />\n </>\n )}\n </ToolContent>\n </Tool>\n {/* Kept outside the collapsed card so a pending approval is always visible. */}\n <InputRequestActions\n canRespond={canRespond}\n part={part}\n onInputResponses={onInputResponses}\n />\n </>\n );\n }\n }\n}\n\nfunction QuestionRequest({\n canRespond,\n inputRequest,\n inputResponse,\n onInputResponses,\n}: {\n readonly canRespond: boolean;\n readonly inputRequest: EveMessageInputRequest;\n readonly inputResponse?: AgentInputResponse;\n readonly onInputResponses: (responses: readonly AgentInputResponse[]) => void | Promise<void>;\n}) {\n const options = inputRequest.options ?? [];\n const acceptsFreeform = inputRequest.allowFreeform === true || options.length === 0;\n const disabled = !canRespond || inputResponse !== undefined;\n\n const submitResponse = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const answer = new FormData(event.currentTarget).get(inputRequest.requestId);\n if (typeof answer !== "string") {\n return;\n }\n\n const option = options.find(({ id }) => id === answer);\n void onInputResponses([\n option === undefined\n ? { requestId: inputRequest.requestId, text: answer.trim() }\n : { optionId: option.id, requestId: inputRequest.requestId },\n ]);\n };\n\n return (\n <Questionnaire\n className="gap-4 rounded-xl border bg-card p-4"\n // Validation reads disabled answers as missing, so locking a submitted form in place would\n // flag it invalid. Remounting restores the answer from the response instead.\n key={disabled ? "locked" : "open"}\n onSubmit={submitResponse}\n shortcuts="numbers"\n >\n <QuestionnaireItem name={inputRequest.requestId} required>\n <QuestionnaireTitle className="text-sm font-medium">\n {inputRequest.prompt}\n </QuestionnaireTitle>\n <QuestionnaireChoices>\n {options.map((option) => (\n <QuestionnaireChoice\n className={cn(inputResponse?.optionId === option.id && "data-disabled:opacity-100")}\n defaultChecked={inputResponse?.optionId === option.id}\n disabled={disabled}\n key={option.id}\n value={option.id}\n >\n {option.label}\n {option.description ? (\n <QuestionnaireChoiceDescription>\n {option.description}\n </QuestionnaireChoiceDescription>\n ) : null}\n </QuestionnaireChoice>\n ))}\n {acceptsFreeform ? (\n <QuestionnaireInput\n aria-label="Answer"\n className={cn(inputResponse?.text !== undefined && "disabled:opacity-100")}\n defaultValue={inputResponse?.text}\n disabled={disabled}\n placeholder="Type your answer…"\n />\n ) : null}\n </QuestionnaireChoices>\n <QuestionnaireError />\n </QuestionnaireItem>\n {disabled ? null : (\n <QuestionnaireActions>\n <QuestionnaireSubmit size="sm">Answer</QuestionnaireSubmit>\n </QuestionnaireActions>\n )}\n </Questionnaire>\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: (requestId: string) => 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 // An approval can settle before its batch resolves, without an input response.\n const settledApproval =\n part.approval?.approved === undefined\n ? undefined\n : part.approval.approved\n ? "Approved"\n : "Denied";\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 || settledApproval ? (\n <p className="font-medium text-sm">\n Responded:{" "}\n {selectedOption?.label ??\n inputResponse?.text ??\n inputResponse?.optionId ??\n settledApproval}\n </p>\n ) : (\n <div className="flex flex-wrap gap-2">\n {inputRequest.options?.map((option) => (\n <Button\n disabled={!canRespond(inputRequest.requestId)}\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 part.attemptId === undefined\n ? `authorization:${part.turnId}:${part.stepIndex}:${part.name}`\n : `authorization:${part.attemptId}`;\n case "dynamic-tool":\n return part.toolCallId;\n case "reasoning":\n case "text":\n return `${part.type}:${part.id ?? index}`;\n default:\n return `${part.type}:${index}`;\n }\n}\n';
|
|
4
4
|
readonly "app/apple-icon.tsx": 'import { ImageResponse } from "next/og";\n\nexport const size = {\n width: 180,\n height: 180,\n};\n\nexport const contentType = "image/png";\n\nexport default function AppleIcon() {\n return new ImageResponse(\n <svg fill="none" viewBox="0 0 102 102" xmlns="http://www.w3.org/2000/svg">\n <path d="M0 0h102v102H0z" fill="#000" />\n <path\n d="M49.28 66.94 75.03 34.96h-6.89L47.91 60.11l-5.49 6.83h6.86ZM0 34.96h42.4v5.11H0zm0 13.32h27.66v5.11H0zm0 13.54h27.66v5.11H0zm69.63-26.86H102v5.11H69.63zm4.71 13.32H102v5.11H74.34zm0 13.54H102v5.11H74.34z"\n fill="#fff"\n />\n </svg>,\n size,\n );\n}\n';
|
|
5
5
|
readonly "app/eve-agent.ts": '/** Named workspace agent selected by the Web Chat installer. */\nexport const WEB_CHAT_AGENT: string | undefined = undefined;\n';
|
|
@@ -3,7 +3,7 @@ const WEB_APP_TEMPLATE_FILES={"app/_components/agent-chat.tsx":`"use client";
|
|
|
3
3
|
import type { UserContent } from "ai";
|
|
4
4
|
import { useEveAgent } from "eve/react";
|
|
5
5
|
import { AlertCircleIcon, BrainIcon, PlusIcon, SquareIcon } from "lucide-react";
|
|
6
|
-
import { useState } from "react";
|
|
6
|
+
import { useRef, useState } from "react";
|
|
7
7
|
import {
|
|
8
8
|
Conversation,
|
|
9
9
|
ConversationContent,
|
|
@@ -37,8 +37,21 @@ export function AgentChat({
|
|
|
37
37
|
}) {
|
|
38
38
|
const [cancellationError, setCancellationError] = useState<string>();
|
|
39
39
|
const [hasInputText, setHasInputText] = useState(false);
|
|
40
|
+
const hasSubmittedMessage = useRef(false);
|
|
41
|
+
const replaceSessionRoute = (nextSessionId: string) => {
|
|
42
|
+
if (sessionId !== undefined) return;
|
|
43
|
+
// Framework routers (Next.js, TanStack Router) patch window.history; navigating
|
|
44
|
+
// through them would remount this route and detach the active stream.
|
|
45
|
+
History.prototype.replaceState.call(
|
|
46
|
+
window.history,
|
|
47
|
+
window.history.state,
|
|
48
|
+
"",
|
|
49
|
+
\`/s/\${encodeURIComponent(nextSessionId)}\`,
|
|
50
|
+
);
|
|
51
|
+
};
|
|
40
52
|
const agent = useEveAgent({
|
|
41
53
|
agent: WEB_CHAT_AGENT,
|
|
54
|
+
prewarm: hasInputText,
|
|
42
55
|
initialSession:
|
|
43
56
|
sessionId === undefined
|
|
44
57
|
? undefined
|
|
@@ -48,15 +61,8 @@ export function AgentChat({
|
|
|
48
61
|
},
|
|
49
62
|
resume: sessionId !== undefined,
|
|
50
63
|
onSessionChange(session) {
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
// through them would remount this route and detach the active stream.
|
|
54
|
-
History.prototype.replaceState.call(
|
|
55
|
-
window.history,
|
|
56
|
-
window.history.state,
|
|
57
|
-
"",
|
|
58
|
-
\`/s/\${encodeURIComponent(session.sessionId)}\`,
|
|
59
|
-
);
|
|
64
|
+
if (hasSubmittedMessage.current && session !== undefined) {
|
|
65
|
+
replaceSessionRoute(session.sessionId);
|
|
60
66
|
}
|
|
61
67
|
},
|
|
62
68
|
});
|
|
@@ -98,6 +104,8 @@ export function AgentChat({
|
|
|
98
104
|
|
|
99
105
|
setHasInputText(false);
|
|
100
106
|
setCancellationError(undefined);
|
|
107
|
+
hasSubmittedMessage.current = true;
|
|
108
|
+
if (agent.session !== undefined) replaceSessionRoute(agent.session.sessionId);
|
|
101
109
|
const options = isBusy ? { turnPolicy: "steer" as const } : undefined;
|
|
102
110
|
|
|
103
111
|
if (message.files.length === 0) {
|
|
@@ -170,6 +170,7 @@ export type RuntimeToolResultActionResult = z.infer<typeof runtimeToolResultActi
|
|
|
170
170
|
*/
|
|
171
171
|
declare const runtimeToolResultActionResultSchema: z.ZodObject<{
|
|
172
172
|
callId: z.ZodString;
|
|
173
|
+
errorName: z.ZodOptional<z.ZodString>;
|
|
173
174
|
isError: z.ZodOptional<z.ZodBoolean>;
|
|
174
175
|
kind: z.ZodLiteral<"tool-result">;
|
|
175
176
|
output: z.ZodType<import("#shared/json.js").JsonValue, unknown, z.core.$ZodTypeInternals<import("#shared/json.js").JsonValue, unknown>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict();z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`workflow-tool-call`),toolName:z.string(),workflowId:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict();const runtimeRemoteAgentDispatchRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),workflowToolCallEntrySchema=z.discriminatedUnion(`entryPoint`,[z.object({entryPoint:z.literal(`execute`)}).strict(),z.object({entryPoint:z.literal(`task`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`serve`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`receive`),taskId:z.string()}).strict()]),runtimeWorkflowTaskRequestSchema=z.object({callId:z.string(),entry:workflowToolCallEntrySchema,executeInput:jsonValueSchema.optional(),input:jsonObjectSchema,kind:z.literal(`workflow-task`),toolName:z.string(),workflowId:z.string()}).strict();z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`),name:z.string()}).strict();const RUNTIME_WORKFLOW_TOOL_ACTION=Symbol.for(`eve:runtime-workflow-tool-action`);function markRuntimeWorkflowToolAction(e){return Object.defineProperty(e,RUNTIME_WORKFLOW_TOOL_ACTION,{value:!0}),e}function isRuntimeWorkflowToolAction(e){return e.kind===`workflow-tool-call`||e.kind===`tool-call`&&Reflect.get(e,RUNTIME_WORKFLOW_TOOL_ACTION)===!0}z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.literal(!0),kind:z.literal(`subagent-result`),origin:z.literal(`dispatch`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),name:z.string(),output:jsonValueSchema}).strict();export{isRuntimeWorkflowToolAction,markRuntimeWorkflowToolAction,runtimeRemoteAgentDispatchRequestSchema,runtimeToolCallActionRequestSchema,runtimeWorkflowTaskRequestSchema};
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{jsonObjectSchema,jsonValueSchema}from"#shared/json-schemas.js";const runtimeToolCallActionRequestSchema=z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`tool-call`),toolName:z.string()}).strict();z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`workflow-tool-call`),toolName:z.string(),workflowId:z.string()}).strict(),z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`subagent-call`),name:z.string(),nodeId:z.string(),subagentName:z.string()}).strict();const runtimeRemoteAgentDispatchRequestSchema=z.object({callId:z.string(),description:z.string(),input:jsonObjectSchema,kind:z.literal(`remote-agent-call`),name:z.string(),nodeId:z.string(),remoteAgentName:z.string()}).strict(),workflowToolCallEntrySchema=z.discriminatedUnion(`entryPoint`,[z.object({entryPoint:z.literal(`execute`)}).strict(),z.object({entryPoint:z.literal(`task`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`serve`),taskId:z.string()}).strict(),z.object({entryPoint:z.literal(`receive`),taskId:z.string()}).strict()]),runtimeWorkflowTaskRequestSchema=z.object({callId:z.string(),entry:workflowToolCallEntrySchema,executeInput:jsonValueSchema.optional(),input:jsonObjectSchema,kind:z.literal(`workflow-task`),toolName:z.string(),workflowId:z.string()}).strict();z.object({callId:z.string(),input:jsonObjectSchema,kind:z.literal(`load-skill`),name:z.string()}).strict();const RUNTIME_WORKFLOW_TOOL_ACTION=Symbol.for(`eve:runtime-workflow-tool-action`);function markRuntimeWorkflowToolAction(e){return Object.defineProperty(e,RUNTIME_WORKFLOW_TOOL_ACTION,{value:!0}),e}function isRuntimeWorkflowToolAction(e){return e.kind===`workflow-tool-call`||e.kind===`tool-call`&&Reflect.get(e,RUNTIME_WORKFLOW_TOOL_ACTION)===!0}z.object({callId:z.string(),errorName:z.string().optional(),isError:z.boolean().optional(),kind:z.literal(`tool-result`),output:jsonValueSchema,toolName:z.string()}).strict(),z.object({callId:z.string(),isError:z.literal(!0),kind:z.literal(`subagent-result`),origin:z.literal(`dispatch`),output:jsonValueSchema,subagentName:z.string()}).strict(),z.object({callId:z.string(),isError:z.boolean().optional(),kind:z.literal(`load-skill-result`),name:z.string(),output:jsonValueSchema}).strict();export{isRuntimeWorkflowToolAction,markRuntimeWorkflowToolAction,runtimeRemoteAgentDispatchRequestSchema,runtimeToolCallActionRequestSchema,runtimeWorkflowTaskRequestSchema};
|
package/dist/src/shared/git.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Buffer}from"node:buffer";function isFullGitSha(e){return/^[a-f0-9]{40}$/iu.test(e)}function isValidGitRef(e){return!(e.length===0||e.startsWith(`-`)||e.endsWith(`.`)||e.endsWith(`/`)||e.includes(`..`)||e.includes(`//`)||e.includes(`@{`)||e.includes(`\\`)||e.split(`/`).some(e=>e.length===0||e.endsWith(`.lock`))||/[\x00-\x20~^:?*[]/u.test(e))}function gitHubRemoteUrl(e){return`https://github.com/${e.owner}/${e.repo}.git`}function gitHubGitBrokerNetworkPolicy(e){let t=[{transform:[{headers:{Authorization:`Basic ${Buffer.from(`x-access-token:${e}`).toString(`base64`)}`}}]}];return{allow:{"*":[],"github.com":t,"codeload.github.com":t}}}export{gitHubGitBrokerNetworkPolicy,gitHubRemoteUrl,isFullGitSha,isValidGitRef};
|
|
1
|
+
import{Buffer}from"node:buffer";function isFullGitSha(e){return/^[a-f0-9]{40}$/iu.test(e)}function isValidGitRef(e){return!(e.length===0||e.startsWith(`-`)||e.endsWith(`.`)||e.endsWith(`/`)||e.includes(`..`)||e.includes(`//`)||e.includes(`@{`)||e.includes(`\\`)||e.split(`/`).some(e=>e.length===0||e.startsWith(`.`)||e.endsWith(`.lock`))||/[\x00-\x20\x7f~^:?*[]/u.test(e))}function gitHubRemoteUrl(e){return`https://github.com/${e.owner}/${e.repo}.git`}function gitHubGitBrokerNetworkPolicy(e){let t=[{transform:[{headers:{Authorization:`Basic ${Buffer.from(`x-access-token:${e}`).toString(`base64`)}`}}]}];return{allow:{"*":[],"github.com":t,"codeload.github.com":t}}}export{gitHubGitBrokerNetworkPolicy,gitHubRemoteUrl,isFullGitSha,isValidGitRef};
|
|
@@ -7,5 +7,5 @@ export interface InstrumentationContentContext {
|
|
|
7
7
|
}
|
|
8
8
|
/** Content is public evidence, or local debugging evidence in development. */
|
|
9
9
|
export declare function shouldCaptureInstrumentationContent(context: InstrumentationContentContext): boolean;
|
|
10
|
-
/**
|
|
10
|
+
/** An explicit policy overrides defaults only for the audience it evaluated. */
|
|
11
11
|
export declare function applyAudienceCeiling(decision: InstrumentationDecision, context: InstrumentationContentContext): InstrumentationDecision;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function shouldCaptureInstrumentationContent(e){return e.audience===`public`||e.environment===`development`}function applyAudienceCeiling(e,t){return e.action===`drop`||shouldCaptureInstrumentationContent(t)?e:{action:`record`,recordInputs:!1,recordOutputs:!1}}export{applyAudienceCeiling,shouldCaptureInstrumentationContent};
|
|
1
|
+
function shouldCaptureInstrumentationContent(e){return e.audience===`public`||e.environment===`development`}function applyAudienceCeiling(e,t){return e.action===`drop`||e.explicitContentAudience===t.audience||shouldCaptureInstrumentationContent(t)?e:{action:`record`,recordInputs:!1,recordOutputs:!1}}export{applyAudienceCeiling,shouldCaptureInstrumentationContent};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { type ChannelAudience } from "#shared/channel-audience.js";
|
|
1
2
|
export type InstrumentationDecision = {
|
|
2
3
|
readonly action: "drop";
|
|
3
4
|
} | {
|
|
4
5
|
readonly action: "record";
|
|
5
6
|
readonly recordInputs: boolean;
|
|
6
7
|
readonly recordOutputs: boolean;
|
|
8
|
+
/** The audience for which an explicit policy authorized content. */
|
|
9
|
+
readonly explicitContentAudience?: ChannelAudience;
|
|
7
10
|
};
|
|
8
11
|
export declare const DROP_INSTRUMENTATION: InstrumentationDecision;
|
|
9
12
|
/** Reads durable decision state, treating malformed persisted values as drop. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const DROP_INSTRUMENTATION={action:`drop`};function readInstrumentationDecision(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return DROP_INSTRUMENTATION;let t=e;return t.action===`drop`?DROP_INSTRUMENTATION:t.action===`record`&&typeof t.recordInputs==`boolean`&&typeof t.recordOutputs==`boolean`?{action:`record`,recordInputs:t.recordInputs,recordOutputs:t.recordOutputs}:DROP_INSTRUMENTATION}function intersectInstrumentationDecisions(e,t){
|
|
1
|
+
import{CHANNEL_AUDIENCES}from"#shared/channel-audience.js";const DROP_INSTRUMENTATION={action:`drop`};function readInstrumentationDecision(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return DROP_INSTRUMENTATION;let t=e;return t.action===`drop`?DROP_INSTRUMENTATION:t.action===`record`&&typeof t.recordInputs==`boolean`&&typeof t.recordOutputs==`boolean`?{action:`record`,recordInputs:t.recordInputs,recordOutputs:t.recordOutputs,...t.explicitContentAudience!==void 0&&CHANNEL_AUDIENCES.includes(t.explicitContentAudience)?{explicitContentAudience:t.explicitContentAudience}:void 0}:DROP_INSTRUMENTATION}function intersectInstrumentationDecisions(e,t){if(e.action===`drop`||t.action===`drop`)return DROP_INSTRUMENTATION;let n=e.explicitContentAudience===void 0?t.explicitContentAudience:t.explicitContentAudience===void 0||e.explicitContentAudience===t.explicitContentAudience?e.explicitContentAudience:void 0;return{action:`record`,recordInputs:e.recordInputs&&t.recordInputs,recordOutputs:e.recordOutputs&&t.recordOutputs,...n===void 0?void 0:{explicitContentAudience:n}}}export{DROP_INSTRUMENTATION,intersectInstrumentationDecisions,readInstrumentationDecision};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{dirname,join}from"node:path";import{resolveSandboxSkillRoot,resolveSandboxSkillWritePath}from"#shared/skill-paths.js";import{Buffer}from"node:buffer";function stripSkillFrontmatter(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,``)}function skillPackageRevision(e){let t=createHash(`sha256`);for(let n of e.files)t.update(`${n.relativePath}\0${n.content.byteLength}\0`).update(n.content);return t.digest(`hex`)}function normalizeSkillPackage(e){assertSafeSkillPackageName(e.name);let t=[{content:Buffer.from(e.markdown,`utf8`),relativePath:`SKILL.md`}];for(let[n,r]of Object.entries(e.files??{}))assertSafeSkillPackageFilePath(n),t.push({content:contentToBuffer(r),relativePath:n});return t.sort((e,t)=>comparePaths(e.relativePath,t.relativePath)),{deferred:e.deferred,description:e.description,files:t,license:e.license,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name}}async function writeSkillPackageDirectory(e){for(let t of e.skill.files){let n=join(e.rootPath,`skills`,e.skill.name,t.relativePath);await mkdir(dirname(n),{recursive:!0}),await writeFile(n,t.content)}}async function writeSkillPackageToSandbox(e){
|
|
1
|
+
import{createHash}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{dirname,join}from"node:path";import{resolveSandboxSkillRoot,resolveSandboxSkillWritePath}from"#shared/skill-paths.js";import{Buffer}from"node:buffer";import{mapWithConcurrency}from"#shared/map-with-concurrency.js";function stripSkillFrontmatter(e){return e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,``)}function skillPackageRevision(e){let t=createHash(`sha256`);for(let n of e.files)t.update(`${n.relativePath}\0${n.content.byteLength}\0`).update(n.content);return t.digest(`hex`)}function normalizeSkillPackage(e){assertSafeSkillPackageName(e.name);let t=[{content:Buffer.from(e.markdown,`utf8`),relativePath:`SKILL.md`}];for(let[n,r]of Object.entries(e.files??{}))assertSafeSkillPackageFilePath(n),t.push({content:contentToBuffer(r),relativePath:n});return t.sort((e,t)=>comparePaths(e.relativePath,t.relativePath)),{deferred:e.deferred,description:e.description,files:t,license:e.license,markdown:e.markdown,metadata:e.metadata===void 0?void 0:{...e.metadata},name:e.name}}async function writeSkillPackageDirectory(e){for(let t of e.skill.files){let n=join(e.rootPath,`skills`,e.skill.name,t.relativePath);await mkdir(dirname(n),{recursive:!0}),await writeFile(n,t.content)}}async function writeSkillPackageToSandbox(e){await mapWithConcurrency(e.skill.files,16,async t=>{await e.sandbox.writeBinaryFile({content:t.content,path:await resolveSandboxSkillWritePath({name:e.skill.name,relativePath:t.relativePath,sandbox:e.sandbox})})})}async function removeSkillPackageFromSandbox(e){assertSafeSkillPackageName(e.name);let t=await resolveSandboxSkillRoot({sandbox:e.sandbox});await e.sandbox.removePath({force:!0,path:`${t}/${e.name}`,recursive:!0})}function assertSafeSkillPackageName(e){if(e.length===0||e.startsWith(`.`)||e.includes(`/`)||e.includes(`\\`)||e.includes(`..`)||!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(e)||/^[A-Za-z]:/.test(e))throw Error(`Expected skill name to be a non-empty shell-safe path segment starting with an alphanumeric character and containing only alphanumerics, ".", "_", or "-".`)}function assertSafeSkillPackageFilePath(e){if(e===`SKILL.md`)throw Error(`Skill package files must not include "SKILL.md"; eve generates it.`);if(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||/^[A-Za-z]:/.test(e)||e.split(`/`).some(e=>e.length===0||e===`.`||e===`..`))throw Error(`Expected skill package file paths to be relative POSIX paths.`)}function contentToBuffer(e){return typeof e==`string`?Buffer.from(e,`utf8`):Buffer.from(e)}function comparePaths(e,t){return e<t?-1:+(e>t)}export{normalizeSkillPackage,removeSkillPackageFromSandbox,skillPackageRevision,stripSkillFrontmatter,writeSkillPackageDirectory,writeSkillPackageToSandbox};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{shouldCaptureInstrumentationContent}from"#shared/instrumentation-content.js";import{DROP_INSTRUMENTATION}from"#shared/instrumentation-decision.js";function isSampledTrace(e){return!!(e.traceFlags&1)}function resolveTracePolicy(e,t,n){try{let n=e?.(t);return resolveTracePolicyDecision(n
|
|
1
|
+
import{shouldCaptureInstrumentationContent}from"#shared/instrumentation-content.js";import{DROP_INSTRUMENTATION}from"#shared/instrumentation-decision.js";function isSampledTrace(e){return!!(e.traceFlags&1)}function resolveTracePolicy(e,t,n){try{let n=e?.(t);return resolveTracePolicyDecision(n??!0,t)}catch(e){try{n?.(e)}catch{}return DROP_INSTRUMENTATION}}function resolveTracePolicyDecision(e,t){if(e===!1)return DROP_INSTRUMENTATION;if(e===!0){let e=shouldCaptureInstrumentationContent(t);return{action:`record`,recordInputs:e,recordOutputs:e}}return e.emit?{action:`record`,recordInputs:e.recordInputs,recordOutputs:e.recordOutputs,...e.recordInputs||e.recordOutputs?{explicitContentAudience:t.audience}:void 0}:DROP_INSTRUMENTATION}export{isSampledTrace,resolveTracePolicy,resolveTracePolicyDecision};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createErrorId,createLogger}from"#internal/logging.js";import{ContinuationTokenKey,SessionIdKey,SessionInboxKey}from"#context/keys.js";import{resolvedForParent}from"#harness/
|
|
1
|
+
import{createErrorId,createLogger}from"#internal/logging.js";import{ContinuationTokenKey,SessionIdKey,SessionInboxKey}from"#context/keys.js";import{resolvedForParent}from"#harness/hitl/relays.js";import{SUBAGENT_ADAPTER_KIND,isSubagentAdapterState}from"#subagents/adapter-state.js";const log=createLogger(`execution.subagent-adapter`),SUBAGENT_ADAPTER={kind:SUBAGENT_ADAPTER_KIND,async"approval.candidate"(e,t){await forwardSubagentAuthorizationEvent({data:e,type:`approval.candidate`},t)},async"approval.settled"(e,t){await forwardSubagentAuthorizationEvent({data:e,type:`approval.settled`},t)},async"authorization.required"(e,t){await forwardSubagentAuthorizationEvent({data:e,type:`authorization.required`},t)},async"authorization.completed"(e,t){await forwardSubagentAuthorizationEvent({data:e,type:`authorization.completed`},t)},async"input.resolved"(e,t){let n=resolvedForParent(e);n!==void 0&&await forwardSubagentAuthorizationEvent({data:n,type:`input.resolved`},t)},async"input.requested"(e,t){let n=t.state;isSubagentAdapterState(n)&&await forwardSubagentInputRequestStep({hookPayload:{callId:n.callId,childContinuationToken:t.ctx.require(ContinuationTokenKey),childSessionId:t.ctx.require(SessionIdKey),childSessionInbox:t.ctx.get(SessionInboxKey),inputSource:t.inputSource,event:{requests:e.requests,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},kind:`subagent-input-request`,subagentName:n.subagentName},parentContinuationToken:n.parentContinuationToken})}};async function forwardSubagentAuthorizationEvent(e,t){let n=t.state;isSubagentAdapterState(n)&&await forwardSubagentAuthorizationEventStep({hookPayload:{callId:n.callId,childSessionId:t.ctx.require(SessionIdKey),event:e,kind:`subagent-authorization-event`,subagentName:n.subagentName},parentContinuationToken:n.parentContinuationToken})}async function forwardSubagentAuthorizationEventStep(e){"use step";try{await resumeParentHook(e.parentContinuationToken,e.hookPayload)}catch(t){let n=createErrorId();throw log.warn(`failed to forward subagent authorization event to parent`,{callId:e.hookPayload.callId,childSessionId:e.hookPayload.childSessionId,errorId:n,eventType:e.hookPayload.event.type,parentContinuationToken:e.parentContinuationToken,subagentName:e.hookPayload.subagentName,error:t}),t}}async function forwardSubagentInputRequestStep(e){"use step";try{await resumeParentHook(e.parentContinuationToken,e.hookPayload)}catch(t){let n=createErrorId();throw log.warn(`failed to forward proxied HITL batch to parent`,{callId:e.hookPayload.callId,childContinuationToken:e.hookPayload.childContinuationToken,childSessionId:e.hookPayload.childSessionId,errorId:n,parentContinuationToken:e.parentContinuationToken,subagentName:e.hookPayload.subagentName,error:t}),t}}async function resumeParentHook(e,t){let{resumeHook:n}=await import(`#internal/workflow/runtime.js`);await n(e,t)}export{SUBAGENT_ADAPTER};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SubagentAuthorizationEventHookPayload, SubagentInputRequestHookPayload } from "#channel/types.js";
|
|
2
2
|
import { type PublishedSessionEvents, type RestoredSessionStep, type SessionStepState } from "#execution/publish-session-events.js";
|
|
3
3
|
import { type SessionStateTransition } from "#execution/session/state-delta.js";
|
|
4
|
-
import type { WorkflowAskRoute } from "#harness/
|
|
4
|
+
import type { WorkflowAskRoute } from "#harness/hitl/relays.js";
|
|
5
5
|
type SubagentEventHookPayload = SubagentAuthorizationEventHookPayload | SubagentInputRequestHookPayload;
|
|
6
6
|
/** Proxies one child event through its parent channel across a durable step boundary. */
|
|
7
7
|
export declare function runProxySubagentEventStep(input: SessionStepState & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{readHitlState}from"#harness/hitl/index.js";import{commitSessionStep,restoreSessionStep}from"#execution/publish-session-events.js";import{withSessionStateDelta}from"#execution/session/state-delta.js";import{relay}from"#harness/session-machine/transitions.js";async function runProxySubagentEventStep(e){"use step";return await withSessionStateDelta(e,async e=>emitProxiedSubagentEvent({...await restoreSessionStep(e),workflowAsk:e.workflowAsk,runId:e.runId,hookPayload:e.hookPayload}))}async function emitProxiedSubagentEvent(e){let{hookPayload:t,runId:n,workflowAsk:r}=e,i=new Set(t.kind===`subagent-input-request`?t.event.requests.map(e=>e.requestId):[]),a=t.kind===`subagent-input-request`?[...readHitlState(e.durableSession.state).relays].filter(([e,n])=>n.childContinuationToken===t.childContinuationToken&&n.inputSource===t.inputSource&&!i.has(e)).map(([e])=>e):[];return await commitSessionStep(e,e=>[relay(e,{payload:t,replacedRequestIds:a,runId:n,workflowAsk:r})],{origin:`relayed`,inputSource:t.kind===`subagent-input-request`?JSON.stringify([t.childContinuationToken,t.inputSource??null]):void 0})}export{emitProxiedSubagentEvent,runProxySubagentEventStep};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SessionInboxAddress } from "#execution/session-inbox/address.js";
|
|
2
2
|
import type { DeliverPayload } from "#channel/types.js";
|
|
3
3
|
import type { StepCoordinates as PendingInputBatchEvent } from "#harness/session-machine/view.js";
|
|
4
|
-
import type { WorkflowAskRoute, ProxyInputRequest } from "#harness/
|
|
4
|
+
import type { WorkflowAskRoute, ProxyInputRequest } from "#harness/hitl/relays.js";
|
|
5
5
|
import type { SessionStateMap } from "#harness/types.js";
|
|
6
6
|
import type { InputResolution } from "#protocol/message.js";
|
|
7
7
|
import type { InputResponse } from "#shared/input.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{inputTextKey,readAnswerText}from"#internal/input-text.js";import{firstOpenInput}from"#harness/open-input-request.js";import{resolveTextToResponse}from"#channel/resolve-text.js";import{storedProjection}from"#harness/session-machine/view.js";import{
|
|
1
|
+
import{inputTextKey,readAnswerText}from"#internal/input-text.js";import{firstOpenInput}from"#harness/open-input-request.js";import{resolveTextToResponse}from"#channel/resolve-text.js";import{storedProjection}from"#harness/session-machine/view.js";import{readHitlState}from"#harness/hitl/index.js";import{resolvedByChild}from"#harness/hitl/relays.js";import{resolveInputOutcome}from"#harness/input-request-resolution.js";import{SESSION_LIMIT_STOP_OPTION_ID}from"#harness/hitl/budget-request.js";const CONSUMED_MESSAGE_KEYS=new Set([`context`,`message`,inputTextKey]);function routeDeliverPayload(e){let t=readHitlState(e.state).relays,routable=(t,n)=>n!==void 0&&e.allowRoute?.(t,n)!==!1,n=resolveMessageAgainstFirstRequest({enabled:e.resolveMessage===!0,entries:t,payload:e.payload,routable,state:e.state}),[r]=n.responses,i=[...e.payload.inputResponses??[],...n.responses],a=new Map,o=[],s,bucketFor=e=>{let t=JSON.stringify([e.childContinuationToken,e.childSessionInbox?.sessionId??``,e.remote?.sessionId??``,e.event.sequence,e.event.stepIndex,e.event.turnId,e.inputSource??null]),n=a.get(t);if(n!==void 0)return n;let r={childContinuationToken:e.childContinuationToken,remote:e.remote,event:e.event,parentRequestIds:[],responses:[],routes:[],...e.childSessionInbox!==void 0&&{childSessionInbox:e.childSessionInbox},...e.workflowAsk!==void 0&&{workflowAsk:e.workflowAsk}};return a.set(t,r),r},c=new Set;for(let e of i){let n=t.get(e.requestId);if(n===void 0||!routable(e.requestId,n)){o.push(e);continue}if(c.has(e.requestId))continue;c.add(e.requestId),n.kind===`session-limit`&&e.optionId===SESSION_LIMIT_STOP_OPTION_ID&&(s={kind:`cancel-turn`});let r=bucketFor(n);r.parentRequestIds.push(e.requestId),r.responses.push(e),r.routes.push(n)}let l=[...a.values()].map(({workflowAsk:n,remote:i,childContinuationToken:a,childSessionInbox:o,event:s,parentRequestIds:c,responses:l,routes:u})=>{let d=new Set(c),decided=e=>{let n=t.get(e)?.kind;return n===void 0||!resolvedByChild(n)},f=new Set([...d].filter(decided));for(let e of u)if(e.batch!==void 0&&batchResolves({batch:e.batch,childContinuationToken:a,entries:t,responseIds:d}))for(let t of e.batch.requestIds)decided(t)&&f.add(t);return{childContinuationToken:a,payload:{inputResponses:l},resolved:{event:s,resolutions:resolveRetiredRequests({entries:t,responses:l,retireRequestIds:f})},...o!==void 0&&{childSessionInbox:o},...r!==void 0&&l.includes(r)&&{message:e.payload.message},...n!==void 0&&{workflowAsk:n},...i!==void 0&&{remote:i},...u[0]?.inputSource!==void 0&&{inputSource:u[0].inputSource}}}),u={};for(let[t,r]of Object.entries(e.payload))t!==`inputResponses`&&r!==void 0&&(n.consumed&&CONSUMED_MESSAGE_KEYS.has(t)||(u[t]=r));return o.length>0&&(u.inputResponses=o),{forChildren:l,forSelf:Object.keys(u).length>0?u:void 0,parentAction:s}}function resolveRetiredRequests(e){let t=new Map(e.responses.map(e=>[e.requestId,e])),n=[];for(let r of e.retireRequestIds){let i=e.entries.get(r);i!==void 0&&n.push(toInputResolution(r,i,t.get(r)))}return n}function toInputResolution(e,t,n){let r=resolveInputOutcome(t.kind,n),i={kind:t.kind,outcome:r,requestId:e};return n===void 0?i:{...i,response:n}}function resolveMessageAgainstFirstRequest(e){let t={consumed:!1,responses:[]};if(!e.enabled||(e.payload.inputResponses?.length??0)>0)return t;let n=readAnswerText(e.payload);if(n===void 0)return t;let answered=t=>{let n=e.entries.get(t);return n!==void 0&&!e.routable(t,n)},r=firstOpenInput(storedProjection(e.state),answered)?.request.requestId??[...e.entries.keys()].find(e=>!answered(e)),i=r===void 0?void 0:e.entries.get(r)?.reply;if(r===void 0||i===void 0)return t;let a=resolveTextToResponse(n,{requestId:r,...i});return a===void 0?t:{consumed:!0,responses:[a]}}function batchResolves(e){return e.batch.approvalRequestIds.length===0||e.batch.approvalRequestIds.every(t=>{let n=e.entries.get(t);return n===void 0||!sameBatch(n,e)||e.responseIds.has(t)})}function sameBatch(e,t){return e.childContinuationToken===t.childContinuationToken&&e.batch?.requestIds.length===t.batch.requestIds.length&&e.batch.requestIds.every((e,n)=>e===t.batch.requestIds[n])}export{routeDeliverPayload};
|
package/dist/src/svelte/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as conversationProjection, i as openConversationInputs, n as conversationReducer, o as callStatus, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-
|
|
1
|
+
import { a as conversationProjection, i as openConversationInputs, n as conversationReducer, o as callStatus, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-Ch-Q-s12.js";
|
|
2
2
|
|
|
3
3
|
//#region src/client/tool-call-state.ts
|
|
4
4
|
function toolCallState(conversation, callId, options = {}) {
|
|
@@ -104,6 +104,12 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
|
|
|
104
104
|
readonly optimistic?: boolean;
|
|
105
105
|
/** Follow each subagent call's session into `conversation.agents` while mounted. @default false */
|
|
106
106
|
readonly followSubagents?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Keep the session stream open between turns to show events that arrive from schedules,
|
|
109
|
+
* channels, or other clients. Set to false to close it once the session is idle and reopen it
|
|
110
|
+
* on the next send, answer, or resume. @default true
|
|
111
|
+
*/
|
|
112
|
+
readonly followIdle?: boolean;
|
|
107
113
|
/** Prewarm an owned session on mount and after reset. @default false */
|
|
108
114
|
readonly prewarm?: boolean;
|
|
109
115
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ModelMessage, ToolExecutionOptions } from "ai";
|
|
2
2
|
import type { StandardJSONSchemaV1, StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
3
3
|
import type { ToolApproval } from "#approval/definition.js";
|
|
4
|
+
import type { SessionAuthContext } from "#channel/types.js";
|
|
4
5
|
import type { SessionContext } from "#context/session-context.js";
|
|
5
6
|
import type { JsonObject } from "#shared/json.js";
|
|
6
7
|
import type { TokenResult } from "#shared/connection-types.js";
|
|
@@ -10,7 +11,12 @@ import type { ToolModelOutput } from "#tools/model-output.js";
|
|
|
10
11
|
type ApprovalContextInput<TInput> = unknown extends TInput ? Record<string, unknown> : TInput;
|
|
11
12
|
export type { ToolAuthDefinition, ToolAuthOptions, ToolAuthProvider } from "#tools/auth.js";
|
|
12
13
|
export type { ToolModelOutput, ToolModelOutputPart } from "#tools/model-output.js";
|
|
13
|
-
export type ToolExecuteOptions = Omit<ToolExecutionOptions<unknown>, "context"
|
|
14
|
+
export type ToolExecuteOptions = Omit<ToolExecutionOptions<unknown>, "context"> & {
|
|
15
|
+
/** Who approved the call, when it runs after a person approved it. */
|
|
16
|
+
readonly approval?: {
|
|
17
|
+
readonly responder: SessionAuthContext;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
14
20
|
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
|
|
15
21
|
interface ToolDefinitionBase {
|
|
16
22
|
/** Whether delegated agent sessions receive this tool. Defaults to `true`. */
|
|
@@ -176,7 +182,38 @@ export type ToolContext = SessionContext & {
|
|
|
176
182
|
* token returned by {@link getToken}.
|
|
177
183
|
*/
|
|
178
184
|
requireAuth(provider: ToolAuthProvider, options?: ToolAuthOptions): never;
|
|
185
|
+
/**
|
|
186
|
+
* The person who approved this call. Present only when the call runs after a
|
|
187
|
+
* person approved it; absent for calls that needed no approval.
|
|
188
|
+
*/
|
|
189
|
+
readonly approval?: ApprovedCall;
|
|
179
190
|
};
|
|
191
|
+
/**
|
|
192
|
+
* The approval behind an approved tool call. The call still runs as the
|
|
193
|
+
* requester, `ctx.session.auth.current`; this only lets it read who approved
|
|
194
|
+
* it and act with their credentials where the tool chooses to.
|
|
195
|
+
*/
|
|
196
|
+
export interface ApprovedCall {
|
|
197
|
+
/** Who approved the call: the same principal its response policy saw. */
|
|
198
|
+
readonly responder: ApprovalResponder;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The person who approved a call, with access to their own credentials. A
|
|
202
|
+
* transient object built for each approved call: its identity fields are the
|
|
203
|
+
* stored responder record, and `getToken` is not serialized with them.
|
|
204
|
+
*/
|
|
205
|
+
export interface ApprovalResponder extends SessionAuthContext {
|
|
206
|
+
/**
|
|
207
|
+
* Resolves the responder's token for an inline provider, as
|
|
208
|
+
* {@link ToolContext.getToken} does for the requester. It never starts a
|
|
209
|
+
* sign-in: when the responder has no token, it throws a non-retryable
|
|
210
|
+
* `ConnectionAuthorizationFailedError` with
|
|
211
|
+
* `reason: "approver_authorization_required"`. It shares the call's
|
|
212
|
+
* providers with `ctx.getToken`, so two inline providers without provider
|
|
213
|
+
* metadata need `options.authKey` across both getters too.
|
|
214
|
+
*/
|
|
215
|
+
getToken(provider: ToolAuthProvider, options?: ToolAuthOptions): Promise<TokenResult>;
|
|
216
|
+
}
|
|
180
217
|
/**
|
|
181
218
|
* Public tool definition authored in `agent/tools/*.ts`.
|
|
182
219
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.79.
|
|
1
|
+
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.79.2//executeAskQuestionTool`;export{executeAskQuestionTool,toAskQuestionOutput,toAskQuestionRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.79.
|
|
1
|
+
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.79.2//executeSleepTool`;export{executeSleepTool};
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* as comments. Rendering is deterministic, so the same schemas always produce
|
|
8
8
|
* the same text.
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
interface SignatureInput {
|
|
11
11
|
readonly name: string;
|
|
12
12
|
readonly inputSchema?: Record<string, unknown>;
|
|
13
13
|
readonly outputSchema?: Record<string, unknown>;
|
|
14
|
-
}
|
|
14
|
+
}
|
|
15
|
+
export declare function renderToolSignature(input: SignatureInput): string;
|
|
16
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";const CONSTRAINT_KEYS=[`format`,`pattern`,`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`,`minLength`,`maxLength`,`minItems`,`maxItems`,`default`],IDENTIFIER=/^[A-Za-z_$][\w$]*$/u;function renderToolSignature(e){let t=e
|
|
1
|
+
import{isObject}from"#shared/guards.js";const MAX_SIGNATURE_LENGTH=4e3,CONSTRAINT_KEYS=[`format`,`pattern`,`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`,`minLength`,`maxLength`,`minItems`,`maxItems`,`default`],IDENTIFIER=/^[A-Za-z_$][\w$]*$/u;function renderToolSignature(e){let t=renderSignature(e,!0);if(t.length<=MAX_SIGNATURE_LENGTH)return t;let n=renderSignature(e,!1);return n.length>MAX_SIGNATURE_LENGTH?`${n.slice(0,3997)}...`:n}function renderSignature(e,t){let render=e=>renderType(e,{budget:{remaining:1e3},depth:0,descriptions:t,refs:new Set,root:e}),n=e.inputSchema===void 0?`{}`:render(e.inputSchema),r=e.outputSchema===void 0?`unknown`:render(e.outputSchema);return`${e.name}(input: ${n}): Promise<${r}>`}function renderType(e,t){if(e===!0||!isObject(e)||t.depth>6||t.budget.remaining<=0)return`unknown`;if(--t.budget.remaining,typeof e.$ref==`string`){let n=resolveRef(e.$ref,t);return n===void 0?`unknown`:renderType(n,{...t,refs:new Set([...t.refs,e.$ref])})}if(`const`in e)return literal(e.const);if(Array.isArray(e.enum))return union(e.enum.map(literal));let n=Array.isArray(e.anyOf)?e.anyOf:Array.isArray(e.oneOf)?e.oneOf:void 0;if(n!==void 0)return union(n.map(e=>renderType(e,next(t))));if(Array.isArray(e.allOf))return e.allOf.map(e=>wrap(renderType(e,next(t)))).join(` & `);let r=(Array.isArray(e.type)?e.type:[e.type]).filter(e=>typeof e==`string`).map(n=>renderPrimitive(n,e,t));return r.length>0?union(r):isObject(e.properties)||e.additionalProperties!==void 0?renderObject(e,t):e.items===void 0?`unknown`:renderPrimitive(`array`,e,t)}function renderPrimitive(e,t,n){switch(e){case`string`:return`string`;case`number`:case`integer`:return`number`;case`boolean`:return`boolean`;case`null`:return`null`;case`array`:return`${wrap(renderType(t.items,next(n)))}[]`;case`object`:return renderObject(t,n);default:return`unknown`}}function renderObject(e,t){let n=isObject(e.properties)?e.properties:{},r=new Set(Array.isArray(e.required)?e.required.filter(e=>typeof e==`string`):[]),i=Object.entries(n).map(([e,n])=>{let i=IDENTIFIER.test(e)?e:JSON.stringify(e),a=r.has(e)?``:`?`,o=isObject(n)?propertyComment(n,t.descriptions):``;return`${i}${a}: ${renderType(n,next(t))}${o}`}),a=e.additionalProperties;return isObject(a)&&i.push(`[key: string]: ${renderType(a,next(t))}`),i.length===0?a===!1?`{}`:`Record<string, unknown>`:`{ ${i.join(`; `)} }`}function propertyComment(e,t){let n=[],r=t&&typeof e.description==`string`?e.description.replaceAll(/\s+/gu,` `).replace(/[\s.;,:]+$/u,``).trim():``;r.length>0&&n.push(truncate(r));for(let t of CONSTRAINT_KEYS)e[t]!==void 0&&n.push(`${t}: ${JSON.stringify(e[t])}`);return n.length===0?``:` /* ${n.join(`; `).replaceAll(`*/`,`* /`)} */`}function resolveRef(e,t){if(t.refs.has(e)||!e.startsWith(`#`))return;let n=t.root;for(let t of e.slice(1).split(`/`).filter(Boolean)){if(!isObject(n))return;n=n[t.replaceAll(`~1`,`/`).replaceAll(`~0`,`~`)]}return n}function next(e){return{...e,depth:e.depth+1}}function literal(e){return e===void 0?`undefined`:JSON.stringify(e)}function union(e){let t=[...new Set(e)];return t.length===0?`never`:t.join(` | `)}function wrap(e){return e.includes(` | `)||e.includes(` & `)?`(${e})`:e}function truncate(e){return e.length>120?`${e.slice(0,117)}...`:e}export{renderToolSignature};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{isUserMessageKind}from"#harness/messages.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{isSampledTrace}from"#shared/trace-policy.js";import{ROOT_CONTEXT,context,trace}from"#compiled/@opentelemetry/api/index.js";import{createAgentToolInstrumentation}from"#tracing/eve/agent-tool-instrumentation.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{createEveTracing}from"#tracing/eve/operation-input.js";import{createAgentApprovalInstrumentation}from"#tracing/eve/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/eve/agent-channel-delivery-instrumentation.js";import{eveActivationMetadata}from"#tracing/eve/metadata.js";import{createAgentMemoryInstrumentation}from"#tracing/eve/agent-memory-instrumentation.js";import{
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{isUserMessageKind}from"#harness/messages.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{isSampledTrace}from"#shared/trace-policy.js";import{ROOT_CONTEXT,context,trace}from"#compiled/@opentelemetry/api/index.js";import{gatewayCostAttributes,readGatewayCostData}from"#tracing/eve/gateway.js";import{createAgentToolInstrumentation}from"#tracing/eve/agent-tool-instrumentation.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{createEveTracing}from"#tracing/eve/operation-input.js";import{createAgentApprovalInstrumentation}from"#tracing/eve/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/eve/agent-channel-delivery-instrumentation.js";import{eveActivationMetadata}from"#tracing/eve/metadata.js";import{createAgentMemoryInstrumentation}from"#tracing/eve/agent-memory-instrumentation.js";import{createEveSessionTracing}from"#tracing/eve/session.js";import{createEveCapturePolicy}from"#tracing/eve/policy.js";function createAgentOtelInstrumentation(e){let t=e.environment??resolveInstrumentationEnvironment(),n=e.recordInputs??!1,r=e.recordOutputs??!1,i=createEveTracing(e),a=new Map,o=new Map,s=createEveSessionTracing({...e,environment:t,tracing:i}),{prepareSessionTrace:c,prepareTurnTrace:l}=s;async function attemptFor(e){let t=a.get(e.attemptId);if(t!==void 0)return t;let n=await s.turnFor(e.sessionId,e.turnId,withChannelAudience(ROOT_CONTEXT,e.channelAudience)),r={stepIndex:e.stepIndex,attempt:e.attemptIndex};return n?.findAttempt(r)??(n?.finished===!1?n.attempt(r):void 0)}let u=createAgentToolInstrumentation({tracing:i,attemptFor,stepFor:e=>a.get(e.attemptId),recordInputs:n,recordOutputs:r,stateStore:e.stateStore}),d=createAgentApprovalInstrumentation({tracing:i,actionStateFor:u.stateFor}),f=createAgentMemoryInstrumentation({...e,environment:t,tracing:i}),p=createEveCapturePolicy({stateStore:e.stateStore,environment:t,recordInputs:n,recordOutputs:r});function turnState(t){return e.stateStore.get(`turn`,JSON.stringify([t.sessionId,t.turnId]))}let onSessionStarted=async e=>{await c(e)},onTurnStarted=async e=>{await l(e)},onStepStarted=async t=>{let n=await turnState(t.scope);if(n===void 0||!isSampledTrace(n.context))return;let r=await e.stateStore.get(`session`,t.scope.sessionId),i=await s.turnFor(t.scope.sessionId,t.scope.turnId,withChannelAudience(ROOT_CONTEXT,t.scope.channelAudience));if(i===void 0||i.finished)return;let o=trace.getSpan(context.active())?.spanContext(),c=await i.attempt({stepIndex:t.scope.stepIndex,attempt:t.scope.attemptIndex,runtimeContext:t.runtimeContext,channel:eveActivationMetadata({session:r,turn:n,sessionId:t.scope.sessionId}).channel,links:o===void 0||o.traceId===n.context.traceId?void 0:[{relationship:`execution.delivery`,context:o}]});a.set(t.scope.attemptId,c)},onStepTerminal=async e=>{let t=e.type===`step.attempt.failed`?{error:e.error}:void 0;await drainOpenSpans(e),await u.drain(e.scope.attemptId,t);let n=a.get(e.scope.attemptId)??await attemptFor(e.scope);a.delete(e.scope.attemptId),t===void 0?await n?.complete():(await n?.fail(t.error),await u.forgetAttempt(e.scope))},onSessionTransition=async t=>{await s.sessionTransition(t),(t.type===`session.completed`||t.type===`session.failed`)&&(await u.deleteForSession(t.sessionId),await e.stateStore.delete(`session`,t.sessionId))},onModelCallStarted=async e=>{let t=a.get(e.scope.attemptId);if(t===void 0)return;let r=await t.modelCall({provider:e.model.provider,modelId:e.model.modelId,messages:n?e.input?.messages.map(e=>isObject(e)&&e.role===`user`?{...e,kind:isUserMessageKind(e.kind)?e.kind:void 0}:e):void 0,instructions:n?e.input?.instructions:void 0,tools:n?e.input?.tools:void 0,runtimeContext:e.runtimeContext},e.idempotencyKey),i=o.get(e.scope.attemptId);i===void 0&&o.set(e.scope.attemptId,i=new Map),i.set(e.idempotencyKey,r)},onModelCallTerminal=async e=>{let t=o.get(e.scope.attemptId),n=t?.get(e.idempotencyKey);t?.delete(e.idempotencyKey),n!==void 0&&(e.type===`model.call.failed`?await n.fail(e.error):await n.complete({outcome:`completed`,result:{...e,content:r?e.content:void 0}}))},m=createAgentChannelDeliveryInstrumentation({recordInputs:n,stateStore:e.stateStore}),onStepMetadata=e=>{let t=a.get(e.scope.attemptId);if(t===void 0)return;let n=readGatewayCostData(e.providerMetadata);n!==void 0&&t.attributes(gatewayCostAttributes(n))};return{hook:{events:{...m,...d,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...u.events,"turn.cancelled":s.turnTerminal,"turn.completed":s.turnTerminal,"turn.failed":s.turnTerminal,"turn.started":onTurnStarted},name:`eve.otel`,projectEvent:p.projectEvent,tracePolicy:()=>({emit:!0,recordInputs:n,recordOutputs:r})},prepareSessionTrace:c,prepareTurnTrace:l,async runInContext(t,n){if(t.type===`memory.operation`)return f.runInContext(t,n);let r={emit:!0,...await p.forOperation(t.scope)},inTurn=async()=>{let i=await s.turnFor(t.scope.sessionId,t.scope.turnId,withChannelAudience(ROOT_CONTEXT,t.scope.channelAudience));if(i!==void 0&&!i.finished)return i.run(n,r);let{sessionId:a,turnId:o}=t.scope;return e.telemetry.suppressed!==void 0&&await s.dropped(a,o)?e.telemetry.suppressed(n):n()};if(t.type===`tool.call`)return u.runInContext(t,n,r,inTurn);let i=o.get(t.scope.attemptId)?.get(t.idempotencyKey);return i!==void 0&&!i.finished?i.run(n,r):inTurn()}};async function drainOpenSpans(e){for(let t of o.get(e.scope.attemptId)?.values()??[])e.type===`step.attempt.failed`?await t.fail(e.error):await t.complete({outcome:`completed`,result:{finishReason:`unknown`,usage:{}}});o.delete(e.scope.attemptId)}}export{createAgentOtelInstrumentation};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/** Converts Gateway response metadata to cost data. */
|
|
2
1
|
import type { Attributes } from "#compiled/@eve/tracing/index.js";
|
|
2
|
+
export declare function createGatewayTraceContextHeaders(): Record<string, string> | undefined;
|
|
3
|
+
/** Converts Gateway response metadata to cost data. */
|
|
3
4
|
export declare function gatewayCostAttributes(input: {
|
|
4
5
|
cost?: number;
|
|
5
6
|
gatewayCost?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function gatewayCostAttributes(e){return{"gen_ai.usage.cost":e.cost,"gen_ai.usage.gateway_cost":e.gatewayCost,"gen_ai.usage.input_cost":e.inputCost,"gen_ai.usage.output_cost":e.outputCost,"gen_ai.generation.id":e.generationId}}function readGatewayCostData(e){if(e===void 0)return;let t=e.gateway;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;return{cost:readUsd(n.cost),gatewayCost:readUsd(n.gatewayCost),inputCost:readUsd(n.inputInferenceCost),outputCost:readUsd(n.outputInferenceCost),generationId:typeof n.generationId==`string`&&n.generationId.length>0?n.generationId:void 0}}function readUsd(e){if(typeof e!=`string`||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}export{gatewayCostAttributes,readGatewayCostData};
|
|
1
|
+
import{stripEveTraceBaggage}from"#protocol/baggage.js";import{context,createContextKey,propagation,trace}from"#compiled/@opentelemetry/api/index.js";const SUPPRESS_TRACING_KEY=createContextKey(`OpenTelemetry SDK Context Key SUPPRESS_TRACING`),traceContextSetter={set(e,t,n){e[t]=n}};function createGatewayTraceContextHeaders(){let e=context.active();if(e.getValue(SUPPRESS_TRACING_KEY)===!0||trace.getSpan(e)===void 0)return;let t={};return propagation.inject(e,t,traceContextSetter),stripEveTraceBaggage(t),Object.keys(t).length===0?void 0:t}function gatewayCostAttributes(e){return{"gen_ai.usage.cost":e.cost,"gen_ai.usage.gateway_cost":e.gatewayCost,"gen_ai.usage.input_cost":e.inputCost,"gen_ai.usage.output_cost":e.outputCost,"gen_ai.generation.id":e.generationId}}function readGatewayCostData(e){if(e===void 0)return;let t=e.gateway;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;return{cost:readUsd(n.cost),gatewayCost:readUsd(n.gatewayCost),inputCost:readUsd(n.inputInferenceCost),outputCost:readUsd(n.outputInferenceCost),generationId:typeof n.generationId==`string`&&n.generationId.length>0?n.generationId:void 0}}function readUsd(e){if(typeof e!=`string`||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}export{createGatewayTraceContextHeaders,gatewayCostAttributes,readGatewayCostData};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/local/inspection.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{operationConversationId}from"#tracing/eve/conversation-context.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{context}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/eve/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{contentAttribute,mcpLifecycle,withErrorContent}from"#compiled/@eve/tracing/otel.js";import{otelTelemetry}from"#compiled/@eve/tracing/index.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{MCP_SERIALIZER}from"#tracing/eve/mcp.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{eveOutputMapping}from"#tracing/eve/profile.js";const log=createLogger(`invoke-tool`),agentTelemetry=()=>otelTelemetry({tracerName:`eve.agent`,mapping:eveOutputMapping()});async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=agentTelemetry(),a=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),o=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...a})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:a.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),s=r.otelSettings;if(s===void 0)return await n(o.observer(void 0));let c=resolveTracePolicy(s.tracePolicy,{agentName:e.agentName,...a},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(c.action===`drop`)return await i.suppressed(()=>n(o.observer(void 0)));let l=applyLiveDeliveryAudienceCeiling({
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/local/inspection.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{operationConversationId}from"#tracing/eve/conversation-context.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{context}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/eve/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{contentAttribute,mcpLifecycle,withErrorContent}from"#compiled/@eve/tracing/otel.js";import{otelTelemetry}from"#compiled/@eve/tracing/index.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{MCP_SERIALIZER}from"#tracing/eve/mcp.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{eveOutputMapping}from"#tracing/eve/profile.js";const log=createLogger(`invoke-tool`),agentTelemetry=()=>otelTelemetry({tracerName:`eve.agent`,mapping:eveOutputMapping()});async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=agentTelemetry(),a=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),o=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...a})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:a.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),s=r.otelSettings;if(s===void 0)return await n(o.observer(void 0));let c=resolveTracePolicy(s.tracePolicy,{agentName:e.agentName,...a},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(c.action===`drop`)return await i.suppressed(()=>n(o.observer(void 0)));let l=applyLiveDeliveryAudienceCeiling({...c,recordInputs:s.recordInputs&&c.recordInputs,recordOutputs:s.recordOutputs&&c.recordOutputs},a.audience,void 0,a.environment),u=l.action===`record`&&l.recordInputs,d=l.action===`record`&&l.recordOutputs,f=`execute_tool ${e.toolName}`,p=withChannelAudience(t,a.audience),m={"agent.tool.is_framework":!1,"gen_ai.agent.name":e.agentName,"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,[DIRECT_TOOL_CALL_ATTRIBUTE]:DIRECT_TOOL_CALL_VALUE,"operation.name":`execute_tool`,"resource.name":f,"agent.run.id":e.sessionId,"agent.trace.schema.version":4,"gen_ai.conversation.id":operationConversationId({sessionId:e.sessionId})};process.env.VERCEL_ENV!==void 0&&(m[`vercel.session_id`]=e.sessionId),e.origin!==void 0&&(m[`eve.channel.kind`]=a.channel.kind,m[`eve.channel.name`]=e.origin.channelName);let h=i.startSpan({type:`tool`,operationId:e.callId,name:f,kind:`INTERNAL`,attributes:m},{context:p}),g={emit:!0,recordInputs:u,recordOutputs:d},_=markAgentTraceContext(withErrorContent(p,d)),v=mcpLifecycle({serializer:MCP_SERIALIZER,...g,write:e=>setDefined(h,e),error:(e,t)=>h.fail(d?e:void 0,t)}),y,b=o.observer({failedWith:e=>{y={error:e}},recordInputs:u,span:h});try{let e=await i.run({type:`tool`,reference:h.reference,capture:g,mcp:v},()=>n(b),_);if(h.setAttribute(`eve.tool.outcome`,e.status),e.status===`completed`&&d){let t=contentAttribute(e.output);t!==void 0&&h.setAttribute(`gen_ai.tool.call.result`,t)}return e.status===`invalid-input`?h.fail(void 0,e.status):e.status===`failed`&&h.fail(d?y?.error:void 0,y===void 0?e.status:void 0),e}catch(e){throw h.fail(d?e:void 0),e}finally{h.end(),await r.forceFlush().catch(e=>{log.warn(`flushing a tool call's trace failed`,{error:formatError(e)})})}}const silentObserver={executed:async()=>{},executing:async()=>{},failedWith:()=>{}};function toolCallEvents(e,t,n){let r=e.capturesInputs??e.capturesContent,i=e.capturesOutputs??e.capturesContent,a=toolCallIdempotencyKey(t,n.callId,0);return{observer(o){return{async executing(i){if(o?.recordInputs){let e=contentAttribute(i);e!==void 0&&o.span.setAttribute(`gen_ai.tool.call.arguments`,e)}await e.publish(Object.freeze({callId:n.callId,idempotencyKey:a,input:r?i:void 0,scope:t,toolName:n.toolName,type:`tool.call.started`}))},async executed(n){o?.span.setAttribute(`gen_ai.execute_tool.duration`,n.durationMs/1e3);let r=n.type===`result`?i?{output:n.output,type:`result`}:{type:`result`}:i?{error:n.error,type:`error`}:{type:`error`};await e.publish(Object.freeze({durationMs:n.durationMs,idempotencyKey:a,output:Object.freeze(r),scope:t,type:`tool.call.completed`,outcome:n.type===`result`?`completed`:`failed`}))},failedWith(e){o?.failedWith(e)}}}}}function setDefined(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&e.setAttribute(n,r)}export{withInvokeToolSpan};
|
|
@@ -33,14 +33,15 @@ export interface OtelOptions {
|
|
|
33
33
|
/**
|
|
34
34
|
* Process-wide trace and content decision. Boolean returns preserve the
|
|
35
35
|
* existing audience-aware behavior; explicit decisions can disable emission
|
|
36
|
-
* or select input and output capture independently
|
|
37
|
-
* every audience, with content only for public
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* parent's effective ceiling, so every
|
|
42
|
-
*
|
|
43
|
-
*
|
|
36
|
+
* or select input and output capture independently for any audience.
|
|
37
|
+
* Defaults to emitting every audience, with content only for public
|
|
38
|
+
* conversations or development. Explicit content decisions override defaults
|
|
39
|
+
* for the evaluated audience, but destination settings can only narrow them.
|
|
40
|
+
* For a trusted remote trace, eve evaluates this policy against the immutable
|
|
41
|
+
* origin audience and intersects it with the parent's effective ceiling, so every
|
|
42
|
+
* hop can only narrow capture. It never changes what lifecycle instrumentation
|
|
43
|
+
* receives. A thrown error rejects trace production without silencing
|
|
44
|
+
* lifecycle providers. The policy may be invoked more than once
|
|
44
45
|
* while a new session is being prepared, so it must be deterministic for
|
|
45
46
|
* consistent results.
|
|
46
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{applyLiveDeliveryAudienceCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#shared/trace-policy.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";function createEveCapturePolicy(e){return{async projectEvent(t){let n=await e.stateStore.get(`session`,`scope`in t?t.scope.sessionId:t.sessionId),r=audienceForEvent(t,n?.channelAudience),i=`traceSeed`in t?t.traceSeed:void 0,a=contextStorage.getStore()?.get(SessionTraceSeedKey),o=resolveForwardedTraceSeed(a),s=resolveForwardedTraceSeed(i,o?.forwardedTracePolicy),decisionForTrace=t=>t===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(t),{audience:r,environment:e.environment}),c=s?.decision??o?.decision??readInstrumentationDecision(n?.decision)??decisionForTrace(i)??decisionForTrace(a)??decisionForTrace(n?.context);if(c===void 0)return withoutInstrumentationContent(t);let l=s===void 0||!(`traceSeed`in t)||t.traceSeed===void 0?t:{...t,traceSeed:{...t.traceSeed,decision:s.decision,traceFlags:s.traceFlags}};return instrumentationEventForTraceDecision(l,applyLiveDeliveryAudienceCeiling(c.action===`drop`?c:{
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{applyLiveDeliveryAudienceCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#shared/trace-policy.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";function createEveCapturePolicy(e){return{async projectEvent(t){let n=await e.stateStore.get(`session`,`scope`in t?t.scope.sessionId:t.sessionId),r=audienceForEvent(t,n?.channelAudience),i=`traceSeed`in t?t.traceSeed:void 0,a=contextStorage.getStore()?.get(SessionTraceSeedKey),o=resolveForwardedTraceSeed(a),s=resolveForwardedTraceSeed(i,o?.forwardedTracePolicy),decisionForTrace=t=>t===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(t),{audience:r,environment:e.environment}),c=s?.decision??o?.decision??readInstrumentationDecision(n?.decision)??decisionForTrace(i)??decisionForTrace(a)??decisionForTrace(n?.context);if(c===void 0)return withoutInstrumentationContent(t);let l=s===void 0||!(`traceSeed`in t)||t.traceSeed===void 0?t:{...t,traceSeed:{...t.traceSeed,decision:s.decision,traceFlags:s.traceFlags}};return instrumentationEventForTraceDecision(l,applyLiveDeliveryAudienceCeiling(c.action===`drop`?c:{...c,recordInputs:e.recordInputs&&c.recordInputs,recordOutputs:e.recordOutputs&&c.recordOutputs},r,s?.forwardedTracePolicy??o?.forwardedTracePolicy,e.environment),{audience:r,environment:e.environment},{applyAudienceCeiling:!1})},async forOperation(t){let n=await e.stateStore.get(`session`,t.sessionId),r=resolveForwardedTraceSeed(contextStorage.getStore()?.get(SessionTraceSeedKey)),i=r?.decision??n?.decision,a=i===void 0?void 0:applyLiveDeliveryAudienceCeiling(i,normalizeChannelAudience(t.channelAudience),r?.forwardedTracePolicy,e.environment);return{recordInputs:e.recordInputs&&a?.action===`record`&&a.recordInputs,recordOutputs:e.recordOutputs&&a?.action===`record`&&a.recordOutputs}}}}function audienceForEvent(e,t){return`delivery`in e?normalizeChannelAudience(e.delivery.channelAudience):`scope`in e&&e.scope.channelAudience!==void 0?normalizeChannelAudience(e.scope.channelAudience):e.type===`session.started`?normalizeChannelAudience(e.channelAudience):normalizeChannelAudience(t)}export{createEveCapturePolicy};
|