eve 0.27.8 → 0.27.9

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 (89) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/cli/commands/registry.d.ts +5 -1
  3. package/dist/src/cli/commands/registry.js +1 -1
  4. package/dist/src/cli/commands/trace.d.ts +32 -0
  5. package/dist/src/cli/commands/trace.js +6 -0
  6. package/dist/src/cli/run.js +2 -1
  7. package/dist/src/compiled/.vendor-stamp.json +3 -1
  8. package/dist/src/compiled/@ai-sdk/otel/index.js +3 -3
  9. package/dist/src/compiled/@opentelemetry/api/index.d.ts +23 -5
  10. package/dist/src/compiled/@opentelemetry/otlp-transformer/LICENSE +201 -0
  11. package/dist/src/compiled/@opentelemetry/otlp-transformer/index.d.ts +3 -0
  12. package/dist/src/compiled/@opentelemetry/otlp-transformer/index.js +1 -0
  13. package/dist/src/compiled/@vercel/otel/LICENSE +21 -0
  14. package/dist/src/compiled/@vercel/otel/index.d.ts +16 -0
  15. package/dist/src/compiled/@vercel/otel/index.js +17 -0
  16. package/dist/src/compiled/@workflow/world-vercel/index.js +7 -7
  17. package/dist/src/compiled/_chunks/workflow/chunk-5MU5Z6L3-BYQ2wtp-.js +1 -0
  18. package/dist/src/compiled/_chunks/workflow/chunk-NWCAEW5Y-Dp6gZq6P.js +1 -0
  19. package/dist/src/compiled/_chunks/workflow/getMachineId-bsd-WEBNKY2R-Cls8BaDr.js +1 -0
  20. package/dist/src/compiled/_chunks/workflow/getMachineId-darwin-LT47KAXP-Bpw5H-nL.js +2 -0
  21. package/dist/src/compiled/_chunks/workflow/getMachineId-linux-LTVQO6VW-CpqQTfzr.js +1 -0
  22. package/dist/src/compiled/_chunks/workflow/getMachineId-unsupported-UKWBA27G-2_M88Nra.js +1 -0
  23. package/dist/src/compiled/_chunks/workflow/getMachineId-win-NLJKOPY6-D0EDY-ev.js +1 -0
  24. package/dist/src/compiler/extension-compatibility.d.ts +4 -4
  25. package/dist/src/compiler/extension-compatibility.js +1 -1
  26. package/dist/src/execution/node-step.js +1 -1
  27. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  28. package/dist/src/execution/turn-workflow.js +1 -1
  29. package/dist/src/execution/web-fetch/request.d.ts +14 -0
  30. package/dist/src/execution/web-fetch/request.js +1 -0
  31. package/dist/src/execution/web-fetch/tool.js +1 -1
  32. package/dist/src/execution/workflow-steps.js +1 -1
  33. package/dist/src/harness/agent-otel-provider.d.ts +49 -0
  34. package/dist/src/harness/agent-otel-provider.js +1 -0
  35. package/dist/src/harness/agent-trace-context-store.d.ts +12 -0
  36. package/dist/src/harness/agent-trace-context-store.js +1 -0
  37. package/dist/src/harness/agent-trace-span-processor.d.ts +12 -0
  38. package/dist/src/harness/agent-trace-span-processor.js +1 -0
  39. package/dist/src/harness/ai-sdk-hook-bridge.d.ts +4 -0
  40. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -0
  41. package/dist/src/harness/compaction-prompt.d.ts +7 -0
  42. package/dist/src/harness/compaction-prompt.js +1 -1
  43. package/dist/src/harness/compaction.js +1 -1
  44. package/dist/src/harness/instrumentation-lifecycle.d.ts +142 -0
  45. package/dist/src/harness/instrumentation-lifecycle.js +1 -0
  46. package/dist/src/harness/instrumentation-native-events.d.ts +12 -0
  47. package/dist/src/harness/instrumentation-native-events.js +1 -0
  48. package/dist/src/harness/instrumentation-runtime.d.ts +13 -0
  49. package/dist/src/harness/instrumentation-runtime.js +1 -0
  50. package/dist/src/harness/local-instrumentation-runtime.d.ts +7 -0
  51. package/dist/src/harness/local-instrumentation-runtime.js +1 -0
  52. package/dist/src/harness/local-trace-span-processor.d.ts +10 -0
  53. package/dist/src/harness/local-trace-span-processor.js +1 -0
  54. package/dist/src/harness/otel-integration.d.ts +3 -0
  55. package/dist/src/harness/otel-integration.js +1 -1
  56. package/dist/src/harness/tool-loop.js +2 -2
  57. package/dist/src/harness/tool-model-output.d.ts +40 -0
  58. package/dist/src/harness/tool-model-output.js +1 -0
  59. package/dist/src/harness/tools.js +1 -1
  60. package/dist/src/harness/types.d.ts +6 -0
  61. package/dist/src/internal/application/package.js +1 -1
  62. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  63. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.d.ts +1 -0
  64. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -0
  65. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  66. package/dist/src/public/definitions/tool.d.ts +1 -1
  67. package/dist/src/public/tools/index.d.ts +2 -1
  68. package/dist/src/public/tools/index.js +1 -1
  69. package/dist/src/public/tools/output-builders.d.ts +53 -0
  70. package/dist/src/public/tools/output-builders.js +1 -0
  71. package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
  72. package/dist/src/setup/scaffold/channels-catalog.d.ts +2 -0
  73. package/dist/src/setup/scaffold/channels-catalog.js +1 -1
  74. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  75. package/dist/src/setup/scaffold/create/project.js +2 -2
  76. package/dist/src/setup/scaffold/update/channels.js +1 -1
  77. package/dist/src/shared/network-address.d.ts +6 -0
  78. package/dist/src/shared/network-address.js +1 -1
  79. package/dist/src/shared/tool-definition.d.ts +29 -0
  80. package/docs/channels/overview.mdx +2 -2
  81. package/docs/connections/overview.mdx +1 -1
  82. package/docs/extensions.md +1 -0
  83. package/docs/guides/instrumentation.md +17 -7
  84. package/docs/guides/state.md +1 -1
  85. package/docs/install-integrations.mdx +3 -1
  86. package/docs/patterns/multi-tenant-memory.md +1 -1
  87. package/docs/reference/cli.md +14 -1
  88. package/docs/tools/overview.mdx +29 -0
  89. package/package.json +8 -4
