eve 0.22.0 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/src/channel/types.d.ts +18 -1
  3. package/dist/src/cli/commands/init-repl.d.ts +6 -5
  4. package/dist/src/compiled/.vendor-stamp.json +6 -4
  5. package/dist/src/compiled/@workflow/core/create-hook.d.ts +2 -2
  6. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +1 -1
  7. package/dist/src/compiled/@workflow/core/index.js +2 -2
  8. package/dist/src/compiled/@workflow/core/private.js +1 -1
  9. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +14 -0
  10. package/dist/src/compiled/@workflow/core/runtime/get-world-lazy.d.ts +3 -12
  11. package/dist/src/compiled/@workflow/core/runtime/wait-continuation.d.ts +2 -2
  12. package/dist/src/compiled/@workflow/core/runtime/world-compatibility.d.ts +5 -0
  13. package/dist/src/compiled/@workflow/core/runtime/world-init.d.ts +16 -41
  14. package/dist/src/compiled/@workflow/core/runtime/world-target.d.ts +11 -0
  15. package/dist/src/compiled/@workflow/core/runtime/world.d.ts +21 -9
  16. package/dist/src/compiled/@workflow/core/runtime.d.ts +2 -1
  17. package/dist/src/compiled/@workflow/core/runtime.js +3 -141
  18. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  19. package/dist/src/compiled/@workflow/core/workflow/world-init-stub.d.ts +2 -2
  20. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  21. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  22. package/dist/src/compiled/@workflow/world/analytics.d.ts +182 -0
  23. package/dist/src/compiled/@workflow/world/env-config.d.ts +39 -0
  24. package/dist/src/compiled/@workflow/world/events.d.ts +25 -0
  25. package/dist/src/compiled/@workflow/world/index.d.ts +6 -3
  26. package/dist/src/compiled/@workflow/world/interfaces.d.ts +14 -7
  27. package/dist/src/compiled/@workflow/world/runs.d.ts +9 -1
  28. package/dist/src/compiled/@workflow/world/shared.d.ts +15 -0
  29. package/dist/src/compiled/@workflow/world/steps.d.ts +8 -0
  30. package/dist/src/compiled/@workflow/world-local/LICENSE.md +201 -0
  31. package/dist/src/compiled/@workflow/world-local/index.js +4 -0
  32. package/dist/src/compiled/@workflow/world-vercel/LICENSE.md +201 -0
  33. package/dist/src/compiled/@workflow/world-vercel/index.js +42 -0
  34. package/dist/src/compiled/_chunks/workflow/attribute-changes-BnKD8Y3m.js +20 -0
  35. package/dist/src/compiled/_chunks/workflow/{dist-FLIfyJ4Y.js → dist-CttsoN4D.js} +1 -1
  36. package/dist/src/compiled/_chunks/workflow/dist-DJU_7R9s.js +40 -0
  37. package/dist/src/compiled/_chunks/workflow/dist-DpDDcpTl.js +3 -0
  38. package/dist/src/compiled/_chunks/workflow/resume-hook-DjPY9VGg.js +1 -0
  39. package/dist/src/compiled/_chunks/workflow/run-BSANnUPR.js +1 -0
  40. package/dist/src/compiled/_chunks/workflow/sleep-phozDCW8.js +1 -0
  41. package/dist/src/compiled/_chunks/workflow/token-CaY0nA5J.js +1 -0
  42. package/dist/src/compiled/_chunks/workflow/token-D4VIwGlD.js +1 -0
  43. package/dist/src/compiled/_chunks/workflow/undici-fb54XL8i.js +95 -0
  44. package/dist/src/execution/reconcile-session-continuation-token.d.ts +4 -0
  45. package/dist/src/execution/reconcile-session-continuation-token.js +1 -0
  46. package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
  47. package/dist/src/execution/sandbox/ensure.js +1 -1
  48. package/dist/src/execution/subagent-adapter.js +1 -1
  49. package/dist/src/execution/subagent-event-proxy-step.d.ts +23 -0
  50. package/dist/src/execution/subagent-event-proxy-step.js +1 -0
  51. package/dist/src/execution/turn-workflow.js +1 -1
  52. package/dist/src/execution/workflow-steps.d.ts +1 -22
  53. package/dist/src/execution/workflow-steps.js +1 -1
  54. package/dist/src/harness/emission.js +1 -1
  55. package/dist/src/harness/model-call-error.d.ts +5 -0
  56. package/dist/src/harness/model-call-error.js +1 -1
  57. package/dist/src/harness/prompt-cache.d.ts +18 -9
  58. package/dist/src/harness/prompt-cache.js +1 -1
  59. package/dist/src/harness/tool-loop.js +1 -1
  60. package/dist/src/internal/application/compiled-artifacts.d.ts +4 -0
  61. package/dist/src/internal/application/compiled-artifacts.js +5 -4
  62. package/dist/src/internal/application/package.d.ts +9 -5
  63. package/dist/src/internal/application/package.js +1 -1
  64. package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
  65. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  66. package/dist/src/internal/nitro/routes/health.d.ts +3 -3
  67. package/dist/src/internal/workflow/runtime.js +1 -1
  68. package/dist/src/internal/workflow/validate-world.d.ts +16 -0
  69. package/dist/src/internal/workflow/validate-world.js +1 -0
  70. package/dist/src/internal/workflow/world-compatibility.d.ts +1 -12
  71. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/index.js +1 -0
  72. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/parse-name.js +1 -0
  73. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/pluralize.js +1 -0
  74. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/promise.js +1 -0
  75. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/time.js +1 -0
  76. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/workflow-routes.js +1 -0
  77. package/dist/src/node_modules/.pnpm/@workflow_utils@5.0.0-beta.6/node_modules/@workflow/utils/dist/world-target.js +1 -0
  78. package/dist/src/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js +1 -0
  79. package/dist/src/public/channels/slack/action-status.d.ts +19 -0
  80. package/dist/src/public/channels/slack/action-status.js +1 -0
  81. package/dist/src/public/channels/slack/defaults.js +2 -2
  82. package/dist/src/public/channels/slack/hitl.d.ts +3 -2
  83. package/dist/src/public/channels/slack/hitl.js +3 -3
  84. package/dist/src/public/channels/slack/index.d.ts +2 -1
  85. package/dist/src/public/channels/slack/index.js +1 -1
  86. package/dist/src/public/channels/slack/interactions.js +1 -1
  87. package/dist/src/public/channels/slack/limits.d.ts +18 -0
  88. package/dist/src/public/channels/slack/limits.js +1 -1
  89. package/dist/src/public/channels/slack/slackChannel.d.ts +1 -1
  90. package/dist/src/public/next/index.d.ts +9 -9
  91. package/dist/src/public/next/index.js +1 -1
  92. package/dist/src/public/next/vercel-output-config.js +1 -1
  93. package/dist/src/runtime/sandbox/keys.d.ts +4 -0
  94. package/dist/src/runtime/sandbox/keys.js +1 -1
  95. package/dist/src/runtime/sandbox/template-plan.d.ts +0 -2
  96. package/dist/src/setup/scaffold/create/project.js +2 -2
  97. package/dist/src/shared/vercel-project.d.ts +25 -0
  98. package/dist/src/shared/vercel-project.js +1 -0
  99. package/docs/agent-config.md +1 -1
  100. package/docs/channels/github.mdx +35 -2
  101. package/docs/channels/linear.mdx +35 -5
  102. package/docs/channels/slack.mdx +30 -3
  103. package/docs/concepts/execution-model-and-durability.md +1 -1
  104. package/docs/connections/overview.mdx +2 -0
  105. package/docs/guides/deployment.md +1 -1
  106. package/docs/guides/frontend/nextjs.mdx +7 -7
  107. package/docs/sandbox.mdx +3 -1
  108. package/docs/subagents.mdx +3 -1
  109. package/package.json +7 -5
  110. package/dist/src/compiled/_chunks/workflow/attribute-changes-zAifvEhb.js +0 -59
  111. package/dist/src/compiled/_chunks/workflow/dist-Dxrjttr2.js +0 -3
  112. package/dist/src/compiled/_chunks/workflow/resume-hook-C15uJ2ik.js +0 -1
  113. package/dist/src/compiled/_chunks/workflow/run-BJUPZ0Ni.js +0 -1
  114. package/dist/src/compiled/_chunks/workflow/sleep-C8B-TYir.js +0 -1
  115. package/dist/src/compiled/_chunks/workflow/token-Bm-WLAUB.js +0 -1
  116. package/dist/src/compiled/_chunks/workflow/token-J7YP0s9a.js +0 -1
  117. package/dist/src/internal/workflow/configure-world.d.ts +0 -18
  118. package/dist/src/internal/workflow/configure-world.js +0 -1
