eve 0.27.7 → 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 (97) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/src/cli/commands/register-registry-commands.d.ts +12 -0
  3. package/dist/src/cli/commands/register-registry-commands.js +1 -0
  4. package/dist/src/cli/commands/registry-project.d.ts +10 -0
  5. package/dist/src/cli/commands/registry-project.js +1 -0
  6. package/dist/src/cli/commands/registry.d.ts +21 -0
  7. package/dist/src/cli/commands/registry.js +1 -0
  8. package/dist/src/cli/commands/trace.d.ts +32 -0
  9. package/dist/src/cli/commands/trace.js +6 -0
  10. package/dist/src/cli/run.js +3 -2
  11. package/dist/src/compiled/.vendor-stamp.json +4 -1
  12. package/dist/src/compiled/@ai-sdk/otel/index.js +3 -3
  13. package/dist/src/compiled/@opentelemetry/api/index.d.ts +23 -5
  14. package/dist/src/compiled/@opentelemetry/otlp-transformer/LICENSE +201 -0
  15. package/dist/src/compiled/@opentelemetry/otlp-transformer/index.d.ts +3 -0
  16. package/dist/src/compiled/@opentelemetry/otlp-transformer/index.js +1 -0
  17. package/dist/src/compiled/@vercel/otel/LICENSE +21 -0
  18. package/dist/src/compiled/@vercel/otel/index.d.ts +16 -0
  19. package/dist/src/compiled/@vercel/otel/index.js +17 -0
  20. package/dist/src/compiled/@workflow/world-vercel/index.js +7 -7
  21. package/dist/src/compiled/_chunks/workflow/chunk-5MU5Z6L3-BYQ2wtp-.js +1 -0
  22. package/dist/src/compiled/_chunks/workflow/chunk-NWCAEW5Y-Dp6gZq6P.js +1 -0
  23. package/dist/src/compiled/_chunks/workflow/getMachineId-bsd-WEBNKY2R-Cls8BaDr.js +1 -0
  24. package/dist/src/compiled/_chunks/workflow/getMachineId-darwin-LT47KAXP-Bpw5H-nL.js +2 -0
  25. package/dist/src/compiled/_chunks/workflow/getMachineId-linux-LTVQO6VW-CpqQTfzr.js +1 -0
  26. package/dist/src/compiled/_chunks/workflow/getMachineId-unsupported-UKWBA27G-2_M88Nra.js +1 -0
  27. package/dist/src/compiled/_chunks/workflow/getMachineId-win-NLJKOPY6-D0EDY-ev.js +1 -0
  28. package/dist/src/compiled/shadcn-registry/LICENSE.md +21 -0
  29. package/dist/src/compiled/shadcn-registry/index.d.ts +56 -0
  30. package/dist/src/compiled/shadcn-registry/index.js +33491 -0
  31. package/dist/src/compiler/extension-compatibility.d.ts +4 -4
  32. package/dist/src/compiler/extension-compatibility.js +1 -1
  33. package/dist/src/execution/node-step.js +1 -1
  34. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  35. package/dist/src/execution/turn-workflow.js +1 -1
  36. package/dist/src/execution/web-fetch/request.d.ts +14 -0
  37. package/dist/src/execution/web-fetch/request.js +1 -0
  38. package/dist/src/execution/web-fetch/tool.js +1 -1
  39. package/dist/src/execution/workflow-steps.js +1 -1
  40. package/dist/src/harness/agent-otel-provider.d.ts +49 -0
  41. package/dist/src/harness/agent-otel-provider.js +1 -0
  42. package/dist/src/harness/agent-trace-context-store.d.ts +12 -0
  43. package/dist/src/harness/agent-trace-context-store.js +1 -0
  44. package/dist/src/harness/agent-trace-span-processor.d.ts +12 -0
  45. package/dist/src/harness/agent-trace-span-processor.js +1 -0
  46. package/dist/src/harness/ai-sdk-hook-bridge.d.ts +4 -0
  47. package/dist/src/harness/ai-sdk-hook-bridge.js +1 -0
  48. package/dist/src/harness/compaction-prompt.d.ts +7 -0
  49. package/dist/src/harness/compaction-prompt.js +1 -1
  50. package/dist/src/harness/compaction.js +1 -1
  51. package/dist/src/harness/instrumentation-lifecycle.d.ts +142 -0
  52. package/dist/src/harness/instrumentation-lifecycle.js +1 -0
  53. package/dist/src/harness/instrumentation-native-events.d.ts +12 -0
  54. package/dist/src/harness/instrumentation-native-events.js +1 -0
  55. package/dist/src/harness/instrumentation-runtime.d.ts +13 -0
  56. package/dist/src/harness/instrumentation-runtime.js +1 -0
  57. package/dist/src/harness/local-instrumentation-runtime.d.ts +7 -0
  58. package/dist/src/harness/local-instrumentation-runtime.js +1 -0
  59. package/dist/src/harness/local-trace-span-processor.d.ts +10 -0
  60. package/dist/src/harness/local-trace-span-processor.js +1 -0
  61. package/dist/src/harness/otel-integration.d.ts +3 -0
  62. package/dist/src/harness/otel-integration.js +1 -1
  63. package/dist/src/harness/tool-loop.js +2 -2
  64. package/dist/src/harness/tool-model-output.d.ts +40 -0
  65. package/dist/src/harness/tool-model-output.js +1 -0
  66. package/dist/src/harness/tools.js +1 -1
  67. package/dist/src/harness/types.d.ts +6 -0
  68. package/dist/src/internal/application/package.js +1 -1
  69. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  70. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.d.ts +1 -0
  71. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -0
  72. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  73. package/dist/src/public/definitions/tool.d.ts +1 -1
  74. package/dist/src/public/tools/index.d.ts +2 -1
  75. package/dist/src/public/tools/index.js +1 -1
  76. package/dist/src/public/tools/output-builders.d.ts +53 -0
  77. package/dist/src/public/tools/output-builders.js +1 -0
  78. package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
  79. package/dist/src/setup/scaffold/channels-catalog.d.ts +2 -0
  80. package/dist/src/setup/scaffold/channels-catalog.js +1 -1
  81. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  82. package/dist/src/setup/scaffold/create/project.js +2 -2
  83. package/dist/src/setup/scaffold/update/channels.js +1 -1
  84. package/dist/src/shared/network-address.d.ts +6 -0
  85. package/dist/src/shared/network-address.js +1 -1
  86. package/dist/src/shared/tool-definition.d.ts +29 -0
  87. package/docs/channels/overview.mdx +2 -2
  88. package/docs/connections/overview.mdx +1 -1
  89. package/docs/extensions.md +1 -0
  90. package/docs/guides/instrumentation.md +17 -7
  91. package/docs/guides/state.md +1 -1
  92. package/docs/install-integrations.mdx +108 -0
  93. package/docs/meta.json +1 -0
  94. package/docs/patterns/multi-tenant-memory.md +1 -1
  95. package/docs/reference/cli.md +32 -1
  96. package/docs/tools/overview.mdx +29 -0
  97. package/package.json +9 -4
