eve 0.36.0 → 0.37.1
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 +29 -0
- package/README.md +1 -0
- package/dist/src/channel/routes.d.ts +13 -3
- package/dist/src/channel/routes.js +1 -1
- package/dist/src/channel/session-callback.js +1 -1
- package/dist/src/channel/session.d.ts +2 -1
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +41 -0
- package/dist/src/chunks/{use-eve-agent-CnppTEFk.js → use-eve-agent-Bi5fRxcZ.js} +9 -1
- package/dist/src/chunks/{use-eve-agent-COmP-H8R.js → use-eve-agent-DbKUBhl-.js} +9 -1
- package/dist/src/cli/commands/agent-instructions.d.ts +4 -4
- package/dist/src/cli/commands/init-confirm.d.ts +12 -0
- package/dist/src/cli/commands/init-confirm.js +1 -0
- package/dist/src/cli/commands/init-git.js +1 -1
- package/dist/src/cli/commands/init-recovery.d.ts +3 -0
- package/dist/src/cli/commands/init-recovery.js +3 -0
- package/dist/src/cli/commands/init-target.d.ts +21 -0
- package/dist/src/cli/commands/init-target.js +1 -0
- package/dist/src/cli/commands/init.d.ts +6 -5
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +8 -0
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.d.ts +27 -22
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.d.ts +16 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
- package/dist/src/cli/dev/tui/tool-presentation.js +1 -1
- package/dist/src/cli/run.d.ts +1 -0
- package/dist/src/cli/run.js +3 -3
- package/dist/src/client/open-stream.d.ts +2 -0
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +3 -1
- package/dist/src/compiled/@modelcontextprotocol/server/LICENSE +216 -0
- package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +98 -0
- package/dist/src/compiled/@modelcontextprotocol/server/index.js +80 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +339 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +1 -1
- package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +25 -1
- package/dist/src/compiled/@vercel/sandbox/drive.d.ts +140 -0
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +3 -2
- package/dist/src/compiled/@vercel/sandbox/index.js +13 -13
- package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +55 -18
- package/dist/src/compiled/@vercel/sandbox-stable/LICENSE +201 -0
- package/dist/src/compiled/@vercel/sandbox-stable/_async-retry.d.ts +8 -0
- package/dist/src/compiled/@vercel/sandbox-stable/_workflow-serde.d.ts +5 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/api-client.d.ts +1456 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/api-error.d.ts +29 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/base-client.d.ts +39 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/file-writer.d.ts +66 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/index.d.ts +2 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/validators.d.ts +899 -0
- package/dist/src/compiled/@vercel/sandbox-stable/api-client/with-retry.d.ts +10 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/error.d.ts +15 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/file.d.ts +18 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/index.d.ts +6 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/oauth.d.ts +111 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/poll-for-token.d.ts +28 -0
- package/dist/src/compiled/@vercel/sandbox-stable/auth/project.d.ts +40 -0
- package/dist/src/compiled/@vercel/sandbox-stable/command.d.ts +292 -0
- package/dist/src/compiled/@vercel/sandbox-stable/constants.d.ts +5 -0
- package/dist/src/compiled/@vercel/sandbox-stable/execution-context.d.ts +116 -0
- package/dist/src/compiled/@vercel/sandbox-stable/filesystem.d.ts +258 -0
- package/dist/src/compiled/@vercel/sandbox-stable/index.d.ts +12 -0
- package/dist/src/compiled/@vercel/sandbox-stable/index.js +1 -0
- package/dist/src/compiled/@vercel/sandbox-stable/network-policy.d.ts +169 -0
- package/dist/src/compiled/@vercel/sandbox-stable/proxy.d.ts +55 -0
- package/dist/src/compiled/@vercel/sandbox-stable/sandbox-user.d.ts +212 -0
- package/dist/src/compiled/@vercel/sandbox-stable/sandbox.d.ts +1216 -0
- package/dist/src/compiled/@vercel/sandbox-stable/session.d.ts +433 -0
- package/dist/src/compiled/@vercel/sandbox-stable/snapshot.d.ts +229 -0
- package/dist/src/compiled/@vercel/sandbox-stable/utils/get-credentials.d.ts +21 -0
- package/dist/src/compiled/@vercel/sandbox-stable/utils/paginator.d.ts +16 -0
- package/dist/src/compiled/@vercel/sandbox-stable/utils/resolveSignal.d.ts +15 -0
- package/dist/src/compiled/@vercel/sandbox-stable/utils/sandbox-snapshot.d.ts +11 -0
- package/dist/src/compiled/@vercel/sandbox-stable/utils/types.d.ts +11 -0
- package/dist/src/compiled/_chunks/node/{auth-BS3UoyvT.js → auth-BaNbsImr.js} +1 -1
- package/dist/src/compiled/_chunks/node/version-BYHw-SDY.js +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-subagent.d.ts +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/context/serialized-dynamic-model-selection.d.ts +2 -0
- package/dist/src/context/serialized-dynamic-model-selection.js +1 -0
- package/dist/src/execution/agent-handle-dispatch.d.ts +15 -1
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/delegated-parent-notification.d.ts +17 -0
- package/dist/src/execution/delegated-parent-notification.js +1 -1
- package/dist/src/execution/deliver-payloads.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +155 -0
- package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -0
- package/dist/src/execution/dispatch-runtime-actions-step.d.ts +18 -14
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-workflow-runtime-actions-step.d.ts +7 -2
- package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
- package/dist/src/execution/effective-output-schema.d.ts +21 -0
- package/dist/src/execution/effective-output-schema.js +1 -0
- package/dist/src/execution/eve-workflow-attributes.d.ts +2 -0
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/parked-delivery-wait.d.ts +8 -12
- package/dist/src/execution/parked-delivery-wait.js +1 -1
- package/dist/src/execution/{route-proxied-deliver-step.d.ts → proxied-deliver-step.d.ts} +7 -4
- package/dist/src/execution/proxied-deliver-step.js +1 -0
- package/dist/src/execution/remote-agent-dispatch.d.ts +32 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/remote-agent-route-url.d.ts +2 -0
- package/dist/src/execution/remote-agent-route-url.js +1 -0
- package/dist/src/execution/route-child-delivery.d.ts +2 -1
- package/dist/src/execution/route-child-delivery.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +2 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session-callback-step.d.ts +11 -0
- package/dist/src/execution/session-callback-step.js +1 -1
- package/dist/src/execution/session-command-wire.js +1 -1
- package/dist/src/execution/session-state-cursor.d.ts +25 -0
- package/dist/src/execution/session-state-cursor.js +1 -0
- package/dist/src/execution/settle-cancelled-turn-step.d.ts +2 -0
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-event-proxy-step.d.ts +15 -0
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.d.ts +14 -7
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/subagent-start-local.d.ts +29 -0
- package/dist/src/execution/subagent-start-local.js +1 -0
- package/dist/src/execution/subagent-start-remote.d.ts +23 -0
- package/dist/src/execution/subagent-start-remote.js +1 -0
- package/dist/src/execution/task-event-callback.d.ts +13 -0
- package/dist/src/execution/task-event-callback.js +1 -0
- package/dist/src/execution/task-input-capability.d.ts +4 -0
- package/dist/src/execution/task-input-capability.js +1 -0
- package/dist/src/execution/tasks/child/steps.d.ts +46 -0
- package/dist/src/execution/tasks/child/steps.js +1 -0
- package/dist/src/execution/tasks/child/workflow.d.ts +31 -0
- package/dist/src/execution/tasks/child/workflow.js +1 -0
- package/dist/src/execution/tasks/parent/agent-identity.d.ts +13 -0
- package/dist/src/execution/tasks/parent/agent-identity.js +1 -0
- package/dist/src/execution/tasks/parent/agent-views.d.ts +6 -0
- package/dist/src/execution/tasks/parent/agent-views.js +1 -0
- package/dist/src/execution/tasks/parent/continuation-dispatch.d.ts +37 -0
- package/dist/src/execution/tasks/parent/continuation-dispatch.js +1 -0
- package/dist/src/execution/tasks/parent/control-shared.d.ts +36 -0
- package/dist/src/execution/tasks/parent/control-shared.js +1 -0
- package/dist/src/execution/tasks/parent/delegate.d.ts +70 -0
- package/dist/src/execution/tasks/parent/delegate.js +1 -0
- package/dist/src/execution/tasks/parent/dispatch-task-step.d.ts +19 -0
- package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -0
- package/dist/src/execution/tasks/parent/dispatch.d.ts +33 -0
- package/dist/src/execution/tasks/parent/dispatch.js +1 -0
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.d.ts +29 -0
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -0
- package/dist/src/execution/tasks/parent/run-parent.d.ts +72 -0
- package/dist/src/execution/tasks/parent/run-parent.js +1 -0
- package/dist/src/execution/tasks/parent/send.d.ts +25 -0
- package/dist/src/execution/tasks/parent/send.js +1 -0
- package/dist/src/execution/tasks/workflow-target.d.ts +2 -0
- package/dist/src/execution/tasks/workflow-target.js +1 -0
- package/dist/src/execution/terminate-child-sessions-step.d.ts +1 -0
- package/dist/src/execution/terminate-child-sessions-step.js +1 -1
- package/dist/src/execution/turn-control-receiver.d.ts +10 -0
- package/dist/src/execution/turn-control-receiver.js +1 -1
- package/dist/src/execution/turn-dispatch.d.ts +2 -0
- package/dist/src/execution/turn-dispatch.js +1 -1
- package/dist/src/execution/turn-execution-cursor.d.ts +2 -8
- package/dist/src/execution/turn-execution-cursor.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-callback-url.d.ts +5 -0
- package/dist/src/execution/workflow-callback-url.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +9 -0
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +7 -21
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/advertised-tools.js +1 -1
- package/dist/src/harness/authorization.js +1 -1
- package/dist/src/harness/execute-tool.d.ts +7 -0
- package/dist/src/harness/handles/prompt.d.ts +12 -0
- package/dist/src/harness/handles/prompt.js +2 -1
- package/dist/src/harness/handles/query.js +1 -1
- package/dist/src/harness/handles/store.d.ts +9 -2
- package/dist/src/harness/handles/store.js +1 -1
- package/dist/src/harness/handles/transitions.d.ts +10 -1
- package/dist/src/harness/handles/transitions.js +1 -1
- package/dist/src/harness/proxy-input-requests.d.ts +21 -4
- package/dist/src/harness/proxy-input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.d.ts +2 -0
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/workflow-runtime-action-state.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/invocation/agent-invocation.d.ts +54 -0
- package/dist/src/internal/invocation/agent-invocation.js +1 -0
- package/dist/src/internal/invocation/attributes.d.ts +2 -0
- package/dist/src/internal/invocation/attributes.js +1 -0
- package/dist/src/internal/invocation/metadata.d.ts +9 -0
- package/dist/src/internal/invocation/metadata.js +1 -0
- package/dist/src/internal/invocation/workflow-execution.d.ts +32 -0
- package/dist/src/internal/invocation/workflow-execution.js +1 -0
- package/dist/src/internal/mcp/http-security.d.ts +12 -0
- package/dist/src/internal/mcp/http-security.js +1 -0
- package/dist/src/internal/mcp/protected-resource.d.ts +9 -0
- package/dist/src/internal/mcp/protected-resource.js +1 -0
- package/dist/src/internal/mcp/streamable-http-server.d.ts +51 -0
- package/dist/src/internal/mcp/streamable-http-server.js +1 -0
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +14 -0
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/internal/nitro/routes/runtime-stack.d.ts +2 -0
- package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
- package/dist/src/internal/vercel-agent-summary.d.ts +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/message.d.ts +28 -0
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/routes.d.ts +14 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/auth.d.ts +36 -0
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/mcp.d.ts +19 -0
- package/dist/src/public/channels/mcp.js +1 -0
- package/dist/src/public/definitions/channel.d.ts +2 -2
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/sandbox/backends/vercel.d.ts +5 -4
- package/dist/src/public/sandbox/backends/vercel.js +1 -1
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +25 -1
- package/dist/src/public/sandbox/vercel.d.ts +2 -1
- package/dist/src/public/sandbox/vercel.js +1 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/actions/types.d.ts +9 -0
- package/dist/src/runtime/actions/types.js +1 -1
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/connections/authorization-complete-page.js +70 -28
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/framework-tools/tasks.d.ts +95 -0
- package/dist/src/runtime/framework-tools/tasks.js +1 -0
- package/dist/src/runtime/prompt/compose.d.ts +1 -0
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/session-callback-route.js +1 -1
- package/dist/src/runtime/task-input-response-route.d.ts +5 -0
- package/dist/src/runtime/task-input-response-route.js +1 -0
- package/dist/src/setup/scaffold/create/add-to-project.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 +0 -1
- package/dist/src/shared/agent-definition.d.ts +7 -0
- package/dist/src/shared/sandbox-network-policy.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tasks/json.d.ts +88 -0
- package/dist/src/tasks/json.js +1 -0
- package/dist/src/tasks/session-index.d.ts +48 -0
- package/dist/src/tasks/session-index.js +1 -0
- package/dist/src/tasks/task-id.d.ts +34 -0
- package/dist/src/tasks/task-id.js +1 -0
- package/dist/src/tasks/transitions.d.ts +23 -0
- package/dist/src/tasks/transitions.js +1 -0
- package/dist/src/tasks/types.d.ts +295 -0
- package/dist/src/tasks/types.js +1 -0
- package/dist/src/tasks/wire.d.ts +26 -0
- package/dist/src/tasks/wire.js +1 -0
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/eve.mdx +14 -0
- package/docs/guides/client/streaming.mdx +1 -1
- package/docs/reference/cli.md +10 -6
- package/docs/tools/human-in-the-loop.md +3 -1
- package/package.json +8 -1
- package/dist/src/compiled/_chunks/node/version-Cztrk7z6.js +0 -1
- package/dist/src/execution/route-proxied-deliver-step.js +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Runtime } from "#channel/types.js";
|
|
2
|
+
import type { RemoteAgentStreamHeadersResolver } from "#internal/nitro/routes/channel-route-context.js";
|
|
2
3
|
import type { ResolvedChannelDefinition } from "#runtime/types.js";
|
|
3
4
|
import { type NitroArtifactsConfig } from "#internal/nitro/routes/runtime-artifacts.js";
|
|
4
5
|
/**
|
|
@@ -12,6 +13,7 @@ import { type NitroArtifactsConfig } from "#internal/nitro/routes/runtime-artifa
|
|
|
12
13
|
*/
|
|
13
14
|
export interface NitroChannelRuntimeBundle {
|
|
14
15
|
readonly channels: readonly ResolvedChannelDefinition[];
|
|
16
|
+
readonly resolveRemoteAgentStreamHeaders?: RemoteAgentStreamHeadersResolver;
|
|
15
17
|
readonly runtime: Runtime;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";async function resolveNitroChannelRuntimeBundle(
|
|
1
|
+
import{resolveRemoteAgentStreamHeaders}from"#execution/remote-agent-dispatch.js";import{createWorkflowRuntime}from"#execution/workflow-runtime.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";async function resolveNitroChannelRuntimeBundle(t){let n=resolveNitroCompiledArtifactsSource(t),r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:n}),i=createWorkflowRuntime({compiledArtifactsSource:n});return{channels:r.graph.root.channels,resolveRemoteAgentStreamHeaders:async e=>await resolveRemoteAgentStreamHeaders({bundle:r,...e}),runtime:i}}export{resolveNitroChannelRuntimeBundle};
|
|
@@ -140,7 +140,7 @@ export interface VercelEveConnectionEntry {
|
|
|
140
140
|
}
|
|
141
141
|
export interface VercelEveChannelEntry {
|
|
142
142
|
readonly name: string;
|
|
143
|
-
readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "WEBSOCKET";
|
|
143
|
+
readonly method: "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "WEBSOCKET";
|
|
144
144
|
readonly urlPath: string;
|
|
145
145
|
readonly type: VercelEveChannelType;
|
|
146
146
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function connectionProtocols(e){return[e.mcp?`mcp`:null,e.openapi?`openapi`:null].filter(e=>e!==null)}const INTEGRATIONS=[{slug:`slack`,name:`Slack`,kind:`channel`,tagline:`Mention your agent in channels and DMs, with Connect-managed auth.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`discord`,name:`Discord`,kind:`channel`,tagline:`Run your agent as a Discord bot across servers and threads.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`teams`,name:`Microsoft Teams`,kind:`channel`,tagline:`Bring your agent into Teams chats and channels.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`telegram`,name:`Telegram`,kind:`channel`,tagline:`Connect your agent to a Telegram bot for 1:1 and group chats.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`twilio`,name:`Twilio`,kind:`channel`,tagline:`Put your agent on a phone number: SMS and speech-transcribed calls.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github`,name:`GitHub`,kind:`channel`,tagline:`Drive your agent from issues, pull requests, and comments, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linear-agent`,name:`Linear Agent`,kind:`channel`,tagline:`Delegate Linear issues and comments through Agent Sessions, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`eve`,name:`Web Chat`,kind:`channel`,tagline:`Embed a first-party web chat UI backed by your agent.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`buzz`,name:`Buzz`,kind:`channel`,tagline:`Talk to your eve agent from Buzz through its ACP desktop harness.`,surfaces:{scaffoldable:!1,registry:!1,gallery:!0}},{slug:`chat-sdk-gchat`,name:`Google Chat`,kind:`channel`,tagline:`Google Chat spaces and DMs via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-whatsapp`,name:`WhatsApp`,kind:`channel`,tagline:`Customer messaging through WhatsApp Business Cloud via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-x`,name:`X`,kind:`channel`,tagline:`Public mentions and DMs on X via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-messenger`,name:`Messenger`,kind:`channel`,tagline:`Facebook Messenger bots with templates, buttons, and reactions via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-zernio`,name:`Zernio`,kind:`channel`,tagline:`Reach seven social and messaging platforms through one Zernio integration.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-velt`,name:`Velt`,kind:`channel`,tagline:`Add agents to anchored comments across documents, canvases, PDFs, and video.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-sendblue`,name:`Sendblue`,kind:`channel`,tagline:`Send and receive iMessage, SMS, and RCS through Sendblue.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-novu`,name:`Novu`,kind:`channel`,tagline:`Reach Slack, Teams, WhatsApp, Telegram, and email through Novu.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-liveblocks`,name:`Liveblocks`,kind:`channel`,tagline:`Bring your agent into Liveblocks comment threads, mentions, and reactions.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-linq`,name:`Linq`,kind:`channel`,tagline:`iMessage and SMS conversations, media, and tapbacks through Linq.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-kapso`,name:`Kapso`,kind:`channel`,tagline:`Managed WhatsApp conversations, media, buttons, and history through Kapso.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`photon`,name:`Photon`,kind:`channel`,tagline:`iMessage through Photon, with guided project and phone setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-dial`,name:`Dial`,kind:`channel`,tagline:`Give your agent a phone number for SMS, MMS, iMessage, and voice transcripts.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-agentphone`,name:`AgentPhone`,kind:`channel`,tagline:`SMS, MMS, iMessage, and voice conversations through AgentPhone.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-lark`,name:`Lark / Feishu`,kind:`channel`,tagline:`Lark and Feishu chats with native card streaming via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-beeper`,name:`Beeper`,kind:`channel`,tagline:`Matrix rooms and bridged messaging networks through Beeper.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-resend`,name:`Resend`,kind:`channel`,tagline:`Send and receive threaded email through Resend via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`agent-browser`,name:`agent-browser`,kind:`extension`,tagline:`Add browser automation tools backed by agent-browser to an eve agent.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browserbase`,name:`Browserbase`,kind:`extension`,tagline:`Search, fetch, and automate the web with Browserbase and Stagehand.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github-tools`,name:`GitHub Tools`,kind:`extension`,tagline:`Add scoped GitHub tools with Vercel Connect authentication and approval rules.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jetty`,name:`Jetty`,kind:`extension`,tagline:`Grade agent turns, compare experiments, and store durable evaluation trajectories.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`kernel`,name:`KERNEL`,kind:`extension`,tagline:`Let your eve agent use the Internet with KERNEL browser infra, o11y, and stealth. Integrated natively with Vercel Connect and AI Gateway.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`upstash-agentkit`,name:`Upstash AgentKit`,kind:`extension`,tagline:`Add long-term memory, Redis Search, and durable chat history with Upstash Redis.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arcana`,name:`Kybernesis Arcana`,kind:`extension`,tagline:`Give your agent workspace-scoped long-term memory with recall, storage, and brain notes.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`hindsight`,name:`Hindsight`,kind:`extension`,tagline:`Recall relevant context before every turn and retain each exchange automatically.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browser-use`,name:`Browser Use`,kind:`connection`,tagline:`Run managed browser automation tasks through Browser Use's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Browser Use: run browser automation tasks, inspect sessions, and manage browser profiles.`,mcp:{url:`https://api.browser-use.com/v3/mcp`}}},{slug:`vercel`,name:`Vercel`,kind:`connection`,tagline:`Manage Vercel projects, deployments, and logs through Vercel's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Vercel: manage projects and deployments, inspect logs, and search documentation.`,mcp:{url:`https://mcp.vercel.com`}}},{slug:`linear`,name:`Linear`,kind:`connection`,tagline:`Issues, projects, cycles, and comments via Linear's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Linear workspace: issues, projects, cycles, and comments.`,mcp:{url:`https://mcp.linear.app/mcp`}}},{slug:`notion`,name:`Notion`,kind:`connection`,tagline:`Search and edit Notion pages and databases over MCP or OpenAPI.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Notion workspace: search and edit pages and databases.`,mcp:{url:`https://mcp.notion.com/mcp`},openapi:{spec:`https://developers.notion.com/openapi.json`,baseUrl:`https://api.notion.com`,headers:{"Notion-Version":`2022-06-28`}}}},{slug:`datadog`,name:`Datadog`,kind:`connection`,tagline:`Query metrics, monitors, and logs through Datadog's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Datadog: query metrics, monitors, logs, and incidents.`,mcp:{url:`https://mcp.datadoghq.com/api/mcp`}}},{slug:`honeycomb`,name:`Honeycomb`,kind:`connection`,tagline:`Explore traces and run queries through Honeycomb's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Honeycomb: explore traces, run queries, and inspect datasets.`,mcp:{url:`https://mcp.honeycomb.io/mcp`}}},{slug:`airtable`,name:`Airtable`,kind:`connection`,tagline:`Bases, tables, and records through Airtable's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Airtable: bases, tables, and records.`,mcp:{url:`https://mcp.airtable.com/mcp`}}},{slug:`bitly`,name:`Bitly`,kind:`connection`,tagline:`Shorten links, generate QR Codes, and track performance.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Bitly: shorten links, generate QR Codes, and track link performance.`,mcp:{url:`https://api-ssl.bitly.com/v4/mcp`}}},{slug:`brex`,name:`Brex`,kind:`connection`,tagline:`Expenses, cards, and cash through Brex's finance automation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Brex: expenses, cards, budgets, and cash.`,mcp:{url:`https://api.brex.com/mcp`}}},{slug:`candid`,name:`Candid`,kind:`connection`,tagline:`Research nonprofits and funders using Candid's data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Candid: research nonprofits, funders, and grants.`,mcp:{url:`https://mcp.candid.org/mcp`}}},{slug:`clickhouse`,name:`ClickHouse`,kind:`connection`,tagline:`Query and explore your ClickHouse Cloud data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`ClickHouse Cloud: query and explore databases and tables.`,mcp:{url:`https://mcp.clickhouse.cloud/mcp`}}},{slug:`cloudinary`,name:`Cloudinary`,kind:`connection`,tagline:`Manage, transform, and deliver your images and videos.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Cloudinary: manage, transform, and deliver image and video assets.`,mcp:{url:`https://asset-management.mcp.cloudinary.com/sse`}}},{slug:`coda`,name:`Coda`,kind:`connection`,tagline:`Create, search, and update docs and tables.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Coda: create, search, and update docs and tables.`,mcp:{url:`https://coda.io/apis/mcp`}}},{slug:`egnyte`,name:`Egnyte`,kind:`connection`,tagline:`Securely access and analyze Egnyte content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Egnyte: search, access, and analyze governed content.`,mcp:{url:`https://mcp-server.egnyte.com/mcp`}}},{slug:`embat`,name:`Embat`,kind:`connection`,tagline:`Ask Embat about cash, debt, payments, and accounting.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Embat: cash, debt, payments, and accounting.`,mcp:{url:`https://tellme.embat.io/mcp`}}},{slug:`hugging-face`,name:`Hugging Face`,kind:`connection`,tagline:`Access the Hugging Face Hub and thousands of Gradio apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Hugging Face: models, datasets, Spaces, and Gradio apps on the Hub.`,mcp:{url:`https://huggingface.co/mcp?login&gradio=none`}}},{slug:`local-falcon`,name:`Local Falcon`,kind:`connection`,tagline:`AI visibility and local search intelligence.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Local Falcon: local search rankings and AI visibility reports.`,mcp:{url:`https://mcp.localfalcon.com`}}},{slug:`make`,name:`Make`,kind:`connection`,tagline:`Run Make scenarios and manage your Make account.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Make: run scenarios and manage automations.`,mcp:{url:`https://mcp.make.com`}}},{slug:`manufact`,name:`Manufact`,kind:`connection`,tagline:`Deploy and monitor MCP servers with Manufact.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Manufact: deploy and monitor MCP servers.`,mcp:{url:`https://mcp.manufact.com/mcp`}}},{slug:`mem0`,name:`Mem0`,kind:`connection`,tagline:`Persistent memory for AI agents and assistants.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mem0: store and retrieve persistent agent memory.`,mcp:{url:`https://mcp.mem0.ai/mcp`}}},{slug:`miro`,name:`Miro`,kind:`connection`,tagline:`Access and create content on Miro boards.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Miro: read and create content on boards.`,mcp:{url:`https://mcp.miro.com/`}}},{slug:`mixpanel`,name:`Mixpanel`,kind:`connection`,tagline:`Analyze, query, and manage your Mixpanel data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mixpanel: analyze, query, and manage analytics data.`,mcp:{url:`https://mcp.mixpanel.com/mcp`}}},{slug:`natural`,name:`Natural`,kind:`connection`,tagline:`Send, request, and manage payments with Natural.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Natural: agentic payments — send and request payments, check balances, and move funds.`,mcp:{url:`https://mcp.natural.com/mcp`}}},{slug:`netlify`,name:`Netlify`,kind:`connection`,tagline:`Create, deploy, manage, and secure websites on Netlify.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Netlify: create, deploy, manage, and secure sites.`,mcp:{url:`https://netlify-mcp.netlify.app/mcp`}}},{slug:`oreilly`,name:`O'Reilly`,kind:`connection`,tagline:`Discover O'Reilly's expert learning content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`O'Reilly: search books, courses, and learning content.`,mcp:{url:`https://api.oreilly.com/api/content-discovery/v1/mcp/`}}},{slug:`planetscale`,name:`PlanetScale`,kind:`connection`,tagline:`Authenticated access to your PlanetScale Postgres and MySQL databases.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PlanetScale: query Postgres and MySQL databases.`,mcp:{url:`https://mcp.pscale.dev/mcp/planetscale`}}},{slug:`posthog`,name:`PostHog`,kind:`connection`,tagline:`Query, analyze, and manage your PostHog insights.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PostHog: insights, events, and feature flags.`,mcp:{url:`https://mcp.posthog.com/mcp`}}},{slug:`postman`,name:`Postman`,kind:`connection`,tagline:`Give API context to your coding agents with Postman.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Postman: APIs, collections, and workspaces.`,mcp:{url:`https://mcp.postman.com/minimal`}}},{slug:`razorpay`,name:`Razorpay`,kind:`connection`,tagline:`Razorpay payments, settlements, and dashboard data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Razorpay: payments, settlements, and dashboard data.`,mcp:{url:`https://mcp.razorpay.com/mcp`}}},{slug:`sentry`,name:`Sentry`,kind:`connection`,tagline:`Search, query, and debug errors intelligently.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Sentry: search, query, and debug errors and issues.`,mcp:{url:`https://mcp.sentry.dev/mcp`}}},{slug:`similarweb`,name:`Similarweb`,kind:`connection`,tagline:`Real-time web, mobile app, and market data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Similarweb: web traffic, app, and market intelligence data.`,mcp:{url:`https://mcp.similarweb.com`}}},{slug:`stripe`,name:`Stripe`,kind:`connection`,tagline:`Payment processing and financial infrastructure tools.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Stripe: payments, customers, billing, and financial infrastructure.`,mcp:{url:`https://mcp.stripe.com`}}},{slug:`supabase`,name:`Supabase`,kind:`connection`,tagline:`Manage databases, authentication, and storage.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Supabase: databases, authentication, and storage.`,mcp:{url:`https://mcp.supabase.com/mcp`}}},{slug:`ticket-tailor`,name:`Ticket Tailor`,kind:`connection`,tagline:`Manage tickets, orders, and events with Ticket Tailor.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Ticket Tailor: events, tickets, and orders.`,mcp:{url:`https://mcp.tickettailor.ai/mcp`}}},{slug:`ticktick`,name:`TickTick`,kind:`connection`,tagline:`Search, create, and manage your tasks and habits in TickTick.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`TickTick: tasks, habits, and lists.`,mcp:{url:`https://mcp.ticktick.com`}}},{slug:`tinybird`,name:`Tinybird`,kind:`connection`,tagline:`Query pipes and data sources in your Tinybird Workspace.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Tinybird: query pipes and data sources, and run SQL. A token grants one Workspace, so add a connection per Workspace.`,mcp:{url:`https://mcp.tinybird.co`}}},{slug:`todoist`,name:`Todoist`,kind:`connection`,tagline:`Search, complete, and manage your tasks in Todoist.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Todoist: search, complete, and manage tasks.`,mcp:{url:`https://ai.todoist.net/mcp`}}},{slug:`webflow`,name:`Webflow`,kind:`connection`,tagline:`Manage Webflow CMS, pages, assets, and sites.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Webflow: CMS items, pages, assets, and sites.`,mcp:{url:`https://mcp.webflow.com/mcp`}}},{slug:`wix`,name:`Wix`,kind:`connection`,tagline:`Manage and build sites and apps on Wix.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Wix: manage and build sites and apps.`,mcp:{url:`https://mcp.wix.com/mcp`}}},{slug:`zapier`,name:`Zapier`,kind:`connection`,tagline:`Automate workflows across thousands of apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zapier: run and manage automations across apps.`,mcp:{url:`https://mcp.zapier.com/api/v1/connect`}}},{slug:`zomato`,name:`Zomato`,kind:`connection`,tagline:`Online food ordering and delivery through Zomato.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zomato: food ordering and delivery.`,mcp:{url:`https://mcp-server.zomato.com/mcp`}}},{slug:`braintrust`,name:`Braintrust`,kind:`instrumentation`,tagline:`Export AI SDK spans to Braintrust for tracing, evals, and monitoring.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`posthog-instrumentation`,name:`PostHog`,kind:`instrumentation`,tagline:`Send agent traces and generations to PostHog AI Observability.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`sentry-instrumentation`,name:`Sentry`,kind:`instrumentation`,tagline:`Send agent traces to Sentry's OTLP endpoint for tracing and debugging.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`datadog-instrumentation`,name:`Datadog`,kind:`instrumentation`,tagline:`Export agent traces to Datadog APM alongside the rest of your stack.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`honeycomb-instrumentation`,name:`Honeycomb`,kind:`instrumentation`,tagline:`Send OpenTelemetry traces to Honeycomb and query every agent turn.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arize`,name:`Arize`,kind:`instrumentation`,tagline:`Export traces to Arize AX for LLM observability and evaluation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`raindrop`,name:`Raindrop`,kind:`instrumentation`,tagline:`Send agent traces to Raindrop to detect and debug AI product issues.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jaeger`,name:`Jaeger`,kind:`instrumentation`,tagline:`Trace your agent with a local or self-hosted Jaeger OTLP backend.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}}];new Map(INTEGRATIONS.map(e=>[e.slug,e]));function integrationsByKind(t){return INTEGRATIONS.filter(e=>e.kind===t)}function connectionEntries(){return integrationsByKind(`connection`)}function channelEntries(){return integrationsByKind(`channel`)}export{INTEGRATIONS,channelEntries,connectionEntries,connectionProtocols,integrationsByKind};
|
|
1
|
+
function connectionProtocols(e){return[e.mcp?`mcp`:null,e.openapi?`openapi`:null].filter(e=>e!==null)}const INTEGRATIONS=[{slug:`slack`,name:`Slack`,kind:`channel`,tagline:`Mention your agent in channels and DMs, with Connect-managed auth.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`discord`,name:`Discord`,kind:`channel`,tagline:`Run your agent as a Discord bot across servers and threads.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`teams`,name:`Microsoft Teams`,kind:`channel`,tagline:`Bring your agent into Teams chats and channels.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`telegram`,name:`Telegram`,kind:`channel`,tagline:`Connect your agent to a Telegram bot for 1:1 and group chats.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`twilio`,name:`Twilio`,kind:`channel`,tagline:`Put your agent on a phone number: SMS and speech-transcribed calls.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github`,name:`GitHub`,kind:`channel`,tagline:`Drive your agent from issues, pull requests, and comments, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`linear-agent`,name:`Linear Agent`,kind:`channel`,tagline:`Delegate Linear issues and comments through Agent Sessions, with guided Connect setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`eve`,name:`Web Chat`,kind:`channel`,tagline:`Embed a first-party web chat UI backed by your agent.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0}},{slug:`buzz`,name:`Buzz`,kind:`channel`,tagline:`Talk to your eve agent from Buzz through its ACP desktop harness.`,surfaces:{scaffoldable:!1,registry:!1,gallery:!0}},{slug:`chat-sdk-gchat`,name:`Google Chat`,kind:`channel`,tagline:`Google Chat spaces and DMs via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-whatsapp`,name:`WhatsApp`,kind:`channel`,tagline:`Customer messaging through WhatsApp Business Cloud via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-x`,name:`X`,kind:`channel`,tagline:`Public mentions and DMs on X via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-messenger`,name:`Messenger`,kind:`channel`,tagline:`Facebook Messenger bots with templates, buttons, and reactions via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-zernio`,name:`Zernio`,kind:`channel`,tagline:`Reach seven social and messaging platforms through one Zernio integration.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-velt`,name:`Velt`,kind:`channel`,tagline:`Add agents to anchored comments across documents, canvases, PDFs, and video.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-sendblue`,name:`Sendblue`,kind:`channel`,tagline:`Send and receive iMessage, SMS, and RCS through Sendblue.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-novu`,name:`Novu`,kind:`channel`,tagline:`Reach Slack, Teams, WhatsApp, Telegram, and email through Novu.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-liveblocks`,name:`Liveblocks`,kind:`channel`,tagline:`Bring your agent into Liveblocks comment threads, mentions, and reactions.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-linq`,name:`Linq`,kind:`channel`,tagline:`iMessage and SMS conversations, media, and tapbacks through Linq.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-kapso`,name:`Kapso`,kind:`channel`,tagline:`Managed WhatsApp conversations, media, buttons, and history through Kapso.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`photon`,name:`Photon`,kind:`channel`,tagline:`iMessage through Photon, with guided project and phone setup.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-dial`,name:`Dial`,kind:`channel`,tagline:`Give your agent a phone number for SMS, MMS, iMessage, and voice transcripts.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-agentphone`,name:`AgentPhone`,kind:`channel`,tagline:`SMS, MMS, iMessage, and voice conversations through AgentPhone.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-lark`,name:`Lark / Feishu`,kind:`channel`,tagline:`Lark and Feishu chats with native card streaming via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-beeper`,name:`Beeper`,kind:`channel`,tagline:`Matrix rooms and bridged messaging networks through Beeper.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`chat-sdk-resend`,name:`Resend`,kind:`channel`,tagline:`Send and receive threaded email through Resend via the Chat SDK.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`agent-browser`,name:`agent-browser`,kind:`extension`,tagline:`Add browser automation tools backed by agent-browser to an eve agent.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browserbase`,name:`Browserbase`,kind:`extension`,tagline:`Search, fetch, and automate the web with Browserbase and Stagehand.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`github-tools`,name:`GitHub Tools`,kind:`extension`,tagline:`Add scoped GitHub tools with Vercel Connect authentication and approval rules.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jetty`,name:`Jetty`,kind:`extension`,tagline:`Grade agent turns, compare experiments, and store durable evaluation trajectories.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`kernel`,name:`KERNEL`,kind:`extension`,tagline:`Let your eve agent use the Internet with KERNEL browser infra, o11y, and stealth. Integrated natively with Vercel Connect and AI Gateway.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`upstash-agentkit`,name:`Upstash AgentKit`,kind:`extension`,tagline:`Add long-term memory, Redis Search, and durable chat history with Upstash Redis.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arcana`,name:`Kybernesis Arcana`,kind:`extension`,tagline:`Give your agent workspace-scoped long-term memory with recall, storage, and brain notes.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`hindsight`,name:`Hindsight`,kind:`extension`,tagline:`Recall relevant context before every turn and retain each exchange automatically.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`browser-use`,name:`Browser Use`,kind:`connection`,tagline:`Run managed browser automation tasks through Browser Use's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Browser Use: run browser automation tasks, inspect sessions, and manage browser profiles.`,mcp:{url:`https://api.browser-use.com/v3/mcp`}}},{slug:`vercel`,name:`Vercel`,kind:`connection`,tagline:`Manage Vercel projects, deployments, and logs through Vercel's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Vercel: manage projects and deployments, inspect logs, and search documentation.`,mcp:{url:`https://mcp.vercel.com`}}},{slug:`linear`,name:`Linear`,kind:`connection`,tagline:`Issues, projects, cycles, and comments via Linear's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Linear workspace: issues, projects, cycles, and comments.`,mcp:{url:`https://mcp.linear.app/mcp`}}},{slug:`notion`,name:`Notion`,kind:`connection`,tagline:`Search and edit Notion pages and databases over MCP or OpenAPI.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Notion workspace: search and edit pages and databases.`,mcp:{url:`https://mcp.notion.com/mcp`},openapi:{spec:`https://developers.notion.com/openapi.json`,baseUrl:`https://api.notion.com`,headers:{"Notion-Version":`2022-06-28`}}}},{slug:`datadog`,name:`Datadog`,kind:`connection`,tagline:`Query metrics, monitors, and logs through Datadog's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Datadog: query metrics, monitors, logs, and incidents.`,mcp:{url:`https://mcp.datadoghq.com/api/mcp`}}},{slug:`honeycomb`,name:`Honeycomb`,kind:`connection`,tagline:`Explore traces and run queries through Honeycomb's MCP server.`,surfaces:{scaffoldable:!0,registry:!0,gallery:!0},connection:{description:`Honeycomb: explore traces, run queries, and inspect datasets.`,mcp:{url:`https://mcp.honeycomb.io/mcp`}}},{slug:`airtable`,name:`Airtable`,kind:`connection`,tagline:`Bases, tables, and records through Airtable's MCP server.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Airtable: bases, tables, and records.`,mcp:{url:`https://mcp.airtable.com/mcp`}}},{slug:`bitly`,name:`Bitly`,kind:`connection`,tagline:`Shorten links, generate QR Codes, and track performance.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Bitly: shorten links, generate QR Codes, and track link performance.`,mcp:{url:`https://api-ssl.bitly.com/v4/mcp`}}},{slug:`brex`,name:`Brex`,kind:`connection`,tagline:`Expenses, cards, and cash through Brex's finance automation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Brex: expenses, cards, budgets, and cash.`,mcp:{url:`https://api.brex.com/mcp`}}},{slug:`candid`,name:`Candid`,kind:`connection`,tagline:`Research nonprofits and funders using Candid's data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Candid: research nonprofits, funders, and grants.`,mcp:{url:`https://mcp.candid.org/mcp`}}},{slug:`clickhouse`,name:`ClickHouse`,kind:`connection`,tagline:`Query and explore your ClickHouse Cloud data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`ClickHouse Cloud: query and explore databases and tables.`,mcp:{url:`https://mcp.clickhouse.cloud/mcp`}}},{slug:`cloudinary`,name:`Cloudinary`,kind:`connection`,tagline:`Manage, transform, and deliver your images and videos.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Cloudinary: manage, transform, and deliver image and video assets.`,mcp:{url:`https://asset-management.mcp.cloudinary.com/sse`}}},{slug:`coda`,name:`Coda`,kind:`connection`,tagline:`Create, search, and update docs and tables.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Coda: create, search, and update docs and tables.`,mcp:{url:`https://coda.io/apis/mcp`}}},{slug:`context`,name:`context.dev`,kind:`connection`,tagline:`search, scrape, extract, and monitor live web data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`context.dev: search the live web, scrape and crawl sites, extract structured data, parse files, retrieve brand intelligence, monitor changes, and run batch jobs.`,mcp:{url:`https://mcp.context.dev/mcp`}}},{slug:`egnyte`,name:`Egnyte`,kind:`connection`,tagline:`Securely access and analyze Egnyte content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Egnyte: search, access, and analyze governed content.`,mcp:{url:`https://mcp-server.egnyte.com/mcp`}}},{slug:`embat`,name:`Embat`,kind:`connection`,tagline:`Ask Embat about cash, debt, payments, and accounting.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Embat: cash, debt, payments, and accounting.`,mcp:{url:`https://tellme.embat.io/mcp`}}},{slug:`hugging-face`,name:`Hugging Face`,kind:`connection`,tagline:`Access the Hugging Face Hub and thousands of Gradio apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Hugging Face: models, datasets, Spaces, and Gradio apps on the Hub.`,mcp:{url:`https://huggingface.co/mcp?login&gradio=none`}}},{slug:`local-falcon`,name:`Local Falcon`,kind:`connection`,tagline:`AI visibility and local search intelligence.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Local Falcon: local search rankings and AI visibility reports.`,mcp:{url:`https://mcp.localfalcon.com`}}},{slug:`make`,name:`Make`,kind:`connection`,tagline:`Run Make scenarios and manage your Make account.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Make: run scenarios and manage automations.`,mcp:{url:`https://mcp.make.com`}}},{slug:`manufact`,name:`Manufact`,kind:`connection`,tagline:`Deploy and monitor MCP servers with Manufact.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Manufact: deploy and monitor MCP servers.`,mcp:{url:`https://mcp.manufact.com/mcp`}}},{slug:`mem0`,name:`Mem0`,kind:`connection`,tagline:`Persistent memory for AI agents and assistants.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mem0: store and retrieve persistent agent memory.`,mcp:{url:`https://mcp.mem0.ai/mcp`}}},{slug:`miro`,name:`Miro`,kind:`connection`,tagline:`Access and create content on Miro boards.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Miro: read and create content on boards.`,mcp:{url:`https://mcp.miro.com/`}}},{slug:`mixpanel`,name:`Mixpanel`,kind:`connection`,tagline:`Analyze, query, and manage your Mixpanel data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Mixpanel: analyze, query, and manage analytics data.`,mcp:{url:`https://mcp.mixpanel.com/mcp`}}},{slug:`natural`,name:`Natural`,kind:`connection`,tagline:`Send, request, and manage payments with Natural.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Natural: agentic payments — send and request payments, check balances, and move funds.`,mcp:{url:`https://mcp.natural.com/mcp`}}},{slug:`netlify`,name:`Netlify`,kind:`connection`,tagline:`Create, deploy, manage, and secure websites on Netlify.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Netlify: create, deploy, manage, and secure sites.`,mcp:{url:`https://netlify-mcp.netlify.app/mcp`}}},{slug:`oreilly`,name:`O'Reilly`,kind:`connection`,tagline:`Discover O'Reilly's expert learning content.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`O'Reilly: search books, courses, and learning content.`,mcp:{url:`https://api.oreilly.com/api/content-discovery/v1/mcp/`}}},{slug:`planetscale`,name:`PlanetScale`,kind:`connection`,tagline:`Authenticated access to your PlanetScale Postgres and MySQL databases.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PlanetScale: query Postgres and MySQL databases.`,mcp:{url:`https://mcp.pscale.dev/mcp/planetscale`}}},{slug:`posthog`,name:`PostHog`,kind:`connection`,tagline:`Query, analyze, and manage your PostHog insights.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`PostHog: insights, events, and feature flags.`,mcp:{url:`https://mcp.posthog.com/mcp`}}},{slug:`postman`,name:`Postman`,kind:`connection`,tagline:`Give API context to your coding agents with Postman.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Postman: APIs, collections, and workspaces.`,mcp:{url:`https://mcp.postman.com/minimal`}}},{slug:`razorpay`,name:`Razorpay`,kind:`connection`,tagline:`Razorpay payments, settlements, and dashboard data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Razorpay: payments, settlements, and dashboard data.`,mcp:{url:`https://mcp.razorpay.com/mcp`}}},{slug:`sentry`,name:`Sentry`,kind:`connection`,tagline:`Search, query, and debug errors intelligently.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Sentry: search, query, and debug errors and issues.`,mcp:{url:`https://mcp.sentry.dev/mcp`}}},{slug:`similarweb`,name:`Similarweb`,kind:`connection`,tagline:`Real-time web, mobile app, and market data.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Similarweb: web traffic, app, and market intelligence data.`,mcp:{url:`https://mcp.similarweb.com`}}},{slug:`stripe`,name:`Stripe`,kind:`connection`,tagline:`Payment processing and financial infrastructure tools.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Stripe: payments, customers, billing, and financial infrastructure.`,mcp:{url:`https://mcp.stripe.com`}}},{slug:`supabase`,name:`Supabase`,kind:`connection`,tagline:`Manage databases, authentication, and storage.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Supabase: databases, authentication, and storage.`,mcp:{url:`https://mcp.supabase.com/mcp`}}},{slug:`ticket-tailor`,name:`Ticket Tailor`,kind:`connection`,tagline:`Manage tickets, orders, and events with Ticket Tailor.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Ticket Tailor: events, tickets, and orders.`,mcp:{url:`https://mcp.tickettailor.ai/mcp`}}},{slug:`ticktick`,name:`TickTick`,kind:`connection`,tagline:`Search, create, and manage your tasks and habits in TickTick.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`TickTick: tasks, habits, and lists.`,mcp:{url:`https://mcp.ticktick.com`}}},{slug:`tinybird`,name:`Tinybird`,kind:`connection`,tagline:`Query pipes and data sources in your Tinybird Workspace.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Tinybird: query pipes and data sources, and run SQL. A token grants one Workspace, so add a connection per Workspace.`,mcp:{url:`https://mcp.tinybird.co`}}},{slug:`todoist`,name:`Todoist`,kind:`connection`,tagline:`Search, complete, and manage your tasks in Todoist.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Todoist: search, complete, and manage tasks.`,mcp:{url:`https://ai.todoist.net/mcp`}}},{slug:`webflow`,name:`Webflow`,kind:`connection`,tagline:`Manage Webflow CMS, pages, assets, and sites.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Webflow: CMS items, pages, assets, and sites.`,mcp:{url:`https://mcp.webflow.com/mcp`}}},{slug:`wix`,name:`Wix`,kind:`connection`,tagline:`Manage and build sites and apps on Wix.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Wix: manage and build sites and apps.`,mcp:{url:`https://mcp.wix.com/mcp`}}},{slug:`zapier`,name:`Zapier`,kind:`connection`,tagline:`Automate workflows across thousands of apps.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zapier: run and manage automations across apps.`,mcp:{url:`https://mcp.zapier.com/api/v1/connect`}}},{slug:`zomato`,name:`Zomato`,kind:`connection`,tagline:`Online food ordering and delivery through Zomato.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0},connection:{description:`Zomato: food ordering and delivery.`,mcp:{url:`https://mcp-server.zomato.com/mcp`}}},{slug:`braintrust`,name:`Braintrust`,kind:`instrumentation`,tagline:`Export AI SDK spans to Braintrust for tracing, evals, and monitoring.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`posthog-instrumentation`,name:`PostHog`,kind:`instrumentation`,tagline:`Send agent traces and generations to PostHog AI Observability.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`sentry-instrumentation`,name:`Sentry`,kind:`instrumentation`,tagline:`Send agent traces to Sentry's OTLP endpoint for tracing and debugging.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`datadog-instrumentation`,name:`Datadog`,kind:`instrumentation`,tagline:`Export agent traces to Datadog APM alongside the rest of your stack.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`honeycomb-instrumentation`,name:`Honeycomb`,kind:`instrumentation`,tagline:`Send OpenTelemetry traces to Honeycomb and query every agent turn.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`arize`,name:`Arize`,kind:`instrumentation`,tagline:`Export traces to Arize AX for LLM observability and evaluation.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`raindrop`,name:`Raindrop`,kind:`instrumentation`,tagline:`Send agent traces to Raindrop to detect and debug AI product issues.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}},{slug:`jaeger`,name:`Jaeger`,kind:`instrumentation`,tagline:`Trace your agent with a local or self-hosted Jaeger OTLP backend.`,surfaces:{scaffoldable:!1,registry:!0,gallery:!0}}];new Map(INTEGRATIONS.map(e=>[e.slug,e]));function integrationsByKind(t){return INTEGRATIONS.filter(e=>e.kind===t)}function connectionEntries(){return integrationsByKind(`connection`)}function channelEntries(){return integrationsByKind(`channel`)}export{INTEGRATIONS,channelEntries,connectionEntries,connectionProtocols,integrationsByKind};
|
|
@@ -262,10 +262,22 @@ export interface SubagentCalledStreamEvent {
|
|
|
262
262
|
data: {
|
|
263
263
|
callId: string;
|
|
264
264
|
childSessionId: string;
|
|
265
|
+
childStreamPath: string;
|
|
265
266
|
sessionId: string;
|
|
266
267
|
sequence: number;
|
|
267
268
|
name: string;
|
|
268
269
|
remote?: {
|
|
270
|
+
/**
|
|
271
|
+
* Key to the authored credential functions (`auth`/`headers`) for this
|
|
272
|
+
* remote child, resolved at stream-proxy time by
|
|
273
|
+
* `resolveRemoteAgentStreamHeaders`. Static subagent → the node id in
|
|
274
|
+
* `subagentRegistry.subagentsByNodeId`; dynamic subagent → its
|
|
275
|
+
* `credentialsStepId` in the step registry. The event stores this key —
|
|
276
|
+
* never resolved header values — because tokens expire and this event
|
|
277
|
+
* is persisted and streamed to clients. Absent when the remote child
|
|
278
|
+
* has no authored credentials.
|
|
279
|
+
*/
|
|
280
|
+
resolverId?: string;
|
|
269
281
|
url: string;
|
|
270
282
|
};
|
|
271
283
|
toolName: string;
|
|
@@ -302,6 +314,15 @@ export interface SubagentChildEventStreamEvent {
|
|
|
302
314
|
*/
|
|
303
315
|
export interface SubagentCompletedStreamEvent {
|
|
304
316
|
data: {
|
|
317
|
+
/**
|
|
318
|
+
* Present when the originating call completed with a background-task
|
|
319
|
+
* receipt while the child itself kept running. Consumers must not treat
|
|
320
|
+
* this as the child's terminal boundary; the child stream owns that.
|
|
321
|
+
*/
|
|
322
|
+
backgroundTask?: {
|
|
323
|
+
taskId: string;
|
|
324
|
+
status: "working";
|
|
325
|
+
};
|
|
305
326
|
callId: string;
|
|
306
327
|
output: string;
|
|
307
328
|
subagentName: string;
|
|
@@ -507,6 +528,8 @@ export interface CompactionCompletedStreamEvent {
|
|
|
507
528
|
*/
|
|
508
529
|
export interface AuthorizationRequiredStreamEvent {
|
|
509
530
|
data: {
|
|
531
|
+
/** Stable identity of this exact authorization attempt. */
|
|
532
|
+
attemptId?: string;
|
|
510
533
|
authorization?: ConnectionAuthorizationChallenge;
|
|
511
534
|
candidateId?: string;
|
|
512
535
|
description: string;
|
|
@@ -537,6 +560,8 @@ export type ConnectionAuthorizationOutcome = AuthorizationOutcome;
|
|
|
537
560
|
*/
|
|
538
561
|
export interface AuthorizationCompletedStreamEvent {
|
|
539
562
|
data: {
|
|
563
|
+
/** Stable identity shared with the matching required event. */
|
|
564
|
+
attemptId?: string;
|
|
540
565
|
candidateId?: string;
|
|
541
566
|
/**
|
|
542
567
|
* The challenge from the matching `authorization.required` event,
|
|
@@ -667,6 +692,7 @@ export declare function createActionsRequestedEvent(input: {
|
|
|
667
692
|
* for `getToken`-only authorization sources that authorize out of band.
|
|
668
693
|
*/
|
|
669
694
|
export declare function createAuthorizationRequiredEvent(input: {
|
|
695
|
+
readonly attemptId?: string;
|
|
670
696
|
readonly authorization?: ConnectionAuthorizationChallenge;
|
|
671
697
|
readonly candidateId?: string;
|
|
672
698
|
readonly description: string;
|
|
@@ -682,6 +708,7 @@ export declare function createAuthorizationRequiredEvent(input: {
|
|
|
682
708
|
* authorization deadline has expired.
|
|
683
709
|
*/
|
|
684
710
|
export declare function createAuthorizationCompletedEvent(input: {
|
|
711
|
+
readonly attemptId?: string;
|
|
685
712
|
readonly authorization?: ConnectionAuthorizationChallenge;
|
|
686
713
|
readonly candidateId?: string;
|
|
687
714
|
readonly name: string;
|
|
@@ -735,6 +762,7 @@ export declare function createSubagentCalledEvent(input: {
|
|
|
735
762
|
readonly sequence: number;
|
|
736
763
|
readonly name: string;
|
|
737
764
|
readonly remote?: {
|
|
765
|
+
readonly resolverId?: string;
|
|
738
766
|
readonly url: string;
|
|
739
767
|
};
|
|
740
768
|
readonly toolName: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{deserializeUrlFilePart,hasInternalRefScheme,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";import{decodeSandboxRef,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";import{createEventId}from"#protocol/event-id.js";const EVE_SESSION_ID_HEADER=`x-eve-session-id`,EVE_STREAM_FORMAT_HEADER=`x-eve-stream-format`,EVE_STREAM_TAIL_INDEX_HEADER=`x-eve-stream-tail-index`,EVE_STREAM_VERSION_HEADER=`x-eve-stream-version`,EVE_MESSAGE_STREAM_CONTENT_TYPE=`application/x-ndjson; charset=utf-8`,EVE_MESSAGE_STREAM_FORMAT=`ndjson`,EVE_MESSAGE_STREAM_VERSION=`22`,textEncoder=new TextEncoder;function isCurrentTurnBoundaryEvent(e){return e.type===`session.completed`||e.type===`session.failed`||e.type===`session.waiting`}function isTurnFailureEvent(e){return e.type===`session.failed`||e.type===`step.failed`||e.type===`turn.failed`}function createSessionStartedEvent(e){let t={};return e?.invocation!==void 0&&(t.invocation=e.invocation),e?.runtime!==void 0&&(t.runtime=e.runtime),e?.trace!==void 0&&(t.trace=e.trace),{data:t,type:`session.started`}}function createTurnStartedEvent(e){let t={sequence:e.sequence,turnId:e.turnId};return e.trace!==void 0&&(t.trace=e.trace),{data:t,type:`turn.started`}}function createMessageReceivedEvent(e){return{data:{message:summarizeUserContent(e.message),parts:projectUserContentParts(e.message),sequence:e.sequence,turnId:e.turnId},type:`message.received`}}function summarizeUserContent(e){if(typeof e==`string`)return e;let t=[];for(let n of e)if(n.type===`text`)t.push(n.text);else if(n.type===`file`){let e=n.filename??n.mediaType;t.push(`[file: ${e} (${n.mediaType})]`)}else n.type===`image`&&t.push(`[image: ${n.mediaType??`image`}]`);return t.join(`
|
|
2
|
-
`)}function projectUserContentParts(e){if(typeof e==`string`)return[{text:e,type:`text`}];let t=[];for(let n of e)n.type===`text`?t.push({text:n.text,type:`text`}):n.type===`file`?t.push(projectFileLikePart(n.data,n.mediaType,n.filename)):n.type===`image`&&t.push(projectFileLikePart(n.image,n.mediaType??`application/octet-stream`,void 0));return t}function projectFileLikePart(e,t,n){if(isSandboxRefUrl(e)){let t=decodeSandboxRef(e);return createProjectedFilePart({filename:basenameOf(n??t.path),mediaType:t.mediaType,size:t.size})}let r=projectTaggedFileData(e,t,n);if(r!==void 0)return r;let i=byteLengthOf(e);return createProjectedFilePart(i===void 0?{filename:n,mediaType:t,...clientUrlFragment(e)}:{filename:n,mediaType:t,size:i})}function projectTaggedFileData(e,t,n){if(isTaggedFileData(e))switch(e.type){case`data`:{let r=byteLengthOf(e.data);return createProjectedFilePart(r===void 0?{filename:n,mediaType:t}:{filename:n,mediaType:t,size:r})}case`reference`:case`text`:return createProjectedFilePart({filename:n,mediaType:t});case`url`:return createProjectedFilePart({filename:n,mediaType:t,...clientUrlFragment(e.url)})}}function createProjectedFilePart(e){let t={mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),e.size!==void 0&&(t.size=e.size),e.url!==void 0&&(t.url=e.url),t}function isTaggedFileData(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`data`||t===`reference`||t===`text`||t===`url`}function byteLengthOf(e){if(e instanceof Uint8Array||e instanceof ArrayBuffer)return e.byteLength}function clientUrlFragment(r){if(isSerializedUrlFilePart(r))try{let t=deserializeUrlFilePart(r);return isClientResolvableUrl(t)?{url:t.href}:{}}catch{return{}}if(r instanceof URL)return isClientResolvableUrl(r)?{url:r.href}:{};if(typeof r!=`string`||hasInternalRefScheme(r))return{};if(r.startsWith(`data:`))return{url:r};try{let e=new URL(r);return isClientResolvableUrl(e)?{url:e.href}:{}}catch{return{}}}function isClientResolvableUrl(e){return e.protocol===`http:`||e.protocol===`https:`||e.protocol===`data:`}function basenameOf(e){let t=e.replaceAll(`\\`,`/`),n=t.slice(t.lastIndexOf(`/`)+1);return n.length>0?n:e}function createActionsRequestedEvent(e){return{data:{actions:e.actions,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`actions.requested`}}function createAuthorizationRequiredEvent(e){let t={description:e.description,name:e.name,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.authorization!==void 0&&(t.authorization=e.authorization),e.candidateId!==void 0&&(t.candidateId=e.candidateId),e.webhookUrl!==void 0&&(t.webhookUrl=e.webhookUrl),{data:t,type:`authorization.required`}}function createAuthorizationCompletedEvent(e){let t={name:e.name,outcome:e.outcome,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.authorization!==void 0&&(t.authorization=e.authorization),e.candidateId!==void 0&&(t.candidateId=e.candidateId),e.reason!==void 0&&(t.reason=e.reason),{data:t,type:`authorization.completed`}}function createApprovalCandidateEvent(e){return{data:e,type:`approval.candidate`}}function createApprovalSettledEvent(e){return{data:e,type:`approval.settled`}}function createInputRequestedEvent(e){return{data:{requests:e.requests,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`input.requested`}}function createActionResultEvent(e){let t=e.rejected===!0?{error:buildActionResultError(e.result),status:`rejected`}:normalizeActionResultOutcome(e.result);return{data:{error:t.error,result:e.result,sequence:e.sequence,status:t.status,stepIndex:e.stepIndex,turnId:e.turnId},type:`action.result`}}function createActionPartialEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`action.partial`}}function createSubagentCalledEvent(e){return{data:{callId:e.callId,childSessionId:e.childSessionId,sessionId:e.sessionId,sequence:e.sequence,name:e.name,remote:e.remote,toolName:e.toolName,turnId:e.turnId,workflowId:e.workflowId},type:`subagent.called`}}function createMessageAppendedEvent(e){return{data:{messageDelta:e.messageDelta,messageSoFar:e.messageSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.appended`}}function createReasoningAppendedEvent(e){return{data:{reasoningDelta:e.reasoningDelta,reasoningSoFar:e.reasoningSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.appended`}}function createMessageCompletedEvent(e){return{data:{finishReason:e.finishReason??`stop`,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.completed`}}function createReasoningCompletedEvent(e){return{data:{reasoning:e.reasoning,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.completed`}}function createResultCompletedEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`result.completed`}}function createStepStartedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.started`}}function createStepCompletedEvent(e){let t={finishReason:e.finishReason,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.usage!==void 0&&(t.usage=e.usage),e.providerMetadata!==void 0&&(t.providerMetadata=e.providerMetadata),{data:t,type:`step.completed`}}function createStepFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.failed`}}function createTurnCompletedEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.completed`}}function createTurnFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,turnId:e.turnId},type:`turn.failed`}}function createTurnCancelledEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.cancelled`}}function createContextClearedEvent(e){return{data:{sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`context.cleared`}}function createCompactionRequestedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId,usageInputTokens:e.usageInputTokens??null},type:`compaction.requested`}}function createCompactionCompletedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`compaction.completed`}}function createSessionWaitingEvent(e=``){return{data:{continuationToken:toChannelLocalContinuationToken(e),wait:`next-user-message`},type:`session.waiting`}}function createSessionFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sessionId:e.sessionId},type:`session.failed`}}function createSessionCompletedEvent(){return{type:`session.completed`}}function stampMessageStreamEvent(e){return{...e,meta:{at:new Date().toISOString(),id:createEventId()}}}function encodeMessageStreamEvent(e){return textEncoder.encode(`${JSON.stringify(e)}\n`)}function normalizeActionResultOutcome(e){if(e.isError===!0)return{error:buildActionResultError(e),status:`failed`};let t=readActionResultOutputError(e.output);return t===void 0?{status:`completed`}:{error:t,status:`failed`}}function buildActionResultError(e){let t=readActionResultOutputError(e.output);return t===void 0?{code:`ACTION_RESULT_FAILED`,message:formatActionResultOutput(e.output)}:t}function readActionResultOutputError(e){let t=parseActionResultOutputRecord(e);if(t===void 0)return;let n=typeof t.code==`string`&&t.code.length>0?t.code:void 0,r=typeof t.message==`string`&&t.message.length>0?t.message:void 0;if(!(n===void 0||r===void 0))return{code:n,message:r}}function parseActionResultOutputRecord(e){if(typeof e==`object`&&e)return e;if(typeof e!=`string`)return;let t=e.trim();if(t.length!==0)try{let e=JSON.parse(t);if(typeof e==`object`&&e)return e}catch{return}}function formatActionResultOutput(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return typeof t==`string`&&t.length>0?t:`Action failed.`}export{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER,createActionPartialEvent,createActionResultEvent,createActionsRequestedEvent,createApprovalCandidateEvent,createApprovalSettledEvent,createAuthorizationCompletedEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createContextClearedEvent,createInputRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createResultCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepCompletedEvent,createStepFailedEvent,createStepStartedEvent,createSubagentCalledEvent,createTurnCancelledEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent,encodeMessageStreamEvent,isCurrentTurnBoundaryEvent,isTurnFailureEvent,stampMessageStreamEvent};
|
|
1
|
+
import{deserializeUrlFilePart,hasInternalRefScheme,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath}from"#protocol/routes.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";import{decodeSandboxRef,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";import{createEventId}from"#protocol/event-id.js";const EVE_SESSION_ID_HEADER=`x-eve-session-id`,EVE_STREAM_FORMAT_HEADER=`x-eve-stream-format`,EVE_STREAM_TAIL_INDEX_HEADER=`x-eve-stream-tail-index`,EVE_STREAM_VERSION_HEADER=`x-eve-stream-version`,EVE_MESSAGE_STREAM_CONTENT_TYPE=`application/x-ndjson; charset=utf-8`,EVE_MESSAGE_STREAM_FORMAT=`ndjson`,EVE_MESSAGE_STREAM_VERSION=`22`,textEncoder=new TextEncoder;function isCurrentTurnBoundaryEvent(e){return e.type===`session.completed`||e.type===`session.failed`||e.type===`session.waiting`}function isTurnFailureEvent(e){return e.type===`session.failed`||e.type===`step.failed`||e.type===`turn.failed`}function createSessionStartedEvent(e){let t={};return e?.invocation!==void 0&&(t.invocation=e.invocation),e?.runtime!==void 0&&(t.runtime=e.runtime),e?.trace!==void 0&&(t.trace=e.trace),{data:t,type:`session.started`}}function createTurnStartedEvent(e){let t={sequence:e.sequence,turnId:e.turnId};return e.trace!==void 0&&(t.trace=e.trace),{data:t,type:`turn.started`}}function createMessageReceivedEvent(e){return{data:{message:summarizeUserContent(e.message),parts:projectUserContentParts(e.message),sequence:e.sequence,turnId:e.turnId},type:`message.received`}}function summarizeUserContent(e){if(typeof e==`string`)return e;let t=[];for(let n of e)if(n.type===`text`)t.push(n.text);else if(n.type===`file`){let e=n.filename??n.mediaType;t.push(`[file: ${e} (${n.mediaType})]`)}else n.type===`image`&&t.push(`[image: ${n.mediaType??`image`}]`);return t.join(`
|
|
2
|
+
`)}function projectUserContentParts(e){if(typeof e==`string`)return[{text:e,type:`text`}];let t=[];for(let n of e)n.type===`text`?t.push({text:n.text,type:`text`}):n.type===`file`?t.push(projectFileLikePart(n.data,n.mediaType,n.filename)):n.type===`image`&&t.push(projectFileLikePart(n.image,n.mediaType??`application/octet-stream`,void 0));return t}function projectFileLikePart(e,t,n){if(isSandboxRefUrl(e)){let t=decodeSandboxRef(e);return createProjectedFilePart({filename:basenameOf(n??t.path),mediaType:t.mediaType,size:t.size})}let r=projectTaggedFileData(e,t,n);if(r!==void 0)return r;let i=byteLengthOf(e);return createProjectedFilePart(i===void 0?{filename:n,mediaType:t,...clientUrlFragment(e)}:{filename:n,mediaType:t,size:i})}function projectTaggedFileData(e,t,n){if(isTaggedFileData(e))switch(e.type){case`data`:{let r=byteLengthOf(e.data);return createProjectedFilePart(r===void 0?{filename:n,mediaType:t}:{filename:n,mediaType:t,size:r})}case`reference`:case`text`:return createProjectedFilePart({filename:n,mediaType:t});case`url`:return createProjectedFilePart({filename:n,mediaType:t,...clientUrlFragment(e.url)})}}function createProjectedFilePart(e){let t={mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),e.size!==void 0&&(t.size=e.size),e.url!==void 0&&(t.url=e.url),t}function isTaggedFileData(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`data`||t===`reference`||t===`text`||t===`url`}function byteLengthOf(e){if(e instanceof Uint8Array||e instanceof ArrayBuffer)return e.byteLength}function clientUrlFragment(r){if(isSerializedUrlFilePart(r))try{let t=deserializeUrlFilePart(r);return isClientResolvableUrl(t)?{url:t.href}:{}}catch{return{}}if(r instanceof URL)return isClientResolvableUrl(r)?{url:r.href}:{};if(typeof r!=`string`||hasInternalRefScheme(r))return{};if(r.startsWith(`data:`))return{url:r};try{let e=new URL(r);return isClientResolvableUrl(e)?{url:e.href}:{}}catch{return{}}}function isClientResolvableUrl(e){return e.protocol===`http:`||e.protocol===`https:`||e.protocol===`data:`}function basenameOf(e){let t=e.replaceAll(`\\`,`/`),n=t.slice(t.lastIndexOf(`/`)+1);return n.length>0?n:e}function createActionsRequestedEvent(e){return{data:{actions:e.actions,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`actions.requested`}}function createAuthorizationRequiredEvent(e){let t={description:e.description,name:e.name,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.attemptId!==void 0&&(t.attemptId=e.attemptId),e.authorization!==void 0&&(t.authorization=e.authorization),e.candidateId!==void 0&&(t.candidateId=e.candidateId),e.webhookUrl!==void 0&&(t.webhookUrl=e.webhookUrl),{data:t,type:`authorization.required`}}function createAuthorizationCompletedEvent(e){let t={name:e.name,outcome:e.outcome,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.attemptId!==void 0&&(t.attemptId=e.attemptId),e.authorization!==void 0&&(t.authorization=e.authorization),e.candidateId!==void 0&&(t.candidateId=e.candidateId),e.reason!==void 0&&(t.reason=e.reason),{data:t,type:`authorization.completed`}}function createApprovalCandidateEvent(e){return{data:e,type:`approval.candidate`}}function createApprovalSettledEvent(e){return{data:e,type:`approval.settled`}}function createInputRequestedEvent(e){return{data:{requests:e.requests,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`input.requested`}}function createActionResultEvent(e){let t=e.rejected===!0?{error:buildActionResultError(e.result),status:`rejected`}:normalizeActionResultOutcome(e.result);return{data:{error:t.error,result:e.result,sequence:e.sequence,status:t.status,stepIndex:e.stepIndex,turnId:e.turnId},type:`action.result`}}function createActionPartialEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`action.partial`}}function createSubagentCalledEvent(e){return{data:{callId:e.callId,childSessionId:e.childSessionId,childStreamPath:e.remote===void 0?createEveSessionStreamRoutePath(e.childSessionId):createEveSubagentStreamRoutePath({callId:e.callId,childSessionId:e.childSessionId,parentSessionId:e.sessionId}),sessionId:e.sessionId,sequence:e.sequence,name:e.name,remote:e.remote,toolName:e.toolName,turnId:e.turnId,workflowId:e.workflowId},type:`subagent.called`}}function createMessageAppendedEvent(e){return{data:{messageDelta:e.messageDelta,messageSoFar:e.messageSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.appended`}}function createReasoningAppendedEvent(e){return{data:{reasoningDelta:e.reasoningDelta,reasoningSoFar:e.reasoningSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.appended`}}function createMessageCompletedEvent(e){return{data:{finishReason:e.finishReason??`stop`,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.completed`}}function createReasoningCompletedEvent(e){return{data:{reasoning:e.reasoning,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.completed`}}function createResultCompletedEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`result.completed`}}function createStepStartedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.started`}}function createStepCompletedEvent(e){let t={finishReason:e.finishReason,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.usage!==void 0&&(t.usage=e.usage),e.providerMetadata!==void 0&&(t.providerMetadata=e.providerMetadata),{data:t,type:`step.completed`}}function createStepFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.failed`}}function createTurnCompletedEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.completed`}}function createTurnFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,turnId:e.turnId},type:`turn.failed`}}function createTurnCancelledEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.cancelled`}}function createContextClearedEvent(e){return{data:{sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`context.cleared`}}function createCompactionRequestedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId,usageInputTokens:e.usageInputTokens??null},type:`compaction.requested`}}function createCompactionCompletedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`compaction.completed`}}function createSessionWaitingEvent(e=``){return{data:{continuationToken:toChannelLocalContinuationToken(e),wait:`next-user-message`},type:`session.waiting`}}function createSessionFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sessionId:e.sessionId},type:`session.failed`}}function createSessionCompletedEvent(){return{type:`session.completed`}}function stampMessageStreamEvent(e){return{...e,meta:{at:new Date().toISOString(),id:createEventId()}}}function encodeMessageStreamEvent(e){return textEncoder.encode(`${JSON.stringify(e)}\n`)}function normalizeActionResultOutcome(e){if(e.isError===!0)return{error:buildActionResultError(e),status:`failed`};let t=readActionResultOutputError(e.output);return t===void 0?{status:`completed`}:{error:t,status:`failed`}}function buildActionResultError(e){let t=readActionResultOutputError(e.output);return t===void 0?{code:`ACTION_RESULT_FAILED`,message:formatActionResultOutput(e.output)}:t}function readActionResultOutputError(e){let t=parseActionResultOutputRecord(e);if(t===void 0)return;let n=typeof t.code==`string`&&t.code.length>0?t.code:void 0,r=typeof t.message==`string`&&t.message.length>0?t.message:void 0;if(!(n===void 0||r===void 0))return{code:n,message:r}}function parseActionResultOutputRecord(e){if(typeof e==`object`&&e)return e;if(typeof e!=`string`)return;let t=e.trim();if(t.length!==0)try{let e=JSON.parse(t);if(typeof e==`object`&&e)return e}catch{return}}function formatActionResultOutput(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return typeof t==`string`&&t.length>0?t:`Action failed.`}export{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER,createActionPartialEvent,createActionResultEvent,createActionsRequestedEvent,createApprovalCandidateEvent,createApprovalSettledEvent,createAuthorizationCompletedEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createContextClearedEvent,createInputRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createResultCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepCompletedEvent,createStepFailedEvent,createStepStartedEvent,createSubagentCalledEvent,createTurnCancelledEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent,encodeMessageStreamEvent,isCurrentTurnBoundaryEvent,isTurnFailureEvent,stampMessageStreamEvent};
|
|
@@ -27,6 +27,10 @@ export declare const EVE_SESSION_CLEAR_ROUTE_PATTERN = "/eve/v1/session/:session
|
|
|
27
27
|
export declare const EVE_SESSION_RESET_ROUTE_PATTERN = "/eve/v1/session/:sessionId/reset";
|
|
28
28
|
/** Stable event-stream route pattern for one exact session ID. */
|
|
29
29
|
export declare const EVE_SESSION_STREAM_ROUTE_PATTERN = "/eve/v1/session/:sessionId/stream";
|
|
30
|
+
/**
|
|
31
|
+
* Parent-origin proxy route for one remotely executed child session stream.
|
|
32
|
+
*/
|
|
33
|
+
export declare const EVE_SUBAGENT_STREAM_ROUTE_PATTERN = "/eve/v1/session/:parentSessionId/subagents/:callId/:childSessionId/stream";
|
|
30
34
|
/**
|
|
31
35
|
* Framework-owned route pattern for dispatching one authored schedule
|
|
32
36
|
* exactly once from the dev server.
|
|
@@ -89,10 +93,18 @@ export declare const EVE_LEGACY_CONNECTION_CALLBACK_ROUTE_PATTERN = "/eve/v1/con
|
|
|
89
93
|
* is unauthenticated by design and resumes the matching parked runtime action.
|
|
90
94
|
*/
|
|
91
95
|
export declare const EVE_CALLBACK_ROUTE_PATTERN = "/eve/v1/callback/:token";
|
|
96
|
+
/** Capability route used by a parent task to answer a remote child HITL batch. */
|
|
97
|
+
export declare const EVE_TASK_INPUT_ROUTE_PATTERN = "/eve/v1/task-input/:token";
|
|
92
98
|
/** Builds the ID-addressed message route for one session. */
|
|
93
99
|
export declare function createEveSessionRoutePath(sessionId: string): string;
|
|
94
100
|
/** Builds the ID-addressed cancel route for one session. */
|
|
95
101
|
export declare function createEveSessionCancelRoutePath(sessionId: string): string;
|
|
102
|
+
/** Builds the parent-origin stream path for one remote child session. */
|
|
103
|
+
export declare function createEveSubagentStreamRoutePath(input: {
|
|
104
|
+
readonly callId: string;
|
|
105
|
+
readonly childSessionId: string;
|
|
106
|
+
readonly parentSessionId: string;
|
|
107
|
+
}): string;
|
|
96
108
|
/** Builds the ID-addressed compact route for one session. */
|
|
97
109
|
export declare function createEveSessionCompactRoutePath(sessionId: string): string;
|
|
98
110
|
/** Builds the ID-addressed clear route for one session. */
|
|
@@ -116,3 +128,5 @@ export declare function createEveConnectionCallbackRoutePath(name: string, attem
|
|
|
116
128
|
* Creates the stable framework-owned terminal callback route path.
|
|
117
129
|
*/
|
|
118
130
|
export declare function createEveCallbackRoutePath(token: string): string;
|
|
131
|
+
/** Builds the capability path used to answer one remote child turn. */
|
|
132
|
+
export declare function createEveTaskInputRoutePath(token: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,EVE_SESSION_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/session`,EVE_SESSION_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId`,EVE_SESSION_CANCEL_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/cancel`,EVE_SESSION_COMPACT_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`,EVE_SESSION_CLEAR_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`,EVE_SESSION_RESET_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`,EVE_SESSION_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/suspend`,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/resume`;function createEveDevDispatchSchedulePath(t){return`${EVE_ROUTE_PREFIX}/dev/schedules/${encodeURIComponent(t)}`}const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:attemptId/:token`,EVE_LEGACY_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,EVE_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/callback/:token`;function createEveSessionRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}`}function createEveSessionCancelRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/cancel`}function createEveSessionCompactRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/compact`}function createEveSessionClearRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/clear`}function createEveSessionResetRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/reset`}function createEveSessionStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/stream`}function createEveConnectionCallbackRoutePath(t,n,r){return`${EVE_ROUTE_PREFIX}/connections/${encodeURIComponent(t)}/callback/${encodeURIComponent(n)}/${encodeURIComponent(r)}`}function createEveCallbackRoutePath(t){return`${EVE_ROUTE_PREFIX}/callback/${encodeURIComponent(t)}`}export{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_LEGACY_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,createEveCallbackRoutePath,createEveConnectionCallbackRoutePath,createEveDevDispatchSchedulePath,createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath,createEveSessionStreamRoutePath};
|
|
1
|
+
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,EVE_SESSION_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/session`,EVE_SESSION_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId`,EVE_SESSION_CANCEL_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/cancel`,EVE_SESSION_COMPACT_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`,EVE_SESSION_CLEAR_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`,EVE_SESSION_RESET_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`,EVE_SESSION_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`,EVE_SUBAGENT_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:parentSessionId/subagents/:callId/:childSessionId/stream`,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/suspend`,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/resume`;function createEveDevDispatchSchedulePath(t){return`${EVE_ROUTE_PREFIX}/dev/schedules/${encodeURIComponent(t)}`}const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:attemptId/:token`,EVE_LEGACY_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,EVE_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/callback/:token`,EVE_TASK_INPUT_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/task-input/:token`;function createEveSessionRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}`}function createEveSessionCancelRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/cancel`}function createEveSubagentStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e.parentSessionId)}/subagents/${encodeURIComponent(e.callId)}/${encodeURIComponent(e.childSessionId)}/stream`}function createEveSessionCompactRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/compact`}function createEveSessionClearRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/clear`}function createEveSessionResetRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/reset`}function createEveSessionStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/stream`}function createEveConnectionCallbackRoutePath(t,n,r){return`${EVE_ROUTE_PREFIX}/connections/${encodeURIComponent(t)}/callback/${encodeURIComponent(n)}/${encodeURIComponent(r)}`}function createEveCallbackRoutePath(t){return`${EVE_ROUTE_PREFIX}/callback/${encodeURIComponent(t)}`}function createEveTaskInputRoutePath(t){return`${EVE_ROUTE_PREFIX}/task-input/${encodeURIComponent(t)}`}export{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_LEGACY_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,EVE_TASK_INPUT_ROUTE_PATTERN,createEveCallbackRoutePath,createEveConnectionCallbackRoutePath,createEveDevDispatchSchedulePath,createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath,createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath,createEveTaskInputRoutePath};
|
|
@@ -196,6 +196,8 @@ export interface UnauthorizedResponseOptions {
|
|
|
196
196
|
* challenge, and a `{ ok: false, code, error }` body.
|
|
197
197
|
*/
|
|
198
198
|
export declare function createUnauthorizedResponse(opts?: UnauthorizedResponseOptions): Response;
|
|
199
|
+
/** @internal Escapes a value for an HTTP auth challenge quoted string. */
|
|
200
|
+
export declare function escapeAuthChallengeParameter(value: string): string;
|
|
199
201
|
/**
|
|
200
202
|
* Options accepted by auth error classes. The class chooses the HTTP status.
|
|
201
203
|
*/
|
|
@@ -230,6 +232,39 @@ export declare class ForbiddenError extends Error {
|
|
|
230
232
|
* traffic, include {@link none} as the final entry.
|
|
231
233
|
*/
|
|
232
234
|
export type AuthFn<TEvent = Request> = (event: TEvent) => SessionAuthContext | null | undefined | Promise<SessionAuthContext | null | undefined>;
|
|
235
|
+
/**
|
|
236
|
+
* OAuth protected-resource metadata attached to an inbound auth policy.
|
|
237
|
+
* `issuer` is shorthand for a single authorization server.
|
|
238
|
+
*/
|
|
239
|
+
export type OAuthResourceOptions = {
|
|
240
|
+
readonly metadataPath?: string;
|
|
241
|
+
readonly resource?: string;
|
|
242
|
+
readonly scopes?: readonly string[];
|
|
243
|
+
} & ({
|
|
244
|
+
readonly authorizationServers?: never;
|
|
245
|
+
readonly issuer: string;
|
|
246
|
+
} | {
|
|
247
|
+
readonly authorizationServers: readonly string[];
|
|
248
|
+
readonly issuer?: never;
|
|
249
|
+
});
|
|
250
|
+
declare const OAUTH_RESOURCE_SYMBOL: unique symbol;
|
|
251
|
+
/**
|
|
252
|
+
* An ordinary route authenticator decorated with OAuth protected-resource
|
|
253
|
+
* discovery metadata.
|
|
254
|
+
*/
|
|
255
|
+
export type OAuthResourceAuth = AuthFn<Request> & {
|
|
256
|
+
readonly [OAUTH_RESOURCE_SYMBOL]: OAuthResourceOptions;
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Adds OAuth protected-resource metadata to an existing inbound auth policy.
|
|
260
|
+
*
|
|
261
|
+
* The returned value remains an {@link AuthFn}: it preserves the ordered auth
|
|
262
|
+
* walk and can be used by any channel. A protocol-aware channel such as
|
|
263
|
+
* `mcpChannel` may additionally publish the metadata and discovery challenge.
|
|
264
|
+
*/
|
|
265
|
+
export declare function oauthResource(auth: AuthFn<Request> | readonly AuthFn<Request>[], options: OAuthResourceOptions): OAuthResourceAuth;
|
|
266
|
+
/** @internal Reads OAuth resource metadata without widening `AuthFn`. */
|
|
267
|
+
export declare function readOAuthResourceOptions(auth: AuthFn<Request> | readonly AuthFn<Request>[]): OAuthResourceOptions | undefined;
|
|
233
268
|
/**
|
|
234
269
|
* Attaches declared `www-authenticate` challenges to an {@link AuthFn}
|
|
235
270
|
* without changing its call signature or behavior. {@link routeAuth} reads
|
|
@@ -463,3 +498,4 @@ export declare function jwtEcdsa(config: VerifyJwtEcdsaConfig): AuthFn<Request>;
|
|
|
463
498
|
* for {@link routeAuth}'s 401.
|
|
464
499
|
*/
|
|
465
500
|
export declare function oidc(config: VerifyOidcConfig): AuthFn<Request>;
|
|
501
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#runtime/governance/auth/vercel-oidc-project.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}};return await authenticateOidcStrategy({strategy:t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeChallengeValue(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeChallengeValue(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?r:[{scheme:`Bearer`}]})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=resolveCurrentVercelProject(t),i=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:r,issuer:n.issuer,subjects:t.subjects??[]});return i.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:i.principal.principalType,subject:i.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(i.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:i.kind,subjectsConfigured:(t.subjects??[]).length>0,...i.kind===`misconfigured`?{detail:i.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return withAuthChallenges(async t=>{let r=extractBearerToken(t.headers.get(`authorization`)),i=e.currentVercelProject??(r!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(t):void 0),a=await verifyVercelOidc(r,i===void 0?e:{...e,currentVercelProject:i});return a.ok?a.sessionAuth:null},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oidc,placeholderAuth,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{isLoopbackHostname}from"#shared/network-address.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{resolveVercelOidcCurrentProject}from"#runtime/governance/auth/vercel-oidc-project.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}};return await authenticateOidcStrategy({strategy:t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e!==null&&isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeAuthChallengeParameter(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeAuthChallengeParameter(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}function isValidOAuthIdentifierUrl(e){try{let n=new URL(e);return(n.protocol===`https:`||n.protocol===`http:`&&isLoopbackHostname(n.hostname))&&n.username.length===0&&n.password.length===0&&n.search.length===0&&n.hash.length===0}catch{return!1}}function isValidMetadataPath(e){if(!e.startsWith(`/`)||e.startsWith(`//`))return!1;let t=new URL(e,`https://eve.invalid`);return t.origin===`https://eve.invalid`&&t.search.length===0&&t.hash.length===0}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};const OAUTH_RESOURCE_SYMBOL=Symbol.for(`eve.channels.auth.oauthResource`);function oauthResource(e,t){let n=t.issuer===void 0?t.authorizationServers:[t.issuer];if(n.length===0||n.some(e=>!isValidOAuthIdentifierUrl(e)))throw Error(`oauthResource requires at least one HTTPS authorization server URL (HTTP is allowed only on loopback).`);if(t.resource!==void 0&&!isValidOAuthIdentifierUrl(t.resource))throw Error(`oauthResource resource must be an HTTPS URL without credentials, query, or fragment (HTTP is allowed only on loopback).`);if(t.metadataPath!==void 0&&!isValidMetadataPath(t.metadataPath))throw Error(`oauthResource metadataPath must be an absolute path without a host, query, or fragment.`);let r=Array.isArray(e)?e:[e],composed=async e=>{for(let t of r){let n=await t(e);if(n)return n}return null},i=collectDeclaredChallenges(r),a=withAuthChallenges(composed,i.length>0?i:[{scheme:`Bearer`}]);return Object.defineProperty(a,OAUTH_RESOURCE_SYMBOL,{enumerable:!1,value:t}),a}function readOAuthResourceOptions(e){if(!Array.isArray(e))return e[OAUTH_RESOURCE_SYMBOL]}const AUTH_CHALLENGES_SYMBOL=Symbol.for(`eve.channels.auth.challenges`);function withAuthChallenges(e,t){let wrapped=t=>e(t);return Object.defineProperty(wrapped,AUTH_CHALLENGES_SYMBOL,{value:t}),wrapped}function getDeclaredChallenges(e){return e[AUTH_CHALLENGES_SYMBOL]}function collectDeclaredChallenges(e){let t=new Set,n=[];for(let r of e)for(let e of getDeclaredChallenges(r)??[]){let r=formatChallenge(e);t.has(r)||(t.add(r),n.push(e))}return n}async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}let r=collectDeclaredChallenges(n);return createUnauthorizedResponse({challenges:r.length>0?addInvalidBearerTokenError(e,r):[{scheme:`Bearer`}]})}function addInvalidBearerTokenError(e,t){let n=e.headers.get(`authorization`);return n===null||!/^Bearer(?:\s|$)/i.test(n.trim())||!t.some(e=>e.scheme===`Bearer`)?t:t.map(e=>e.scheme!==`Bearer`||e.parameters?.error!==void 0?e:{...e,parameters:{...e.parameters,error:`invalid_token`}})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return()=>isLocalDevelopmentServer()?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}function isLocalDevelopmentServer(){return process.env.VERCEL&&process.env.VERCEL_ENV===`development`?!0:isEveDevEnvironment()}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=resolveCurrentVercelProject(t),i=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:r,issuer:n.issuer,subjects:t.subjects??[]});return i.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:i.principal.principalType,subject:i.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(i.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:i.kind,subjectsConfigured:(t.subjects??[]).length>0,...i.kind===`misconfigured`?{detail:i.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return withAuthChallenges(async t=>{let n=extractBearerToken(t.headers.get(`authorization`)),i=e.currentVercelProject??(n!==null&&isLocalDevelopmentVercelOidc()?await resolveVercelOidcCurrentProject(t):void 0),a=await verifyVercelOidc(n,i===void 0?e:{...e,currentVercelProject:i});return a.ok?a.sessionAuth:null},[{scheme:`Bearer`}])}function isLocalDevelopmentVercelOidc(){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isEveDevEnvironment()}function httpBasic(e,t){return withAuthChallenges(t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null},[{parameters:{realm:t?.realm??`eve`,charset:`UTF-8`},scheme:`Basic`}])}function jwtHmac(e){return withAuthChallenges(async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function jwtEcdsa(e){return withAuthChallenges(async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function oidc(e){return withAuthChallenges(async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null},[{scheme:`Bearer`}])}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,escapeAuthChallengeParameter,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oauthResource,oidc,placeholderAuth,readOAuthResourceOptions,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc,withAuthChallenges};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_INFO_ROUTE_PATH,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{parseTraceparent}from"#protocol/traceparent.js";import{readAgentInfoRouteResponse,readRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{routeAuth}from"#public/channels/auth.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let n=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),turnPolicy:e.turnPolicy,routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(EVE_SESSION_ROUTE_PATH,async(r,i)=>{let a=await routeAuth(r,e.auth);if(a instanceof Response)return a;let o=await parseJsonRequest(r);if(o instanceof Response)return o;let s=rejectSessionContinuationToken(o);if(s!==null)return s;let c=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:a,payload:o});if(c instanceof Response)return c;let l=parseCreateBody(o);if(l instanceof Response)return l;let u=parseTraceparent(r.headers.get(`traceparent`)),d=checkUploadPolicy(l,n);if(d!==null)return d;let f=await resolveOnMessage({auth:c.auth,config:e,message:l.message,request:r});if(f instanceof Response)return f;let p=readRouteSessionCreator(i);if(p===void 0)return Response.json({error:`Session creation requires internal channel dispatch context.`,ok:!1},{status:500});let m;try{m=await p({auth:f.auth,capabilities:l.capabilities??(l.mode===`task`?void 0:{requestInput:!0}),callback:l.callback,initiatorAuth:c.accepted?c.initiatorAuth:void 0,input:{message:l.message,context:mergeContext(l.context,f.context),outputSchema:l.outputSchema},mode:l.mode??`conversation`,parentTraceContext:u})}catch(e){let n=logError(log,`session-create request failed`,e);return Response.json({error:`Failed to create the session.`,errorId:n,ok:!1},{status:500})}return Response.json({ok:!0,sessionId:m.sessionId,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.sessionId},status:202})}),POST(EVE_SESSION_ROUTE_PATTERN,async(r,{attachSession:i,params:a})=>{let o=await routeAuth(r,e.auth);if(o instanceof Response)return o;let s=requireSessionId(a);if(s instanceof Response)return s;let c=await parseJsonRequest(r);if(c instanceof Response)return c;let l=parseSessionMessageBody(c);if(l instanceof Response)return l;let u=checkUploadPolicy(l,n);if(u!==null)return u;let d=l.context,f=o;if(l.message!==void 0){let t=await resolveOnMessage({auth:o,config:e,message:l.message,request:r,sessionId:s});if(t instanceof Response)return t;d=mergeContext(l.context,t.context),f=t.auth}let p;try{let e=i(s),t={auth:f,callback:l.callback,context:d,outputSchema:l.outputSchema,turnPolicy:l.turnPolicy};p=l.inputResponses===void 0?await e.send(l.message,t):await e.respond(l.inputResponses,t)}catch(e){let n=logError(log,`session-message request failed`,e,{sessionId:s});return Response.json({error:`Failed to send the session message.`,errorId:n,ok:!1},{status:500})}return p.status===`session_not_active`?Response.json({code:`session_not_active`,error:`The session is no longer active.`,ok:!1},{headers:{"cache-control":`no-store`},status:409}):Response.json({ok:!0,sessionId:p.sessionId,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:p.sessionId},status:202})}),POST(EVE_SESSION_CANCEL_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseCancelTurnBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).cancel({turnId:s.turnId})}catch(e){let n=logError(log,`cancel-turn request failed`,e,{sessionId:o});return Response.json({error:`Failed to cancel the turn.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_turn`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_COMPACT_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseSessionControlBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).compact()}catch(e){let n=logError(log,`session-compaction request failed`,e,{sessionId:o});return Response.json({error:`Failed to compact the session.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_CLEAR_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseSessionControlBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).clear()}catch(e){let n=logError(log,`session-clear request failed`,e,{sessionId:o});return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_RESET_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseResetBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).reset({reason:s.reason})}catch(e){let n=logError(log,`session-reset request failed`,e,{sessionId:o});return Response.json({error:`Failed to reset the session.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`reset`?{ok:!0,previousSessionId:c.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`}})}),GET(EVE_SESSION_STREAM_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);return a instanceof Response?a:await createSessionStreamResponse(t,n(a))})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{if(r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message),r==null)throw TypeError(`eveChannel onMessage must return an auth result.`)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r.context===void 0?{auth:r.auth}:{auth:r.auth,context:r.context}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function parseCreateBody(e){if(e.inputResponses!==void 0)return Response.json({error:`'inputResponses' is only accepted for an existing session.`,ok:!1},{status:400});let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseCapabilitiesField(e.capabilities);if(i instanceof Response)return i;let a=parseModeField(e.mode);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);return o instanceof Response?o:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,capabilities:i,message:t,mode:a,context:n,outputSchema:o}}function parseSessionMessageBody(e){let t=rejectSessionContinuationToken(e);if(t!==null)return t;if(e.forwardedPrincipal!==void 0)return Response.json({error:`A forwarded principal is only accepted on session creation.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseInputResponses(e.inputResponses);if(i instanceof Response)return i;let a=parseClientContextField(e.clientContext);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);if(o instanceof Response)return o;let s=parseTurnPolicyField(e.turnPolicy);return s instanceof Response?s:n===void 0&&i===void 0?Response.json({error:`Expected a non-empty 'message' or a non-empty 'inputResponses' array.`,ok:!1},{status:400}):n!==void 0&&i!==void 0?Response.json({error:`'message' and 'inputResponses' are mutually exclusive.`,ok:!1},{status:400}):{callback:r,message:n,inputResponses:i,context:a,outputSchema:o,turnPolicy:s}}async function parseCancelTurnBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.turnId;return r===void 0?{}:typeof r!=`string`||r.length===0?Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400}):{turnId:r}}async function parseJsonRequest(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof t!=`object`||!t||Array.isArray(t)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):t}async function parseResetBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.reason;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'reason' to be a non-empty string.`,ok:!1},{status:400}):r===void 0?{}:{reason:r}}async function parseSessionControlBody(e){let t=await parseOptionalJsonRequest(e);return t instanceof Response?t:rejectSessionContinuationToken(t)??t}async function parseOptionalJsonRequest(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof n!=`object`||!n||Array.isArray(n)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):n}function rejectSessionContinuationToken(e){return`continuationToken`in e?Response.json({error:`Session-ID routes do not accept 'continuationToken'.`,ok:!1},{status:400}):null}function requireSessionId(e){return e.sessionId||Response.json({error:`Missing session id.`,ok:!1},{status:400})}async function createSessionStreamResponse(e,t){let n=parseStartIndex(e);if(n instanceof Response)return n;let r=parseIncludeTailIndex(e);try{let e=r?await t.getStreamTailIndex():void 0,i=await t.getEventStream({startIndex:n}),a=new Headers({"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:t.id,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION});return e!==void 0&&a.set(EVE_STREAM_TAIL_INDEX_HEADER,String(e)),new Response(serializeAsNdjson(i),{headers:a})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseCapabilitiesField(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return Response.json({error:`Expected 'capabilities' to be an object.`,ok:!1},{status:400});let t=Object.keys(e),n=Reflect.get(e,`requestInput`);return t.some(e=>e!==`requestInput`)||n!==void 0&&typeof n!=`boolean`?Response.json({error:`Expected 'capabilities.requestInput' to be a boolean when provided.`,ok:!1},{status:400}):n===void 0?{}:{requestInput:n}}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseTurnPolicyField(e){if(e!==void 0)return e===`queue`||e===`steer`?e:Response.json({error:`Expected 'turnPolicy' to be either 'queue' or 'steer'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{isRuntimeSessionOwnershipConflictError}from"#execution/runtime-errors.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_INFO_ROUTE_PATH,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,EVE_SUBAGENT_STREAM_ROUTE_PATTERN,createEveSessionStreamRoutePath,createEveSubagentStreamRoutePath}from"#protocol/routes.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{parseTraceparent}from"#protocol/traceparent.js";import{routeAuth}from"#public/channels/auth.js";import{readAgentInfoRouteResponse,readRemoteAgentStreamHeadersResolver,readRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{resolveForwardedPrincipal}from"#channel/forwarded-principal.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let r=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),turnPolicy:e.turnPolicy,routes:[GET(EVE_INFO_ROUTE_PATH,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=readAgentInfoRouteResponse(n);return i===void 0?Response.json({error:`Agent info route requires internal channel dispatch context.`,ok:!1},{status:500}):await i()}),POST(EVE_SESSION_ROUTE_PATH,async(i,a)=>{let o=await routeAuth(i,e.auth);if(o instanceof Response)return o;let s=await parseJsonRequest(i);if(s instanceof Response)return s;let c=rejectSessionContinuationToken(s);if(c!==null)return c;let l=await resolveForwardedPrincipal({trustedForwarders:e.trustedForwarders,forwarder:o,payload:s});if(l instanceof Response)return l;let u=parseCreateBody(s);if(u instanceof Response)return u;let d=parseTraceparent(i.headers.get(`traceparent`)),f=checkUploadPolicy(u,r);if(f!==null)return f;if(u.operationId!==void 0&&l.auth.principalType===`anonymous`)return Response.json({error:`operationId requires an authenticated principal.`,ok:!1},{status:400});let p=u.operationId===void 0?void 0:await deriveOperationContinuationToken({auth:l.auth,operationId:u.operationId});if(p!==void 0){let e=await a.resolveSession(p);if(e!==void 0)return Response.json({ok:!0,sessionId:e.id,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.id},status:202})}let m=await resolveOnMessage({auth:l.auth,config:e,message:u.message,request:i});if(m instanceof Response)return m;let h=readRouteSessionCreator(a);if(h===void 0)return Response.json({error:`Session creation requires internal channel dispatch context.`,ok:!1},{status:500});let g;try{g=await h({auth:m.auth,capabilities:u.capabilities??(u.mode===`task`?void 0:{requestInput:!0}),callback:u.callback,continuationToken:p,initiatorAuth:l.accepted?l.initiatorAuth:void 0,input:{message:u.message,context:mergeContext(u.context,m.context),outputSchema:u.outputSchema},mode:u.mode??`conversation`,parentTraceContext:d})}catch(e){if(p!==void 0&&isRuntimeSessionOwnershipConflictError(e))return Response.json({ok:!0,sessionId:e.ownerSessionId,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:e.ownerSessionId},status:202});let r=logError(log,`session-create request failed`,e);return Response.json({error:`Failed to create the session.`,errorId:r,ok:!1},{status:500})}return Response.json({ok:!0,sessionId:g.sessionId,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:g.sessionId},status:202})}),POST(EVE_SESSION_ROUTE_PATTERN,async(n,{attachSession:i,params:a})=>{let o=await routeAuth(n,e.auth);if(o instanceof Response)return o;let s=requireSessionId(a);if(s instanceof Response)return s;let c=await parseJsonRequest(n);if(c instanceof Response)return c;let l=parseSessionMessageBody(c);if(l instanceof Response)return l;let u=checkUploadPolicy(l,r);if(u!==null)return u;let d=l.context,f=o;if(l.message!==void 0){let t=await resolveOnMessage({auth:o,config:e,message:l.message,request:n,sessionId:s});if(t instanceof Response)return t;d=mergeContext(l.context,t.context),f=t.auth}let p;try{let e=i(s),t={auth:f,callback:l.callback,context:d,outputSchema:l.outputSchema,turnPolicy:l.turnPolicy};p=l.inputResponses===void 0?await e.send(l.message,t):await e.respond(l.inputResponses,t)}catch(e){let n=logError(log,`session-message request failed`,e,{sessionId:s});return Response.json({error:`Failed to send the session message.`,errorId:n,ok:!1},{status:500})}return p.status===`session_not_active`?Response.json({code:`session_not_active`,error:`The session is no longer active.`,ok:!1},{headers:{"cache-control":`no-store`},status:409}):Response.json({ok:!0,sessionId:p.sessionId,status:`accepted`},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:p.sessionId},status:202})}),POST(EVE_SESSION_CANCEL_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseCancelTurnBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).cancel({taskId:s.taskId,turnId:s.turnId})}catch(e){let n=logError(log,`cancel-turn request failed`,e,{sessionId:o});return Response.json({error:`Failed to cancel the turn.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_turn`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_COMPACT_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseSessionControlBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).compact()}catch(e){let n=logError(log,`session-compaction request failed`,e,{sessionId:o});return Response.json({error:`Failed to compact the session.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_CLEAR_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseSessionControlBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).clear()}catch(e){let n=logError(log,`session-clear request failed`,e,{sessionId:o});return Response.json({error:`Failed to clear the session context.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`accepted`?{ok:!0,sessionId:c.sessionId,status:`accepted`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`},status:c.status===`accepted`?202:200})}),POST(EVE_SESSION_RESET_ROUTE_PATTERN,async(n,{attachSession:r,params:i})=>{let a=await routeAuth(n,e.auth);if(a instanceof Response)return a;let o=requireSessionId(i);if(o instanceof Response)return o;let s=await parseResetBody(n);if(s instanceof Response)return s;let c;try{c=await r(o).reset({reason:s.reason})}catch(e){let n=logError(log,`session-reset request failed`,e,{sessionId:o});return Response.json({error:`Failed to reset the session.`,errorId:n,ok:!1},{status:500})}return Response.json(c.status===`reset`?{ok:!0,previousSessionId:c.previousSessionId,status:`reset`}:{ok:!0,status:`no_active_session`},{headers:{"cache-control":`no-store`}})}),GET(EVE_SESSION_STREAM_ROUTE_PATTERN,async(t,{attachSession:n,params:r})=>{let i=await routeAuth(t,e.auth);if(i instanceof Response)return i;let a=requireSessionId(r);return a instanceof Response?a:await createSessionStreamResponse(t,n(a))}),GET(EVE_SUBAGENT_STREAM_ROUTE_PATTERN,async(t,n)=>{let r=await routeAuth(t,e.auth);if(r instanceof Response)return r;let i=n.params.parentSessionId,a=n.params.callId,o=n.params.childSessionId;if(!i||!a||!o)return Response.json({error:`Missing subagent stream coordinates.`,ok:!1},{status:400});let s=parseStartIndex(t);if(s instanceof Response)return s;let c=parseIncludeTailIndex(t),l=createEveSubagentStreamRoutePath({callId:a,childSessionId:o,parentSessionId:i}),u;try{let e=await findRemoteSubagentBinding({callId:a,childSessionId:o,childStreamPath:l,parentSessionId:i,parent:n.attachSession(i)});if(e===void 0)throw Error(`Remote subagent binding not found.`);u=e}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let d=readRemoteAgentStreamHeadersResolver(n);if(d===void 0)return Response.json({error:`Subagent stream proxy requires internal channel dispatch context.`,ok:!1},{status:500});let f;try{f=await d({name:u.data.toolName,resolverId:u.data.remote.resolverId,url:u.data.remote.url})}catch{return Response.json({error:`Subagent stream not found.`,ok:!1},{status:404})}let h=new URL(createEveSessionStreamRoutePath(o).replace(/^\/+/,``),`${u.data.remote.url.replace(/\/+$/,``)}/`);s!==void 0&&h.searchParams.set(`startIndex`,String(s)),c&&h.searchParams.set(`includeTailIndex`,`1`);let g=await fetch(h,{cache:`no-store`,headers:f,redirect:`manual`,signal:t.signal}),_=new Headers;for(let e of[`cache-control`,`content-type`,`x-accel-buffering`,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER]){let t=g.headers.get(e);t!==null&&_.set(e,t)}return new Response(g.body,{headers:_,status:g.status,statusText:g.statusText})})],events:e.events})}async function findRemoteSubagentBinding(e){let t=await e.parent.getStreamTailIndex();if(t<0)return;let n=(await e.parent.getEventStream({startIndex:0})).getReader(),r;try{for(let i=0;i<=t;i+=1){let t=await n.read();if(t.done)break;let i=t.value;i.type===`subagent.called`&&i.data.sessionId===e.parentSessionId&&i.data.callId===e.callId&&i.data.childSessionId===e.childSessionId&&i.data.childStreamPath===e.childStreamPath&&i.data.remote!==void 0&&(r=i)}}finally{await n.cancel().catch(()=>{})}return r}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{if(r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message),r==null)throw TypeError(`eveChannel onMessage must return an auth result.`)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r.context===void 0?{auth:r.auth}:{auth:r.auth,context:r.context}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}async function deriveOperationContinuationToken(e){let t=JSON.stringify([`eve:create-session:v1`,e.auth.authenticator,e.auth.issuer??null,e.auth.principalType,e.auth.principalId,e.operationId]),n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(t));return`eve:op:${Array.from(new Uint8Array(n),e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,32)}`}function parseCreateBody(e){if(e.inputResponses!==void 0)return Response.json({error:`'inputResponses' is only accepted for an existing session.`,ok:!1},{status:400});let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseCapabilitiesField(e.capabilities);if(i instanceof Response)return i;let a=parseModeField(e.mode);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);if(o instanceof Response)return o;if(t===void 0)return Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400});let s=e.operationId;if(s!==void 0&&(typeof s!=`string`||!s))return Response.json({error:`Expected 'operationId' to be a non-empty string.`,ok:!1},{status:400});let c={callback:r,capabilities:i,message:t,mode:a,context:n,outputSchema:o};return typeof s==`string`&&(c.operationId=s),c}function parseSessionMessageBody(e){let t=rejectSessionContinuationToken(e);if(t!==null)return t;if(e.forwardedPrincipal!==void 0)return Response.json({error:`A forwarded principal is only accepted on session creation.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseInputResponses(e.inputResponses);if(i instanceof Response)return i;let a=parseClientContextField(e.clientContext);if(a instanceof Response)return a;let o=parseOutputSchemaField(e.outputSchema);if(o instanceof Response)return o;let s=parseTurnPolicyField(e.turnPolicy);return s instanceof Response?s:n===void 0&&i===void 0?Response.json({error:`Expected a non-empty 'message' or a non-empty 'inputResponses' array.`,ok:!1},{status:400}):n!==void 0&&i!==void 0?Response.json({error:`'message' and 'inputResponses' are mutually exclusive.`,ok:!1},{status:400}):{callback:r,message:n,inputResponses:i,context:a,outputSchema:o,turnPolicy:s}}async function parseCancelTurnBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.turnId,i=t.taskId;if(r!==void 0&&(typeof r!=`string`||r.length===0))return Response.json({error:`Expected 'turnId' to be a non-empty string.`,ok:!1},{status:400});if(i!==void 0&&(typeof i!=`string`||i.length===0))return Response.json({error:`Expected 'taskId' to be a non-empty string.`,ok:!1},{status:400});let a={};return typeof i==`string`&&(a.taskId=i),typeof r==`string`&&(a.turnId=r),a}async function parseJsonRequest(e){let t;try{t=await e.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof t!=`object`||!t||Array.isArray(t)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):t}async function parseResetBody(e){let t=await parseOptionalJsonRequest(e);if(t instanceof Response)return t;let n=rejectSessionContinuationToken(t);if(n!==null)return n;let r=t.reason;return r!==void 0&&(typeof r!=`string`||r.length===0)?Response.json({error:`Expected 'reason' to be a non-empty string.`,ok:!1},{status:400}):r===void 0?{}:{reason:r}}async function parseSessionControlBody(e){let t=await parseOptionalJsonRequest(e);return t instanceof Response?t:rejectSessionContinuationToken(t)??t}async function parseOptionalJsonRequest(e){let t;try{t=await e.text()}catch{return Response.json({error:`Unreadable request body.`,ok:!1},{status:400})}if(t.trim().length===0)return{};let n;try{n=JSON.parse(t)}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}return typeof n!=`object`||!n||Array.isArray(n)?Response.json({error:`Expected a JSON object.`,ok:!1},{status:400}):n}function rejectSessionContinuationToken(e){return`continuationToken`in e?Response.json({error:`Session-ID routes do not accept 'continuationToken'.`,ok:!1},{status:400}):null}function requireSessionId(e){return e.sessionId||Response.json({error:`Missing session id.`,ok:!1},{status:400})}async function createSessionStreamResponse(e,t){let n=parseStartIndex(e);if(n instanceof Response)return n;let r=parseIncludeTailIndex(e);try{let e=r?await t.getStreamTailIndex():void 0,i=await t.getEventStream({startIndex:n}),a=new Headers({"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:t.id,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION});return e!==void 0&&a.set(EVE_STREAM_TAIL_INDEX_HEADER,String(e)),new Response(serializeAsNdjson(i),{headers:a})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseCapabilitiesField(e){if(e===void 0)return;if(typeof e!=`object`||!e||Array.isArray(e))return Response.json({error:`Expected 'capabilities' to be an object.`,ok:!1},{status:400});let t=Object.keys(e),n=Reflect.get(e,`requestInput`);return t.some(e=>e!==`requestInput`)||n!==void 0&&typeof n!=`boolean`?Response.json({error:`Expected 'capabilities.requestInput' to be a boolean when provided.`,ok:!1},{status:400}):n===void 0?{}:{requestInput:n}}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseTurnPolicyField(e){if(e!==void 0)return e===`queue`||e===`steer`?e:Response.json({error:`Expected 'turnPolicy' to be either 'queue' or 'steer'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
|
|
2
2
|
${e}`}function parseIncludeTailIndex(e){let t=new URL(e.url).searchParams.get(`includeTailIndex`);return t===`1`||t===`true`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number(t);return!/^-?\d+$/.test(t)||!Number.isSafeInteger(n)?Response.json({error:`Expected startIndex to be an integer.`,ok:!1},{status:400}):n}function serializeAsNdjson(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({start(e){e.enqueue(t.encode(`
|
|
3
3
|
`))},transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}export{defaultEveAuth,eveChannel};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Channel } from "#public/definitions/channel.js";
|
|
2
|
+
import { type AuthFn } from "#public/channels/auth.js";
|
|
3
|
+
export interface McpChannelInput {
|
|
4
|
+
/** Existing eve route-auth policy. Use `none()` for explicit public access. */
|
|
5
|
+
readonly auth: AuthFn<Request> | readonly AuthFn<Request>[];
|
|
6
|
+
/** Streamable HTTP endpoint path. Defaults to `/mcp`. */
|
|
7
|
+
readonly path?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Public MCP channel exposing durable agent invocation compatibility tools. */
|
|
10
|
+
export type McpChannel = Channel;
|
|
11
|
+
/**
|
|
12
|
+
* Publishes this agent as a stateless Streamable HTTP MCP server.
|
|
13
|
+
*
|
|
14
|
+
* This channel owns only MCP transport and durable eve invocation. It reuses
|
|
15
|
+
* eve's inbound auth strategies and recognizes `oauthResource(...)` metadata
|
|
16
|
+
* when OAuth discovery is needed.
|
|
17
|
+
* The file containing this channel must be `agent/channels/mcp.ts`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function mcpChannel(input: McpChannelInput): McpChannel;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{inputRequestSchema,inputResponseSchema}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import{DELETE,GET,HEAD,OPTIONS,POST,defineChannel}from"#public/definitions/channel.js";import{escapeAuthChallengeParameter,readOAuthResourceOptions,routeAuth}from"#public/channels/auth.js";import{readAgentInfoRouteResponse,readRouteChannelName,readRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{WorkflowAgentInvocationExecution}from"#internal/invocation/workflow-execution.js";import{validateMcpHttpRequest,validateMcpMetadataRequest}from"#internal/mcp/http-security.js";import{createMcpStreamableHttpServer,defineMcpTool}from"#internal/mcp/streamable-http-server.js";import{createMcpProtectedResourceMetadata,createMcpResourceChallenge}from"#internal/mcp/protected-resource.js";function mcpChannel(e){if(e?.auth===void 0)throw Error(`mcpChannel requires auth. Use none() for explicit public access.`);let t=e.path??`/mcp`,n=readOAuthResourceOptions(e.auth),r=[GET(t,async(t,r)=>await authenticateMcpRequest(t,r,e.auth,n)),POST(t,async(t,r)=>await authenticateMcpRequest(t,r,e.auth,n)),DELETE(t,async(t,r)=>await authenticateMcpRequest(t,r,e.auth,n))];return n!==void 0&&r.unshift(...protectedResourceMetadataRoutes(n,t)),defineChannel({routes:r})}function protectedResourceMetadataRoutes(e,t){let n=e.metadataPath??`/.well-known/oauth-protected-resource`;return[GET(n,async n=>protectedResourceMetadataResponse(n,e,t,!1)),HEAD(n,async n=>protectedResourceMetadataResponse(n,e,t,!0)),OPTIONS(n,async e=>protectedResourceMetadataOptionsResponse(e))]}function protectedResourceMetadataResponse(e,t,n,r){let i=validateMcpMetadataRequest(e);if(i!==void 0)return i;let a=t.resource??new URL(n,new URL(e.url).origin).toString(),o=t.issuer===void 0?t.authorizationServers:[t.issuer],s=Response.json(createMcpProtectedResourceMetadata({authorizationServers:o,resource:a,scopesSupported:t.scopes}),{headers:{"access-control-allow-origin":`*`,"cache-control":`no-store`}});return r?new Response(null,{headers:s.headers,status:s.status}):s}function protectedResourceMetadataOptionsResponse(e){let t=validateMcpMetadataRequest(e);if(t!==void 0)return t;let n=new Headers({"access-control-allow-methods":`GET, HEAD, OPTIONS`,"access-control-allow-origin":`*`,"cache-control":`no-store`}),r=e.headers.get(`access-control-request-headers`);return r!==null&&(n.set(`access-control-allow-headers`,r),n.set(`vary`,`Access-Control-Request-Headers`)),new Response(null,{headers:n,status:204})}function addResourceChallenge(e,t,n){if(e.status!==401&&e.status!==403)return e;let r=n.metadataPath??`/.well-known/oauth-protected-resource`,i=n.resource??new URL(t.url).origin,a=new URL(r,i).toString(),o=new Headers(e.headers),s=o.get(`www-authenticate`);if(e.status===401)o.set(`www-authenticate`,mergeMcpBearerChallenge(s,a,n.scopes));else{let t=augmentInsufficientScopeChallenge(s,a);if(t===void 0)return e;o.set(`www-authenticate`,t)}return new Response(e.body,{headers:o,status:e.status,statusText:e.statusText})}function mergeMcpBearerChallenge(e,t,n){let r=parseAuthChallenges(e),i=r.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`))??r.find(e=>e.scheme.toLowerCase()===`bearer`);return replaceBearerChallenges(r,i,i===void 0?createMcpResourceChallenge(t,n):augmentBearerChallenge(i.value,t,n))}function augmentInsufficientScopeChallenge(e,t){let n=parseAuthChallenges(e),r=n.find(e=>e.scheme.toLowerCase()===`bearer`&&hasAuthParameter(e.value,`error`,`insufficient_scope`));if(r!==void 0)return replaceBearerChallenges(n,r,augmentBearerChallenge(r.value,t))}function replaceBearerChallenges(e,t,n){let r=[],i=!1;for(let a of e){if(a.scheme.toLowerCase()!==`bearer`){r.push(a.value);continue}!i&&a===t&&(r.push(n),i=!0)}return i||r.push(n),r.join(`, `)}function augmentBearerChallenge(e,t,n){let r=e;return hasAuthParameter(r,`resource_metadata`)||(r=appendAuthParameter(r,`resource_metadata`,t)),n?.length&&!hasAuthParameter(r,`scope`)&&(r=appendAuthParameter(r,`scope`,n.join(` `))),r}function appendAuthParameter(e,t,n){return`${e}${e.trim().toLowerCase()===`bearer`?` `:`, `}${t}="${escapeAuthChallengeParameter(n)}"`}function hasAuthParameter(e,t,n){let r=t.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);if(n===void 0)return RegExp(`(?:^|[\\s,])${r}\\s*=`,`i`).test(e);let i=n.replaceAll(/[.*+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`(?:^|[\\s,])${r}\\s*=\\s*(?:"${i}"|${i})(?=$|[\\s,])`,`i`).test(e)}function parseAuthChallenges(e){if(e===null)return[];let t=[];for(let n of splitQuotedHeaderList(e)){let e=readChallengeScheme(n);if(e!==void 0){t.push({scheme:e,value:n});continue}let r=t.at(-1);r!==void 0&&(r.value+=`, ${n}`)}return t}function splitQuotedHeaderList(e){let t=[],n=!1,r=!1,i=0;for(let a=0;a<e.length;a++){let o=e[a];if(n)n=!1;else if(o===`\\`)n=!0;else if(o===`"`)r=!r;else if(o===`,`&&!r){let n=e.slice(i,a).trim();n.length>0&&t.push(n),i=a+1}}let a=e.slice(i).trim();return a.length>0&&t.push(a),t}function readChallengeScheme(e){let t=/^([!#$%&'*+\-.^_`|~0-9A-Za-z]+)(?:\s+|$)/.exec(e);if(t===null)return;let n=t[1];if(n!==void 0)return e.slice(n.length).trimStart().startsWith(`=`)?void 0:n}async function authenticateMcpRequest(e,t,n,r){let i=validateMcpHttpRequest(e);if(i!==void 0)return i;let a=await routeAuth(e,n);return a instanceof Response?r===void 0?a:addResourceChallenge(a,e,r):await handleMcpRequest(e,t,a)}async function handleMcpRequest(e,n,r){let i=readRouteSessionCreator(n),a=readRouteChannelName(n),o=readAgentInfoRouteResponse(n);if(a===void 0||i===void 0||o===void 0)return Response.json({error:`MCP requires agent route context.`},{status:500});let s=await o();if(!s.ok)return s;let c=await s.json();if(typeof c.agent?.name!=`string`)return Response.json({error:`MCP requires compiled agent metadata.`},{status:500});let l=typeof c.agent.description==`string`?c.agent.description:void 0,u=new WorkflowAgentInvocationExecution({createSession:i,from:n.from});return await createMcpStreamableHttpServer({authenticate:async()=>r,name:c.agent.name,tools:createInvocationTools(u,l,r.authenticator===`none`&&r.principalType===`anonymous`),version:resolveInstalledPackageInfo().version})(e)}function createInvocationTools(t,n,i){let a=i?` On this public channel, the invocation ID is a bearer capability until workflow retention expires.`:``,o=`Starts durable work and returns an invocation handle immediately.${a}`;return[defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:n===void 0?o:`${n} ${o}`,inputSchema:z.strictObject({message:z.string().min(1),outputSchema:z.looseObject({}).optional()}),name:`agent_start`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(e,n){return invocationResult(await t.create({auth:n.auth,message:e.message,outputSchema:asJsonObject(e.outputSchema)}))}}),defineMcpTool({definition:{annotations:{destructiveHint:!1,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!0},description:`Reads complete durable invocation state.${a}`,inputSchema:z.strictObject({invocationId:z.string().min(1)}),name:`agent_get`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(e,n){return invocationResult(requiredInvocation(await t.read({auth:n.auth,invocationId:e.invocationId})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!1,openWorldHint:!0,readOnlyHint:!1},description:`Answers a pending input request on a durable invocation.`,inputSchema:z.strictObject({invocationId:z.string().min(1),responses:z.array(inputResponseSchema).min(1)}),name:`agent_update`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(e,n){return invocationResult(requiredMutation(await t.update({auth:n.auth,invocationId:e.invocationId,responses:e.responses})))}}),defineMcpTool({definition:{annotations:{destructiveHint:!0,idempotentHint:!0,openWorldHint:!1,readOnlyHint:!1},description:`Requests cancellation of a durable invocation. Read it again to observe acknowledgement.`,inputSchema:z.strictObject({invocationId:z.string().min(1)}),name:`agent_cancel`,outputSchema:AGENT_INVOCATION_OUTPUT_SCHEMA},async call(e,n){return invocationResult(requiredInvocation(await t.cancel({auth:n.auth,invocationId:e.invocationId})))}})]}function requiredInvocation(e){if(e===void 0)throw Error(`Invocation not found.`);return e}function requiredMutation(e){switch(e.type){case`success`:return e.invocation;case`conflict`:throw Error(e.message);case`not_found`:throw Error(`Invocation not found.`)}}function invocationResult(e){let t=parseJsonObject(e);return{content:[{text:JSON.stringify(t),type:`text`}],structuredContent:t}}function asJsonObject(e){if(e===void 0)return;let t=parseJsonObject(e);return validateOutputSchemaComplexity(t),t}const AUTHORIZATION_CHALLENGE_SCHEMA=z.strictObject({displayName:z.string().optional(),expiresAt:z.iso.datetime().optional(),instructions:z.string().optional(),url:z.url().optional(),userCode:z.string().optional()}),AUTHORIZATION_REQUEST_SCHEMA=z.strictObject({authorization:AUTHORIZATION_CHALLENGE_SCHEMA.optional(),description:z.string(),name:z.string(),webhookUrl:z.url().optional()}),MCP_INPUT_REQUEST_SCHEMA=inputRequestSchema.safeExtend({action:z.strictObject({callId:z.string(),input:z.record(z.string(),z.json()),kind:z.literal(`tool-call`),toolName:z.string()})}),AGENT_INVOCATION_BASE_SCHEMA=z.strictObject({createdAt:z.iso.datetime(),expiresAt:z.iso.datetime().optional(),invocationId:z.string()}),AGENT_INVOCATION_OUTPUT_SCHEMA=z.discriminatedUnion(`status`,[AGENT_INVOCATION_BASE_SCHEMA.extend({pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`working`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({inputRequests:z.record(z.string(),MCP_INPUT_REQUEST_SCHEMA),result:z.json().optional(),status:z.literal(`input_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({authorizations:z.array(AUTHORIZATION_REQUEST_SCHEMA).min(1),pollAfterMs:z.number().int().nonnegative(),result:z.json().optional(),status:z.literal(`authorization_required`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({result:z.json().optional(),status:z.literal(`completed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({error:z.strictObject({code:z.number().int(),data:z.json().optional(),message:z.string()}),status:z.literal(`failed`)}),AGENT_INVOCATION_BASE_SCHEMA.extend({status:z.literal(`cancelled`)})]);function validateOutputSchemaComplexity(e){if(new TextEncoder().encode(JSON.stringify(e)).byteLength>65536)throw Error(`outputSchema must be at most 65536 bytes.`);let t=0,visit=(e,n)=>{if(t++,t>2048)throw Error(`outputSchema must contain at most 2048 nodes.`);if(n>32)throw Error(`outputSchema must be at most 32 levels deep.`);if(Array.isArray(e)){for(let t of e)visit(t,n+1);return}if(!(typeof e!=`object`||!e))for(let[t,r]of Object.entries(e)){if(t===`$ref`&&typeof r==`string`&&!r.startsWith(`#`))throw Error(`outputSchema external $ref values are not supported.`);visit(r,n+1)}};visit(e,0)}export{mcpChannel};
|
|
@@ -12,14 +12,14 @@ export type { Session, SessionHandle } from "#channel/session.js";
|
|
|
12
12
|
export type { SessionRespondOptions, SessionSendOptions } from "#channel/session.js";
|
|
13
13
|
export type { ChannelFrom, ChannelReceiveContext, ChannelResolveSession, ChannelRespondOptions, ChannelSendOptions, ChannelSource, };
|
|
14
14
|
export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
|
|
15
|
-
export { GET,
|
|
15
|
+
export { DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, WS } from "#channel/routes.js";
|
|
16
16
|
export type { AttachSessionFn, HttpRouteDefinition, RouteDefinition, RouteHandlerArgs, WebSocketMessage, WebSocketPeer, WebSocketRouteDefinition, WebSocketRouteHandler, WebSocketRouteHooks, WebSocketUpgradeRequest, WebSocketUpgradeResult, } from "#channel/routes.js";
|
|
17
17
|
/**
|
|
18
18
|
* HTTP method a route handles. Defaults to `"POST"` — almost every route
|
|
19
19
|
* is a webhook. Override only when authoring a non-webhook route such as a
|
|
20
20
|
* long-poll endpoint or an event-stream reader.
|
|
21
21
|
*/
|
|
22
|
-
export type ChannelMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
22
|
+
export type ChannelMethod = "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
|
|
23
23
|
/**
|
|
24
24
|
* Method-like discriminator used by compiled channel route entries.
|
|
25
25
|
*
|