@@ -14,8 +14,6 @@ export type RuntimeSandboxTemplatePlan = {
14
14
  readonly kind: "bootstrap";
15
15
  readonly revalidationKey?: string;
16
16
  readonly sourceHash: string;
17
- } | {
18
- readonly kind: "source-graph";
19
17
  };
20
18
  /**
21
19
  * Chooses the template strategy for one resolved sandbox definition.
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.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.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.22.0`,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{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.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.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.22.2`,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__",
@@ -95,4 +95,4 @@ export default defineAgent({
95
95
  },
96
96
  },
97
97
  });
98
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){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(o){let s=resolve(o.targetDirectory??process.cwd(),o.projectName),c=o.projectName===`.`,l=o.overwriteExisting??!1,u=o.byokProvider??!1,d=o.packageManager??`pnpm`,f=resolveEvePackageContract(o.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(o.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:o.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,o.aiPackageVersion??`^7.0.0`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,o.connectPackageVersion??`0.2.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,o.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,o.typescriptPackageVersion??`7.0.1-rc`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,r]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let i=`${s}/${e}`,a=await pathExists(i);await writeTextFile(i,renderTemplate(r,g),{force:c&&l}),a&&await o.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!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,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
98
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){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(o){let s=resolve(o.targetDirectory??process.cwd(),o.projectName),c=o.projectName===`.`,l=o.overwriteExisting??!1,u=o.byokProvider??!1,d=o.packageManager??`pnpm`,f=resolveEvePackageContract(o.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(o.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:o.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,o.aiPackageVersion??`^7.0.0`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,o.connectPackageVersion??`0.2.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,o.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,o.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,r]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let i=`${s}/${e}`,a=await pathExists(i);await writeTextFile(i,renderTemplate(r,g),{force:c&&l}),a&&await o.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!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,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Claims eve reads from a Vercel OIDC token payload.
3
+ *
4
+ * Decoded locally without signature verification: callers use the values
5
+ * as stable identifiers (sandbox key derivation, credential routing),
6
+ * never to make authentication decisions.
7
+ */
8
+ export interface VercelOidcTokenClaims {
9
+ readonly ownerId: string | undefined;
10
+ readonly projectId: string | undefined;
11
+ }
12
+ /**
13
+ * Decodes the payload claims of a Vercel OIDC token. Values that are not
14
+ * decodable JWTs, or that carry no recognized claims, decode to empty
15
+ * claims — callers only ever check individual fields.
16
+ */
17
+ export declare function decodeVercelOidcTokenClaims(token: string): VercelOidcTokenClaims;
18
+ /**
19
+ * Resolves the Vercel project id visible to this process: the
20
+ * `VERCEL_PROJECT_ID` env var when exposed, otherwise the `project_id`
21
+ * claim of `VERCEL_OIDC_TOKEN`. Both sources exist at build time and at
22
+ * deployed runtime and name the same project, so identifiers derived
23
+ * from this value agree across the two phases.
24
+ */
25
+ export declare function resolveVercelProjectIdFromEnvironment(): string | undefined;
@@ -0,0 +1 @@
1
+ const EMPTY_CLAIMS={ownerId:void 0,projectId:void 0};function decodeVercelOidcTokenClaims(t){let n=t.split(`.`)[1];if(n===void 0||n.length===0)return EMPTY_CLAIMS;let r;try{r=JSON.parse(Buffer.from(n,`base64url`).toString(`utf8`))}catch{return EMPTY_CLAIMS}if(typeof r!=`object`||!r)return EMPTY_CLAIMS;let i=r;return{ownerId:typeof i.owner_id==`string`?i.owner_id:void 0,projectId:typeof i.project_id==`string`?i.project_id:void 0}}function resolveVercelProjectIdFromEnvironment(){let e=process.env.VERCEL_PROJECT_ID?.trim();if(e!==void 0&&e.length>0)return e;let t=process.env.VERCEL_OIDC_TOKEN?.trim();if(!(t===void 0||t.length===0))return decodeVercelOidcTokenClaims(t).projectId}export{decodeVercelOidcTokenClaims,resolveVercelProjectIdFromEnvironment};
@@ -191,7 +191,7 @@ pnpm add @workflow/world-postgres@5.0.0-beta.x
191
191
  ```
192
192
 
193
193
  The npm `latest` tag can lag behind that line, so an unpinned install may pull
194
- an incompatible major that fails with `ZodError: invalid_union` at run replay.
194
+ an incompatible protocol version that the Workflow SDK rejects during initialization.
195
195
 
196
196
  Put credentials and host-specific options in runtime environment variables read
197
197
  by the world package, not in `agent.ts`. For the Postgres world, that means
@@ -1,13 +1,46 @@
1
1
  ---
2
2
  title: "GitHub"
3
- description: "Reach your agent from GitHub App webhooks, with @mention dispatch, PR diff context, and sandbox checkout."
3
+ description: "Reach your agent from GitHub App webhooks, with @mention dispatch, PR diff context, sandbox checkout, and Vercel Connect credentials."
4
4
  type: integration
5
5
  ---
6
6
 
7
- The GitHub channel lets the agent work directly on a repository. Someone `@mentions` it in an issue, PR, or review comment, and the agent answers right there in the thread, with the PR diff already in context and the repo checked out into the sandbox. It takes GitHub App webhooks at `/eve/v1/github`, checks the signature, derives auth from whoever triggered the event, and replies on the native surface. See [Channels](./overview) for the contract this builds on.
7
+ The GitHub channel lets the agent work directly on a repository. Someone `@mentions` it in an issue, PR, or review comment, and the agent answers right there in the thread, with the PR diff already in context and the repo checked out into the sandbox. It takes GitHub App webhooks at `/eve/v1/github`, checks the signature, derives auth from whoever triggered the event, and replies on the native surface. Credentials can run through [Vercel Connect](../guides/auth-and-route-protection), which manages the GitHub App, the installation token, and inbound webhook verification, so there's no app private key or webhook secret for you to hold. See [Channels](./overview) for the contract this builds on.
8
+
9
+ ## Set up Connect
10
+
11
+ Create a GitHub Connect client and copy its UID (e.g. `github/my-agent`), then attach this project as the trigger destination at eve's GitHub route:
12
+
13
+ ```bash
14
+ npm install -g vercel@latest
15
+ vercel connect create github --triggers
16
+ vercel connect detach <uid> --yes
17
+ vercel connect attach <uid> --triggers --trigger-path /eve/v1/github --yes
18
+ ```
19
+
20
+ The `create` step provisions the GitHub App and a trigger destination at the default Connect path. `detach` then `attach --trigger-path /eve/v1/github` re-points the trigger at the eve GitHub route, since eve does not serve the default Connect path. `--triggers` makes Connect receive the App's webhooks, verify them, and forward them to your deployment. During registration, subscribe to `issue_comment` and `pull_request_review_comment` for mention-driven turns — the managed App defaults to `pull_request` only — and add `issues`, `pull_request`, `check_suite`, `check_run`, or `workflow_run` if you wire up their opt-in hooks. You can also create the client from the [Connect dashboard](https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Go+to+Connect).
8
21
 
9
22
  ## Add the channel
10
23
 
24
+ ```bash
25
+ npm install @vercel/connect
26
+ ```
27
+
28
+ ```ts title="agent/channels/github.ts"
29
+ import { connectGitHubCredentials } from "@vercel/connect/eve";
30
+ import { githubChannel } from "eve/channels/github";
31
+
32
+ export default githubChannel({
33
+ botName: "my-agent",
34
+ credentials: connectGitHubCredentials("github/my-agent"),
35
+ });
36
+ ```
37
+
38
+ `connectGitHubCredentials` returns `{ installationToken, webhookVerifier }`: eve uses the Connect-managed installation token directly for GitHub API calls, skipping its native App JWT exchange, and verifies Connect-forwarded webhooks by their Vercel OIDC signature instead of a GitHub webhook secret. Token rotation, refresh, and multi-installation tenancy stay inside Connect, so there is no `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, or `GITHUB_WEBHOOK_SECRET` to manage.
39
+
40
+ ### Bring your own GitHub App
41
+
42
+ To run a GitHub App you manage yourself, pass its credentials directly instead:
43
+
11
44
  ```ts title="agent/channels/github.ts"
12
45
  import { githubChannel } from "eve/channels/github";
13
46
 
@@ -1,13 +1,45 @@
1
1
  ---
2
2
  title: "Linear"
3
- description: "Reach your agent through Linear Agent Sessions, with native Agent Activities for progress, questions, and responses."
3
+ description: "Reach your agent through Linear Agent Sessions, with native Agent Activities for progress, questions, and responses, and Vercel Connect credentials."
4
4
  type: integration
5
5
  ---
6
6
 
7
- The Linear channel uses Linear's Agent Session surface rather than ordinary comments. Users delegate work to the agent from Linear, eve receives `AgentSessionEvent` webhooks at `/eve/v1/linear`, and the channel replies with native Agent Activities, including `thought`, `action`, `elicitation`, `response`, and `error`. See [Channels](./overview) for the contract this builds on.
7
+ The Linear channel uses Linear's Agent Session surface rather than ordinary comments. Users delegate work to the agent from Linear, eve receives `AgentSessionEvent` webhooks at `/eve/v1/linear`, and the channel replies with native Agent Activities, including `thought`, `action`, `elicitation`, `response`, and `error`. Credentials can run through [Vercel Connect](../guides/auth-and-route-protection), which manages the Linear app, its access token, and inbound webhook verification, so there's no API key or webhook secret for you to hold. See [Channels](./overview) for the contract this builds on.
8
+
9
+ ## Set up Connect
10
+
11
+ Create a Linear Connect client and copy its UID (e.g. `linear/my-agent`), then attach this project as the trigger destination at eve's Linear route:
12
+
13
+ ```bash
14
+ npm install -g vercel@latest
15
+ vercel connect create linear --triggers
16
+ vercel connect detach <uid> --yes
17
+ vercel connect attach <uid> --triggers --trigger-path /eve/v1/linear --yes
18
+ ```
19
+
20
+ The `create` step provisions the Linear app — with the `app:assignable` and `app:mentionable` scopes the agent surface needs — and a trigger destination at the default Connect path. `detach` then `attach --trigger-path /eve/v1/linear` re-points the trigger at the eve Linear route, since eve does not serve the default Connect path. `--triggers` makes Connect receive Linear's webhooks, verify them, and forward them to your deployment. During registration, subscribe to the `AgentSessionEvent` webhook category — the managed app defaults to `Comment` and `Issue` — so Linear sends `created` events when the agent is delegated or mentioned and `prompted` events when the user continues the session. You can also create the client from the [Connect dashboard](https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Go+to+Connect).
8
21
 
9
22
  ## Add the channel
10
23
 
24
+ ```bash
25
+ npm install @vercel/connect
26
+ ```
27
+
28
+ ```ts title="agent/channels/linear.ts"
29
+ import { connectLinearCredentials } from "@vercel/connect/eve";
30
+ import { linearChannel } from "eve/channels/linear";
31
+
32
+ export default linearChannel({
33
+ credentials: connectLinearCredentials("linear/my-agent"),
34
+ });
35
+ ```
36
+
37
+ `connectLinearCredentials` returns `{ accessToken, webhookVerifier }`: eve uses the Connect-managed app token for Linear GraphQL calls and verifies Connect-forwarded webhooks by their Vercel OIDC signature instead of a Linear webhook secret. Token rotation, refresh, and multi-workspace tenancy stay inside Connect, so there is no `LINEAR_AGENT_ACCESS_TOKEN` or `LINEAR_WEBHOOK_SECRET` to manage.
38
+
39
+ ### Bring your own Linear app
40
+
41
+ To run a Linear OAuth app you manage yourself, pass its credentials directly instead:
42
+
11
43
  ```ts title="agent/channels/linear.ts"
