eve 0.70.3 → 0.71.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/channel/agent-description.d.ts +33 -0
  3. package/dist/src/channel/agent-description.js +1 -0
  4. package/dist/src/channel/resolved-prompt.d.ts +12 -0
  5. package/dist/src/channel/resolved-prompt.js +1 -0
  6. package/dist/src/channel/routes.d.ts +7 -0
  7. package/dist/src/channel/tool-eligibility.d.ts +39 -0
  8. package/dist/src/channel/tool-eligibility.js +1 -0
  9. package/dist/src/compiled/.vendor-stamp.json +1 -1
  10. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  11. package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +18 -0
  12. package/dist/src/compiler/extension-compatibility.d.ts +2 -2
  13. package/dist/src/compiler/extension-compatibility.js +1 -1
  14. package/dist/src/context/memory-tools.js +1 -1
  15. package/dist/src/context/serialize.js +1 -1
  16. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  17. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  18. package/dist/src/execution/proxied-deliver-step.js +1 -1
  19. package/dist/src/execution/sandbox/bash.d.ts +34 -11
  20. package/dist/src/execution/sandbox/bash.js +24 -1
  21. package/dist/src/execution/sandbox/bindings/docker-session.js +1 -1
  22. package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +1 -1
  23. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
  24. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  25. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  26. package/dist/src/execution/sandbox/bindings/local-provider-utils.js +1 -1
  27. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  28. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  29. package/dist/src/execution/sandbox/ensure.js +1 -1
  30. package/dist/src/execution/sandbox/glob-tool.js +1 -1
  31. package/dist/src/execution/sandbox/grep-tool.js +1 -1
  32. package/dist/src/execution/sandbox/prewarm.js +1 -1
  33. package/dist/src/execution/sandbox/read-file.js +3 -3
  34. package/dist/src/execution/session/handoff-steps.js +1 -1
  35. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  36. package/dist/src/internal/application/package.js +1 -1
  37. package/dist/src/internal/attachments/media-metadata.d.ts +2 -0
  38. package/dist/src/internal/attachments/media-metadata.js +1 -1
  39. package/dist/src/internal/authored-definition/source-identity.d.ts +17 -8
  40. package/dist/src/internal/authored-definition/source-identity.js +1 -1
  41. package/dist/src/internal/authored-module-map-loader.js +1 -1
  42. package/dist/src/internal/mcp/streamable-http-server.js +1 -1
  43. package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +1 -1
  44. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  45. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +9 -0
  46. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
  47. package/dist/src/public/channels/chat-sdk/input-actions.d.ts +4 -2
  48. package/dist/src/public/channels/chat-sdk/input-actions.js +1 -1
  49. package/dist/src/public/channels/discord/defaults.js +1 -1
  50. package/dist/src/public/channels/discord/discordChannel.d.ts +10 -0
  51. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  52. package/dist/src/public/channels/index.d.ts +1 -1
  53. package/dist/src/public/channels/teams/defaults.js +1 -1
  54. package/dist/src/public/channels/teams/teamsChannel.d.ts +8 -3
  55. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  56. package/dist/src/public/channels/telegram/defaults.d.ts +5 -2
  57. package/dist/src/public/channels/telegram/defaults.js +1 -1
  58. package/dist/src/public/channels/telegram/hitl.d.ts +23 -1
  59. package/dist/src/public/channels/telegram/hitl.js +2 -2
  60. package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -0
  61. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  62. package/dist/src/public/definitions/channel.d.ts +1 -0
  63. package/dist/src/public/tools/result.js +1 -1
  64. package/dist/src/runtime/resolve-connection.js +1 -1
  65. package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
  66. package/dist/src/runtime/resolve-tool.js +1 -1
  67. package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
  68. package/dist/src/setup/scaffold/create/project.js +1 -1
  69. package/dist/src/subagents/hitl-proxy.d.ts +2 -0
  70. package/dist/src/subagents/hitl-proxy.js +1 -1
  71. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  72. package/dist/src/tools/provided/bash.d.ts +17 -2
  73. package/dist/src/tools/provided/bash.js +1 -1
  74. package/dist/src/tools/provided/read-file.js +1 -1
  75. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  76. package/docs/channels/custom.mdx +1 -0
  77. package/docs/concepts/built-in-tools.md +18 -1
  78. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  79. package/docs/extensions.md +1 -1
  80. package/docs/guides/hooks.md +2 -0
  81. package/docs/memory/custom-provider.md +4 -1
  82. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
- import{MAX_OUTPUT_BYTES}from"#execution/sandbox/truncate-output.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{normalizeModelPath}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGlobOnSandbox(e,t){let n=t.path??`/workspace`,r=await resolveAbsoluteFilePath(e,n),i=normalizeModelPath(r),a=Math.min(Math.max(1,t.limit??100),1e3),o=await ripgrepIsAvailable(e)?buildRipgrepCommand({normalizedPath:i,pattern:t.pattern}):buildPosixFindCommand({normalizedPath:i,pattern:t.pattern}),s=await e.run({command:o});if(s.exitCode!==0&&s.exitCode!==1||s.exitCode===1&&s.stderr.trim().length>0)throw buildGlobExecutionError(o,s.exitCode,s.stderr);let c=s.stdout.split(`
1
+ import{shellQuote}from"#execution/sandbox/shell-quote.js";import{MAX_OUTPUT_BYTES}from"#execution/sandbox/truncate-output.js";import{normalizeModelPath}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGlobOnSandbox(e,t){let n=t.path??`/workspace`,r=await resolveAbsoluteFilePath(e,n),i=normalizeModelPath(r),a=Math.min(Math.max(1,t.limit??100),1e3),o=await ripgrepIsAvailable(e)?buildRipgrepCommand({normalizedPath:i,pattern:t.pattern}):buildPosixFindCommand({normalizedPath:i,pattern:t.pattern}),s=await e.run({command:o});if(s.exitCode!==0&&s.exitCode!==1||s.exitCode===1&&s.stderr.trim().length>0)throw buildGlobExecutionError(o,s.exitCode,s.stderr);let c=s.stdout.split(`
2
2
  `).filter(e=>e.length>0),l=c.length>a,u=l?c.slice(0,a):c,d=[],f=0,p=!1;for(let e of u){let t=normalizeModelPath(e),n=Buffer.byteLength(t,`utf8`)+1;if(f+n>MAX_OUTPUT_BYTES&&d.length>0){p=!0;break}d.push(t),f+=n}if(d.length===0)return{content:`No files found`,count:0,path:i,truncated:!1};let m=l||p,h=[...d];return m&&(h.push(``),h.push(`(Results truncated: showing first ${d.length} results out of more. Use a more specific path or pattern to narrow results.)`)),{content:h.join(`
3
3
  `),count:d.length,path:i,truncated:m}}function buildRipgrepCommand(e){return[`rg --files --hidden`,`--glob '!.git/*'`,`--glob ${shellQuote(e.pattern)}`,shellQuote(e.normalizedPath)].join(` `)}function buildPosixFindCommand(e){let t=translateGlobToFindPattern(e.pattern),n=t.includes(`/`)?`-path ${shellQuote(`*/${t}`)}`:`-name ${shellQuote(t)}`;return[`find ${shellQuote(e.normalizedPath)}`,`-type f`,`-not -path '*/.git/*'`,n].join(` `)}function translateGlobToFindPattern(e){let t=e.replaceAll(`**`,`*`);for(;t.startsWith(`*/`);)t=t.slice(2);return t}function buildGlobExecutionError(e,t,n){let r=n.trim(),i=r.length>0?r:`no stderr output`;return Error(`glob failed (exit ${t}): ${i}\nCommand: ${e}`)}export{executeGlobOnSandbox};