@@ -1,2 +1,2 @@
1
- import{z}from"#compiled/zod/index.js";import{executeWebFetchTool}from"#execution/web-fetch/tool.js";async function executeWebFetch(e,t){return executeWebFetchTool(e,{abortSignal:t?.abortSignal})}const WEB_FETCH_INPUT_SCHEMA=z.strictObject({format:z.enum([`markdown`,`text`,`html`]).describe(`The format to return the content in (text, markdown, or html). HTML responses are automatically converted to the requested format. Defaults to "markdown".`).optional(),timeout:z.number().describe(`Optional timeout in seconds. Defaults to 30, max 120.`).optional(),url:z.string().describe(`The fully-formed URL to fetch content from. Must start with http:// or https://.`)}),WEB_FETCH_OUTPUT_SCHEMA=z.strictObject({content:z.string(),contentType:z.string(),truncated:z.boolean(),url:z.string()}),WEB_FETCH_TOOL_DEFINITION={description:[`Fetch a webpage and return its content in the requested format. Use this to retrieve and analyze content from URLs.`,``,`Usage notes:`,`- The URL must be a fully-formed valid URL starting with http:// or https://`,`- HTML responses are automatically converted to markdown or plain text based on the requested format`,`- Format options: "markdown" (default), "text", or "html"`,`- Default timeout is 30 seconds (max 120 seconds)`,`- Maximum response size is 5 MB; content is further capped at the shared tool-output budget (50 KB / 2000 lines)`,`- This tool is read-only and does not modify any files`].join(`
1
+ import{z}from"#compiled/zod/index.js";import{executeWebFetchTool}from"#execution/web-fetch/tool.js";async function executeWebFetch(e,t){return executeWebFetchTool(e,{abortSignal:t?.abortSignal})}const WEB_FETCH_INPUT_SCHEMA=z.strictObject({format:z.enum([`markdown`,`text`,`html`]).describe(`The format to return the content in (text, markdown, or html). HTML responses are automatically converted to the requested format. Defaults to "markdown".`).optional(),timeout:z.number().describe(`Optional timeout in seconds. Defaults to 30, max 120.`).optional(),url:z.string().describe(`The fully-formed URL to fetch content from. Must start with https://.`)}),WEB_FETCH_OUTPUT_SCHEMA=z.strictObject({content:z.string(),contentType:z.string(),truncated:z.boolean(),url:z.string()}),WEB_FETCH_TOOL_DEFINITION={description:[`Fetch a webpage and return its content in the requested format. Use this to retrieve and analyze content from URLs.`,``,`Usage notes:`,`- The URL must be a fully-formed valid URL starting with https://`,`- HTML responses are automatically converted to markdown or plain text based on the requested format`,`- Format options: "markdown" (default), "text", or "html"`,`- Default timeout is 30 seconds (max 120 seconds)`,`- Maximum response size is 5 MB; content is further capped at the shared tool-output budget (50 KB / 2000 lines)`,`- This tool is read-only and does not modify any files`].join(`
2
2
  `),execute:executeWebFetch,inputSchema:WEB_FETCH_INPUT_SCHEMA,logicalPath:`eve:framework/web-fetch`,name:`web_fetch`,outputSchema:WEB_FETCH_OUTPUT_SCHEMA,sourceId:`eve:web-fetch-tool`,sourceKind:`module`};export{WEB_FETCH_INPUT_SCHEMA,WEB_FETCH_OUTPUT_SCHEMA,WEB_FETCH_TOOL_DEFINITION};
@@ -16,6 +16,8 @@ export interface ScaffoldableChannel {
16
16
  slug: string;
17
17
  /** Internal scaffolder kind passed to `ensureChannel`. */
18
18
  kind: ChannelKind;
19
+ /** Canonical item in the official eve registry. */
20
+ registryItem: `channel/${ChannelKind}`;
19
21
  /** Picker label. */
20
22
  label: string;
21
23
  /** Optional picker hint. */
@@ -1 +1 @@
1
- import{channelEntries}from"../../packages/eve-catalog/src/index.js";const CHANNEL_SCAFFOLDS=[{slug:`eve`,kind:`web`,label:`Web Chat`,hint:`Next.js app`},{slug:`slack`,kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`}];function buildScaffoldableChannels(){let n=new Set(channelEntries().filter(e=>e.surfaces.scaffoldable).map(e=>e.slug)),r=[];for(let e of CHANNEL_SCAFFOLDS){if(!n.delete(e.slug))throw Error(`Channel overlay "${e.slug}" is not a scaffoldable channel in @vercel/eve-catalog.`);let t={slug:e.slug,kind:e.kind,label:e.label};e.hint!==void 0&&(t.hint=e.hint),r.push(t)}if(n.size>0){let e=[...n].sort().join(`, `);throw Error(`Scaffoldable catalog channels missing a scaffolder overlay: ${e}.`)}return r}const SCAFFOLDABLE_CHANNELS=buildScaffoldableChannels();export{SCAFFOLDABLE_CHANNELS};
1
+ import{channelEntries}from"../../packages/eve-catalog/src/index.js";const CHANNEL_SCAFFOLDS=[{slug:`eve`,kind:`web`,registryItem:`channel/web`,label:`Web Chat`,hint:`Next.js app`},{slug:`slack`,kind:`slack`,registryItem:`channel/slack`,label:`Slack`,hint:`Slack app mentions and DMs`}];function buildScaffoldableChannels(){let n=new Set(channelEntries().filter(e=>e.surfaces.scaffoldable).map(e=>e.slug)),r=[];for(let e of CHANNEL_SCAFFOLDS){if(!n.delete(e.slug))throw Error(`Channel overlay "${e.slug}" is not a scaffoldable channel in @vercel/eve-catalog.`);let t={slug:e.slug,kind:e.kind,registryItem:e.registryItem,label:e.label};e.hint!==void 0&&(t.hint=e.hint),r.push(t)}if(n.size>0){let e=[...n].sort().join(`, `);throw Error(`Scaffoldable catalog channels missing a scaffolder overlay: ${e}.`)}return r}const SCAFFOLDABLE_CHANNELS=buildScaffoldableChannels();export{SCAFFOLDABLE_CHANNELS};
@@ -1 +1 @@
1
- import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.34`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.2`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
1
+ import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.38`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.2`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.34`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.27.8`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.27.9`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -93,4 +93,4 @@ export default defineAgent({
93
93
  },
94
94
  },
95
95
  });
96
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let s=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??s),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let g={appName:basename(s),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.34`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,g),{force:c&&l}),o&&await t.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
96
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let s=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??s),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let g={appName:basename(s),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.38`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,g),{force:c&&l}),o&&await t.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -1,4 +1,4 @@
1
- import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.34`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c){let d=join(e,`package.json`);if(!await pathExists(d))return{mutations:[]};let p=resolveEvePackageContract(a.evePackage),h=pinnedNodeEngineMajor(p.nodeEngine),g={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(p.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},_={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":h,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},v=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,y=isPackageManagerWorkspaceMember(n,r),b={dependencies:g,devDependencies:_,scripts:v};y||(b.nodeEngineRequirement=p.nodeEngine);let x=await patchPackageJson(d,b),S=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:g.ai,nodeEngineRequirement:p.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??x.nodeEngineOverride;return{mutations:[{path:d,dependencies:Object.keys(g),devDependencies:Object.keys(_),scripts:Object.keys(v)}],nodeEngineOverride:S}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
1
+ import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.38`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c){let d=join(e,`package.json`);if(!await pathExists(d))return{mutations:[]};let p=resolveEvePackageContract(a.evePackage),h=pinnedNodeEngineMajor(p.nodeEngine),g={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(p.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},_={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":h,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},v=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,y=isPackageManagerWorkspaceMember(n,r),b={dependencies:g,devDependencies:_,scripts:v};y||(b.nodeEngineRequirement=p.nodeEngine);let x=await patchPackageJson(d,b),S=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:g.ai,nodeEngineRequirement:p.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??x.nodeEngineOverride;return{mutations:[{path:d,dependencies:Object.keys(g),devDependencies:Object.keys(_),scripts:Object.keys(v)}],nodeEngineOverride:S}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
2
2
  import { slackChannel } from "eve/channels/slack";
3
3
 
4
4
  export default slackChannel({
@@ -21,3 +21,9 @@ export declare function isLoopbackServerUrl(urlText: string): boolean;
21
21
  * hostname that resolves to a private address is not caught at this layer.
22
22
  */
23
23
  export declare function isReservedIpAddress(host: string): boolean;
24
+ /**
25
+ * Whether `host` is an IP literal that must not be used as the destination of
26
+ * an untrusted outbound request. Unlike {@link isReservedIpAddress}, this also
27
+ * blocks loopback addresses.
28
+ */
29
+ export declare function isPrivateOrReservedIpAddress(host: string): boolean;
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{BlockList,isIP}from"node:net";const httpServerUrlSchema=z.url({protocol:/^https?$/}),reservedRanges=new BlockList;reservedRanges.addSubnet(`0.0.0.0`,8,`ipv4`),reservedRanges.addSubnet(`10.0.0.0`,8,`ipv4`),reservedRanges.addSubnet(`100.64.0.0`,10,`ipv4`),reservedRanges.addSubnet(`169.254.0.0`,16,`ipv4`),reservedRanges.addSubnet(`172.16.0.0`,12,`ipv4`),reservedRanges.addSubnet(`192.168.0.0`,16,`ipv4`),reservedRanges.addSubnet(`198.18.0.0`,15,`ipv4`),reservedRanges.addAddress(`::`,`ipv6`),reservedRanges.addSubnet(`fc00::`,7,`ipv6`),reservedRanges.addSubnet(`fe80::`,10,`ipv6`);function normalizeAddress(e){let t=e.trim().replace(/^\[(.*)\]$/u,`$1`),n=t.indexOf(`%`),r=n===-1?t:t.slice(0,n);if(r.toLowerCase().startsWith(`::ffff:`)){let e=r.slice(7);if(isIP(e)===4)return e}return r}function isLoopbackHostname(e){let t=normalizeAddress(e).toLowerCase();if(t===`localhost`||t.endsWith(`.localhost`))return!0;let n=isIP(t);return n===4?t.startsWith(`127.`):n===6&&t===`::1`}function isLoopbackServerUrl(e){let t=httpServerUrlSchema.safeParse(e);return t.success&&isLoopbackHostname(new URL(t.data).hostname)}function isReservedIpAddress(e){let t=normalizeAddress(e),n=isIP(t);return n===0?!1:reservedRanges.check(t,n===4?`ipv4`:`ipv6`)}export{httpServerUrlSchema,isLoopbackHostname,isLoopbackServerUrl,isReservedIpAddress};
1
+ import{z}from"#compiled/zod/index.js";import{BlockList,isIP}from"node:net";const httpServerUrlSchema=z.url({protocol:/^https?$/}),reservedRanges=new BlockList;reservedRanges.addSubnet(`0.0.0.0`,8,`ipv4`),reservedRanges.addSubnet(`10.0.0.0`,8,`ipv4`),reservedRanges.addSubnet(`100.64.0.0`,10,`ipv4`),reservedRanges.addSubnet(`169.254.0.0`,16,`ipv4`),reservedRanges.addSubnet(`172.16.0.0`,12,`ipv4`),reservedRanges.addSubnet(`192.0.0.0`,24,`ipv4`),reservedRanges.addSubnet(`192.0.2.0`,24,`ipv4`),reservedRanges.addSubnet(`192.88.99.0`,24,`ipv4`),reservedRanges.addSubnet(`192.168.0.0`,16,`ipv4`),reservedRanges.addSubnet(`198.18.0.0`,15,`ipv4`),reservedRanges.addSubnet(`198.51.100.0`,24,`ipv4`),reservedRanges.addSubnet(`203.0.113.0`,24,`ipv4`),reservedRanges.addSubnet(`224.0.0.0`,4,`ipv4`),reservedRanges.addSubnet(`240.0.0.0`,4,`ipv4`),reservedRanges.addAddress(`::`,`ipv6`),reservedRanges.addSubnet(`::`,96,`ipv6`),reservedRanges.addSubnet(`64:ff9b::`,96,`ipv6`),reservedRanges.addSubnet(`64:ff9b:1::`,48,`ipv6`),reservedRanges.addSubnet(`100::`,64,`ipv6`),reservedRanges.addSubnet(`2001::`,23,`ipv6`),reservedRanges.addSubnet(`2001:db8::`,32,`ipv6`),reservedRanges.addSubnet(`2002::`,16,`ipv6`),reservedRanges.addSubnet(`fc00::`,7,`ipv6`),reservedRanges.addSubnet(`fe80::`,10,`ipv6`),reservedRanges.addSubnet(`ff00::`,8,`ipv6`);const loopbackRanges=new BlockList;loopbackRanges.addSubnet(`127.0.0.0`,8,`ipv4`),loopbackRanges.addAddress(`::1`,`ipv6`);function normalizeAddress(e){let t=e.trim().replace(/^\[(.*)\]$/u,`$1`),n=t.indexOf(`%`),r=n===-1?t:t.slice(0,n);if(r.toLowerCase().startsWith(`::ffff:`)){let e=r.slice(7);if(isIP(e)===4)return e}return r}function isLoopbackHostname(e){let t=normalizeAddress(e).toLowerCase().replace(/\.$/u,``);if(t===`localhost`||t.endsWith(`.localhost`))return!0;let n=isIP(t);return n!==0&&loopbackRanges.check(t,n===4?`ipv4`:`ipv6`)}function isLoopbackServerUrl(e){let t=httpServerUrlSchema.safeParse(e);return t.success&&isLoopbackHostname(new URL(t.data).hostname)}function isReservedIpAddress(e){let t=normalizeAddress(e);if(isLoopbackHostname(t))return!1;let n=isIP(t);return n===0?!1:reservedRanges.check(t,n===4?`ipv4`:`ipv6`)}function isPrivateOrReservedIpAddress(e){return isLoopbackHostname(e)||isReservedIpAddress(e)}export{httpServerUrlSchema,isLoopbackHostname,isLoopbackServerUrl,isPrivateOrReservedIpAddress,isReservedIpAddress};
@@ -46,6 +46,10 @@ export interface PublicToolDefinitionWithExecuteFn<TInput = unknown, TOutput = u
46
46
  * eve-owned shape for the model-facing tool result produced by
47
47
  * `toModelOutput`. Structurally compatible with the AI SDK's
48
48
  * `ToolResultOutput` so the harness can forward it without conversion.
49
+ *
50
+ * The `content` variant carries an ordered list of
51
+ * {@link ToolModelOutputPart} entries, letting a tool hand the model
52
+ * text alongside inline files (e.g. a screenshot as vision input).
49
53
  */
50
54
  export type ToolModelOutput = {
51
55
  readonly type: "text";
@@ -53,5 +57,30 @@ export type ToolModelOutput = {
53
57
  } | {
54
58
  readonly type: "json";
55
59
  readonly value: unknown;
60
+ } | {
61
+ readonly type: "content";
62
+ readonly value: readonly ToolModelOutputPart[];
63
+ };
64
+ /**
65
+ * One part of a `content` {@link ToolModelOutput}. Mirrors the AI SDK's
66
+ * `ToolResultOutput` content parts narrowed to the JSON-safe subset:
67
+ * file data is the SDK's tagged `FileData` union restricted to
68
+ * `{ type: "data" }` with a base64 string, so persisted tool results
69
+ * survive the durable JSON boundary. Use the `toolOutputPart` builders
70
+ * from `eve/tools` to construct parts without hand-writing the nesting.
71
+ */
72
+ export type ToolModelOutputPart = {
73
+ readonly type: "text";
74
+ readonly text: string;
75
+ } | {
76
+ readonly type: "file";
77
+ /** Tagged file data; only JSON-safe base64 payloads are accepted. */
78
+ readonly data: {
79
+ readonly type: "data";
80
+ readonly data: string;
81
+ };
82
+ /** IANA media type, e.g. `image/png`. */
83
+ readonly mediaType: string;
84
+ readonly filename?: string;
56
85
  };
57
86
  export {};
@@ -9,7 +9,7 @@ A channel is the edge adapter between a platform and your agent. It does three t
9
9
  - Owns the `continuationToken`, the resume handle for a conversation on that surface.
10
10
  - Decides delivery, meaning how, where, and whether a response goes back.
11
11
 
12
- eve ships a base HTTP channel plus first-class platform channels, and you can author your own. Browse the full set in the [Integrations](/integrations) gallery.
12
+ eve ships a base HTTP channel plus first-class platform channels, and you can author your own. Browse the full set in the [Integrations](/integrations?filter=channel) gallery.
13
13
 
14
14
  After a channel normalizes input, eve runs the same agent runtime regardless of where the message came from. Tools and instructions do not need channel-specific logic.
15
15
 
@@ -70,4 +70,4 @@ Where an eve agent communicates with people, you may be required to disclose tha
70
70
  - [Slack](./slack): the most common platform channel, end to end
71
71
  - [Custom channels](./custom): build a channel for any surface with `defineChannel`
72
72
  - [Frontend](../guides/frontend/overview): browser chat on the eve channel with `useEveAgent`
73
- - [Integrations](/integrations): browse every built-in channel and connection in one gallery
73
+ - [Integrations](/integrations?filter=channel): browse every built-in channel in one gallery
@@ -274,6 +274,6 @@ A tool can require both sign-in (`auth`) and a human approval. The model's appro
274
274
 
275
275
  - [MCP connections](/docs/connections/mcp): connect to remote MCP servers.
276
276
  - [OpenAPI connections](/docs/connections/openapi): generate tools from OpenAPI operations.
277
- - [Integrations](/integrations): browse every channel and connection eve ships, in one gallery.
277
+ - [Integrations](/integrations?filter=connection): browse every connection eve ships, in one gallery.
278
278
  - [Tools](/docs/tools): authored tools live alongside connection-provided tools; the same approval helpers apply.
279
279
  - [Security model](/docs/concepts/security-model): how connection credentials stay out of the model's reach.
@@ -321,6 +321,7 @@ At build time, eve checks the extension's generated capability metadata. If the
321
321
 
322
322
  ## What to read next
323
323
 
324
+ - [Extension integrations](/integrations?filter=extension): browse ready-to-install extensions
324
325
  - [Tools](/docs/tools): static tools, approval, and tool output
325
326
  - [Dynamic capabilities](/docs/guides/dynamic-capabilities): dynamic tools, skills, and instructions
326
327
  - [Instructions](/docs/instructions): static and TypeScript instructions
@@ -7,15 +7,25 @@ description: "Trace an agent with OpenTelemetry in instrumentation.ts, read the
7
7
 
8
8
  If you intend to export telemetry, review the exporter destination, data categories, and required legal approvals before enabling telemetry.
9
9
 
10
+ ## Zero-config local traces
11
+
12
+ When no authored `instrumentation.ts` exists, `eve dev` records agent, AI SDK, and user-created OpenTelemetry spans under `.eve/traces/v1`. Each session has one trace, rooted independently from Workflow telemetry, with turns, model steps, and tool actions represented explicitly. Spans created by application code while a model or tool is executing inherit that active agent context.
13
+
14
+ The directory is an immutable OTLP/JSON spool and remains available after `eve dev` exits. Inspection tools may build a query index from these segments, but the index is derived and can be rebuilt without changing the captured trace data.
15
+
16
+ Use `eve trace ls` to list captured traces and `eve trace <trace>` to inspect a session's span tree.
17
+
18
+ The local writer is an internal development default, not a second provider layered over authored instrumentation. When `instrumentation.ts` exists, its setup retains control and the zero-config writer is not installed.
19
+
10
20
  ## Three observability surfaces
11
21
 
12
22
  eve observes an agent through three distinct surfaces. They do not all live in this file, and they write to different places:
13
23
 
14
- | Surface | Configured in `instrumentation.ts`? | What it is |
15
- | -------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
- | **Workflow run tags** (`$eve.*`) | No (automatic) | Framework-owned attributes on each Vercel Workflow run. Let dashboards stitch session, turn, and subagent runs into a tree and surface model and token usage. |
17
- | **OpenTelemetry export** | Yes: `setup`, `recordInputs`, `recordOutputs`, `functionId` | Where AI SDK spans are exported and what they record. |
18
- | **Runtime context events** | Yes: `events["step.started"]` | Per-model-call values written into the AI SDK's runtime context, which the AI SDK carries onto its spans. |
24
+ | Surface | Configured in `instrumentation.ts`? | What it is |
25
+ | -------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
+ | **Workflow run tags** (`$eve.*`) | No (automatic) | Framework-owned attributes on each Vercel Workflow run. Let dashboards stitch session, turn, and subagent runs into a tree and surface model and token usage. |
27
+ | **OpenTelemetry export** | Local: automatic. Authored: `setup` and capture settings | Where agent and AI spans are exported and what they record. |
28
+ | **Runtime context events** | Yes: `events["step.started"]` | Per-model-call values written into the AI SDK's runtime context, which the AI SDK carries onto its spans. |
19
29
 
20
30
  The two configurable surfaces send AI SDK spans to your OpenTelemetry backend. Workflow run tags are a separate system, queryable in the Workflow dashboard rather than on your OTel spans. The sections below cover what you configure here; [Workflow run tags](#workflow-run-tags) documents what eve emits on its own.
21
31
 
@@ -98,9 +108,9 @@ A channel exposes its identity through `kind`. For authored channels it is `chan
98
108
 
99
109
  Channel metadata is channel-owned. Built-in channels expose only the fields they choose to make observable; Slack, for example, projects `channelId`, `teamId`, `threadTs`, and `triggeringUserId` from its durable channel state. User-authored channels expose their own projection by returning `metadata(state)` from `defineChannel`. Runtime instrumentation never falls back to raw channel state.
100
110
 
101
- ## Trace hierarchy
111
+ ## Authored trace hierarchy
102
112
 
103
- When telemetry is enabled, each turn produces a trace like:
113
+ The existing authored `instrumentation.ts` path remains separate from zero-config local traces. When authored telemetry is enabled, each turn currently produces a trace like:
104
114
 
105
115
  ```text
106
116
  ai.eve.turn {eve.session.id}
@@ -69,7 +69,7 @@ Every [subagent](../subagents) starts with its own fresh state, whether it's a b
69
69
 
70
70
  ## State vs. connection-side storage
71
71
 
72
- `defineState` holds conversation-scoped working memory that lives and dies with the session, including counters, the current plan, and what the user has told you this conversation. It is the agent's short-term memory, persisted durably for the life of the session. Anything that has to outlive the session, be shared across sessions or users, or be queried independently of a turn belongs in an external store, either a [connection](../connections) or your own database.
72
+ `defineState` holds conversation-scoped working memory that lives and dies with the session, including counters, the current plan, and what the user has told you this conversation. It is the agent's short-term memory, persisted durably for the life of the session. Anything that has to outlive the session, be shared across sessions or users, or be queried independently of a turn belongs in an external store. Start with a packaged [memory integration](/integrations?filter=memory), a general [connection](../connections), or your own database.
73
73
 
74
74
  ## What to read next
75
75
 
@@ -12,9 +12,11 @@ Run `eve add` from an eve agent project. This installs the integration's depende
12
12
 
13
13
  ```bash
14
14
  eve add extension/agent-browser
15
+ eve add connection/linear
16
+ eve add instrumentation/braintrust
15
17
  ```
16
18
 
17
- The integration may create an extension mount under `agent/extensions/`. Configure that mount and any required environment variables before running your agent.
19
+ Extensions may create a mount under `agent/extensions/`. Connections write their initial definition under `agent/connections/` and install `@vercel/connect` when required. Instrumentation providers write `agent/instrumentation.ts`; because an agent has one instrumentation file, compose multiple exporters there by hand. Configure generated files and required environment variables before running your agent.
18
20
 
19
21
  ## Find an integration
20
22
 
@@ -3,7 +3,7 @@ title: "Multi-tenant memory"
3
3
  description: "Compose dynamic instructions, authenticated session context, and ordinary tools into tenant-scoped long-term memory."
4
4
  ---
5
5
 
6
- eve does not have a tenant-aware memory subsystem. You can build one today by composing three existing primitives:
6
+ You can add long-term memory with a packaged [memory integration](/integrations?filter=memory), or build tenant-aware memory from your own application store by composing three existing eve primitives:
7
7
 
8
8
  1. route auth puts the tenant and user on `ctx.session.auth`;
9
9
  2. dynamic instructions load that caller's memories before each turn;
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "CLI"
3
- description: "Reference for every eve CLI command: init, info, build, start, dev, logs, link, deploy, eval, channels, and extension."
3
+ description: "Reference for every eve CLI command: init, info, build, start, dev, logs, trace, link, deploy, eval, channels, and extension."
4
4
  ---
5
5
 
6
6
  The `eve` binary (`bin: eve`) runs from your app root, and every command first loads `.env`/`.env.local` from that root. Running `eve` with no command runs `eve dev`.
@@ -17,6 +17,8 @@ The `eve` binary (`bin: eve`) runs from your app root, and every command first l
17
17
  | `eve dev <url>` | Connect the UI to an existing server URL (e.g. a remote deployment) instead of booting a local server |
18
18
  | `eve logs [logid]` | Print an `eve dev` diagnostic log (the most recent when `logid` is omitted) |
19
19
  | `eve logs ls` | List `eve dev` diagnostic logs, most recent first |
20
+ | `eve trace ls` | List locally captured agent traces, most recent first |
21
+ | `eve trace [trace]` | Show a local span tree (the most recent when omitted) |
20
22
  | `eve link` | Link the directory to a Vercel project and pull AI Gateway credentials |
21
23
  | `eve deploy` | Deploy the agent to Vercel production (links first if needed) |
22
24
  | `eve eval` | Run evals against the local app or a remote target |
@@ -213,6 +215,17 @@ A log id is the file name without `.log` (for example `dev-2026-07-15T12-00-00.0
213
215
 
214
216
  Each log has a same-named `.dump` sibling holding environment diagnostics and session stats as one JSON document. `eve logs --dump` (with or without a log id) prepends that document to the JSONL log body; the combined output is a valid JSON value stream (`eve logs --dump | jq -c .`), one self-contained report to attach to an issue. When a log has no dump, the flag is silently a no-op.
215
217
 
218
+ ## `eve trace`
219
+
220
+ ```bash
221
+ eve trace ls # list traces, most recent first
222
+ eve trace ls --json # emit machine-readable trace summaries
223
+ eve trace # show the most recent span tree
224
+ eve trace <trace> # show one span tree
225
+ ```
226
+
227
+ `eve trace ls` reads the immutable OTLP/JSON segments captured under `.eve/traces/v1`; `eve dev` does not need to be running. `eve trace` accepts a full trace id, an `agent.session.id`, or an unambiguous prefix of either. Malformed or incomplete segments are skipped without hiding valid spans from the same trace.
228
+
216
229
  ## `eve link`
217
230
 
218
231
  ```bash
@@ -82,6 +82,35 @@ toModelOutput(output) {
82
82
 
83
83
  Tool outputs must be JSON-serializable. Return plain objects, arrays, strings, numbers, booleans, or `null`; convert values like `Date`, `Map`, `Set`, `NaN`, and cyclic objects before returning them from `execute` or from a `{ type: "json" }` `toModelOutput`.
84
84
 
85
+ ### Send images to the model with content parts
86
+
87
+ A tool that produces an image — a screenshot, a rendered chart — can hand the pixels to a vision-capable model by returning a `content` output from `toModelOutput`. Build outputs with the `toolOutput` helpers and parts with the `toolOutputPart` helpers, both from `eve/tools`:
88
+
89
+ ```ts
90
+ import { defineTool, toolOutput, toolOutputPart } from "eve/tools";
91
+
92
+ export default defineTool({
93
+ description: "Capture a screenshot of the current page",
94
+ inputSchema: z.object({ url: z.string() }),
95
+ async execute(input) {
96
+ const png = await captureScreenshot(input.url);
97
+ return { path: png.path, screenshotBase64: png.base64 };
98
+ },
99
+ toModelOutput(output) {
100
+ return toolOutput.content([
101
+ toolOutputPart.text(`Screenshot of ${output.path}:`),
102
+ toolOutputPart.file(output.screenshotBase64, { mediaType: "image/png" }),
103
+ ]);
104
+ },
105
+ });
106
+ ```
107
+
108
+ The `toolOutput.text` and `toolOutput.json` builders construct the other two output shapes; hand-written literals remain valid everywhere.
109
+
110
+ File payloads must be base64 strings — raw bytes (`Uint8Array`, `Buffer`) are rejected because they do not survive eve's durable JSON boundary. Keep payloads small: a content-part image is persisted in session history and re-sent on every subsequent model call, and eve warns above 3 MiB. Sending image parts to a model without vision support fails with that provider's error, the same as image parts in user messages.
111
+
112
+ When older turns are compacted, file payloads are dropped from the summary and replaced with a text stub naming the file and media type — the model cannot re-see a compacted image. Content parts are for "look at this now"; if the agent may need an artifact again later, write it to the [sandbox](/docs/sandbox) and return its path.
113
+
85
114
  Do not return secrets, credentials, unnecessary personal data, or unbounded sensitive content from tools. Filter, minimize, and redact tool outputs before returning them.
86
115
 
87
116
  ## What to read next
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.27.8",
3
+ "version": "0.27.9",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -279,7 +279,8 @@
279
279
  "access": "public"
280
280
  },
281
281
  "dependencies": {
282
- "nitro": "3.0.260610-beta"
282
+ "nitro": "3.0.260610-beta",
283
+ "undici": "7.28.0"
283
284
  },
284
285
  "devDependencies": {
285
286
  "@ai-sdk/anthropic": "^4.0.18",
@@ -294,6 +295,8 @@
294
295
  "@chat-adapter/twilio": "4.34.0",
295
296
  "@clack/core": "1.3.1",
296
297
  "@nuxt/kit": "^4.0.0",
298
+ "@opentelemetry/otlp-transformer": "0.214.0",
299
+ "@opentelemetry/sdk-trace-base": "^2.6.1",
297
300
  "@standard-schema/spec": "1.1.0",
298
301
  "@sveltejs/kit": "^2.0.0",
299
302
  "@types/json-schema": "7.0.15",
@@ -301,6 +304,7 @@
301
304
  "@types/react-test-renderer": "19.1.0",
302
305
  "@vercel/detect-agent": "1.2.3",
303
306
  "@vercel/oidc": "3.8.0",
307
+ "@vercel/otel": "2.1.3",
304
308
  "@vercel/sandbox": "2.8.0",
305
309
  "@vercel/sdk": "1.28.8",
306
310
  "@workflow/core": "5.0.0-beta.36",
@@ -310,7 +314,7 @@
310
314
  "@workflow/world": "5.0.0-beta.22",
311
315
  "@workflow/world-local": "5.0.0-beta.30",
312
316
  "@workflow/world-vercel": "5.0.0-beta.32",
313
- "ai": "^7.0.34",
317
+ "ai": "^7.0.38",
314
318
  "autoevals": "0.0.132",
315
319
  "chat": "4.34.0",
316
320
  "chokidar": "5.0.0",
@@ -342,7 +346,7 @@
342
346
  },
343
347
  "peerDependencies": {
344
348
  "@opentelemetry/api": "^1.0.0",
345
- "ai": "^7.0.34",
349
+ "ai": "^7.0.38",
346
350
  "braintrust": "^3.0.0",
347
351
  "just-bash": "^3.0.0",
348
352
  "microsandbox": "^0.5.0"