12
44
  import { linearChannel } from "eve/channels/linear";
13
45
 
@@ -26,9 +58,7 @@ LINEAR_WEBHOOK_SECRET=... # verifies Linear-Signature
26
58
 
27
59
  The sample passes credentials explicitly. To rely on env vars instead, drop the `credentials` block: the access token falls back to `LINEAR_AGENT_ACCESS_TOKEN`, `LINEAR_ACCESS_TOKEN`, `LINEAR_API_KEY`, or `LINEAR_API_TOKEN`, and the webhook secret falls back to `LINEAR_WEBHOOK_SECRET`. Both fields also accept lazy resolver functions.
28
60
 
29
- ## Configure Linear
30
-
31
- Create a Linear OAuth app, enable Agent Session events, and point the webhook URL at:
61
+ Create the Linear OAuth app, enable Agent Session events, and point the webhook URL at:
32
62
 
33
63
  ```text
34
64
  https://<deployment>/eve/v1/linear
@@ -11,13 +11,13 @@ The Slack channel puts your agent inside a workspace. It answers `@mentions` and
11
11
  Create a Slack Connect client and copy its UID (e.g. `slack/my-agent`), then attach this project as the trigger destination at eve's Slack route:
12
12
 
13
13
  ```bash
14
- npm install -g vercel@latest && export FF_CONNECT_ENABLED=1
14
+ npm install -g vercel@latest
15
15
  vercel connect create slack --triggers