@@ -1,3 +1,3 @@
1
- import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{normalizeModelPath}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGrepOnSandbox(e,t){let n=t.path??`/workspace`,r=await resolveAbsoluteFilePath(e,n),i=normalizeModelPath(r),a=Math.min(Math.max(1,t.limit??100),1e3),o=t.context!==void 0&&t.context>0?t.context:0,s=await ripgrepIsAvailable(e)?buildRipgrepCommand({contextLines:o,effectiveLimit:a,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:i,pattern:t.pattern}):buildPosixGrepCommand({contextLines:o,effectiveLimit:a,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:i,pattern:t.pattern}),c=await e.run({command:s});if(c.exitCode!==0&&c.exitCode!==1||c.exitCode===1&&c.stderr.trim().length>0)throw buildGrepExecutionError(s,c.exitCode,c.stderr);let l=c.stdout;return l.trim().length===0?{content:`No matches found`,matchCount:0,path:i,truncated:!1}:processOutput({effectiveLimit:a,normalizedPath:i,stdout:l})}function buildRipgrepCommand(e){let t=[`rg`,`--line-number`,`--color=never`,`--hidden`,`--glob '!.git/*'`];return e.ignoreCase&&t.push(`--ignore-case`),e.literal&&t.push(`--fixed-strings`),e.glob!==void 0&&t.push(`--glob ${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`--context ${e.contextLines}`),t.push(`--max-count ${e.effectiveLimit}`),t.push(`--`),t.push(shellQuote(e.pattern)),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function buildPosixGrepCommand(e){let t=[`grep`,`-r`,`-n`,`--exclude-dir=.git`];return e.ignoreCase&&t.push(`-i`),e.literal?t.push(`-F`):t.push(`-E`),e.glob!==void 0&&t.push(`--include=${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`-C ${e.contextLines}`),t.push(`-m ${e.effectiveLimit}`),t.push(`-e ${shellQuote(e.pattern)}`),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function processOutput(e){let t=e.stdout.split(`
1
+ import{shellQuote}from"#execution/sandbox/shell-quote.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{normalizeModelPath}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{ripgrepIsAvailable}from"#execution/sandbox/ripgrep-probe.js";async function executeGrepOnSandbox(e,t){let n=t.path??`/workspace`,r=await resolveAbsoluteFilePath(e,n),i=normalizeModelPath(r),a=Math.min(Math.max(1,t.limit??100),1e3),o=t.context!==void 0&&t.context>0?t.context:0,s=await ripgrepIsAvailable(e)?buildRipgrepCommand({contextLines:o,effectiveLimit:a,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:i,pattern:t.pattern}):buildPosixGrepCommand({contextLines:o,effectiveLimit:a,glob:t.glob,ignoreCase:t.ignoreCase??!1,literal:t.literal??!1,normalizedPath:i,pattern:t.pattern}),c=await e.run({command:s});if(c.exitCode!==0&&c.exitCode!==1||c.exitCode===1&&c.stderr.trim().length>0)throw buildGrepExecutionError(s,c.exitCode,c.stderr);let l=c.stdout;return l.trim().length===0?{content:`No matches found`,matchCount:0,path:i,truncated:!1}:processOutput({effectiveLimit:a,normalizedPath:i,stdout:l})}function buildRipgrepCommand(e){let t=[`rg`,`--line-number`,`--color=never`,`--hidden`,`--glob '!.git/*'`];return e.ignoreCase&&t.push(`--ignore-case`),e.literal&&t.push(`--fixed-strings`),e.glob!==void 0&&t.push(`--glob ${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`--context ${e.contextLines}`),t.push(`--max-count ${e.effectiveLimit}`),t.push(`--`),t.push(shellQuote(e.pattern)),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function buildPosixGrepCommand(e){let t=[`grep`,`-r`,`-n`,`--exclude-dir=.git`];return e.ignoreCase&&t.push(`-i`),e.literal?t.push(`-F`):t.push(`-E`),e.glob!==void 0&&t.push(`--include=${shellQuote(e.glob)}`),e.contextLines>0&&t.push(`-C ${e.contextLines}`),t.push(`-m ${e.effectiveLimit}`),t.push(`-e ${shellQuote(e.pattern)}`),t.push(shellQuote(e.normalizedPath)),t.join(` `)}function processOutput(e){let t=e.stdout.split(`
2
2
  `),n=[],r=0,i=0,a=!1;for(let e=0;e<t.length;e+=1){let o=t[e]??``;if(o.length===0&&e===t.length-1)continue;o!==`--`&&o.length>0&&/^.+:\d+:/.test(o)&&i++;let s=capLineLength(o),c=Buffer.byteLength(s,`utf8`)+1;if(r+c>MAX_OUTPUT_BYTES&&n.length>0){a=!0;break}n.push(s),r+=c}let o=a||i>=e.effectiveLimit,s=n.join(`
3
3
  `);if(o){let t=[];i>=e.effectiveLimit&&t.push(`Match limit reached (${e.effectiveLimit}). Use a larger limit or more specific pattern.`),a&&t.push(`Output truncated due to size. Use a more specific path or pattern.`),s+=`\n\n[${t.join(` `)}]`}return{content:s,matchCount:i,path:e.normalizedPath,truncated:o}}function buildGrepExecutionError(e,t,n){let r=n.trim(),i=r.length>0?r:`no stderr output`;return Error(`grep failed (exit ${t}): ${i}\nCommand: ${e}`)}export{executeGrepOnSandbox};
@@ -1 +1 @@
1
- import{join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{ROOT_RUNTIME_AGENT_NODE_ID,getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{createSandboxProviderResources}from"#shared/sandbox-provider.js";import{writeSandboxPreparedArtifactsManifest}from"#runtime/sandbox/prepared-artifacts.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";import{loadCompiledModuleMapFromAuthoredSource}from"#internal/authored-module-map-loader.js";import{createAuthoredSourceRuntimeCompiledArtifactsSource}from"#internal/application/runtime-compiled-artifacts-source.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{createSandboxProviderFiles}from"#execution/sandbox/provider-files.js";import{createDevelopmentSandboxProviderHost}from"#execution/sandbox/provider-host-development.js";import{materializeWorkspaceDirectory}from"#runtime/workspace/seed-files.js";const diskPreparedArtifactStore={async write(e){await writeSandboxPreparedArtifactsManifest(e)}};async function prewarmSandboxes(e){let t=await collectPrewarmTargets(e);if(t.length===0)return;let n=e.preparedArtifactStore??diskPreparedArtifactStore,r=e.dispatch??(async({context:e,provider:t})=>await t.implementation.prepare(e));e.log?.(`eve: initializing ${formatSandboxTemplateCount(t.length)}...`);let i=await Promise.allSettled(t.map(async({context:t,label:n,nodeId:i,provider:a})=>{let logProviderProgress=t=>{shouldLogSandboxPrewarmProgress(t)&&e.log?.(`eve: sandbox template "${n}" (${a.providerName}): ${t}`)};try{return{nodeId:i,provider:a,result:await r({context:{...t,log:e.log===void 0?void 0:logProviderProgress},provider:a})}}catch(t){let r=formatPrewarmFailureForEnvironment({providerName:a.providerName,error:t});throw e.log?.(`eve: failed to initialize sandbox template "${n}" on provider "${a.providerName}": ${toErrorMessage(r)}`),r}})),a=i.find(e=>e.status===`rejected`);if(a?.status===`rejected`)throw a.reason;let o=i.flatMap(e=>e.status===`fulfilled`?[{artifact:e.value.result,nodeId:e.value.nodeId,providerName:e.value.provider.providerName}]:[]);await n.write({compileDirectoryPath:e.compileDirectoryPath,entries:o}),e.log?.(`eve: initialized ${formatSandboxTemplateCount(t.length)}.`)}async function prewarmAppSandboxes(e){let t=e.compiledArtifactsSource??createAuthoredSourceRuntimeCompiledArtifactsSource(e.appRoot);if(t.kind!==`disk`)throw Error(`prewarmAppSandboxes requires disk-backed compiled artifacts.`);let n=await(e.loadAgentGraph??loadGraphFromArtifacts)({compiledArtifactsSource:t});await prewarmSandboxes({appRoot:getRuntimeCompiledArtifactsSandboxAppRoot(t)??e.appRoot,compileDirectoryPath:resolveRuntimeCompilerArtifactPaths(t.appRoot).compileDirectoryPath,compiledArtifactsSource:t,dispatch:e.dispatch,graph:n,log:e.log,preparedArtifactStore:e.preparedArtifactStore})}async function collectPrewarmTargets(e){let t=[];return await Promise.all(collectNodeSandboxes(e.graph).map(async({definition:n,nodeId:r,workspaceResourceRoot:i})=>{let a=getResolvedRuntimeAgentNode(e.graph,r).agent,o=join(resolve(e.appRoot,relative(a.metadata.appRoot,a.metadata.agentRoot)),`sandbox`),s=getSandboxEnvironmentRuntime(n.environment),c=await loadResourceRootSeedFiles({compileDirectoryPath:e.compileDirectoryPath,workspaceResourceRoot:i});t.push({context:{files:createSandboxProviderFiles(o),host:createDevelopmentSandboxProviderHost(e.appRoot),resources:createSandboxProviderResources({resourcesKey:i.contentHash,resourcesPath:i.contentHash===void 0?void 0:`${e.compileDirectoryPath}/${i.logicalPath}`,seedFiles:c}),sourceRevision:n.revisionHash,storagePath:resolveSandboxCacheDirectory(e.appRoot)},label:formatLabel(r),nodeId:r,provider:s})})),t.sort((e,t)=>e.label.localeCompare(t.label))}async function loadResourceRootSeedFiles(e){return e.workspaceResourceRoot.contentHash===void 0&&e.workspaceResourceRoot.rootEntries.length===0?[]:(await materializeWorkspaceDirectory(`${e.compileDirectoryPath}/${e.workspaceResourceRoot.logicalPath}`)).map(e=>({content:e.content,path:e.path}))}async function loadGraphFromArtifacts(e){let[t,n]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:e.compiledArtifactsSource}),loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e.compiledArtifactsSource})]);return await resolveRuntimeAgentGraph({manifest:t,moduleMap:n})}function collectNodeSandboxes(e){return[...e.nodesByNodeId.entries()].flatMap(([e,t])=>{let n=t.sandboxRegistry.sandbox;return n.definition.kind===`parent`?[]:[{...n,definition:n.definition,nodeId:e}]})}function formatLabel(e){return e===ROOT_RUNTIME_AGENT_NODE_ID?`root`:e}function formatSandboxTemplateCount(e){return`${e} sandbox ${e===1?`template`:`templates`}`}function shouldLogSandboxPrewarmProgress(e){return!e.startsWith(`checking `)&&!e.startsWith(`reusing `)&&e!==`loading microsandbox runtime`&&e!==`microsandbox runtime ready`}function formatPrewarmFailureForEnvironment(e){return!isVercelEnvironment()||!isLocalSandboxProvider(e.providerName)?e.error:Error(`The ${e.providerName} sandbox provider is not available when deploying on Vercel. Vercel build containers cannot run local Docker containers or microsandbox VMs. Use DefaultSandbox.environment() so eve selects Vercel Sandbox on Vercel, or configure VercelSandbox.environment() explicitly. Original ${e.providerName} error: ${toErrorMessage(e.error)}`,{cause:e.error})}function isVercelEnvironment(){return!!process.env.VERCEL?.trim()}function isLocalSandboxProvider(e){return e===`docker`||e===`microsandbox`}export{prewarmAppSandboxes};
1
+ import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{ROOT_RUNTIME_AGENT_NODE_ID,getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{createSandboxProviderResources}from"#shared/sandbox-provider.js";import{writeSandboxPreparedArtifactsManifest}from"#runtime/sandbox/prepared-artifacts.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";import{loadCompiledModuleMapFromAuthoredSource}from"#internal/authored-module-map-loader.js";import{createAuthoredSourceRuntimeCompiledArtifactsSource}from"#internal/application/runtime-compiled-artifacts-source.js";import{getRuntimeCompiledArtifactsSandboxAppRoot}from"#runtime/compiled-artifacts-source.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{createSandboxProviderFiles}from"#execution/sandbox/provider-files.js";import{createDevelopmentSandboxProviderHost}from"#execution/sandbox/provider-host-development.js";import{materializeWorkspaceDirectory}from"#runtime/workspace/seed-files.js";const diskPreparedArtifactStore={async write(e){await writeSandboxPreparedArtifactsManifest(e)}};async function prewarmSandboxes(e){let t=await collectPrewarmTargets(e);if(t.length===0)return;let n=e.preparedArtifactStore??diskPreparedArtifactStore,r=e.dispatch??(async({context:e,provider:t})=>await t.implementation.prepare(e));e.log?.(`eve: initializing ${formatSandboxTemplateCount(t.length)}...`);let i=await Promise.allSettled(t.map(async({context:t,label:n,nodeId:i,provider:a})=>{let logProviderProgress=t=>{shouldLogSandboxPrewarmProgress(t)&&e.log?.(`eve: sandbox template "${n}" (${a.providerName}): ${t}`)};try{return{nodeId:i,provider:a,result:await r({context:{...t,log:e.log===void 0?void 0:logProviderProgress},provider:a})}}catch(t){let r=formatPrewarmFailureForEnvironment({providerName:a.providerName,error:t});throw e.log?.(`eve: failed to initialize sandbox template "${n}" on provider "${a.providerName}": ${toErrorMessage(r)}`),r}})),a=i.find(e=>e.status===`rejected`);if(a?.status===`rejected`)throw a.reason;let o=i.flatMap(e=>e.status===`fulfilled`?[{artifact:e.value.result,nodeId:e.value.nodeId,providerName:e.value.provider.providerName}]:[]);await n.write({compileDirectoryPath:e.compileDirectoryPath,entries:o}),e.log?.(`eve: initialized ${formatSandboxTemplateCount(t.length)}.`)}async function prewarmAppSandboxes(e){let t=e.compiledArtifactsSource??createAuthoredSourceRuntimeCompiledArtifactsSource(e.appRoot);if(t.kind!==`disk`)throw Error(`prewarmAppSandboxes requires disk-backed compiled artifacts.`);let n=await(e.loadAgentGraph??loadGraphFromArtifacts)({compiledArtifactsSource:t});await prewarmSandboxes({appRoot:getRuntimeCompiledArtifactsSandboxAppRoot(t)??e.appRoot,compileDirectoryPath:resolveRuntimeCompilerArtifactPaths(t.appRoot).compileDirectoryPath,compiledArtifactsSource:t,dispatch:e.dispatch,graph:n,log:e.log,preparedArtifactStore:e.preparedArtifactStore})}async function collectPrewarmTargets(e){let t=[];return await Promise.all(collectNodeSandboxes(e.graph).map(async({definition:n,nodeId:r,workspaceResourceRoot:i})=>{let a=getResolvedRuntimeAgentNode(e.graph,r).agent,o=join(resolve(e.appRoot,relative(a.metadata.appRoot,a.metadata.agentRoot)),`sandbox`),s=getSandboxEnvironmentRuntime(n.environment),c=await loadResourceRootSeedFiles({compileDirectoryPath:e.compileDirectoryPath,workspaceResourceRoot:i});t.push({context:{files:createSandboxProviderFiles(o),host:createDevelopmentSandboxProviderHost(e.appRoot),resources:createSandboxProviderResources({resourcesKey:i.contentHash,resourcesPath:i.contentHash===void 0?void 0:`${e.compileDirectoryPath}/${i.logicalPath}`,seedFiles:c}),sourceRevision:n.revisionHash,storagePath:resolveSandboxCacheDirectory(e.appRoot)},label:formatLabel(r),nodeId:r,provider:s})})),t.sort((e,t)=>e.label.localeCompare(t.label))}async function loadResourceRootSeedFiles(e){return e.workspaceResourceRoot.contentHash===void 0&&e.workspaceResourceRoot.rootEntries.length===0?[]:(await materializeWorkspaceDirectory(`${e.compileDirectoryPath}/${e.workspaceResourceRoot.logicalPath}`)).map(e=>({content:e.content,path:e.path}))}async function loadGraphFromArtifacts(e){let[t,n]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:e.compiledArtifactsSource}),loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e.compiledArtifactsSource})]);return await resolveRuntimeAgentGraph({manifest:t,moduleMap:n})}function collectNodeSandboxes(e){return[...e.nodesByNodeId.entries()].flatMap(([e,t])=>{let n=t.sandboxRegistry.sandbox;return n.definition.kind===`parent`?[]:[{...n,definition:n.definition,nodeId:e}]})}function formatLabel(e){return e===ROOT_RUNTIME_AGENT_NODE_ID?`root`:e}function formatSandboxTemplateCount(e){return`${e} sandbox ${e===1?`template`:`templates`}`}function shouldLogSandboxPrewarmProgress(e){return!e.startsWith(`checking `)&&!e.startsWith(`reusing `)&&e!==`loading microsandbox runtime`&&e!==`microsandbox runtime ready`}function formatPrewarmFailureForEnvironment(e){return!isVercelEnvironment()||!isLocalSandboxProvider(e.providerName)?e.error:Error(`The ${e.providerName} sandbox provider is not available when deploying on Vercel. Vercel build containers cannot run local Docker containers or microsandbox VMs. Use DefaultSandbox.environment() so eve selects Vercel Sandbox on Vercel, or configure VercelSandbox.environment() explicitly. Original ${e.providerName} error: ${toErrorMessage(e.error)}`,{cause:e.error})}function isVercelEnvironment(){return!!process.env.VERCEL?.trim()}function isLocalSandboxProvider(e){return e===`docker`||e===`microsandbox`}export{prewarmAppSandboxes};
@@ -1,3 +1,3 @@
1
- import{loadContext}from"#context/container.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{readMediaMetadata}from"#internal/attachments/media-metadata.js";const IMAGE_MEDIA_TYPES={gif:`image/gif`,jpeg:`image/jpeg`,jpg:`image/jpeg`,png:`image/png`,webp:`image/webp`};async function executeReadFileOnSandbox(e,t){let{filePath:n,offset:r,limit:i}=t,a=await resolveAbsoluteFilePath(e,n),o=normalizeModelPath(a),s=IMAGE_MEDIA_TYPES[o.split(`.`).pop()?.toLowerCase()??``];if(s!==void 0)return await readImageFile(e,a,o,s);let c=r??1,l=i??2e3;if(c<1)throw Error(`offset must be >= 1. Received: ${c}.`);let u=await e.readTextFile({path:a});if(u===null)throw Error(`File not found: ${n}. Verify the path exists and is accessible in the sandbox.`);if(u.includes(`\0`))throw Error(`File "${n}" contains NUL bytes and appears to be a binary file. read_file only supports text files.`);let d=u.split(`
2
- `),f=d.length>0&&d[d.length-1]===``?d.length-1:d.length;if(f===0){if(c>1)throw Error(`offset ${c} is past the end of the file (0 lines). Use the default offset to read an empty file.`)}else if(c>f)throw Error(`offset ${c} is past the end of the file (${f} lines).`);let p=createReadFileStamp({content:u,filePath:o}),m=buildReadFileTargetKey(o);if(setReadFileStamp(loadContext(),m,p),f===0)return{content:``,path:o,totalLines:0,truncated:!1};let h=c-1,g=Math.min(h+l,f),_=d.slice(h,g),v=[],y=0,b=!1;for(let e=0;e<_.length;e++){let t=`${c+e}: ${capLineLength(_[e]??``)}`,n=Buffer.byteLength(t,`utf8`)+1;if(y+n>MAX_OUTPUT_BYTES&&v.length>0){b=!0;break}v.push(t),y+=n}let x=v.join(`
3
- `),S=c+v.length-1;return S<f||b?{content:x,nextOffset:S+1,path:o,totalLines:f,truncated:!0}:{content:x,path:o,totalLines:f,truncated:!1}}async function readImageFile(e,t,n,r){let i=await e.readBinaryFile({path:t});if(i===null)throw Error(`File not found: ${n}. Verify the path exists and is accessible in the sandbox.`);if(i.byteLength>3145728)throw Error(`Image "${n}" is ${i.byteLength} bytes; read_file shows images up to 3 MiB. Resize or crop it in the sandbox first.`);return{content:`Image ${n} (${r}, ${i.byteLength} bytes).`,image:readMediaMetadata(i,r),path:n,totalLines:0,truncated:!1}}export{executeReadFileOnSandbox};
1
+ import{loadContext}from"#context/container.js";import{MAX_OUTPUT_BYTES,capLineLength}from"#execution/sandbox/truncate-output.js";import{buildReadFileTargetKey,createReadFileStamp,normalizeModelPath,setReadFileStamp}from"#execution/tools/file-state.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{detectImageMediaType,readMediaMetadata}from"#internal/attachments/media-metadata.js";async function executeReadFileOnSandbox(e,t){let{filePath:n,offset:r,limit:i}=t,a=await resolveAbsoluteFilePath(e,n),o=normalizeModelPath(a),s=await e.readBinaryFile({path:a});if(s===null)throw Error(`File not found: ${n}. Verify the path exists and is accessible in the sandbox.`);let c=decodeUtf8(s);if(c===void 0||c.includes(`\0`)){let e=detectImageMediaType(s);if(e!==void 0)return buildImageReadResult(s,o,e);throw Error(`File "${n}" appears to be a binary file. read_file only supports text files and PNG, JPEG, GIF, or WebP images.`)}let l=r??1,u=i??2e3;if(l<1)throw Error(`offset must be >= 1. Received: ${l}.`);let d=c.split(`
2
+ `),f=d.length>0&&d[d.length-1]===``?d.length-1:d.length;if(f===0){if(l>1)throw Error(`offset ${l} is past the end of the file (0 lines). Use the default offset to read an empty file.`)}else if(l>f)throw Error(`offset ${l} is past the end of the file (${f} lines).`);let p=createReadFileStamp({content:c,filePath:o}),m=buildReadFileTargetKey(o);if(setReadFileStamp(loadContext(),m,p),f===0)return{content:``,path:o,totalLines:0,truncated:!1};let h=l-1,g=Math.min(h+u,f),_=d.slice(h,g),v=[],y=0,b=!1;for(let e=0;e<_.length;e++){let t=`${l+e}: ${capLineLength(_[e]??``)}`,n=Buffer.byteLength(t,`utf8`)+1;if(y+n>MAX_OUTPUT_BYTES&&v.length>0){b=!0;break}v.push(t),y+=n}let x=v.join(`
3
+ `),S=l+v.length-1;return S<f||b?{content:x,nextOffset:S+1,path:o,totalLines:f,truncated:!0}:{content:x,path:o,totalLines:f,truncated:!1}}function decodeUtf8(e){try{return new TextDecoder(`utf-8`,{fatal:!0}).decode(e)}catch{return}}function buildImageReadResult(e,t,n){if(e.byteLength>3145728)throw Error(`Image "${t}" is ${e.byteLength} bytes; read_file shows images up to 3 MiB. Resize or crop it in the sandbox first.`);return{content:`Image ${t} (${n}, ${e.byteLength} bytes).`,image:readMediaMetadata(e,n),path:t,totalLines:0,truncated:!1}}export{executeReadFileOnSandbox};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{walkCauseChain}from"#shared/errors.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{EntityConflictError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{cancelRun,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";const log=createLogger(`execution.handoff`);function isSessionStateIdleForHandoff(e){let{state:t}=readDurableSession(e),n=getBlockingWorkflowToolRuns(t);if([`eve.runtime.pendingAuthorization`,`eve.runtime.pendingInputBatch`,`eve.runtime.pendingCoordinationBatch`,`eve.runtime.deferredStepInput`,`eve.harness.pendingWorkflowInterrupt`].some(e=>t?.[e]!==void 0))return!1;let r=t?.[`eve.runtime.pendingInputBatches`];if(r!==void 0&&(!Array.isArray(r)||r.length>0))return!1;let i=t?.[`eve.runtime.proxyInputRequests`];return i!==void 0&&(!isObject(i)||Object.keys(i).length>0)?!1:n.length===0}async function isSessionIdleForHandoffStep(e){"use step";return isSessionStateIdleForHandoff(e.sessionState)}async function validateSessionCheckpointStep(e){"use step";let{migration:t}=e,unreadable=t=>(log.warn(`session handoff refused: this deployment cannot read the checkpoint`,{detail:t,readableCheckpointVersion:SESSION_CHECKPOINT_VERSION,sessionId:e.sessionId}),{kind:`incompatible`,reason:`checkpoint-version`});if(t.kind===`incompatible`)return unreadable(t.detail);let{checkpoint:n}=t,r=n.sessionTimeoutMs;if(r!==!1&&(typeof r!=`number`||!Number.isFinite(r)||r<0))throw Error(`Session checkpoint contains an invalid timeout duration.`);let i;try{i=await deserializeContext(n.serializedContext)}catch(e){if(e instanceof IncompatibleStateLayoutError)return unreadable(e.message);throw e}let a=i.require(BundleKey),o=readDurableSession(n.sessionState).sandboxState?.session;if(o!=null){let e=getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.inheritance?.definition??getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.definition;if(e.kind!==`independent`)throw Error(`Session checkpoint sandbox has no resolved provider.`);let t=getSandboxEnvironmentRuntime(e.environment);if(o.providerName!==t.providerName||o.stateProtocolVersion!==t.stateProtocolVersion)throw Error(`Session checkpoint sandbox provider state is incompatible.`)}if(!isSessionStateIdleForHandoff(n.sessionState))throw Error(`Session checkpoint contains pending work and cannot be handed off.`);return{kind:`valid`}}async function stopUntrackedChildSessionsStep(e){"use step";let t=await getWorld();for(let n of e.runIds)if(n!==e.sessionId)try{await cancelRun(t,n,{cancelReason:`Session upgraded`})}catch(t){[...walkCauseChain(t)].some(e=>EntityConflictError.is(e)||RunExpiredError.is(e)||WorkflowRunNotFoundError.is(e))||logError(log,`could not stop a subagent session after handoff`,t,{childRunId:n,sessionId:e.sessionId})}}async function reportSessionHandoffRetainedStep(e){"use step";log.warn(`session handoff failed; the current owner keeps the session`,{...e,checkpointVersion:SESSION_CHECKPOINT_VERSION})}async function signalSessionOwnerActivationStep(e){"use step";await resumeHook(e.token,e.activation)}async function signalSessionAnchorStep(e){"use step";await resumeHook(e.token,e.result)}export{isSessionIdleForHandoffStep,isSessionStateIdleForHandoff,reportSessionHandoffRetainedStep,signalSessionAnchorStep,signalSessionOwnerActivationStep,stopUntrackedChildSessionsStep,validateSessionCheckpointStep};
1
+ import{createLogger,logError}from"#internal/logging.js";import{isObject}from"#shared/guards.js";import{walkCauseChain}from"#shared/errors.js";import{getSandboxEnvironmentRuntime}from"#shared/sandbox-environment.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{readDurableSession}from"#execution/durable-session-store.js";import{getBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{IncompatibleStateLayoutError,deserializeContext}from"#context/serialize.js";import{EntityConflictError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{cancelRun,getWorld,resumeHook}from"#internal/workflow/runtime.js";import{SESSION_CHECKPOINT_VERSION}from"#execution/session/handoff.js";const log=createLogger(`execution.handoff`);function isSessionStateIdleForHandoff(e){let{state:t}=readDurableSession(e),n=getBlockingWorkflowToolRuns(t);if([`eve.runtime.pendingAuthorization`,`eve.runtime.pendingInputBatch`,`eve.runtime.pendingCoordinationBatch`,`eve.runtime.deferredStepInput`,`eve.harness.pendingWorkflowInterrupt`].some(e=>t?.[e]!==void 0))return!1;let r=t?.[`eve.runtime.pendingInputBatches`];if(r!==void 0&&(!Array.isArray(r)||r.length>0))return!1;let i=t?.[`eve.runtime.proxyInputRequests`];return i!==void 0&&(!isObject(i)||Object.keys(i).length>0)?!1:n.length===0}async function isSessionIdleForHandoffStep(e){"use step";return isSessionStateIdleForHandoff(e.sessionState)}async function validateSessionCheckpointStep(e){"use step";let{migration:t}=e,unreadable=t=>(log.warn(`session handoff refused: this deployment cannot read the checkpoint`,{detail:t,readableCheckpointVersion:SESSION_CHECKPOINT_VERSION,sessionId:e.sessionId}),{kind:`incompatible`,reason:`checkpoint-version`});if(t.kind===`incompatible`)return unreadable(t.detail);let{checkpoint:n}=t,r=n.sessionTimeoutMs;if(r!==!1&&(typeof r!=`number`||!Number.isFinite(r)||r<0))throw Error(`Session checkpoint contains an invalid timeout duration.`);let i;try{i=await deserializeContext(n.serializedContext)}catch(e){if(e instanceof IncompatibleStateLayoutError)return unreadable(e.message);throw e}let a=i.require(BundleKey),o=readDurableSession(n.sessionState).sandboxState?.session;if(o!=null&&o.providerName!==void 0){let e=getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.inheritance?.definition??getResolvedRuntimeAgentNode(a.graph,a.nodeId).sandboxRegistry.sandbox.definition;if(e.kind!==`independent`)throw Error(`Session checkpoint sandbox has no resolved provider.`);let t=getSandboxEnvironmentRuntime(e.environment);if(o.providerName!==t.providerName||o.stateProtocolVersion!==t.stateProtocolVersion)throw Error(`Session checkpoint sandbox provider state is incompatible.`)}if(!isSessionStateIdleForHandoff(n.sessionState))throw Error(`Session checkpoint contains pending work and cannot be handed off.`);return{kind:`valid`}}async function stopUntrackedChildSessionsStep(e){"use step";let t=await getWorld();for(let n of e.runIds)if(n!==e.sessionId)try{await cancelRun(t,n,{cancelReason:`Session upgraded`})}catch(t){[...walkCauseChain(t)].some(e=>EntityConflictError.is(e)||RunExpiredError.is(e)||WorkflowRunNotFoundError.is(e))||logError(log,`could not stop a subagent session after handoff`,t,{childRunId:n,sessionId:e.sessionId})}}async function reportSessionHandoffRetainedStep(e){"use step";log.warn(`session handoff failed; the current owner keeps the session`,{...e,checkpointVersion:SESSION_CHECKPOINT_VERSION})}async function signalSessionOwnerActivationStep(e){"use step";await resumeHook(e.token,e.activation)}async function signalSessionAnchorStep(e){"use step";await resumeHook(e.token,e.result)}export{isSessionIdleForHandoffStep,isSessionStateIdleForHandoff,reportSessionHandoffRetainedStep,signalSessionAnchorStep,signalSessionOwnerActivationStep,stopUntrackedChildSessionsStep,validateSessionCheckpointStep};
@@ -1 +1 @@
1
- import{evaluate}from"#ai/evaluate.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await evaluate({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.70.3//runAgentRouterTask`;export{runAgentRouterTask};
1
+ import{evaluate}from"#ai/evaluate.js";async function runAgentRouterTask(e,t){"use workflow";let n=await chooseTarget(e.message,descriptions(t),t.abortSignal),{message:r,status:i}=await(await t.agent(n).send(e.message,{signal:t.abortSignal})).result();if(i===`failed`)throw Error(`Agent "${n}" failed to handle the task.`);return r??null}async function chooseTarget(e,t,n){"use step";let r=Object.keys(t);if(r.length===0)throw Error(`agentRouter requires at least one available agent with a description.`);return r.length===1?r[0]:(await evaluate({abortSignal:n,state:{message:e},questions:{route:{type:`choice`,instructions:`Which subagent should handle this task?`,criteria:t}}})).answers.route.choice}function descriptions(e){return Object.fromEntries(Object.entries(e.agents).flatMap(([e,t])=>{let n=t.description.trim();return n.length===0?[]:[[e,n]]}))}runAgentRouterTask.workflowId=`workflow//eve@0.71.1//runAgentRouterTask`;export{runAgentRouterTask};
@@ -1 +1 @@
1
- import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{fileURLToPath}from"node:url";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";let cachedPackageInfo,cachedPackageLocation;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.70.3`,WORKFLOW_MODULE_ALIASES={"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const packageRequire=createRequire(resolveCurrentModulePath());function tryResolveVerifiedPackageRoot(e){try{let t=realpathSync.native(e);return tryReadInstalledPackageInfo(t,EVE_PACKAGE_NAME)===void 0?void 0:dirname(t)}catch{return}}function findNearestVerifiedPackageRoot(e){let t=e;for(;;){let e=tryResolveVerifiedPackageRoot(join(t,`package.json`));if(e!==void 0)return e;let n=dirname(t);if(n===t)return;t=n}}function tryResolveDirectBuildLocation(e){let t=dirname(e);for(;;){if(basename(t)===`dist`){let e=tryResolveVerifiedPackageRoot(join(dirname(t),`package.json`));if(e!==void 0)return{packageBuildRoot:t,packageRoot:e}}let e=dirname(t);if(e===t)return;t=e}}function isSourceCheckout(e){return existsSync(join(e,`src`,`internal`,`application`,`package.ts`))}function tryCreatePackageLocation(e){if(isSourceCheckout(e))return{packageBuildRoot:null,packageRoot:e};let t=join(e,`dist`);if(existsSync(t))return{packageBuildRoot:t,packageRoot:e}}function resolveSelfPackageJsonPath(e){return createRequire(e).resolve(`${EVE_PACKAGE_NAME}/package.json`)}function resolvePackageLocationFromModulePath(e,t=resolveSelfPackageJsonPath){let n=realpathSync.native(e),r=tryResolveDirectBuildLocation(n);if(r!==void 0)return r;let i=findNearestVerifiedPackageRoot(dirname(n));if(i!==void 0&&isSourceCheckout(i))return{packageBuildRoot:null,packageRoot:i};try{let e=tryResolveVerifiedPackageRoot(t(n)),r=e===void 0?void 0:tryCreatePackageLocation(e);if(r!==void 0)return r}catch{}let a=i===void 0?void 0:tryCreatePackageLocation(i);if(a!==void 0)return a;throw Error(`Failed to resolve the eve package root from "${e}".`)}function resolvePackageLocation(){return cachedPackageLocation??=resolvePackageLocationFromModulePath(resolveCurrentModulePath()),cachedPackageLocation}function resolvePackageBuildRoot(){return resolvePackageLocation().packageBuildRoot}function resolvePackageRoot(){return resolvePackageLocation().packageRoot}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){try{return packageRequire.resolve(e)}catch(t){let n=tryResolvePackageRoot(),r=n===void 0||!isSourceCheckout(n)?void 0:resolveSourceCheckoutExport(n,e);if(r!==void 0)return r;throw t}}function resolveSourceCheckoutExport(e,t){if(t!==EVE_PACKAGE_NAME&&!t.startsWith(`${EVE_PACKAGE_NAME}/`))return;let n=t===EVE_PACKAGE_NAME?`.`:`.${t.slice(EVE_PACKAGE_NAME.length)}`;try{let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).exports?.[n],r=typeof t==`string`?t:t?.[`eve-source`]??t?.import??t?.default;if(r===void 0)return;let i=r.replace(/^\.\/dist\/src\//,`src/`).replace(/\.[cm]?js$/u,`.ts`),a=join(e,i);return existsSync(a)?a:void 0}catch{return}}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(typeof t.name==`string`&&typeof t.version==`string`)return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function readWorkflowVersionFromManifest(e){let t=e;for(let e of[t.devDependencies,t.dependencies,t.peerDependencies]){let t=e?.[`@workflow/core`];if(typeof t==`string`&&t.trim().length>0)return t}}function resolveExpectedWorkflowVersion(){let e=tryResolvePackageRoot();if(e!==void 0)try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(join(e,`package.json`),`utf8`)))}catch{}try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),`utf8`)))}catch{return}}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/api`||e===`workflow/runtime`)return resolvePackageSourceFilePath(`src/internal/workflow/runtime.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?packageRequire.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveExpectedWorkflowVersion,resolveInstalledPackageInfo,resolvePackageCompiledFilePath,resolvePackageDependencyPath,resolvePackageLocationFromModulePath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
1
+ import{createRequire}from"node:module";import{existsSync,readFileSync,realpathSync}from"node:fs";import{basename,dirname,join}from"node:path";import{fileURLToPath}from"node:url";import{EVE_PACKAGE_NAME}from"#internal/package-name.js";let cachedPackageInfo,cachedPackageLocation;const BUNDLED_FALLBACK_PACKAGE_VERSION=`0.71.1`,WORKFLOW_MODULE_ALIASES={"workflow/errors":`src/compiled/@workflow/errors/index.js`,"workflow/internal/private":`src/compiled/@workflow/core/private.js`};function resolveFallbackPackageVersion(){return BUNDLED_FALLBACK_PACKAGE_VERSION.startsWith(`__`)?`0.0.0`:BUNDLED_FALLBACK_PACKAGE_VERSION}const FALLBACK_PACKAGE_INFO={name:EVE_PACKAGE_NAME,version:resolveFallbackPackageVersion()};function resolveCurrentModulePath(){return typeof __filename==`string`?__filename:resolveCurrentModulePathFromStack()}function resolveCurrentModulePathFromStack(){let e=Error.prepareStackTrace;try{Error.prepareStackTrace=(e,t)=>t;let e=Error().stack?.[0]?.getFileName();if(typeof e!=`string`||e.length===0)throw Error(`Failed to resolve the current module path from the stack trace.`);return e.startsWith(`file:`)?fileURLToPath(e):e}finally{Error.prepareStackTrace=e}}const packageRequire=createRequire(resolveCurrentModulePath());function tryResolveVerifiedPackageRoot(e){try{let t=realpathSync.native(e);return tryReadInstalledPackageInfo(t,EVE_PACKAGE_NAME)===void 0?void 0:dirname(t)}catch{return}}function findNearestVerifiedPackageRoot(e){let t=e;for(;;){let e=tryResolveVerifiedPackageRoot(join(t,`package.json`));if(e!==void 0)return e;let n=dirname(t);if(n===t)return;t=n}}function tryResolveDirectBuildLocation(e){let t=dirname(e);for(;;){if(basename(t)===`dist`){let e=tryResolveVerifiedPackageRoot(join(dirname(t),`package.json`));if(e!==void 0)return{packageBuildRoot:t,packageRoot:e}}let e=dirname(t);if(e===t)return;t=e}}function isSourceCheckout(e){return existsSync(join(e,`src`,`internal`,`application`,`package.ts`))}function tryCreatePackageLocation(e){if(isSourceCheckout(e))return{packageBuildRoot:null,packageRoot:e};let t=join(e,`dist`);if(existsSync(t))return{packageBuildRoot:t,packageRoot:e}}function resolveSelfPackageJsonPath(e){return createRequire(e).resolve(`${EVE_PACKAGE_NAME}/package.json`)}function resolvePackageLocationFromModulePath(e,t=resolveSelfPackageJsonPath){let n=realpathSync.native(e),r=tryResolveDirectBuildLocation(n);if(r!==void 0)return r;let i=findNearestVerifiedPackageRoot(dirname(n));if(i!==void 0&&isSourceCheckout(i))return{packageBuildRoot:null,packageRoot:i};try{let e=tryResolveVerifiedPackageRoot(t(n)),r=e===void 0?void 0:tryCreatePackageLocation(e);if(r!==void 0)return r}catch{}let a=i===void 0?void 0:tryCreatePackageLocation(i);if(a!==void 0)return a;throw Error(`Failed to resolve the eve package root from "${e}".`)}function resolvePackageLocation(){return cachedPackageLocation??=resolvePackageLocationFromModulePath(resolveCurrentModulePath()),cachedPackageLocation}function resolvePackageBuildRoot(){return resolvePackageLocation().packageBuildRoot}function resolvePackageRoot(){return resolvePackageLocation().packageRoot}function tryResolvePackageRoot(){try{return resolvePackageRoot()}catch{return}}function rewriteSourceFilePathForBuild(e){return e.replace(/\.[cm]?tsx?$/,`.js`)}function resolvePackageSourceFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),e):join(t,rewriteSourceFilePathForBuild(e))}function resolvePackageSourceDirectoryPath(e){let t=resolvePackageBuildRoot();return join(t===null?resolvePackageRoot():t,e)}function resolvePackageDependencyPath(e){try{return packageRequire.resolve(e)}catch(t){let n=tryResolvePackageRoot(),r=n===void 0||!isSourceCheckout(n)?void 0:resolveSourceCheckoutExport(n,e);if(r!==void 0)return r;throw t}}function resolveSourceCheckoutExport(e,t){if(t!==EVE_PACKAGE_NAME&&!t.startsWith(`${EVE_PACKAGE_NAME}/`))return;let n=t===EVE_PACKAGE_NAME?`.`:`.${t.slice(EVE_PACKAGE_NAME.length)}`;try{let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).exports?.[n],r=typeof t==`string`?t:t?.[`eve-source`]??t?.import??t?.default;if(r===void 0)return;let i=r.replace(/^\.\/dist\/src\//,`src/`).replace(/\.[cm]?js$/u,`.ts`),a=join(e,i);return existsSync(a)?a:void 0}catch{return}}function resolvePackageCompiledFilePath(e){let t=resolvePackageBuildRoot();return t===null?join(resolvePackageRoot(),`.generated`,`compiled`,e.replace(/^src\/compiled\//,``)):join(t,e)}function normalizeInstalledPackageInfo(e){let t=e;if(typeof t.name==`string`&&typeof t.version==`string`)return{name:t.name,version:t.version}}function tryReadInstalledPackageInfo(e,t){let n=normalizeInstalledPackageInfo(JSON.parse(readFileSync(e,`utf8`)));if(n?.name===t)return n}function resolveInstalledPackageInfo(){if(cachedPackageInfo)return cachedPackageInfo;let e=tryResolvePackageRoot(),t=e===void 0?void 0:tryReadInstalledPackageInfo(join(e,`package.json`),EVE_PACKAGE_NAME);if(t)return cachedPackageInfo=t,cachedPackageInfo;try{let e=tryReadInstalledPackageInfo(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),EVE_PACKAGE_NAME);if(e)return cachedPackageInfo=e,cachedPackageInfo}catch{}return cachedPackageInfo={...FALLBACK_PACKAGE_INFO},cachedPackageInfo}function readWorkflowVersionFromManifest(e){let t=e;for(let e of[t.devDependencies,t.dependencies,t.peerDependencies]){let t=e?.[`@workflow/core`];if(typeof t==`string`&&t.trim().length>0)return t}}function resolveExpectedWorkflowVersion(){let e=tryResolvePackageRoot();if(e!==void 0)try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(join(e,`package.json`),`utf8`)))}catch{}try{return readWorkflowVersionFromManifest(JSON.parse(readFileSync(packageRequire.resolve(`${EVE_PACKAGE_NAME}/package.json`),`utf8`)))}catch{return}}function resolveWorkflowModulePath(e){if(e===`workflow`)return resolvePackageSourceFilePath(`src/internal/workflow/index.ts`);if(e===`workflow/api`||e===`workflow/runtime`)return resolvePackageSourceFilePath(`src/internal/workflow/runtime.ts`);if(e===`workflow/internal/builtins`)return resolvePackageSourceFilePath(`src/internal/workflow/builtins.ts`);let t=WORKFLOW_MODULE_ALIASES[e];return t===void 0?packageRequire.resolve(e):resolvePackageCompiledFilePath(t)}export{resolveExpectedWorkflowVersion,resolveInstalledPackageInfo,resolvePackageCompiledFilePath,resolvePackageDependencyPath,resolvePackageLocationFromModulePath,resolvePackageRoot,resolvePackageSourceDirectoryPath,resolvePackageSourceFilePath,resolveWorkflowModulePath};
@@ -18,6 +18,8 @@ export declare function readMediaMetadata(bytes: Uint8Array, mediaType: string):
18
18
  * base64 text, which is how text-only providers receive it.
19
19
  */
20
20
  export declare function estimateMediaTokens(metadata: MediaMetadata): number;
21
+ /** Names the PNG, GIF, JPEG, or WebP format its leading bytes identify. */
22
+ export declare function detectImageMediaType(bytes: Uint8Array): string | undefined;
21
23
  /** Reads PNG, GIF, JPEG, or WebP dimensions from the leading bytes. */
22
24
  export declare function readImageDimensions(bytes: Uint8Array): {
23
25
  readonly width: number;
@@ -1 +1 @@
1
- const MAX_IMAGE_TOKENS=4784;function readMediaMetadata(e,t){let n={mediaType:t,size:e.byteLength};if(t.startsWith(`image/`)){let t=readImageDimensions(e);return t===void 0?n:{...n,...t}}if(t===`application/pdf`){let t=countPdfPages(e);return t===void 0?n:{...n,pages:t}}return n}function estimateMediaTokens(e){if(e.mediaType.startsWith(`image/`)){if(e.width===void 0||e.height===void 0)return MAX_IMAGE_TOKENS;let t=Math.ceil(e.width/28)*Math.ceil(e.height/28);return Math.min(t,MAX_IMAGE_TOKENS)}return e.mediaType===`application/pdf`&&e.pages!==void 0?e.pages*3e3:Math.ceil(e.size/3)}function readImageDimensions(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),ascii=(t,n)=>String.fromCharCode(...e.subarray(t,Math.min(n,e.byteLength)));if(e.byteLength>=24&&t.getUint32(0)===2303741511)return dimensions(t.getUint32(16),t.getUint32(20));if(e.byteLength>=10&&ascii(0,4)===`GIF8`)return dimensions(t.getUint16(6,!0),t.getUint16(8,!0));if(e.byteLength>=4&&t.getUint16(0)===65496)return readJpegDimensions(e,t);if(e.byteLength>=30&&ascii(0,4)===`RIFF`&&ascii(8,12)===`WEBP`){let n=ascii(12,16);if(n===`VP8 `)return dimensions(t.getUint16(26,!0)&16383,t.getUint16(28,!0)&16383);if(n===`VP8L`){let e=t.getUint32(21,!0);return dimensions((e&16383)+1,(e>>>14&16383)+1)}if(n===`VP8X`)return dimensions(readUint24(e,24)+1,readUint24(e,27)+1)}}function readJpegDimensions(e,t){let n=2;for(;n+9<e.byteLength;){if(e[n]!==255)return;let r=e[n+1];if(r===255){n+=1;continue}if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204)return dimensions(t.getUint16(n+7),t.getUint16(n+5));n+=2+t.getUint16(n+2)}}function countPdfPages(e){let t=Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString(`latin1`).match(/\/Type\s*\/Page(?![A-Za-z])/g)?.length??0;return t>0?t:void 0}function readUint24(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16}function dimensions(e,t){return e>0&&t>0?{height:t,width:e}:void 0}export{estimateMediaTokens,readImageDimensions,readMediaMetadata};
1
+ const MAX_IMAGE_TOKENS=4784;function readMediaMetadata(e,t){let n={mediaType:t,size:e.byteLength};if(t.startsWith(`image/`)){let t=readImageDimensions(e);return t===void 0?n:{...n,...t}}if(t===`application/pdf`){let t=countPdfPages(e);return t===void 0?n:{...n,pages:t}}return n}function estimateMediaTokens(e){if(e.mediaType.startsWith(`image/`)){if(e.width===void 0||e.height===void 0)return MAX_IMAGE_TOKENS;let t=Math.ceil(e.width/28)*Math.ceil(e.height/28);return Math.min(t,MAX_IMAGE_TOKENS)}return e.mediaType===`application/pdf`&&e.pages!==void 0?e.pages*3e3:Math.ceil(e.size/3)}function detectImageMediaType(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),ascii=(t,n)=>readAscii(e,t,n);if(e.byteLength>=8&&t.getUint32(0)===2303741511&&t.getUint32(4)===218765834)return`image/png`;if(e.byteLength>=3&&t.getUint16(0)===65496&&e[2]===255)return`image/jpeg`;if(ascii(0,6)===`GIF87a`||ascii(0,6)===`GIF89a`)return`image/gif`;if(ascii(0,4)===`RIFF`&&ascii(8,12)===`WEBP`)return`image/webp`}function readImageDimensions(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength),ascii=(t,n)=>readAscii(e,t,n);if(e.byteLength>=24&&t.getUint32(0)===2303741511)return dimensions(t.getUint32(16),t.getUint32(20));if(e.byteLength>=10&&ascii(0,4)===`GIF8`)return dimensions(t.getUint16(6,!0),t.getUint16(8,!0));if(e.byteLength>=4&&t.getUint16(0)===65496)return readJpegDimensions(e,t);if(e.byteLength>=30&&ascii(0,4)===`RIFF`&&ascii(8,12)===`WEBP`){let n=ascii(12,16);if(n===`VP8 `)return dimensions(t.getUint16(26,!0)&16383,t.getUint16(28,!0)&16383);if(n===`VP8L`){let e=t.getUint32(21,!0);return dimensions((e&16383)+1,(e>>>14&16383)+1)}if(n===`VP8X`)return dimensions(readUint24(e,24)+1,readUint24(e,27)+1)}}function readJpegDimensions(e,t){let n=2;for(;n+9<e.byteLength;){if(e[n]!==255)return;let r=e[n+1];if(r===255){n+=1;continue}if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204)return dimensions(t.getUint16(n+7),t.getUint16(n+5));n+=2+t.getUint16(n+2)}}function countPdfPages(e){let t=Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString(`latin1`).match(/\/Type\s*\/Page(?![A-Za-z])/g)?.length??0;return t>0?t:void 0}function readAscii(e,t,n){return String.fromCharCode(...e.subarray(t,Math.min(n,e.byteLength)))}function readUint24(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16}function dimensions(e,t){return e>0&&t>0?{height:t,width:e}:void 0}export{detectImageMediaType,estimateMediaTokens,readImageDimensions,readMediaMetadata};
@@ -1,17 +1,26 @@
1
+ type DefinitionSourceKind = "connection" | "tool";
1
2
  type DefinitionSourceEntry = {
2
- readonly kind: "connection";
3
- readonly logicalPath?: string;
4
- readonly name: string;
5
- } | {
6
- readonly kind: "tool";
3
+ readonly kind: DefinitionSourceKind;
7
4
  readonly logicalPath?: string;
8
5
  readonly name: string;
9
6
  };
10
- type AmbiguousDefinitionSourceEntry = {
7
+ export type RegisteredDefinitionSource = {
8
+ readonly kind: DefinitionSourceKind;
9
+ readonly names: ReadonlySet<string>;
10
+ } | {
11
11
  readonly kind: "ambiguous";
12
12
  };
13
- type RegisteredDefinitionSource = DefinitionSourceEntry | AmbiguousDefinitionSourceEntry;
13
+ /** Stamps the authoring-time fallback key used for copies eve never loaded. */
14
14
  export declare function stampDefinitionKey(definition: object, key: string): void;
15
- export declare function registerDefinitionSource(key: string, entry: DefinitionSourceEntry): void;
15
+ /**
16
+ * Records a definition object eve loaded under one mounted name. The same
17
+ * object can be mounted more than once, for example when a subagent re-exports
18
+ * an extension tool, so every mounted name matches it.
19
+ *
20
+ * `fallbackKey` also lets copies with the same stamped key match. That
21
+ * fallback is marked ambiguous when different objects with different names
22
+ * share it.
23
+ */
24
+ export declare function registerDefinitionSource(definition: object, entry: DefinitionSourceEntry, fallbackKey?: string): void;
16
25
  export declare function readDefinitionSource(definition: object): RegisteredDefinitionSource | undefined;
17
26
  export {};
@@ -1 +1 @@
1
- const DEFINITION_KEY=Symbol.for(`eve.definition-source-key`),REGISTRY_SYMBOL=Symbol.for(`eve.definition-source-registry`),registryContainer=globalThis;registryContainer[REGISTRY_SYMBOL]??=new Map;const definitionSourceRegistry=registryContainer[REGISTRY_SYMBOL];function stampDefinitionKey(e,t){Object.defineProperty(e,DEFINITION_KEY,{configurable:!0,value:t})}function registerDefinitionSource(e,t){let n=definitionSourceRegistry.get(e);if(n!==void 0&&!sameDefinitionSourceEntry(n,t)){n.kind!==`ambiguous`&&console.warn([`eve could not assign a unique toolResultFrom identity for ${JSON.stringify(e)}.`,`Conflicting definitions: ${formatDefinitionSourceForWarning(n)} and ${formatDefinitionSourceForWarning(t)}.`,`Multiple authored definitions share that fallback identity, so toolResultFrom will not match through it.`,`Use the original definition object loaded by eve so source-derived identity can be used instead.`].join(` `)),definitionSourceRegistry.set(e,{kind:`ambiguous`});return}definitionSourceRegistry.set(e,t)}function readDefinitionSource(e){let t=readDefinitionKey(e);return t===void 0?void 0:definitionSourceRegistry.get(t)}function readDefinitionKey(e){if(DEFINITION_KEY in e)return e[DEFINITION_KEY]}function sameDefinitionSourceEntry(e,t){return e.kind===t.kind&&e.name===t.name}function formatDefinitionSourceForWarning(e){return e.logicalPath===void 0?`${e.kind} "${e.name}"`:`${e.kind} "${e.name}" from "${e.logicalPath}"`}export{readDefinitionSource,registerDefinitionSource,stampDefinitionKey};
1
+ const DEFINITION_KEY=Symbol.for(`eve.definition-source-key`),RESOLVED_REGISTRY_SYMBOL=Symbol.for(`eve.resolved-definition-sources`),FALLBACK_REGISTRY_SYMBOL=Symbol.for(`eve.fallback-definition-sources`),registryContainer=globalThis;registryContainer[RESOLVED_REGISTRY_SYMBOL]??=new WeakMap,registryContainer[FALLBACK_REGISTRY_SYMBOL]??=new Map;const resolvedSources=registryContainer[RESOLVED_REGISTRY_SYMBOL],fallbackSources=registryContainer[FALLBACK_REGISTRY_SYMBOL];function stampDefinitionKey(e,t){Object.defineProperty(e,DEFINITION_KEY,{configurable:!0,value:t})}function registerDefinitionSource(e,t,n){let r=resolvedSources.get(e);r===void 0||r.kind!==t.kind?resolvedSources.set(e,{kind:t.kind,names:new Set([t.name])}):r.names.add(t.name),n!==void 0&&registerFallbackSource(n,e,t)}function readDefinitionSource(e){let t=resolvedSources.get(e);if(t!==void 0)return t;let n=readDefinitionKey(e);return n===void 0?void 0:fallbackSources.get(n)}function registerFallbackSource(e,t,n){let r=fallbackSources.get(e);if(r===void 0){fallbackSources.set(e,{definitions:new WeakSet([t]),firstEntry:n,kind:n.kind,names:new Set([n.name])});return}if(r.kind!==`ambiguous`){if(r.kind===n.kind&&(r.definitions.has(t)||r.names.has(n.name))){r.definitions.add(t),r.names.add(n.name);return}console.warn([`eve could not assign a unique toolResultFrom identity for ${JSON.stringify(e)}.`,`Conflicting definitions: ${formatDefinitionSourceForWarning(r.firstEntry)} and ${formatDefinitionSourceForWarning(n)}.`,`Multiple authored definitions share that fallback identity, so toolResultFrom will not match through it.`,`Use the original definition object loaded by eve so source-derived identity can be used instead.`].join(` `)),fallbackSources.set(e,{kind:`ambiguous`})}}function readDefinitionKey(e){if(DEFINITION_KEY in e)return e[DEFINITION_KEY]}function formatDefinitionSourceForWarning(e){return e.logicalPath===void 0?`${e.kind} "${e.name}"`:`${e.kind} "${e.name}" from "${e.logicalPath}"`}export{readDefinitionSource,registerDefinitionSource,stampDefinitionKey};
@@ -1 +1 @@
1
- import{createHash,randomUUID}from"node:crypto";import{link,mkdir,unlink,writeFile}from"node:fs/promises";import{join,relative,resolve}from"node:path";import{pathToFileURL}from"node:url";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{collectRuntimeModuleBindingsForManifest,compiledModuleMapSchema,resolveExtensionBindingMountId}from"#compiler/module-map.js";import{memoizeModuleNamespaceFactories}from"#compiler/source-graph.js";import{formatValidationError}from"#runtime/validation.js";import{bundleAuthoredModuleMapForGeneration,loadAuthoredModuleNamespace}from"#internal/authored-module-loader.js";import{loadFrameworkProgrammaticModule}from"#framework/sources/registry.js";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{readMaterializedAuthoredModuleIndex}from"#internal/materialized-authored-modules.js";async function loadCompiledModuleMapFromAuthoredSource(e){return await hydrateCompiledModuleMapFromManifest(await loadCompiledManifest({compiledArtifactsSource:e.compiledArtifactsSource}),e.compiledArtifactsSource.appRoot,e.authoredAppRoot)}async function hydrateCompiledModuleMapFromManifest(e,t,n=e.appRoot){let r=await readMaterializedAuthoredModuleIndex(t);if(r!==void 0)return await loadMaterializedCompiledModuleMap({moduleMapPath:r.moduleMap,runtimeAppRoot:t});if([e,...e.subagents.map(e=>e.agent)].some(e=>e.extensionMounts.length>0)){let r=join(t,`.eve`,`compile`,`authored-module-map.mjs`),{code:i}=await bundleAuthoredModuleMapForGeneration({appRoot:n,manifest:e,moduleMapPath:r,resolveExternalPaths:!0}),a=`authored-module-map-${createHash(`sha256`).update(i).digest(`hex`)}.mjs`,o=join(t,`.eve`,`compile`,a);await mkdir(join(t,`.eve`,`compile`),{recursive:!0});let s=`${o}.${randomUUID()}.tmp`;try{await writeFile(s,i,{flag:`wx`});try{await link(s,o)}catch(e){if(e.code!==`EEXIST`)throw e}}finally{await unlink(s).catch(e=>{if(e.code!==`ENOENT`)throw e})}return await loadMaterializedCompiledModuleMap({moduleMapPath:a,runtimeAppRoot:t,instanceId:randomUUID()})}let i={},a=[{manifest:e,nodeId:ROOT_COMPILED_AGENT_NODE_ID},...[...e.subagents].sort((e,t)=>e.nodeId.localeCompare(t.nodeId)).map(e=>({manifest:e.agent,nodeId:e.nodeId}))];for(let t of a)i[t.nodeId]={modules:await hydrateCompiledNodeScope(t.manifest,t=>resolve(n,relative(e.appRoot,t)))};return{nodes:i}}async function hydrateCompiledNodeScope(e,t){let n={};for(let{binding:r,sourceId:i}of collectRuntimeModuleBindingsForManifest(e))n[i]=r.backing.kind===`programmatic`?await loadFrameworkProgrammaticModule(r.backing,Object.fromEntries(Object.entries(r.backing.dependencies??{}).map(([e,t])=>[e,n[t]]))):memoizeModuleNamespaceFactories(await loadAuthoredModuleNamespace(t(r.backing.sourcePath),{externalDependencies:r.backing.externalDependencies,extension:(()=>{let e=resolveExtensionBindingMountId(r);return e===void 0?void 0:{mountId:e}})()}));return n}async function loadMaterializedCompiledModuleMap(e){let t=join(e.runtimeAppRoot,`.eve`,`compile`,e.moduleMapPath),n=await import(`${pathToFileURL(t).href}?generation=${encodeURIComponent(e.instanceId??e.moduleMapPath)}`),r=compiledModuleMapSchema.safeParse(n.moduleMap??n.default);if(!r.success)throw Error(`Expected materialized authored module map "${t}" to export a valid compiled eve module map. ${formatValidationError(r.error)}`);return r.data}export{loadCompiledModuleMapFromAuthoredSource};
1
+ import{createHash,randomUUID}from"node:crypto";import{link,mkdir,unlink,writeFile}from"node:fs/promises";import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{join,relative,resolve}from"node:path";import{pathToFileURL}from"node:url";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{collectRuntimeModuleBindingsForManifest,compiledModuleMapSchema,resolveExtensionBindingMountId}from"#compiler/module-map.js";import{memoizeModuleNamespaceFactories}from"#compiler/source-graph.js";import{formatValidationError}from"#runtime/validation.js";import{bundleAuthoredModuleMapForGeneration,loadAuthoredModuleNamespace}from"#internal/authored-module-loader.js";import{loadFrameworkProgrammaticModule}from"#framework/sources/registry.js";import{readMaterializedAuthoredModuleIndex}from"#internal/materialized-authored-modules.js";async function loadCompiledModuleMapFromAuthoredSource(e){return await hydrateCompiledModuleMapFromManifest(await loadCompiledManifest({compiledArtifactsSource:e.compiledArtifactsSource}),e.compiledArtifactsSource.appRoot,e.authoredAppRoot)}async function hydrateCompiledModuleMapFromManifest(e,t,n=e.appRoot){let r=await readMaterializedAuthoredModuleIndex(t);if(r!==void 0)return await loadMaterializedCompiledModuleMap({moduleMapPath:r.moduleMap,runtimeAppRoot:t});if([e,...e.subagents.map(e=>e.agent)].some(e=>e.extensionMounts.length>0)){let r=join(t,`.eve`,`compile`,`authored-module-map.mjs`),{code:i}=await bundleAuthoredModuleMapForGeneration({appRoot:n,manifest:e,moduleMapPath:r,resolveExternalPaths:!0}),a=`authored-module-map-${createHash(`sha256`).update(i).digest(`hex`)}.mjs`,o=join(t,`.eve`,`compile`,a);await mkdir(join(t,`.eve`,`compile`),{recursive:!0});let s=`${o}.${randomUUID()}.tmp`;try{await writeFile(s,i,{flag:`wx`});try{await link(s,o)}catch(e){if(e.code!==`EEXIST`)throw e}}finally{await unlink(s).catch(e=>{if(e.code!==`ENOENT`)throw e})}return await loadMaterializedCompiledModuleMap({moduleMapPath:a,runtimeAppRoot:t,instanceId:randomUUID()})}let i={},a=[{manifest:e,nodeId:ROOT_COMPILED_AGENT_NODE_ID},...[...e.subagents].sort((e,t)=>e.nodeId.localeCompare(t.nodeId)).map(e=>({manifest:e.agent,nodeId:e.nodeId}))];for(let t of a)i[t.nodeId]={modules:await hydrateCompiledNodeScope(t.manifest,t=>resolve(n,relative(e.appRoot,t)))};return{nodes:i}}async function hydrateCompiledNodeScope(e,t){let n={};for(let{binding:r,sourceId:i}of collectRuntimeModuleBindingsForManifest(e))n[i]=r.backing.kind===`programmatic`?await loadFrameworkProgrammaticModule(r.backing,Object.fromEntries(Object.entries(r.backing.dependencies??{}).map(([e,t])=>[e,n[t]]))):memoizeModuleNamespaceFactories(await loadAuthoredModuleNamespace(t(r.backing.sourcePath),{externalDependencies:r.backing.externalDependencies,extension:(()=>{let e=resolveExtensionBindingMountId(r);return e===void 0?void 0:{mountId:e}})()}));return n}async function loadMaterializedCompiledModuleMap(e){let t=join(e.runtimeAppRoot,`.eve`,`compile`,e.moduleMapPath),n=await import(`${pathToFileURL(t).href}?generation=${encodeURIComponent(e.instanceId??e.moduleMapPath)}`),r=compiledModuleMapSchema.safeParse(n.moduleMap??n.default);if(!r.success)throw Error(`Expected materialized authored module map "${t}" to export a valid compiled eve module map. ${formatValidationError(r.error)}`);return r.data}export{loadCompiledModuleMapFromAuthoredSource};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{McpServer,createMcpHandler}from"#compiled/@modelcontextprotocol/server/index.js";const log=createLogger(`mcp.server`),MCP_PROTOCOL_VERSION=`2026-07-28`,MCP_REQUEST_BODY_MAX_BYTES=1048576;var McpToolOperationError=class extends Error{code;constructor(e,t){super(t),this.name=`McpToolOperationError`,this.code=e}};const RETRYABLE_CODES=new Set([`conflict`]);function defineMcpTool(e){return{name:e.definition.name,register(t,n){t.registerTool(e.definition.name,{...e.definition.annotations===void 0?{}:{annotations:e.definition.annotations},...e.definition.description===void 0?{}:{description:e.definition.description},inputSchema:e.definition.inputSchema,...e.definition.outputSchema===void 0?{}:{outputSchema:e.definition.outputSchema}},async(t,r)=>await callTool(e.call,t,r.mcpReq.signal,n))}}}function createMcpStreamableHttpServer(e){let t=new Map(e.tools.map(e=>[e.name,e]));if(t.size!==e.tools.length)throw Error(`MCP tool names must be unique.`);return async n=>{let r=await e.authenticate(n);if(r instanceof Response)return r;let i=createMcpHandler(()=>createServer(e,t,r),{legacy:`stateless`});if(n.method.toUpperCase()!==`POST`)return await i.fetch(n);let a=await inspectRequestBody(n);if(a.tooLarge)return requestBodyTooLargeResponse();if(a.invalidJson)return invalidJsonResponse();let o=a.value;if(o===void 0)return await i.fetch(n);let s=await preflightModernRequest(n,o);return s===void 0?await i.fetch(n,{parsedBody:o}):s}}async function preflightModernRequest(e,t){return e.headers.has(`mcp-protocol-version`)||!claimsCurrentProtocolVersion(t)?void 0:await probeEarlierValidationFailure(e,t)??headerMismatchResponse(t)}async function inspectRequestBody(e){let t=e.body;if(t===null)return{tooLarge:!1};let n=Number(e.headers.get(`content-length`));if(Number.isFinite(n)&&n>1048576)return await t.cancel().catch(()=>{}),{tooLarge:!0};let r=t.getReader(),i=[],a=0;try{for(;;){let e=await r.read();if(e.done)break;if(a+=e.value.byteLength,a>1048576)return await r.cancel(),{tooLarge:!0};i.push(e.value)}let e=new Uint8Array(a),t=0;for(let n of i)e.set(n,t),t+=n.byteLength;return{tooLarge:!1,value:JSON.parse(new TextDecoder().decode(e))}}catch{return{invalidJson:!0,tooLarge:!1}}}function invalidJsonResponse(){return Response.json({error:{code:-32700,message:`Parse error`},id:null,jsonrpc:`2.0`},{status:400})}function requestBodyTooLargeResponse(){return Response.json({error:{code:-32e3,message:`Request body too large`},id:null,jsonrpc:`2.0`},{status:413,statusText:`Request Entity Too Large`})}function claimsCurrentProtocolVersion(e){return isPlainRecord(e)&&isPlainRecord(e.params)&&isPlainRecord(e.params._meta)&&e.params._meta[`io.modelcontextprotocol/protocolVersion`]===`2026-07-28`}function isPlainRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function probeEarlierValidationFailure(e,t){let n=new Headers(e.headers);n.set(`mcp-protocol-version`,MCP_PROTOCOL_VERSION);let r=new Request(e.url,{body:JSON.stringify(t),headers:n,method:e.method}),i=createMcpHandler(()=>new McpServer({name:`eve-mcp-preflight`,version:`0`}),{legacy:`reject`});try{let e=await i.fetch(r,{parsedBody:t});if(e.status===406||e.status===415)return e;if(e.status===400){let t=await e.clone().json().catch(()=>void 0);if(t?.error?.code===-32700||t?.error?.code===-32600||t?.error?.code===-32602||t?.error?.code===-32022)return e}await e.body?.cancel();return}finally{await i.close().catch(()=>{})}}function headerMismatchResponse(e){let t=`the body carries a modern MCP envelope but the required MCP-Protocol-Version header is absent`;return Response.json({error:{code:-32020,data:{mismatch:{body:t,header:`(missing)`}},message:`Bad Request: the request headers and body disagree: ${t}`},id:readJsonRpcRequestId(e),jsonrpc:`2.0`},{status:400})}function readJsonRpcRequestId(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let t=Reflect.get(e,`id`);return typeof t==`string`||typeof t==`number`?t:null}function createServer(e,t,n){let r={capabilities:{tools:{listChanged:!1}}};e.instructions!==void 0&&(r.instructions=e.instructions);let i=new McpServer({name:e.name,version:e.version},r);for(let e of t.values())e.register(i,n);return i}async function callTool(e,t,n,r){try{return await e(t,{auth:r,signal:n})}catch(e){return e instanceof McpToolOperationError?toolError({code:e.code,message:e.message,retryable:RETRYABLE_CODES.has(e.code)}):toolError({code:`internal`,errorId:logError(log,`MCP tool call failed`,e),message:`The server could not complete this tool call.`,retryable:!1})}}function toolError(e){return{content:[{type:`text`,text:e.errorId===void 0?e.message:`${e.message} (errorId: ${e.errorId})`}],isError:!0,structuredContent:{error:e}}}export{MCP_PROTOCOL_VERSION,MCP_REQUEST_BODY_MAX_BYTES,McpToolOperationError,createMcpStreamableHttpServer,defineMcpTool};
1
+ import{createLogger,logError}from"#internal/logging.js";import{McpServer,createMcpHandler}from"#compiled/@modelcontextprotocol/server/index.js";const log=createLogger(`mcp.server`),MCP_PROTOCOL_VERSION=`2026-07-28`,MCP_REQUEST_BODY_MAX_BYTES=1048576;var McpToolOperationError=class extends Error{code;constructor(e,t){super(t),this.name=`McpToolOperationError`,this.code=e}};const RETRYABLE_CODES=new Set([`conflict`]);function defineMcpTool(e){return{name:e.definition.name,register(t,n){t.registerTool(e.definition.name,{...e.definition.annotations===void 0?{}:{annotations:e.definition.annotations},...e.definition.description===void 0?{}:{description:e.definition.description},inputSchema:advertiseOnly(e.definition.inputSchema),...e.definition.outputSchema===void 0?{}:{outputSchema:e.definition.outputSchema}},async(t,r)=>{let i=await e.definition.inputSchema[`~standard`].validate(t);return i.issues===void 0?await callTool(e.call,i.value,r.mcpReq.signal,n):toolError({code:`invalid_input`,message:`Invalid arguments for tool ${e.definition.name}: ${i.issues.map(formatIssue).join(`, `)}`,retryable:!1})})}}}function advertiseOnly(e){let t=e[`~standard`];return{"~standard":{jsonSchema:t.jsonSchema,validate:e=>({value:e}),vendor:t.vendor,version:t.version}}}function formatIssue(e){return e.path===void 0||e.path.length===0?e.message:`${e.path.map(e=>String(typeof e==`object`?e.key:e)).join(`.`)}: ${e.message}`}function createMcpStreamableHttpServer(e){let t=new Map(e.tools.map(e=>[e.name,e]));if(t.size!==e.tools.length)throw Error(`MCP tool names must be unique.`);return async n=>{let r=await e.authenticate(n);if(r instanceof Response)return r;let i=createMcpHandler(()=>createServer(e,t,r),{legacy:`stateless`});if(n.method.toUpperCase()!==`POST`)return await i.fetch(n);let a=await inspectRequestBody(n);if(a.tooLarge)return requestBodyTooLargeResponse();if(a.invalidJson)return invalidJsonResponse();let o=a.value;if(o===void 0)return await i.fetch(n);let s=await preflightModernRequest(n,o);return s===void 0?await i.fetch(n,{parsedBody:o}):s}}async function preflightModernRequest(e,t){return e.headers.has(`mcp-protocol-version`)||!claimsCurrentProtocolVersion(t)?void 0:await probeEarlierValidationFailure(e,t)??headerMismatchResponse(t)}async function inspectRequestBody(e){let t=e.body;if(t===null)return{tooLarge:!1};let n=Number(e.headers.get(`content-length`));if(Number.isFinite(n)&&n>1048576)return await t.cancel().catch(()=>{}),{tooLarge:!0};let r=t.getReader(),i=[],a=0;try{for(;;){let e=await r.read();if(e.done)break;if(a+=e.value.byteLength,a>1048576)return await r.cancel(),{tooLarge:!0};i.push(e.value)}let e=new Uint8Array(a),t=0;for(let n of i)e.set(n,t),t+=n.byteLength;return{tooLarge:!1,value:JSON.parse(new TextDecoder().decode(e))}}catch{return{invalidJson:!0,tooLarge:!1}}}function invalidJsonResponse(){return Response.json({error:{code:-32700,message:`Parse error`},id:null,jsonrpc:`2.0`},{status:400})}function requestBodyTooLargeResponse(){return Response.json({error:{code:-32e3,message:`Request body too large`},id:null,jsonrpc:`2.0`},{status:413,statusText:`Request Entity Too Large`})}function claimsCurrentProtocolVersion(e){return isPlainRecord(e)&&isPlainRecord(e.params)&&isPlainRecord(e.params._meta)&&e.params._meta[`io.modelcontextprotocol/protocolVersion`]===`2026-07-28`}function isPlainRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function probeEarlierValidationFailure(e,t){let n=new Headers(e.headers);n.set(`mcp-protocol-version`,MCP_PROTOCOL_VERSION);let r=new Request(e.url,{body:JSON.stringify(t),headers:n,method:e.method}),i=createMcpHandler(()=>new McpServer({name:`eve-mcp-preflight`,version:`0`}),{legacy:`reject`});try{let e=await i.fetch(r,{parsedBody:t});if(e.status===406||e.status===415)return e;if(e.status===400){let t=await e.clone().json().catch(()=>void 0);if(t?.error?.code===-32700||t?.error?.code===-32600||t?.error?.code===-32602||t?.error?.code===-32022)return e}await e.body?.cancel();return}finally{await i.close().catch(()=>{})}}function headerMismatchResponse(e){let t=`the body carries a modern MCP envelope but the required MCP-Protocol-Version header is absent`;return Response.json({error:{code:-32020,data:{mismatch:{body:t,header:`(missing)`}},message:`Bad Request: the request headers and body disagree: ${t}`},id:readJsonRpcRequestId(e),jsonrpc:`2.0`},{status:400})}function readJsonRpcRequestId(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let t=Reflect.get(e,`id`);return typeof t==`string`||typeof t==`number`?t:null}function createServer(e,t,n){let r={capabilities:{tools:{listChanged:!1}}};e.instructions!==void 0&&(r.instructions=e.instructions);let i=new McpServer({name:e.name,version:e.version},r);for(let e of t.values())e.register(i,n);return i}async function callTool(e,t,n,r){try{return await e(t,{auth:r,signal:n})}catch(e){return e instanceof McpToolOperationError?toolError({code:e.code,message:e.message,retryable:RETRYABLE_CODES.has(e.code)}):toolError({code:`internal`,errorId:logError(log,`MCP tool call failed`,e),message:`The server could not complete this tool call.`,retryable:!1})}}function toolError(e){return{content:[{type:`text`,text:e.errorId===void 0?e.message:`${e.message} (errorId: ${e.errorId})`}],isError:!0,structuredContent:{error:e}}}export{MCP_PROTOCOL_VERSION,MCP_REQUEST_BODY_MAX_BYTES,McpToolOperationError,createMcpStreamableHttpServer,defineMcpTool};
@@ -1,6 +1,6 @@
1
1
  import type { H3Event } from "nitro";
2
2
  import type { WebSocketRouteHooks } from "#channel/routes.js";
3
- import type { NitroArtifactsConfig } from "#internal/nitro/routes/runtime-artifacts.js";
3
+ import { type NitroArtifactsConfig } from "#internal/nitro/routes/runtime-artifacts.js";
4
4
  /**
5
5
  * Dispatches one channel request identified by `routeKey`.
6
6
  *
@@ -1 +1 @@
1
- import{createAttachSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{createChannelOperations}from"#channel/channel-operations.js";import{getChannelInstrumentationKind}from"#channel/compiled-channel.js";import{createCrossChannelToFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{attachAgentInfoRouteResponse,attachHomeRouteMetadata,attachRemoteAgentStreamHeadersResolver,attachRouteChannelName,attachRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{getWorld}from"#internal/workflow/runtime.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{DEVELOPMENT_WORKFLOW_SECRET_ENV}from"#internal/workflow/development-world-protocol.js";import{readTrustedDevelopmentClientAddress}from"#internal/nitro/dev-client-address.js";import{withLocalDevRequestScope}from"#runtime/local-dev-capability.js";import{traceChannelRequest}from"#internal/nitro/routes/channel-request-instrumentation.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";import{readVercelProjectLink}from"#internal/vercel/project-link.js";import{withVercelOidcProjectResolver}from"#channel/auth/vercel-oidc-project.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,n){return await traceChannelRequest({request:e.req,routeKey:t},async r=>{let i=r?.spanContext()??trace.getSpan(context.active())?.spanContext(),a=await resolveNitroChannelRuntimeBundle(n),o=a.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(o===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});r?.setAttribute(`eve.channel.name`,o.name);let s=getChannelInstrumentationKind(o.definition)??o.adapter?.kind;s!==void 0&&r?.setAttribute(`eve.channel.kind`,s);let c=await buildRouteArgs(e,a,o.name,s??`channel`,n,i),l;try{l=await withDevelopmentVercelOidcContext(n,e.req,async()=>{if(o.handler)return await o.handler(e.req,c.args);let t={waitUntil:c.args.waitUntil,params:c.args.params,requestIp:c.args.requestIp};return await o.fetch(e.req,t)})}catch(n){let r=logError(log,`channel handler threw`,n,{routeKey:t,channel:o.name});return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),Response.json({error:`Channel handler failed.`,errorId:r,ok:!1},{status:500})}return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),l})}async function dispatchChannelWebSocketRequest(e,t,n){let r=await resolveNitroChannelRuntimeBundle(n),i=r.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(i===void 0||i.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let a=i.websocket,o=getChannelInstrumentationKind(i.definition)??i.adapter?.kind??`channel`,s=await buildRouteArgs(e,r,i.name,o,n,void 0);try{let r=await withDevelopmentVercelOidcContext(n,e.req,async()=>await a(e.req,s.args));return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),r}catch(n){let r=logError(log,`channel websocket handler threw`,n,{routeKey:t,channel:i.name});return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:r,ok:!1},500)}}async function withDevelopmentVercelOidcContext(e,t,n){return e.kind===`development`?await withLocalDevRequestScope(t,async()=>await withVercelOidcProjectResolver({request:t,resolveCurrentProject:async()=>{let t=await readVercelProjectLink(e.appRoot);return t===void 0?void 0:{environment:`development`,projectId:t.projectId}}},n)):await n()}async function buildRouteArgs(e,t,n,r,i,a){let o=readVercelRequestId(e.req.headers),s=extractRequestIp(e,i),c=[],l=e.context.params??{},u={};for(let[e,t]of Object.entries(l))u[e]=decodeURIComponent(t);let waitUntil=e=>{c.push(e)},d=t.channels.find(e=>e.name===n),f=d?.adapter??{kind:`channel`},p={acceptedDeploymentId:await resolveAcceptedDeploymentId(i),channelKind:r,channelName:n,requestId:o,requestTraceContext:a===void 0?void 0:{spanId:a.spanId,traceFlags:a.traceFlags,traceId:a.traceId}},m=createChannelOperations({adapter:f,channelName:n,metadata:p,runtime:t.runtime,turnPolicy:d?.turnPolicy}),h=createAttachSessionFn(t.runtime,{...p,turnPolicy:d?.turnPolicy}),g=createCrossChannelToFn(t.runtime,toCrossChannelTargets(t.channels)),_=attachRouteSessionCreator(attachHomeRouteMetadata(attachRouteChannelName(attachAgentInfoRouteResponse({attachSession:h,...m,params:u,requestIp:s,to:g,waitUntil},async()=>{let{handleAgentInfoRequest:e}=await import(`#internal/nitro/routes/info.js`);return await e(i)}),n),{agentName:t.agentName}),async e=>await t.runtime.createSession({...e,adapter:f,channelName:n,continuationToken:e.continuationToken===void 0?void 0:`${n}:${e.continuationToken}`,delivery:createChannelDeliveryMetadata(p),requestId:o}));return t.resolveRemoteAgentStreamHeaders!==void 0&&attachRemoteAgentStreamHeadersResolver(_,t.resolveRemoteAgentStreamHeaders),{args:_,backgroundTasks:c}}async function resolveAcceptedDeploymentId(e){let t=process.env.VERCEL_DEPLOYMENT_ID?.trim();if(t!==void 0&&t.length>0)return validateDeploymentId(t);if(e.kind!==`development`||process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]!==void 0)return validateDeploymentId(await(await getWorld()).getDeploymentId())}function validateDeploymentId(e){if(e.length===0||e===`latest`)throw Error(`Channel ingress could not resolve an exact deployment id.`);return e}function readVercelRequestId(e){let t=e.get(`x-vercel-id`)?.trim();return t===``?void 0:t}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,n,r){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:n,channel:r})}))}function extractRequestIp(e,t){if(t.kind===`development`){let t=readTrustedDevelopmentClientAddress(e.req.headers,process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]);if(t!==void 0)return t}return extractSocketIp(e)}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};
1
+ import{createAttachSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createChannelDeliveryMetadata}from"#channel/delivery-metadata.js";import{createChannelOperations}from"#channel/channel-operations.js";import{getChannelInstrumentationKind}from"#channel/compiled-channel.js";import{createCrossChannelToFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{attachAgentInfoRouteResponse,attachHomeRouteMetadata,attachRemoteAgentStreamHeadersResolver,attachRouteChannelName,attachRouteSessionCreator}from"#internal/nitro/routes/channel-route-context.js";import{getWorld}from"#internal/workflow/runtime.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{DEVELOPMENT_WORKFLOW_SECRET_ENV}from"#internal/workflow/development-world-protocol.js";import{readTrustedDevelopmentClientAddress}from"#internal/nitro/dev-client-address.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{withLocalDevRequestScope}from"#runtime/local-dev-capability.js";import{createAgentDescriptionRouteArgs}from"#channel/agent-description.js";import{traceChannelRequest}from"#internal/nitro/routes/channel-request-instrumentation.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";import{readVercelProjectLink}from"#internal/vercel/project-link.js";import{withVercelOidcProjectResolver}from"#channel/auth/vercel-oidc-project.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,n){return await traceChannelRequest({request:e.req,routeKey:t},async r=>{let i=r?.spanContext()??trace.getSpan(context.active())?.spanContext(),a=await resolveNitroChannelRuntimeBundle(n),o=a.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(o===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});r?.setAttribute(`eve.channel.name`,o.name);let s=getChannelInstrumentationKind(o.definition)??o.adapter?.kind;s!==void 0&&r?.setAttribute(`eve.channel.kind`,s);let c=await buildRouteArgs(e,a,o.name,s??`channel`,n,i),l;try{l=await withDevelopmentVercelOidcContext(n,e.req,async()=>{if(o.handler)return await o.handler(e.req,c.args);let t={waitUntil:c.args.waitUntil,params:c.args.params,requestIp:c.args.requestIp};return await o.fetch(e.req,t)})}catch(n){let r=logError(log,`channel handler threw`,n,{routeKey:t,channel:o.name});return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),Response.json({error:`Channel handler failed.`,errorId:r,ok:!1},{status:500})}return flushBackgroundTasks(e,c.backgroundTasks,t,o.name),l})}async function dispatchChannelWebSocketRequest(e,t,n){let r=await resolveNitroChannelRuntimeBundle(n),i=r.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(i===void 0||i.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let a=i.websocket,o=getChannelInstrumentationKind(i.definition)??i.adapter?.kind??`channel`,s=await buildRouteArgs(e,r,i.name,o,n,void 0);try{let r=await withDevelopmentVercelOidcContext(n,e.req,async()=>await a(e.req,s.args));return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),r}catch(n){let r=logError(log,`channel websocket handler threw`,n,{routeKey:t,channel:i.name});return flushBackgroundTasks(e,s.backgroundTasks,t,i.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:r,ok:!1},500)}}async function withDevelopmentVercelOidcContext(e,t,n){return e.kind===`development`?await withLocalDevRequestScope(t,async()=>await withVercelOidcProjectResolver({request:t,resolveCurrentProject:async()=>{let t=await readVercelProjectLink(e.appRoot);return t===void 0?void 0:{environment:`development`,projectId:t.projectId}}},n)):await n()}async function buildRouteArgs(e,t,n,r,i,a){let o=readVercelRequestId(e.req.headers),s=extractRequestIp(e,i),c=[],l=e.context.params??{},u={};for(let[e,t]of Object.entries(l))u[e]=decodeURIComponent(t);let waitUntil=e=>{c.push(e)},d=t.channels.find(e=>e.name===n),f=d?.adapter??{kind:`channel`},p={acceptedDeploymentId:await resolveAcceptedDeploymentId(i),channelKind:r,channelName:n,requestId:o,requestTraceContext:a===void 0?void 0:{spanId:a.spanId,traceFlags:a.traceFlags,traceId:a.traceId}},m=createChannelOperations({adapter:f,channelName:n,metadata:p,runtime:t.runtime,turnPolicy:d?.turnPolicy}),h=createAttachSessionFn(t.runtime,{...p,turnPolicy:d?.turnPolicy}),g=createCrossChannelToFn(t.runtime,toCrossChannelTargets(t.channels)),_=attachRouteSessionCreator(attachHomeRouteMetadata(attachRouteChannelName(attachAgentInfoRouteResponse({attachSession:h,...m,...createAgentDescriptionRouteArgs(()=>resolveNitroCompiledArtifactsSource(i)),params:u,requestIp:s,to:g,waitUntil},async()=>{let{handleAgentInfoRequest:e}=await import(`#internal/nitro/routes/info.js`);return await e(i)}),n),{agentName:t.agentName}),async e=>await t.runtime.createSession({...e,adapter:f,channelName:n,continuationToken:e.continuationToken===void 0?void 0:`${n}:${e.continuationToken}`,delivery:createChannelDeliveryMetadata(p),requestId:o}));return t.resolveRemoteAgentStreamHeaders!==void 0&&attachRemoteAgentStreamHeadersResolver(_,t.resolveRemoteAgentStreamHeaders),{args:_,backgroundTasks:c}}async function resolveAcceptedDeploymentId(e){let t=process.env.VERCEL_DEPLOYMENT_ID?.trim();if(t!==void 0&&t.length>0)return validateDeploymentId(t);if(e.kind!==`development`||process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]!==void 0)return validateDeploymentId(await(await getWorld()).getDeploymentId())}function validateDeploymentId(e){if(e.length===0||e===`latest`)throw Error(`Channel ingress could not resolve an exact deployment id.`);return e}function readVercelRequestId(e){let t=e.get(`x-vercel-id`)?.trim();return t===``?void 0:t}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,n,r){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:n,channel:r})}))}function extractRequestIp(e,t){if(t.kind===`development`){let t=readTrustedDevelopmentClientAddress(e.req.headers,process.env[DEVELOPMENT_WORKFLOW_SECRET_ENV]);if(t!==void 0)return t}return extractSocketIp(e)}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};
@@ -1,6 +1,8 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { ChannelRespondOptions, ChannelSendOptions } from "#channel/channel-operations.js";
3
3
  import type { SessionAuthContext, TurnPolicy } from "#channel/types.js";
4
+ import type { InputResolution } from "#protocol/message.js";
5
+ import type { InputRequest } from "#shared/input.js";
4
6
  import { type InputResponse, type StrictInputResponses } from "#shared/input.js";
5
7
  import type { ActionEvent, Adapter, ChatConfig, SerializedThread, Thread, WebhookOptions } from "#compiled/chat/index.js";
6
8
  import { Chat } from "#compiled/chat/index.js";
@@ -23,8 +25,15 @@ export interface ChatSdkChannelState extends Record<string, unknown> {
23
25
  pendingToolCallMessage?: string | null;
24
26
  /** Authorization status messages, keyed by connection name. */
25
27
  pendingAuthMessageIds?: Record<string, string>;
28
+ /** Posted input request cards, keyed by message id, until eve resolves every request on them. */
29
+ pendingInputCards?: Record<string, ChatSdkPendingInputCard>;
26
30
  streamStepIndex?: number | null;
27
31
  }
32
+ /** One posted card's requests and the resolutions eve has reported for them so far. */
33
+ export interface ChatSdkPendingInputCard {
34
+ readonly requests: readonly InputRequest[];
35
+ readonly resolved: Readonly<Record<string, InputResolution>>;
36
+ }
28
37
  /**
29
38
  * Thread selector accepted by `chatSdkChannel().receive`. Pass a serialized
30
39
  * Chat SDK thread when possible; `threadId` plus `adapterName` is supported for
@@ -1,3 +1,3 @@
1
- import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{parseInputResponses}from"#shared/input.js";import{ContextContainer,contextStorage}from"#context/container.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import{ContextKey}from"#context/key.js";import{isNotImplemented}from"#public/channels/chat-sdk/notImplemented.js";import{Chat,Message,ThreadImpl}from"#compiled/chat/index.js";import{defaultAuthorizationEvents}from"#public/channels/chat-sdk/authorization.js";import{decodeInputAction,renderInputRequests}from"#public/channels/chat-sdk/input-actions.js";import{chatSdkInstrumentation}from"#public/channels/chat-sdk/audience.js";const log=createLogger(`chat-sdk.channel`),streamTextByState=new WeakMap,ActiveWebhookKey=new ContextKey(`chat-sdk.active-webhook`);function chatSdkChannel(e){let t=new Chat(e),n=e.inputActionPrefix??`eve_input:`,r=e.streaming??!0,i=e.streamingEditIntervalMs??1e3,a={...defaultEvents(n),...e.events};return t.onAction(async r=>{let i=decodeInputAction(r.actionId,n,r.value);if(i){if(!r.thread)throw Error(`chatSdkChannel input actions require a thread on the Chat SDK action event.`);await bridgeRespond(t,[i],{auth:e.resolveInputAuth?await e.resolveInputAuth(r):null,thread:r.thread.toJSON()})}}),{bot:t,channel:defineChannel({kindHint:`chat-sdk`,turnPolicy:e.turnPolicy,state:initialState(),...chatSdkInstrumentation,context(e){return{bot:t,state:e,streaming:r,streamingEditIntervalMs:i,thread:threadFromState(t,e)}},routes:adapterNames(e.adapters).flatMap(n=>{let r=routeForAdapter(n,e),handler=async(r,i)=>{let a=t.webhooks[n],o=new ContextContainer;return o.setVirtualContext(ActiveWebhookKey,{from:i.from}),contextStorage.run(o,()=>a(r,{...e.webhook,waitUntil(e){i.waitUntil(e)}}))};return[GET(r,handler),POST(r,handler)]}),async receive(e,{from:n}){let r=serializeReceiveTarget(t,e.target);return n(r.id).send(e.message,{auth:e.auth,state:{thread:r}})},events:a}),send(e,n){return bridgeSend(t,e,n)},respond(e,n){return bridgeRespond(t,e,n)}}}function defaultEvents(e){return{...defaultAuthorizationEvents(),async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,clearStream(t.state),await safeStartTyping(t.thread,`Working...`)},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await safeStartTyping(t.thread,truncate(r));return}let i=e.actions.map(e=>e.kind===`tool-call`?e.toolName:e.kind);await safeStartTyping(t.thread,truncate(`Running ${i.join(`, `)}...`))},async"message.appended"(e,t,n){if(!t.thread||!canStream(t))return;let r=((t.state.streamStepIndex===e.stepIndex?streamTextByState.get(t.state):void 0)??``)+e.messageDelta;if(!r)return;streamTextByState.set(t.state,r);let i=t.state.anchorMessageId;if(!i||t.state.streamStepIndex!==e.stepIndex){let n=await t.thread.post({markdown:r});t.state.anchorMessageId=n.id,t.state.streamStepIndex=e.stepIndex,t.state.lastEditAtMs=Date.now();return}let a=t.state.lastEditAtMs??0;if(!(Date.now()-a<t.streamingEditIntervalMs))try{await editMessage(t.thread,i,r),t.state.lastEditAtMs=Date.now()}catch(e){if(!isNotImplemented(e))throw e;t.state.editSupported=!1,clearStream(t.state)}},async"input.requested"(t,n,r){n.thread&&t.requests.length!==0&&await n.thread.post(renderInputRequests(t.requests,e))},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null,e.message?await finalizeStreamedMessage(t,e.message,!1):clearStream(t.state);return}if(t.state.pendingToolCallMessage=null,!e.message){clearStream(t.state);return}await finalizeStreamedMessage(t,e.message,!0)},async"turn.failed"(e,t,n){await postFailure(t.thread,`I hit an error while handling your request`,e)},async"session.failed"(e,t){await postFailure(t.thread,`This session could not recover from an error`,e)}}}async function safeStartTyping(e,t){if(e)try{await e.startTyping(t)}catch(e){if(!isNotImplemented(e))throw e}}async function editMessage(e,t,n){await e.adapter.editMessage(e.id,t,{markdown:n})}async function finalizeStreamedMessage(e,t,n){let r=e.thread;if(!r){clearStream(e.state);return}let i=e.state.anchorMessageId;if(canStream(e)&&i)try{await editMessage(r,i,t)}catch(i){if(!isNotImplemented(i))throw i;e.state.editSupported=!1,n&&await r.post({markdown:t})}else n&&await r.post({markdown:t});clearStream(e.state)}function canStream(e){return e.streaming&&e.state.editSupported!==!1}function clearStream(e){e.anchorMessageId=null,e.lastEditAtMs=null,e.streamStepIndex=null,streamTextByState.delete(e)}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function truncate(e,t=80){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}async function postFailure(e,t,n){if(!e)return;let r=formatErrorHint(n),i=extractErrorId(n.details);await e.post([`${t}${r}.`,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[`Error id: ${i}`]:[]].join(`
1
+ import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{parseInputResponses}from"#shared/input.js";import{ContextContainer,contextStorage}from"#context/container.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import{ContextKey}from"#context/key.js";import{isNotImplemented}from"#public/channels/chat-sdk/notImplemented.js";import{Chat,Message,ThreadImpl}from"#compiled/chat/index.js";import{defaultAuthorizationEvents}from"#public/channels/chat-sdk/authorization.js";import{decodeInputAction,renderInputRequests}from"#public/channels/chat-sdk/input-actions.js";import{chatSdkInstrumentation}from"#public/channels/chat-sdk/audience.js";const log=createLogger(`chat-sdk.channel`),streamTextByState=new WeakMap,ActiveWebhookKey=new ContextKey(`chat-sdk.active-webhook`);function chatSdkChannel(e){let t=new Chat(e),n=e.inputActionPrefix??`eve_input:`,r=e.streaming??!0,i=e.streamingEditIntervalMs??1e3,a={...defaultEvents(n),...e.events};return t.onAction(async r=>{let i=decodeInputAction(r.actionId,n,r.value);if(i){if(!r.thread)throw Error(`chatSdkChannel input actions require a thread on the Chat SDK action event.`);await bridgeRespond(t,[i],{auth:e.resolveInputAuth?await e.resolveInputAuth(r):null,thread:r.thread.toJSON()})}}),{bot:t,channel:defineChannel({kindHint:`chat-sdk`,turnPolicy:e.turnPolicy,state:initialState(),...chatSdkInstrumentation,context(e){return{bot:t,state:e,streaming:r,streamingEditIntervalMs:i,thread:threadFromState(t,e)}},routes:adapterNames(e.adapters).flatMap(n=>{let r=routeForAdapter(n,e),handler=async(r,i)=>{let a=t.webhooks[n],o=new ContextContainer;return o.setVirtualContext(ActiveWebhookKey,{from:i.from}),contextStorage.run(o,()=>a(r,{...e.webhook,waitUntil(e){i.waitUntil(e)}}))};return[GET(r,handler),POST(r,handler)]}),async receive(e,{from:n}){let r=serializeReceiveTarget(t,e.target);return n(r.id).send(e.message,{auth:e.auth,state:{thread:r}})},events:a}),send(e,n){return bridgeSend(t,e,n)},respond(e,n){return bridgeRespond(t,e,n)}}}function defaultEvents(e){return{...defaultAuthorizationEvents(),async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,clearStream(t.state),await safeStartTyping(t.thread,`Working...`)},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await safeStartTyping(t.thread,truncate(r));return}let i=e.actions.map(e=>e.kind===`tool-call`?e.toolName:e.kind);await safeStartTyping(t.thread,truncate(`Running ${i.join(`, `)}...`))},async"message.appended"(e,t,n){if(!t.thread||!canStream(t))return;let r=((t.state.streamStepIndex===e.stepIndex?streamTextByState.get(t.state):void 0)??``)+e.messageDelta;if(!r)return;streamTextByState.set(t.state,r);let i=t.state.anchorMessageId;if(!i||t.state.streamStepIndex!==e.stepIndex){let n=await t.thread.post({markdown:r});t.state.anchorMessageId=n.id,t.state.streamStepIndex=e.stepIndex,t.state.lastEditAtMs=Date.now();return}let a=t.state.lastEditAtMs??0;if(!(Date.now()-a<t.streamingEditIntervalMs))try{await editMessage(t.thread,i,r),t.state.lastEditAtMs=Date.now()}catch(e){if(!isNotImplemented(e))throw e;t.state.editSupported=!1,clearStream(t.state)}},async"input.requested"(t,n,r){if(!n.thread||t.requests.length===0)return;let i=await n.thread.post(renderInputRequests(t.requests,e));i.id&&n.state.editSupported!==!1&&(n.state.pendingInputCards={...n.state.pendingInputCards,[i.id]:{requests:t.requests,resolved:{}}})},async"input.resolved"(t,n,r){let i=n.thread;if(i)for(let[r,a]of Object.entries(n.state.pendingInputCards??{})){let o=t.resolutions.filter(e=>a.requests.some(t=>t.requestId===e.requestId));if(o.length===0)continue;let s={...a.resolved,...Object.fromEntries(o.map(e=>[e.requestId,e]))},{[r]:c,...l}=n.state.pendingInputCards??{};n.state.pendingInputCards=a.requests.every(e=>s[e.requestId]!==void 0)?l:{...l,[r]:{requests:a.requests,resolved:s}};try{await i.adapter.editMessage(i.id,r,renderInputRequests(a.requests,e,s))}catch(e){if(!isNotImplemented(e)){log.warn(`answered input card edit failed`,{error:e,messageId:r});continue}n.state.editSupported=!1,n.state.pendingInputCards={};return}}},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null,e.message?await finalizeStreamedMessage(t,e.message,!1):clearStream(t.state);return}if(t.state.pendingToolCallMessage=null,!e.message){clearStream(t.state);return}await finalizeStreamedMessage(t,e.message,!0)},async"turn.failed"(e,t,n){await postFailure(t.thread,`I hit an error while handling your request`,e)},async"session.failed"(e,t){await postFailure(t.thread,`This session could not recover from an error`,e)}}}async function safeStartTyping(e,t){if(e)try{await e.startTyping(t)}catch(e){if(!isNotImplemented(e))throw e}}async function editMessage(e,t,n){await e.adapter.editMessage(e.id,t,{markdown:n})}async function finalizeStreamedMessage(e,t,n){let r=e.thread;if(!r){clearStream(e.state);return}let i=e.state.anchorMessageId;if(canStream(e)&&i)try{await editMessage(r,i,t)}catch(i){if(!isNotImplemented(i))throw i;e.state.editSupported=!1,n&&await r.post({markdown:t})}else n&&await r.post({markdown:t});clearStream(e.state)}function canStream(e){return e.streaming&&e.state.editSupported!==!1}function clearStream(e){e.anchorMessageId=null,e.lastEditAtMs=null,e.streamStepIndex=null,streamTextByState.delete(e)}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function truncate(e,t=80){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}async function postFailure(e,t,n){if(!e)return;let r=formatErrorHint(n),i=extractErrorId(n.details);await e.post([`${t}${r}.`,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[`Error id: ${i}`]:[]].join(`
2
2
 
3
3
  `))}async function bridgeSend(e,t,n){let r=activeFrom(`send`),{adapterName:i,auth:a,thread:o,...s}=n,c=serializeThread(e,o,i);return r(c.id).send(t,{...s,auth:a??null,state:{thread:c}})}async function bridgeRespond(e,t,n){let r=activeFrom(`respond`),{adapterName:i,auth:a,thread:o,...s}=n;return r(serializeThread(e,o,i).id).respond(parseInputResponses(t),{...s,auth:a??null})}function activeFrom(e){let t=contextStorage.getStore()?.get(ActiveWebhookKey);if(!t)throw Error(`chatSdkChannel().${e} can only run during a Chat SDK webhook handler for this bridge.`);return t.from}function initialState(){return{pendingAuthMessageIds:{},thread:null}}function threadFromState(e,t){if(!t.thread)return null;try{let n=t.thread;return new ThreadImpl({adapter:e.getAdapter(n.adapterName),channelId:n.channelId,channelVisibility:n.channelVisibility,currentMessage:n.currentMessage?Message.fromJSON(n.currentMessage):void 0,id:n.id,isDM:n.isDM,stateAdapter:e.getState()})}catch(e){return log.warn(`failed to rebuild Chat SDK thread from channel state`,{error:e}),null}}function serializeReceiveTarget(e,t){if(t.thread)return t.thread;if(!t.threadId)throw Error(`chatSdkChannel().receive requires target.thread or target.threadId.`);return serializeThread(e,t.threadId,t.adapterName)}function serializeThread(e,t,n){if(typeof t==`string`){let r=n??inferAdapterName(t),i=e.getAdapter(r);return{_type:`chat:Thread`,adapterName:r,channelId:i.channelIdFromThreadId(t),channelVisibility:i.getChannelVisibility?.(t),id:t,isDM:!1}}return isSerializedThread(t)?t:t.toJSON()}function isSerializedThread(e){return`_type`in e&&e._type===`chat:Thread`}function inferAdapterName(e){let t=e.indexOf(`:`);if(t<=0)throw Error(`chatSdkChannel string thread references require options.adapterName.`);return e.slice(0,t)}function adapterNames(e){return Object.keys(e)}function routeForAdapter(e,t){return t.routes?.[e]||`${(t.route??`/eve/v1`).replace(/\/$/u,``)}/${e}`}export{chatSdkChannel};
@@ -1,9 +1,11 @@
1
+ import type { InputResolution } from "#protocol/message.js";
1
2
  import type { InputRequest } from "#shared/input.js";
2
3
  /**
3
4
  * Renders pending input requests as a Chat SDK card with one button per option,
4
- * plus fallback text for adapters without cards (such as Photon iMessage).
5
+ * plus fallback text for adapters without cards (such as Photon iMessage). A
6
+ * request in `resolved` shows its outcome in place of its buttons.
5
7
  */
6
- export declare function renderInputRequests(requests: readonly InputRequest[], inputActionPrefix: string): {
8
+ export declare function renderInputRequests(requests: readonly InputRequest[], inputActionPrefix: string, resolved?: Readonly<Record<string, InputResolution>>): {
7
9
  card: import("#compiled/chat/index.js").CardElement;
8
10
  fallbackText: string;
9
11
  };
@@ -1,4 +1,4 @@
1
- import{Actions,Button,Card,CardText}from"#compiled/chat/index.js";const FREEFORM_HINT=`Reply with your answer.`;function renderInputRequests(e,t){return{card:Card({children:e.flatMap(e=>renderInputRequest(e,t))}),fallbackText:e.map(renderInputRequestText).join(`
1
+ import{Actions,Button,Card,CardText}from"#compiled/chat/index.js";import{resolvedPromptLabel}from"#channel/resolved-prompt.js";const FREEFORM_HINT=`Reply with your answer.`;function renderInputRequests(e,t,n={}){let outcome=e=>{let t=n[e.requestId];return t===void 0?void 0:resolvedPromptLabel(t,e.options)};return{card:Card({children:e.flatMap(e=>{let n=outcome(e);return n===void 0?renderInputRequest(e,t):[CardText(e.prompt),CardText(n)]})}),fallbackText:e.map(e=>{let t=outcome(e);return t===void 0?renderInputRequestText(e):`${e.prompt}\n\n${t}`}).join(`
2
2
 
3
3
  `)}}function renderInputRequestText(e){let t=e.options??[];return t.length===0?`${e.prompt}\n\n${FREEFORM_HINT}`:[e.prompt,``,...t.map((e,t)=>{let n=e.description?` - ${e.description}`:``;return`${t+1}. ${e.label}${n}`}),``,e.allowFreeform===!0?`Reply with a number, or with your own answer.`:`Reply with a number to choose.`].join(`
4
4
  `)}function renderInputRequest(e,t){let n=[CardText(e.prompt)];return e.options&&e.options.length>0?(n.push(Actions(e.options.map(n=>Button({id:encodeInputAction(t,e.requestId,n.id),label:n.label,style:n.style,value:n.id})))),e.allowFreeform===!0&&n.push(CardText(`Or reply with your own answer.`)),n):(n.push(CardText(FREEFORM_HINT)),n)}function encodeInputAction(e,t,n){return`${e}${encodeURIComponent(t)}:${encodeURIComponent(n)}`}function decodeInputAction(e,t,n){if(!e.startsWith(t))return null;let r=e.slice(t.length),i=r.indexOf(`:`);if(i<=0)return null;try{let e=decodeURIComponent(r.slice(0,i));return{optionId:n??decodeURIComponent(r.slice(i+1)),requestId:e}}catch{return null}}export{decodeInputAction,renderInputRequests};
@@ -1,3 +1,3 @@
1
- import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{splitDiscordMessageContent}from"#public/channels/discord/api.js";import{renderInputRequestComponents}from"#public/channels/discord/hitl.js";function defaultDiscordAuth(e){let t={channel_id:e.channelId,interaction_id:e.id,user_id:e.user.id,username:e.user.username};return e.guildId!==void 0&&(t.guild_id=e.guildId),e.member?.nick!==void 0&&(t.member_nick=e.member.nick),{attributes:t,authenticator:`discord-interaction`,issuer:e.guildId?`discord:${e.guildId}`:`discord`,principalId:e.guildId?`discord:${e.guildId}:${e.user.id}`:`discord:${e.user.id}`,principalType:e.user.isBot?`service`:`user`}}function defaultOnCommand(e,t){return{auth:defaultDiscordAuth(t)}}const defaultEvents={async"turn.started"(e,t,n){await t.discord.startTyping()},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.discord.startTyping()},async"actions.requested"(e,t,n){await t.discord.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=splitDiscordMessageContent(n.prompt)[0]??n.prompt;await t.discord.post({components:renderInputRequestComponents(n),content:e})}},async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.discord.post(e.message)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.discord.post([`This session could not recover from an error${n}.`,``,`Start a new command to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
1
+ import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{resolvedPromptLabel}from"#channel/resolved-prompt.js";import{DISCORD_MESSAGE_CONTENT_MAX_LENGTH,splitDiscordMessageContent}from"#public/channels/discord/api.js";import{renderInputRequestComponents}from"#public/channels/discord/hitl.js";const log=createLogger(`discord.defaults`);function defaultDiscordAuth(e){let t={channel_id:e.channelId,interaction_id:e.id,user_id:e.user.id,username:e.user.username};return e.guildId!==void 0&&(t.guild_id=e.guildId),e.member?.nick!==void 0&&(t.member_nick=e.member.nick),{attributes:t,authenticator:`discord-interaction`,issuer:e.guildId?`discord:${e.guildId}`:`discord`,principalId:e.guildId?`discord:${e.guildId}:${e.user.id}`:`discord:${e.user.id}`,principalType:e.user.isBot?`service`:`user`}}function defaultOnCommand(e,t){return{auth:defaultDiscordAuth(t)}}const defaultEvents={async"turn.started"(e,t,n){await t.discord.startTyping()},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.discord.startTyping()},async"actions.requested"(e,t,n){await t.discord.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=splitDiscordMessageContent(n.prompt)[0]??n.prompt,r=renderInputRequestComponents(n),i=await t.discord.post({components:r,content:e});r.length!==0&&i.id&&(t.state.hitlPrompts={...t.state.hitlPrompts,[n.requestId]:{content:e,messageId:i.id,options:(n.options??[]).map(({id:e,label:t})=>({id:e,label:t}))}})}},async"input.resolved"(e,t,n){for(let n of e.resolutions){let e=t.state.hitlPrompts?.[n.requestId];if(e===void 0)continue;let{[n.requestId]:r,...i}=t.state.hitlPrompts??{};t.state.hitlPrompts=i;let a=resolvedPromptLabel(n,e.options),o=`${e.content}\n\n${a}`.slice(0,DISCORD_MESSAGE_CONTENT_MAX_LENGTH);try{let r=await t.discord.request(`/channels/${encodeURIComponent(t.discord.channelId)}/messages/${encodeURIComponent(e.messageId)}`,{components:[],content:o},{botAuth:!0,method:`PATCH`});r.ok||log.warn(`Discord answered prompt edit failed`,{requestId:n.requestId,status:r.status})}catch(e){log.warn(`Discord answered prompt edit failed`,{error:e,requestId:n.requestId})}}},async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.discord.post(e.message)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.discord.post([`This session could not recover from an error${n}.`,``,`Start a new command to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
2
2
  `))},async"turn.failed"(e,t,n){let r=formatErrorHint(e),i=extractErrorId(e.details);await t.discord.post([`I hit an error while handling your request${r}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[``,`Error id: ${i}`]:[]].join(`
3
3
  `))}};export{defaultDiscordAuth,defaultEvents,defaultOnCommand};
@@ -8,6 +8,7 @@ import { type DiscordCommandInteraction } from "#public/channels/discord/inbound
8
8
  import { type DiscordWebhookVerifier } from "#public/channels/discord/verify.js";
9
9
  import { type JsonObject } from "#shared/json.js";
10
10
  import { type Channel } from "#public/definitions/channel.js";
11
+ import type { InputOption } from "#shared/input.js";
11
12
  import type { ChannelAudience } from "#shared/channel-audience.js";
12
13
  type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
13
14
  type: T;
@@ -42,6 +43,14 @@ export interface DiscordChannelState {
42
43
  initialResponseSent: boolean;
43
44
  /** Whether `conversationId` is a real Discord message id. */
44
45
  hasMessageAnchor: boolean;
46
+ /** Posted prompts with components, keyed by requestId, until eve resolves them. */
47
+ hitlPrompts?: Record<string, DiscordHitlPrompt>;
48
+ }
49
+ /** What a posted prompt needs so its message can be edited once eve resolves it. */
50
+ export interface DiscordHitlPrompt {
51
+ readonly content: string;
52
+ readonly messageId: string;
53
+ readonly options: readonly Pick<InputOption, "id" | "label">[];
45
54
  }
46
55
  /** Discord channel credentials. */
47
56
  export interface DiscordChannelCredentials extends DiscordCredentials {
@@ -81,6 +90,7 @@ export interface DiscordChannelEvents {
81
90
  readonly "message.completed"?: DiscordEventHandler<"message.completed">;
82
91
  readonly "message.appended"?: DiscordEventHandler<"message.appended">;
83
92
  readonly "input.requested"?: DiscordEventHandler<"input.requested">;
93
+ readonly "input.resolved"?: DiscordEventHandler<"input.resolved">;
84
94
  readonly "turn.failed"?: DiscordEventHandler<"turn.failed">;
85
95
  readonly "turn.completed"?: DiscordEventHandler<"turn.completed">;
86
96
  readonly "turn.cancelled"?: DiscordEventHandler<"turn.cancelled">;
@@ -1 +1 @@
1
- import{discordAudience,discordInstrumentationMetadata}from"./audience.js";import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/discord/verify.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{defaultEvents,defaultOnCommand}from"#public/channels/discord/defaults.js";import{DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,n={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,turnPolicy:e.turnPolicy,state:initialDiscordState(),metadata:discordInstrumentationMetadata,audience:({state:e})=>e.audience??`unknown`,context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(n,{from:r,waitUntil:i})=>{let a=await verifyDiscordInbound(n,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o;try{o=parseJsonObject(JSON.parse(a))}catch(e){return log.warn(`inbound Discord body is not valid JSON`,{error:e}),discordJson({content:`invalid request`,ephemeral:!0})}if(o.type===DISCORD_INTERACTION_TYPE.PING)return discordJson({type:DISCORD_INTERACTION_RESPONSE_TYPE.PONG});let s=parseDiscordInteraction(o);return s===null?discordJson({content:`Unsupported Discord interaction.`,ephemeral:!0}):handleInteraction({config:e,interaction:s,onCommand:t,from:r,waitUntil:i})})],async receive(t,{from:n}){let r=t.target,i=readNonEmptyString(r.channelId);if(!i)throw Error(`discordChannel().receive requires target.channelId.`);let a=readNonEmptyString(r.conversationId),o=r.initialMessage;if(o!==void 0&&a!==void 0)throw Error("discordChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let s=a??``,c=a!==void 0;if(o!==void 0){let t=await buildDiscordHandle({config:e,state:{...initialDiscordState(),channelId:i}}).sendChannelMessage(o);s=t.id,c=t.id.length>0}return n(discordContinuationToken(i,s)).send(t.message,{auth:t.auth,state:{applicationId:null,channelId:i,conversationId:s||null,guildId:null,hasMessageAnchor:c,initialResponseSent:!0,interactionToken:null}})},events:n})}function rebuildDiscordContext(e,t,n){return{discord:buildDiscordHandle({config:n,session:t,state:e}),state:e}}function buildDiscordHandle(e){let t=e.config.api,n=e.state,r=mergeCredentials(e.config.credentials,n);function anchor(t){t.id&&!n.hasMessageAnchor&&(n.conversationId=t.id,n.hasMessageAnchor=!0,n.channelId&&e.session?.continuation?.alias(discordContinuationToken(n.channelId,t.id)))}async function sendViaChannel(e){let i=n.channelId??``;if(!i)throw Error(`discordChannel: missing channel id for outbound message.`);let a=await sendDiscordChannelMessage({apiBaseUrl:t?.apiBaseUrl,body:normalizePostInput(e),credentials:r,fetch:t?.fetch,channelId:i});return anchor(a),a}async function editOriginal(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for original response edit.`);let a=await editDiscordOriginalResponse({apiBaseUrl:t?.apiBaseUrl,body:normalizePostInput(e),credentials:r,fetch:t?.fetch,interactionToken:i});return n.initialResponseSent=!0,anchor(a),a}async function followup(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for followup message.`);let a=await createDiscordFollowupMessage({apiBaseUrl:t?.apiBaseUrl,body:normalizePostInput(e),credentials:r,fetch:t?.fetch,interactionToken:i});return anchor(a),a}async function startTyping(){let e=n.channelId??``;if(e)try{await triggerDiscordTypingIndicator({apiBaseUrl:t?.apiBaseUrl,credentials:r,fetch:t?.fetch,channelId:e})}catch(t){logError(log,`Discord typing indicator failed — swallowed`,t,{channelId:e})}}return{applicationId:n.applicationId??void 0,channelId:n.channelId??``,conversationId:n.conversationId??``,guildId:n.guildId??void 0,interactionToken:n.interactionToken??void 0,request(e,n,i){return callDiscordApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:i?.botAuth===!0?r.botToken:void 0,fetch:t?.fetch,method:i?.method,path:e})},async post(e){let t=expandPostBodies(normalizePostInput(e)),r;for(let e of t){let t=await postOne({body:e,editOriginal,followup,sendViaChannel,state:n});r===void 0&&(r=t)}return r??{id:``,raw:null}},editOriginalResponse:editOriginal,followup,sendChannelMessage:sendViaChannel,startTyping}}async function postOne(e){if(e.state.interactionToken&&e.state.applicationId)try{return e.state.initialResponseSent?await e.followup(e.body):await e.editOriginal(e.body)}catch(e){log.warn(`Discord interaction-token delivery failed, falling back to channel message`,{error:e})}return e.sendViaChannel(e.body)}async function handleInteraction(e){return e.interaction.type===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?handleCommandInteraction({config:e.config,interaction:e.interaction,onCommand:e.onCommand,from:e.from,waitUntil:e.waitUntil}):e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?handleComponentInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil}):handleModalSubmitInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil})}async function handleCommandInteraction(e){let t=stateFromInteraction(e.interaction,{conversationId:e.interaction.id,hasMessageAnchor:!1,initialResponseSent:!1}),n={discord:buildDiscordHandle({config:e.config,state:t})},r;try{r=await e.onCommand(n,e.interaction)}catch(e){return log.error(`command handler failed`,{error:e}),discordJson({content:`The Discord command handler failed.`,ephemeral:!0})}return r==null?discordJson({content:`Command ignored.`,ephemeral:!0}):(e.waitUntil(dispatchCommand({interaction:e.interaction,result:r,from:e.from,state:t})),discordDeferredJson(r.ephemeral===!0))}function handleComponentInteraction(e){if(isDiscordFreeformComponent(e.interaction.customId)){let t=readMessageContent(e.interaction.raw);return discordJsonBody(buildFreeformModalResponse({customId:e.interaction.customId,prompt:t}))}let t=deriveComponentInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId,inputResponses:t,interaction:e.interaction,from:e.from})),discordJsonBody({type:DISCORD_INTERACTION_RESPONSE_TYPE.DEFERRED_UPDATE_MESSAGE})}function handleModalSubmitInteraction(e){let t=deriveModalInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId??e.interaction.id,inputResponses:t,interaction:e.interaction,from:e.from})),discordJson({content:`Answer received.`,ephemeral:!0})}async function dispatchCommand(e){let t=commandInteractionMessage(e.interaction),n=formatDiscordContextBlock({applicationId:e.interaction.applicationId,channelId:e.interaction.channelId,commandName:e.interaction.commandName,guildId:e.interaction.guildId,interactionId:e.interaction.id,userId:e.interaction.user.id,username:e.interaction.user.username}),r=e.result.context??[];try{await e.from(discordContinuationToken(e.interaction.channelId,e.interaction.id)).send(t,{auth:e.result.auth,context:[n,...r],state:e.state,title:e.result.title})}catch(e){log.error(`command delivery failed`,{error:e})}}async function dispatchInputResponses(e){try{await e.from(discordContinuationToken(e.interaction.channelId,e.conversationId)).respond(e.inputResponses,{auth:null})}catch(e){log.error(`interaction response delivery failed`,{error:e})}}function stateFromInteraction(e,t){return{audience:discordAudience(e.channelType),applicationId:e.applicationId,channelId:e.channelId,conversationId:t.conversationId,guildId:e.guildId??null,hasMessageAnchor:t.hasMessageAnchor,initialResponseSent:t.initialResponseSent,interactionToken:e.token}}function initialDiscordState(){return{applicationId:null,channelId:null,conversationId:null,guildId:null,hasMessageAnchor:!1,initialResponseSent:!1,interactionToken:null}}function mergeCredentials(e,t){return{applicationId:t.applicationId??e?.applicationId,botToken:e?.botToken??(()=>resolveDiscordBotToken()),publicKey:e?.publicKey,webhookVerifier:e?.webhookVerifier}}function normalizePostInput(e){return typeof e==`string`?{content:e}:e}function expandPostBodies(e){return typeof e.content==`string`?splitDiscordMessageContent(e.content).map((t,n)=>n===0?{...e,content:t}:{allowed_mentions:e.allowed_mentions,content:t}):[e]}export{discordChannel};
1
+ import{discordAudience,discordInstrumentationMetadata}from"./audience.js";import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/discord/verify.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{defaultEvents,defaultOnCommand}from"#public/channels/discord/defaults.js";import{DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,n={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,turnPolicy:e.turnPolicy,state:initialDiscordState(),metadata:discordInstrumentationMetadata,audience:({state:e})=>e.audience??`unknown`,context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(n,{from:r,waitUntil:i})=>{let a=await verifyDiscordInbound(n,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o;try{o=parseJsonObject(JSON.parse(a))}catch(e){return log.warn(`inbound Discord body is not valid JSON`,{error:e}),discordJson({content:`invalid request`,ephemeral:!0})}if(o.type===DISCORD_INTERACTION_TYPE.PING)return discordJson({type:DISCORD_INTERACTION_RESPONSE_TYPE.PONG});let s=parseDiscordInteraction(o);return s===null?discordJson({content:`Unsupported Discord interaction.`,ephemeral:!0}):handleInteraction({config:e,interaction:s,onCommand:t,from:r,waitUntil:i})})],async receive(t,{from:n}){let r=t.target,i=readNonEmptyString(r.channelId);if(!i)throw Error(`discordChannel().receive requires target.channelId.`);let a=readNonEmptyString(r.conversationId),o=r.initialMessage;if(o!==void 0&&a!==void 0)throw Error("discordChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let s=a??``,c=a!==void 0;if(o!==void 0){let t=await buildDiscordHandle({config:e,state:{...initialDiscordState(),channelId:i}}).sendChannelMessage(o);s=t.id,c=t.id.length>0}return n(discordContinuationToken(i,s)).send(t.message,{auth:t.auth,state:{applicationId:null,channelId:i,conversationId:s||null,guildId:null,hasMessageAnchor:c,initialResponseSent:!0,interactionToken:null}})},events:n})}function rebuildDiscordContext(e,t,n){return{discord:buildDiscordHandle({config:n,session:t,state:e}),state:e}}function buildDiscordHandle(e){let t=e.config.api,n=e.state,r=mergeCredentials(e.config.credentials,n);function anchor(t,r){t.id&&(n.hasMessageAnchor&&r.components===void 0||(n.hasMessageAnchor||=(n.conversationId=t.id,!0),n.channelId&&e.session?.continuation?.alias(discordContinuationToken(n.channelId,t.id))))}async function sendViaChannel(e){let i=n.channelId??``;if(!i)throw Error(`discordChannel: missing channel id for outbound message.`);let a=normalizePostInput(e),o=await sendDiscordChannelMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,channelId:i});return anchor(o,a),o}async function editOriginal(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for original response edit.`);let a=normalizePostInput(e),o=await editDiscordOriginalResponse({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return n.initialResponseSent=!0,anchor(o,a),o}async function followup(e){let i=n.interactionToken??``;if(!i)throw Error(`discordChannel: missing interaction token for followup message.`);let a=normalizePostInput(e),o=await createDiscordFollowupMessage({apiBaseUrl:t?.apiBaseUrl,body:a,credentials:r,fetch:t?.fetch,interactionToken:i});return anchor(o,a),o}async function startTyping(){let e=n.channelId??``;if(e)try{await triggerDiscordTypingIndicator({apiBaseUrl:t?.apiBaseUrl,credentials:r,fetch:t?.fetch,channelId:e})}catch(t){logError(log,`Discord typing indicator failed — swallowed`,t,{channelId:e})}}return{applicationId:n.applicationId??void 0,channelId:n.channelId??``,conversationId:n.conversationId??``,guildId:n.guildId??void 0,interactionToken:n.interactionToken??void 0,request(e,n,i){return callDiscordApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:i?.botAuth===!0?r.botToken:void 0,fetch:t?.fetch,method:i?.method,path:e})},async post(e){let t=expandPostBodies(normalizePostInput(e)),r;for(let e of t){let t=await postOne({body:e,editOriginal,followup,sendViaChannel,state:n});r===void 0&&(r=t)}return r??{id:``,raw:null}},editOriginalResponse:editOriginal,followup,sendChannelMessage:sendViaChannel,startTyping}}async function postOne(e){if(e.state.interactionToken&&e.state.applicationId)try{return e.state.initialResponseSent?await e.followup(e.body):await e.editOriginal(e.body)}catch(e){log.warn(`Discord interaction-token delivery failed, falling back to channel message`,{error:e})}return e.sendViaChannel(e.body)}async function handleInteraction(e){return e.interaction.type===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?handleCommandInteraction({config:e.config,interaction:e.interaction,onCommand:e.onCommand,from:e.from,waitUntil:e.waitUntil}):e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?handleComponentInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil}):handleModalSubmitInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil})}async function handleCommandInteraction(e){let t=stateFromInteraction(e.interaction,{conversationId:e.interaction.id,hasMessageAnchor:!1,initialResponseSent:!1}),n={discord:buildDiscordHandle({config:e.config,state:t})},r;try{r=await e.onCommand(n,e.interaction)}catch(e){return log.error(`command handler failed`,{error:e}),discordJson({content:`The Discord command handler failed.`,ephemeral:!0})}return r==null?discordJson({content:`Command ignored.`,ephemeral:!0}):(e.waitUntil(dispatchCommand({interaction:e.interaction,result:r,from:e.from,state:t})),discordDeferredJson(r.ephemeral===!0))}function handleComponentInteraction(e){if(isDiscordFreeformComponent(e.interaction.customId)){let t=readMessageContent(e.interaction.raw);return discordJsonBody(buildFreeformModalResponse({customId:e.interaction.customId,prompt:t}))}let t=deriveComponentInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId,inputResponses:t,interaction:e.interaction,from:e.from})),discordJsonBody({type:DISCORD_INTERACTION_RESPONSE_TYPE.DEFERRED_UPDATE_MESSAGE})}function handleModalSubmitInteraction(e){let t=deriveModalInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId??e.interaction.id,inputResponses:t,interaction:e.interaction,from:e.from})),discordJson({content:`Answer received.`,ephemeral:!0})}async function dispatchCommand(e){let t=commandInteractionMessage(e.interaction),n=formatDiscordContextBlock({applicationId:e.interaction.applicationId,channelId:e.interaction.channelId,commandName:e.interaction.commandName,guildId:e.interaction.guildId,interactionId:e.interaction.id,userId:e.interaction.user.id,username:e.interaction.user.username}),r=e.result.context??[];try{await e.from(discordContinuationToken(e.interaction.channelId,e.interaction.id)).send(t,{auth:e.result.auth,context:[n,...r],state:e.state,title:e.result.title})}catch(e){log.error(`command delivery failed`,{error:e})}}async function dispatchInputResponses(e){try{await e.from(discordContinuationToken(e.interaction.channelId,e.conversationId)).respond(e.inputResponses,{auth:null})}catch(e){log.error(`interaction response delivery failed`,{error:e})}}function stateFromInteraction(e,t){return{audience:discordAudience(e.channelType),applicationId:e.applicationId,channelId:e.channelId,conversationId:t.conversationId,guildId:e.guildId??null,hasMessageAnchor:t.hasMessageAnchor,initialResponseSent:t.initialResponseSent,interactionToken:e.token}}function initialDiscordState(){return{applicationId:null,channelId:null,conversationId:null,guildId:null,hasMessageAnchor:!1,initialResponseSent:!1,interactionToken:null}}function mergeCredentials(e,t){return{applicationId:t.applicationId??e?.applicationId,botToken:e?.botToken??(()=>resolveDiscordBotToken()),publicKey:e?.publicKey,webhookVerifier:e?.webhookVerifier}}function normalizePostInput(e){return typeof e==`string`?{content:e}:e}function expandPostBodies(e){return typeof e.content==`string`?splitDiscordMessageContent(e.content).map((t,n)=>n===0?{...e,content:t}:{allowed_mentions:e.allowed_mentions,content:t}):[e]}export{discordChannel};
@@ -1,4 +1,4 @@
1
- export { defineChannel, disableRoute, GET, HEAD, OPTIONS, POST, PUT, PATCH, DELETE, WS, type AttachSessionFn, type CancelTurnResult, type ClearSessionResult, type CompactSessionResult, type ResetSessionResult, type Channel, type ChannelAudience, type AudienceCaller, type AudienceContext, type AudienceInput, type AudiencePrincipal, type ConversationEnvironment, type ChannelFrom, type ChannelReceiveContext, type ChannelResolveSession, type ChannelRespondOptions, type ChannelSendOptions, type ChannelSource, type ChannelCors, type ChannelCorsOptions, type ChannelDefinition, type DisabledRouteSentinel, type ChannelContinuationOps, type ChannelEvents, type InferChannelMetadata, type Session, type SessionCallback, type SessionHandle, type SessionRespondOptions, type SessionSendOptions, type TurnPolicy, type RouteDefinition, type RouteHandlerArgs, type HttpRouteDefinition, type WebSocketMessage, type WebSocketPeer, type WebSocketRouteDefinition, type WebSocketRouteHandler, type WebSocketRouteHooks, type WebSocketUpgradeRequest, type WebSocketUpgradeResult, isDisabledRouteSentinel, } from "#public/definitions/channel.js";
1
+ export { defineChannel, disableRoute, GET, HEAD, OPTIONS, POST, PUT, PATCH, DELETE, WS, type AttachSessionFn, type CancelTurnResult, type ClearSessionResult, type CompactSessionResult, type ResetSessionResult, type Channel, type ChannelAudience, type AudienceCaller, type AudienceContext, type AudienceInput, type AudiencePrincipal, type ConversationEnvironment, type ChannelFrom, type ChannelReceiveContext, type ChannelResolveSession, type ChannelRespondOptions, type ChannelSendOptions, type ChannelSource, type ChannelCors, type ChannelCorsOptions, type ChannelDefinition, type DisabledRouteSentinel, type ChannelContinuationOps, type ChannelEvents, type InferChannelMetadata, type Session, type SessionCallback, type SessionHandle, type SessionRespondOptions, type SessionSendOptions, type TurnPolicy, type RouteDefinition, type RouteHandlerArgs, type AgentDescription, type AgentToolDescription, type HttpRouteDefinition, type WebSocketMessage, type WebSocketPeer, type WebSocketRouteDefinition, type WebSocketRouteHandler, type WebSocketRouteHooks, type WebSocketUpgradeRequest, type WebSocketUpgradeResult, isDisabledRouteSentinel, } from "#public/definitions/channel.js";
2
2
  export { createWebSocketUpgradeServer, type WebSocketUpgradeServerBridge, } from "#channel/websocket-upgrade-server.js";