@@ -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.7`,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
 
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: "Install Integrations"
3
+ description: "Discover and install extensions and other integrations from eve and third-party sources."
4
+ contentType: "How-to"
5
+ ---
6
+
7
+ Install integrations from eve's official catalog, a third-party source, or an integration URL. Integrations are distributed using the [shadcn registry format](https://ui.shadcn.com/docs/registry).
8
+
9
+ ## Install an integration
10
+
11
+ Run `eve add` from an eve agent project. This installs the integration's dependencies and writes its declared files into your project.
12
+
13
+ ```bash
14
+ eve add extension/agent-browser
15
+ eve add connection/linear
16
+ eve add instrumentation/braintrust
17
+ ```
18
+
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.
20
+
21
+ ## Find an integration
22
+
23
+ Browse the [Integrations directory](/integrations) to see the official integrations available from the eve registry.
24
+
25
+ List every official integration and configured third-party source:
26
+
27
+ ```bash
28
+ eve registry list
29
+ ```
30
+
31
+ Search the catalog when you know what capability you need:
32
+
33
+ ```bash
34
+ eve registry search browser
35
+ ```
36
+
37
+ Inspect an integration before you install it:
38
+
39
+ ```bash
40
+ eve registry view extension/agent-browser
41
+ ```
42
+
43
+ `list` and `search` include the official eve catalog and every source you add to the project.
44
+
45
+ ## Add a third-party source
46
+
47
+ Give a registry a namespace and an integration URL template:
48
+
49
+ ```bash
50
+ eve registry add @acme=https://registry.acme.com/r/{name}.json
51
+ ```
52
+
53
+ eve stores the mapping in `package.json#registries`. The `{name}` placeholder becomes the integration name, so `@acme/analytics` resolves to `https://registry.acme.com/r/analytics.json`.
54
+
55
+ Limit listing or search to that registry when needed:
56
+
57
+ ```bash
58
+ eve registry list --registry @acme
59
+ eve registry search analytics --registry @acme
60
+ ```
61
+
62
+ Install an integration from that source:
63
+
64
+ ```bash
65
+ eve add @acme/analytics
66
+ ```
67
+
68
+ Install a known integration URL directly when you do not need a namespace:
69
+
70
+ ```bash
71
+ eve add https://registry.acme.com/r/analytics.json
72
+ ```
73
+
74
+ ## Configure generated files
75
+
76
+ Integrations add project files. Read the generated mount before you run the agent, then add the configuration the extension requires.
77
+
78
+ For an extension, this usually means setting environment variables and editing the file under `agent/extensions/`. See [Extensions](./extensions) for mount configuration, namespacing, and overrides.
79
+
80
+ Provider-specific setup lives in the [Integrations directory](/integrations). Follow that guidance for credentials, approval policies, and service-specific options.
81
+
82
+ ## Update an installed integration
83
+
84
+ Treat generated files as project code. Commit or review local changes before you install the integration again.
85
+
86
+ Run the same command when the registry publisher provides an updated scaffold:
87
+
88
+ ```bash
89
+ eve add extension/agent-browser
90
+ ```
91
+
92
+ Pass `--overwrite` only when you intend to replace an existing generated file:
93
+
94
+ ```bash
95
+ eve add extension/agent-browser --overwrite
96
+ ```
97
+
98
+ Update the installed package with your package manager. Check the publisher's release notes before changing the generated mount or package version.
99
+
100
+ ## Choose trusted sources
101
+
102
+ Integrations can add dependencies and write files. Add sources you trust, inspect an integration with `eve registry view`, and review the resulting project diff before you run the agent.
103
+
104
+ ## What to read next
105
+
106
+ - [Extensions](./extensions): configure and override installed extension mounts
107
+ - [Integrations directory](/integrations): provider-specific setup and security guidance
108
+ - [shadcn registry documentation](https://ui.shadcn.com/docs/registry): publish a compatible third-party registry
package/docs/meta.json CHANGED
@@ -4,6 +4,7 @@
4
4
  "getting-started",
5
5
  "installation",
6
6
  "project-structure",
7
+ "install-integrations",
7
8
  "---Build Your Agent---",
8
9
  "agent-config",
9
10
  "instructions",
@@ -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 |
@@ -24,6 +26,8 @@ The `eve` binary (`bin: eve`) runs from your app root, and every command first l
24
26
  | `eve channels list` | List user-authored channels |
25
27
  | `eve extension init [target]` | Create a new extension package |
26
28
  | `eve extension build` | Build the current package as an extension |
29
+ | `eve add <item>` | Install an item from the official or a configured shadcn registry |
30
+ | `eve registry <command>` | Add sources and list, search, or view registry catalog items |
27
31
 
28
32
  When `eve build` fails on discovery errors, it prints the full diagnostics report (severity, message, source path) and the diagnostics artifact path.
29
33
 
@@ -77,6 +81,22 @@ eve extension build
77
81
 
78
82
  Builds the complete agent-shaped extension tree into its configured dist root, emits declarations and compatibility metadata, and fills the package `exports` map. The original TypeScript source is not required in the published package.
79
83
 
84
+ ## Registry items
85
+
86
+ Commands for installing and discovering [shadcn registry](https://ui.shadcn.com/docs/registry) items. Official registry items use a kind and slug (for example, `extension/agent-browser`); URLs and configured registry addresses are also supported.
87
+
88
+ ```bash
89
+ eve add extension/agent-browser
90
+ eve add https://example.com/r/my-extension.json --overwrite
91
+ eve registry add @acme=https://example.com/r/{name}.json
92
+ eve registry search browser
93
+ eve registry search browser --registry @acme
94
+ eve registry view @acme/my-extension
95
+ eve add @acme/my-extension
96
+ ```
97
+
98
+ `eve registry add` records configured sources in `package.json#registries`. `eve registry list` and `search` aggregate the official catalog and all configured sources by default, or browse one supplied URL or namespace. Official and other universal items with explicit file targets do not require shadcn project configuration.
99
+
80
100
  ## `eve info`
81
101
 
82
102
  ```bash
@@ -195,6 +215,17 @@ A log id is the file name without `.log` (for example `dev-2026-07-15T12-00-00.0
195
215
 
196
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.
197
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
+
198
229
  ## `eve link`
199
230
 
200
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.7",
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",
@@ -330,6 +334,7 @@
330
334
  "react": "19.2.6",
331
335
  "react-test-renderer": "19.2.6",
332
336
  "semver": "7.8.4",
337
+ "shadcn": "4.16.0",
333
338
  "svelte": "^5.0.0",
334
339
  "turndown": "7.2.4",
335
340
  "vite": "^8.1.5",
@@ -341,7 +346,7 @@
341
346
  },
342
347
  "peerDependencies": {
343
348
  "@opentelemetry/api": "^1.0.0",
344
- "ai": "^7.0.34",
349
+ "ai": "^7.0.38",
345
350
  "braintrust": "^3.0.0",
346
351
  "just-bash": "^3.0.0",
347
352
  "microsandbox": "^0.5.0"