16
16
  vercel connect detach <uid> --yes
17
17
  vercel connect attach <uid> --triggers --trigger-path /eve/v1/slack --yes
18
18
  ```
19
19
 
20
- `FF_CONNECT_ENABLED=1` turns on the Connect commands, which are feature-flagged in the Vercel CLI today. The `create` step provisions a destination at the default Connect path. `detach` then `attach --trigger-path /eve/v1/slack` re-points the trigger at the eve Slack route, since eve does not serve the default Connect path. `--triggers` turns on Slack Event Subscriptions; without it, Slack never delivers `app_mention` or `message.im`. You can also create the client from the [Connect dashboard](https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Go+to+Connect).
20
+ The `create` step provisions a destination at the default Connect path. `detach` then `attach --trigger-path /eve/v1/slack` re-points the trigger at the eve Slack route, since eve does not serve the default Connect path. `--triggers` turns on Slack Event Subscriptions; without it, Slack never delivers `app_mention` or `message.im`. You can also create the client from the [Connect dashboard](https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Go+to+Connect).
21
21
 
22
22
  ## Add the channel
23
23
 
@@ -70,9 +70,36 @@ export default slackChannel({
70
70
 
71
71
  `threadContext` performs one `conversations.replies` request for each triggering thread reply and requires the matching Slack history scope. Omit it when the agent should see only direct mentions. `loadThreadContextMessages` remains available when you need custom filtering or non-model processing of the raw thread messages.
72
72
 
73
+ ### Slack API calls outside a handler
74
+
75
+ Inside webhook-side handlers (`onAppMention`, `onInteraction`, `events`),
76
+ `ctx.slack.request(operation, body)` is the raw-API escape hatch. Outside
77
+ those contexts there is no handle — a schedule resolving reactions on old
78
+ messages, for example, has no inbound Slack request. For that, call the
79
+ same primitive the handle uses directly:
80
+
81
+ ```ts
82
+ import { callSlackApi, resolveSlackBotToken } from "eve/channels/slack";
83
+ import { connectSlackCredentials } from "@vercel/connect/eve";
84
+
85
+ const { botToken } = connectSlackCredentials("slack/my-agent");
86
+ const response = await callSlackApi({
87
+ botToken,
88
+ operation: "reactions.get",
89
+ body: { channel: "C0123456789", timestamp: "1712345678.000100", full: true },
90
+ });
91
+ if (!response.ok) throw new Error(String(response.error));
92
+ ```
93
+
94
+ `callSlackApi` resolves function-form tokens (secret managers, Connect
95
+ rotation) at call time and form-encodes the body — the only safe default,
96
+ since Slack's JSON support is partial (`conversations.replies` rejects
97
+ JSON). `resolveSlackBotToken` materializes a `SlackBotToken` to a string
98
+ when you need the bearer token itself.
99
+
73
100
  ### Delivery
74
101
 
75
- The default handlers reply in-thread and show progress. Typing indicators post automatically: `Thinking…` on inbound, `Working…` on `turn.started`, a truncated reasoning snippet on `reasoning.appended`, and tool status on `actions.requested`. Reasoning snippets build progressively: extensions of at least four characters appear immediately, while smaller streamed deltas use the five-second refresh interval to avoid one Slack request per token. Override `events["reasoning.appended"]` if you prefer generic wording. Override `onAppMention` or the `events` handlers to customize.
102
+ The default handlers reply in-thread and show progress. Typing indicators post automatically: `Thinking…` on inbound, `Working…` on `turn.started`, a truncated reasoning snippet on `reasoning.appended`, and an action label on `actions.requested` — the tool name plus its most telling argument (`grep useEveAgent`, `read_file agent/agent.ts`), the subagent or remote-agent name for dispatched calls, and `+N more` when the model requests several actions at once. The model's own pre-tool narration, when present, takes precedence over the derived label. Reasoning snippets build progressively: extensions of at least four characters appear immediately, while smaller streamed deltas use the five-second refresh interval to avoid one Slack request per token. Override `events["reasoning.appended"]` if you prefer generic wording. Override `onAppMention` or the `events` handlers to customize.
76
103
 
77
104
  When a session starts without a `threadTs` (say, from a schedule or `receive(slack, ...)`), eve gives it a unique temporary continuation token. The first agent post anchors the session to the Slack message timestamp, and later posts and mentions resume that same session. Pass `initialMessage` with a `Card` to land a structured anchor first instead. `threadTs` and `initialMessage` are mutually exclusive.
78
105
 
@@ -36,7 +36,7 @@ export default defineAgent({
36
36
  });
37
37
  ```