3
3
  import type { Channel, InferChannelMetadata } from "#public/definitions/channel.js";
4
4
  /**
@@ -1,3 +1,3 @@
1
- import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{displayProperName}from"#shared/display-name.js";import{parseJsonObject}from"#shared/json.js";import{splitTeamsMessageText}from"#public/channels/teams/api.js";import{renderAnsweredInputRequestMessage,renderInputRequestMessage}from"#public/channels/teams/hitl.js";function defaultTeamsAuth(e){let t=e.tenantId,n={activity_id:e.id,conversation_id:e.conversation.id,scope:e.scope,user_id:e.from.id};e.from.name!==void 0&&(n.user_name=e.from.name),e.from.aadObjectId!==void 0&&(n.aad_object_id=e.from.aadObjectId),t!==void 0&&(n.tenant_id=t),e.teamId!==void 0&&(n.team_id=e.teamId),e.teamsChannelId!==void 0&&(n.channel_id=e.teamsChannelId);let r=t?`teams:${t}:${e.from.id}`:`teams:${e.from.id}`;return{attributes:n,authenticator:`teams-activity`,issuer:t?`teams:${t}`:`teams`,principalId:r,principalType:e.from.role===`bot`?`service`:`user`,subject:e.from.aadObjectId}}async function defaultOnMessage(e,t){return t.from.role===`bot`||t.from.id===t.recipient.id||t.scope!==`personal`&&!t.isBotMentioned?null:(await e.thread.startTyping(),{auth:defaultTeamsAuth(t)})}const defaultEvents={async"turn.started"(e,t,n){await t.thread.startTyping()},async"actions.requested"(e,t,n){await t.thread.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=await t.thread.post(renderInputRequestMessage(n,{adaptiveCardVersion:t.adaptiveCardVersion,replyToActivityId:t.teams.replyToActivityId}));n.kind===`tool-approval`&&e.id&&(t.state.pendingApprovalCards={...t.state.pendingApprovalCards,[n.requestId]:{activityId:e.id,prompt:n.prompt}})}},async"approval.settled"(e,t,n){let r=t.state.pendingApprovalCards??{},i=r[e.requestId];if(i===void 0)return;let a=t.state.approvalResponderAccounts?.[e.responderPrincipalId],o=e.outcome===`approved`?`Approved`:`Cancelled`,s=a?.name??a?.id;await t.thread.update(i.activityId,renderAnsweredInputRequestMessage({includeText:!1,label:s===void 0?o:`${o} by ${s}`,prompt:i.prompt}));let c={...r};delete c[e.requestId],t.state.pendingApprovalCards=c},async"message.completed"(e,t,n){if(e.finishReason!==`tool-calls`&&e.message)for(let n of splitTeamsMessageText(e.message))await t.thread.post(n)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.thread.post([`This session could not recover from an error${n}.`,``,`Start a new Teams conversation to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
1
+ import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{displayProperName}from"#shared/display-name.js";import{parseJsonObject}from"#shared/json.js";import{resolvedPromptAnswer}from"#channel/resolved-prompt.js";import{splitTeamsMessageText}from"#public/channels/teams/api.js";import{renderAnsweredInputRequestMessage,renderInputRequestMessage}from"#public/channels/teams/hitl.js";function defaultTeamsAuth(e){let t=e.tenantId,n={activity_id:e.id,conversation_id:e.conversation.id,scope:e.scope,user_id:e.from.id};e.from.name!==void 0&&(n.user_name=e.from.name),e.from.aadObjectId!==void 0&&(n.aad_object_id=e.from.aadObjectId),t!==void 0&&(n.tenant_id=t),e.teamId!==void 0&&(n.team_id=e.teamId),e.teamsChannelId!==void 0&&(n.channel_id=e.teamsChannelId);let r=t?`teams:${t}:${e.from.id}`:`teams:${e.from.id}`;return{attributes:n,authenticator:`teams-activity`,issuer:t?`teams:${t}`:`teams`,principalId:r,principalType:e.from.role===`bot`?`service`:`user`,subject:e.from.aadObjectId}}async function defaultOnMessage(e,t){return t.from.role===`bot`||t.from.id===t.recipient.id||t.scope!==`personal`&&!t.isBotMentioned?null:(await e.thread.startTyping(),{auth:defaultTeamsAuth(t)})}const defaultEvents={async"turn.started"(e,t,n){await t.thread.startTyping()},async"actions.requested"(e,t,n){await t.thread.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=await t.thread.post(renderInputRequestMessage(n,{adaptiveCardVersion:t.adaptiveCardVersion,replyToActivityId:t.teams.replyToActivityId}));if(!e.id)continue;let r={activityId:e.id,prompt:n.prompt};t.state.pendingPromptCards={...t.state.pendingPromptCards,[n.requestId]:n.kind===`question`?{...r,options:(n.options??[]).map(({id:e,label:t})=>({id:e,label:t}))}:r}}},async"approval.settled"(e,t,n){let r=t.state.pendingPromptCards??{},i=r[e.requestId];if(i===void 0)return;let a=t.state.approvalResponderAccounts?.[e.responderPrincipalId],o=e.outcome===`approved`?`Approved`:`Cancelled`,s=a?.name??a?.id;await t.thread.update(i.activityId,renderAnsweredInputRequestMessage({includeText:!1,label:s===void 0?o:`${o} by ${s}`,prompt:i.prompt}));let c={...r};delete c[e.requestId],t.state.pendingPromptCards=c},async"input.resolved"(e,t,n){for(let n of e.resolutions){let e=t.state.pendingPromptCards??{},r=e[n.requestId];if(r===void 0)continue;await t.thread.update(r.activityId,renderAnsweredInputRequestMessage({includeText:!1,label:resolvedPromptAnswer(n,r.options),prompt:r.prompt}));let{[n.requestId]:i,...a}=e;t.state.pendingPromptCards=a}},async"message.completed"(e,t,n){if(e.finishReason!==`tool-calls`&&e.message)for(let n of splitTeamsMessageText(e.message))await t.thread.post(n)},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.thread.post([`This session could not recover from an error${n}.`,``,`Start a new Teams conversation to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
2
2
  `))},async"turn.failed"(e,t,n){let r=formatErrorHint(e),i=extractErrorId(e.details);await t.thread.post([`I hit an error while handling your request${r}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[``,`Error id: ${i}`]:[]].join(`
3
3
  `))},async"authorization.required"(e,t,n){let r=e.authorization?.displayName??formatConnectionDisplayName(e.name),i=e.authorization?.url,a=i?`Authorization required for ${r}: ${i}`:`Authorization required for ${r}.`,o=await t.thread.post({attachments:[{content:parseJsonObject({$schema:`http://adaptivecards.io/schemas/adaptive-card.json`,actions:i?[{title:`Sign in with ${r}`,type:`Action.OpenUrl`,url:i}]:[],body:[{text:`Authorization required for ${r}`,type:`TextBlock`,weight:`Bolder`,wrap:!0},{text:t.state.triggeringUser?`Requested by ${t.state.triggeringUser.name??t.state.triggeringUser.id}.`:`No triggering user is available for a private prompt.`,type:`TextBlock`,wrap:!0}],type:`AdaptiveCard`,version:t.adaptiveCardVersion}),contentType:`application/vnd.microsoft.card.adaptive`}],text:a});o.id&&(t.state.pendingAuthActivityId=o.id)},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.thread.startTyping();let r=t.state.pendingAuthActivityId;if(!r)return;let i=buildAuthCompletedText({displayName:e.authorization?.displayName??formatConnectionDisplayName(e.name),outcome:e.outcome,reason:e.reason});await t.thread.update(r,renderAnsweredInputRequestMessage({prompt:i})),t.state.pendingAuthActivityId=null}};function formatConnectionDisplayName(e){return displayProperName(e)}function buildAuthCompletedText(e){if(e.outcome===`authorized`)return`${e.displayName} connected.`;let t=e.reason===void 0?``:` (${e.reason})`;return`${e.displayName} authorization ${e.outcome}${t}.`}function teamsMentionUser(e){let t=e.name??e.id;return{mentioned:{id:e.id,name:e.name},text:`<at>${t}</at>`,type:`mention`}}export{buildAuthCompletedText,defaultEvents,defaultOnMessage,defaultTeamsAuth,formatConnectionDisplayName,teamsMentionUser};
@@ -9,6 +9,7 @@ import { type TeamsInvokeActivity, type TeamsMessageActivity } from "#public/cha
9
9
  import { type TeamsWebhookVerifier } from "#public/channels/teams/verify.js";
10
10
  import { type JsonObject } from "#shared/json.js";
11
11
  import { type Channel } from "#public/definitions/channel.js";
12
+ import type { InputOption } from "#shared/input.js";
12
13
  type EventData<T extends UnstampedMessageStreamEvent["type"]> = Extract<UnstampedMessageStreamEvent, {
13
14
  type: T;
14
15
  }> extends {
@@ -32,11 +33,14 @@ interface TeamsChannelContext extends TeamsContext {
32
33
  /** Event-handler Teams context, including continuation routing. */