38
38
 
39
- The world package backs workflow state, queues, hooks, and streams. Keep secrets and deployment-specific options in runtime environment variables read by that package, not in `agent.ts`. The selected world must match eve's bundled `@workflow/*` line (currently the `5.0.0-beta` line); pin it explicitly, since a mismatched world fails with a `ZodError: invalid_union` during run replay. See the [deployment guide](../guides/deployment#8-deploy-without-vercel) for the install command, plus [agent.ts](../agent-config#workflow-world) and [Workflow Worlds](https://workflow-sdk.dev/worlds).
39
+ The world package backs workflow state, queues, hooks, and streams. Keep secrets and deployment-specific options in runtime environment variables read by that package, not in `agent.ts`. Custom worlds must implement the runtime protocol expected by eve's vendored `@workflow/*` packages (currently the `5.0.0-beta` line); the Workflow SDK rejects incompatible protocol versions during initialization. See the [deployment guide](../guides/deployment#8-deploy-without-vercel) for the install command, plus [agent.ts](../agent-config#workflow-world) and [Workflow Worlds](https://workflow-sdk.dev/worlds).
40
40
 
41
41
  ## Resuming after a crash
42
42
 
@@ -138,6 +138,8 @@ export default defineMcpClientConnection({
138
138
 
139
139
  `"linear/myagent"` is the UID you chose when registering the Connect client. `connect("linear/myagent")` is shorthand for a user-scoped interactive OAuth connection: eve resolves a token for the active user before each tool call, emits `authorization.required` when that user has not authorized yet, and resumes the parked turn after the callback completes.
140
140
 
141
+ When a local subagent needs interactive authorization, eve surfaces the authorization lifecycle on the root session's channel, including through nested subagent chains. The challenge still points to the child session's callback, so completing it resumes the child directly while the parent continues waiting for its result.
142
+
141
143
  That means the channel that creates or continues the session must authenticate a real user. For a web app, configure `agent/channels/eve.ts` so your app session maps to `principalType: "user"`; for platform channels, use the built-in channel auth that maps the sender to a user principal. If no authenticated user is attached to the session, the first user-scoped connection call fails with `reason: "principal_required"`.
142
144
 
143
145
  If the remote service should act as the agent itself instead of the end-user, make the Connect connection app-scoped:
@@ -140,7 +140,7 @@ Eve writes the standard Nitro output under `.output/` instead of Vercel Build Ou
140
140
 
141
141
  Self-deployed agents should make the Vercel-specific choices explicit:
142
142
 
143
- - Let the Workflow SDK use its default local world, which stores workflow state under `.workflow-data`, configure your host so that directory is on persistent storage, or select another world with `experimental.workflow.world` in the root `agent.ts`. When you select a custom world, install a world package built against the same `@workflow/*` line as your eve release (currently the `5.0.0-beta` line). The npm `latest` tag may lag, so pin the version explicitly, for example `pnpm add @workflow/world-postgres@5.0.0-beta.x`. A mismatched world (such as a `4.x` package against a `5.x` core) fails with a `ZodError: invalid_union` during run replay.
143
+ - Let the Workflow SDK use its default local world, which stores workflow state under `.workflow-data`, configure your host so that directory is on persistent storage, or select another world with `experimental.workflow.world` in the root `agent.ts`. When you select a custom world, install a world package built against the same `@workflow/*` line as your eve release (currently the `5.0.0-beta` line). The npm `latest` tag may lag, so pin the version explicitly, for example `pnpm add @workflow/world-postgres@5.0.0-beta.x`. The Workflow SDK rejects worlds with an incompatible runtime protocol during initialization.
144
144
  - If you put a reverse proxy or ingress in front of eve, forward **both** `/eve/` and `/.well-known/workflow/`. The workflow world delivers run callbacks to `/.well-known/workflow/v1/flow`; a proxy restricted to `/eve/` lets sessions start but silently stalls runs forever, because the callbacks never reach eve.
145
145
  - Install the AI SDK package for your provider, then use a direct provider model object and `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` when you want no Gateway dependency.
146
146
  - Use `AI_GATEWAY_API_KEY` if you still want Gateway routing from a non-Vercel host.
@@ -34,12 +34,12 @@ export default withEve(nextConfig, {
34
34
 
35
35
  All fields are optional.
36
36
 
37
- | Option | Type | Default | Purpose |
38
- | -------------------- | -------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
39
- | `eveRoot` | `string` | Next.js app root | Path to the eve app root, relative to `process.cwd()` unless absolute. Set it when the agent lives outside the Next.js project. |
40
- | `eveBuildCommand` | `string` | `"eve build"` | Build command for the generated eve Vercel service. Use it when the eve service needs project-specific prework, without changing the Next.js build. |
41
- | `servicePrefix` | `string` | `"/_eve_internal/eve"` | Private Vercel route namespace for the eve service. Must match the eve service's mount in your Vercel Build Output config when you set it manually. |
42
- | `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the eve development server to become available. |
37
+ | Option | Type | Default | Purpose |
38
+ | -------------------- | -------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
+ | `eveRoot` | `string` | Next.js app root | Path to the eve app root, relative to `process.cwd()` unless absolute. Set it when the agent lives outside the Next.js project. |
40
+ | `eveBuildCommand` | `string` | `"eve build"` | Build command for the generated eve Vercel service. Use it when the eve service needs project-specific prework, without changing the Next.js build. |
41
+ | `servicePrefix` | `string` | `"/_eve_internal/eve"` | Private route namespace for legacy manual Vercel service configs and non-Vercel production proxying. Generated Vercel configs use service routes instead. |
42
+ | `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the eve development server to become available. |
43
43
 
44
44
  For slow cold starts, increase the development timeout:
45
45
 
@@ -75,7 +75,7 @@ For a public demo, use `none()` (also from `eve/channels/auth`) to skip authenti
75
75
  ## Dev vs deploy topology
76
76
 
77
77
  - **Local dev.** `npm run dev` boots the eve dev server next to `next dev` and rewrites the eve routes over to it. The browser only ever talks to the Next.js origin.
78
- - **Vercel.** The web app and the eve runtime deploy as a single project. The web app stays public; the eve runtime sits behind it on the same site origin. When the agent needs its own build step, set `eveBuildCommand`:
78
+ - **Vercel.** The web app and the eve runtime deploy as a single project. `withEve()` writes Build Output `services` for eve and `routes` that send `/eve/v1/**` to that service before filesystem routing; the Next.js app itself remains the default app. When the agent needs its own build step, set `eveBuildCommand`:
79
79
 
80
80
  ```ts
81
81
  export default withEve(nextConfig, {
package/docs/sandbox.mdx CHANGED
@@ -164,7 +164,7 @@ You can also write your own backend. A `SandboxBackend` is an adapter object wit
164
164
  There are two hooks, scoped differently:
165
165
 
166
166
  - **`bootstrap({ use })`** is template-scoped and runs once when the template is built. Put reusable setup here that every later session inherits, such as cloning a baseline repo, installing dependencies, or seeding files. Call `use()` to get a `SandboxSession`. Only template filesystem state and supported backend metadata carry into later sessions; config like network policy does not. If external inputs affect what bootstrap produces, set `revalidationKey: () => string` so eve knows when to rebuild the template (authored sandbox source and seed contents are already tracked for you).
167
- - **`onSession({ use, ctx })`** is durable-session-scoped and runs once per session. Put per-session setup here, including network policy, resources, timeout, per-user credentials, and one-time markers. Because it runs inside the active runtime context, it can read `ctx.session` and derive the current principal without baking credentials into the template. Call `use(opts?)` to get a `SandboxSession`; `opts` flow to the backend's update path after create.
167
+ - **`onSession({ use, ctx })`** is durable-session-scoped and runs once per session (and again if a sandbox definition change replaces the session's sandbox). Put per-session setup here, including network policy, resources, timeout, per-user credentials, and one-time markers. Because it runs inside the active runtime context, it can read `ctx.session` and derive the current principal without baking credentials into the template. Call `use(opts?)` to get a `SandboxSession`; `opts` flow to the backend's update path after create.
168
168
 
169
169
  If you require a network policy or other configuration for every session, configure it on the backend factory or in `onSession`; do not rely on bootstrap-only configuration.
170
170
 
@@ -185,6 +185,8 @@ export default defineSandbox({
185
185
 
186
186
  Sessions are persistent, and how the underlying runtime idles out depends on the backend. On the Vercel backend, the VM times out after a period of inactivity (default 30 minutes); eve preserves the filesystem and resumes the sandbox on the next message as if nothing happened, even days later. The Docker backend keeps a long-lived container per durable session and persists `/workspace` across turns without that timeout, and the just-bash backend stores its virtual filesystem under `.eve/sandbox-cache/`. In every case, `/workspace` survives between turns for the same session.
187
187
 
188
+ Session sandboxes are keyed per durable session, not per deployment, so redeploying your app does not discard them. A session gets a replacement sandbox only when the sandbox definition itself changes — the authored sandbox source, workspace seed content, or `revalidationKey` — in which case the next turn starts from the rebuilt template and `onSession` runs again.
189
+
188
190
  When the eve server stops, no sandbox compute outlives it. `eve dev` stops the sandboxes it started when the dev server closes, and a self-hosted production server stops every open sandbox on shutdown (`SIGTERM`/`SIGINT`). Session state persists across the stop — the next server start reattaches each durable session from its stopped container, VM, or snapshot. Custom `SandboxBackend` adapters participate through the handle's `shutdown()` method: stop the underlying compute, keeping the session reattachable from persisted state where the backend supports it.
189
191
 
190
192
  ## Network policy
@@ -109,7 +109,9 @@ Because the name lives in the same runtime tool namespace as authored tools, a s
109
109
 
110
110
  Do not rely on subagent delegation by itself as an approval boundary. Put sensitive tools behind `approval`, connection approval, route/session authorization, or other controls wherever those tools can be called.
111
111
 
112
- Each delegated subagent spins up its own child session and stream. The parent stream carries only the control-plane events `subagent.called` and `subagent.completed`. To follow the child's full progress, read `subagent.called.data.childSessionId` and subscribe at `GET /eve/v1/session/:childSessionId/stream`.
112
+ Each delegated subagent spins up its own child session and stream. The parent stream carries the control-plane events `subagent.called` and `subagent.completed`, plus interactive `input.requested`, `authorization.required`, and `authorization.completed` events proxied from descendants so the root channel can prompt the user. To follow the child's other progress, read `subagent.called.data.childSessionId` and subscribe at `GET /eve/v1/session/:childSessionId/stream`.
113
+
114
+ Subagent model calls automatically retry classified transient provider failures, including overload errors delivered after a stream starts. eve makes at most three fresh model-call attempts, repeating only the current uncommitted call so completed earlier steps, tool results, and sandbox work remain available to the child. Other recoverable task errors fall back to Workflow's durable step retry from the last committed session snapshot. Exhausting the transient model-call attempts or the dedicated empty-response reissue returns one failed task result instead of stacking both retry budgets; terminal errors fail immediately.
113
115
 
114
116
  ## When to split
115
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.22.0",
3
+ "version": "0.22.2",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -293,11 +293,13 @@
293
293
  "@vercel/oidc": "3.5.0",
294
294
  "@vercel/sandbox": "2.3.0",
295
295
  "@vercel/sdk": "1.28.1",
296
- "@workflow/core": "5.0.0-beta.26",
297
- "@workflow/errors": "5.0.0-beta.8",
296
+ "@workflow/core": "5.0.0-beta.28",
297
+ "@workflow/errors": "5.0.0-beta.10",
298
298
  "@workflow/serde": "5.0.0-beta.2",
299
- "@workflow/world": "5.0.0-beta.14",
300
- "@workflow/world-local": "5.0.0-beta.22",
299
+ "@workflow/utils": "5.0.0-beta.6",
300
+ "@workflow/world": "5.0.0-beta.16",
301
+ "@workflow/world-local": "5.0.0-beta.24",
302
+ "@workflow/world-vercel": "5.0.0-beta.24",
301
303
  "ai": "^7.0.0",
302
304
  "autoevals": "0.0.132",
303
305
  "chat": "4.31.0",