33
34
  export interface TeamsEventContext extends TeamsChannelContext, ChannelContinuationOps {
34
35
  }
35
- /** JSON-serializable Teams channel state. */
36
- export interface TeamsPendingApprovalCard {
36
+ /** A posted question or approval card, kept until eve resolves its request. */
37
+ export interface TeamsPendingPromptCard {
37
38
  readonly activityId: string;
39
+ /** A question's options, so its card can show the chosen label. */
40
+ readonly options?: readonly Pick<InputOption, "id" | "label">[];
38
41
  readonly prompt: string;
39
42
  }
43
+ /** JSON-serializable Teams channel state. */
40
44
  export interface TeamsChannelState {
41
45
  /** Bot account captured from the inbound activity recipient. */
42
46
  bot: TeamsChannelAccount | null;
@@ -53,7 +57,7 @@ export interface TeamsChannelState {
53
57
  triggeringUser: TeamsChannelAccount | null;
54
58
  /** Activity id for the default connection-auth card, when posted. */
55
59
  pendingAuthActivityId?: string | null;
56
- pendingApprovalCards?: Record<string, TeamsPendingApprovalCard>;
60
+ pendingPromptCards?: Record<string, TeamsPendingPromptCard>;
57
61
  approvalResponderAccounts?: Record<string, TeamsChannelAccount>;
58
62
  }
59
63
  /** Teams channel credentials. */
@@ -106,6 +110,7 @@ type TeamsSessionFailedHandler = (data: EventData<"session.failed">, channel: Te
106
110
  export interface TeamsChannelEvents {
107
111
  readonly "approval.candidate"?: TeamsEventHandler<"approval.candidate">;
108
112
  readonly "approval.settled"?: TeamsEventHandler<"approval.settled">;
113
+ readonly "input.resolved"?: TeamsEventHandler<"input.resolved">;
109
114
  readonly "turn.started"?: TeamsEventHandler<"turn.started">;
110
115
  readonly "actions.requested"?: TeamsEventHandler<"actions.requested">;
111
116
  readonly "action.partial"?: TeamsEventHandler<"action.partial">;