eve 0.48.0 → 0.49.0

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 (189) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/channel/channel-address.js +1 -1
  3. package/dist/src/channel/types.d.ts +10 -0
  4. package/dist/src/cli/commands/registry-metadata.d.ts +30 -0
  5. package/dist/src/cli/commands/registry-metadata.js +1 -1
  6. package/dist/src/cli/commands/registry-package.d.ts +6 -0
  7. package/dist/src/cli/commands/registry-package.js +1 -1
  8. package/dist/src/cli/commands/registry-pnpm-build-policy-flow.d.ts +30 -0
  9. package/dist/src/cli/commands/registry-pnpm-build-policy-flow.js +1 -0
  10. package/dist/src/cli/commands/registry-pnpm-build-policy.d.ts +12 -0
  11. package/dist/src/cli/commands/registry-pnpm-build-policy.js +6 -0
  12. package/dist/src/cli/commands/registry-recovery.d.ts +4 -0
  13. package/dist/src/cli/commands/registry-recovery.js +1 -1
  14. package/dist/src/cli/commands/registry.d.ts +1 -1
  15. package/dist/src/cli/commands/registry.js +1 -1
  16. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  17. package/dist/src/compiled/.vendor-stamp.json +7 -7
  18. package/dist/src/compiled/@workflow/core/attribute-changes.d.ts +2 -4
  19. package/dist/src/compiled/@workflow/core/capabilities.d.ts +10 -9
  20. package/dist/src/compiled/@workflow/core/capture-stack.d.ts +1 -1
  21. package/dist/src/compiled/@workflow/core/class-serialization.d.ts +8 -8
  22. package/dist/src/compiled/@workflow/core/context-violation-error.d.ts +5 -5
  23. package/dist/src/compiled/@workflow/core/create-hook.d.ts +2 -2
  24. package/dist/src/compiled/@workflow/core/describe-error.d.ts +7 -7
  25. package/dist/src/compiled/@workflow/core/encryption.d.ts +5 -5
  26. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +49 -14
  27. package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +4 -4
  28. package/dist/src/compiled/@workflow/core/global.d.ts +4 -2
  29. package/dist/src/compiled/@workflow/core/index.d.ts +1 -1
  30. package/dist/src/compiled/@workflow/core/index.js +2 -2
  31. package/dist/src/compiled/@workflow/core/log-format.d.ts +2 -2
  32. package/dist/src/compiled/@workflow/core/private.d.ts +40 -78
  33. package/dist/src/compiled/@workflow/core/private.js +1 -1
  34. package/dist/src/compiled/@workflow/core/replay-payload-cache.d.ts +13 -17
  35. package/dist/src/compiled/@workflow/core/runtime/compute-instance.d.ts +4 -3
  36. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +27 -27
  37. package/dist/src/compiled/@workflow/core/runtime/count-step-started-events.d.ts +7 -7
  38. package/dist/src/compiled/@workflow/core/runtime/deployment-guard.d.ts +7 -7
  39. package/dist/src/compiled/@workflow/core/runtime/get-port-lazy.d.ts +2 -2
  40. package/dist/src/compiled/@workflow/core/runtime/get-world-lazy.d.ts +2 -2
  41. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +30 -49
  42. package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +21 -10
  43. package/dist/src/compiled/@workflow/core/runtime/quickjs-runtime.d.ts +31 -15
  44. package/dist/src/compiled/@workflow/core/runtime/quickjs-serde.d.ts +10 -10
  45. package/dist/src/compiled/@workflow/core/runtime/replay-budget.d.ts +4 -4
  46. package/dist/src/compiled/@workflow/core/runtime/replay-recovery-reporter.d.ts +1 -1
  47. package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +20 -12
  48. package/dist/src/compiled/@workflow/core/runtime/resume-latency.d.ts +37 -30
  49. package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +2 -2
  50. package/dist/src/compiled/@workflow/core/runtime/run.d.ts +22 -5
  51. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +4 -4
  52. package/dist/src/compiled/@workflow/core/runtime/start.d.ts +3 -3
  53. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +14 -14
  54. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +42 -25
  55. package/dist/src/compiled/@workflow/core/runtime/step-ownership.d.ts +6 -6
  56. package/dist/src/compiled/@workflow/core/runtime/step-single-flight.d.ts +1 -1
  57. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +38 -24
  58. package/dist/src/compiled/@workflow/core/runtime/unserializable-step.d.ts +34 -0
  59. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +2 -2
  60. package/dist/src/compiled/@workflow/core/runtime/wait-continuation.d.ts +31 -9
  61. package/dist/src/compiled/@workflow/core/runtime/wait-until.d.ts +1 -1
  62. package/dist/src/compiled/@workflow/core/runtime/world-compatibility.d.ts +20 -9
  63. package/dist/src/compiled/@workflow/core/runtime/world-init.d.ts +5 -5
  64. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  65. package/dist/src/compiled/@workflow/core/sealed-box.d.ts +7 -7
  66. package/dist/src/compiled/@workflow/core/serialization/codec-devalue-vm.d.ts +1 -1
  67. package/dist/src/compiled/@workflow/core/serialization/codec-devalue.d.ts +1 -1
  68. package/dist/src/compiled/@workflow/core/serialization/codec.d.ts +4 -4
  69. package/dist/src/compiled/@workflow/core/serialization/compression.d.ts +12 -11
  70. package/dist/src/compiled/@workflow/core/serialization/encryption.d.ts +7 -7
  71. package/dist/src/compiled/@workflow/core/serialization/format.d.ts +6 -6
  72. package/dist/src/compiled/@workflow/core/serialization/hardened.d.ts +23 -22
  73. package/dist/src/compiled/@workflow/core/serialization/index.d.ts +1 -1
  74. package/dist/src/compiled/@workflow/core/serialization/reducers/class-vm.d.ts +1 -1
  75. package/dist/src/compiled/@workflow/core/serialization/reducers/step-function-vm.d.ts +1 -1
  76. package/dist/src/compiled/@workflow/core/serialization/types.d.ts +5 -5
  77. package/dist/src/compiled/@workflow/core/serialization/workflow-vm.d.ts +1 -1
  78. package/dist/src/compiled/@workflow/core/serialization-format.d.ts +11 -11
  79. package/dist/src/compiled/@workflow/core/serialization.d.ts +18 -19
  80. package/dist/src/compiled/@workflow/core/source-map.d.ts +1 -1
  81. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +5 -5
  82. package/dist/src/compiled/@workflow/core/step/writable-stream.d.ts +3 -3
  83. package/dist/src/compiled/@workflow/core/symbols.d.ts +2 -2
  84. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +71 -20
  85. package/dist/src/compiled/@workflow/core/telemetry.d.ts +15 -3
  86. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  87. package/dist/src/compiled/@workflow/core/vm/script-cache.d.ts +9 -11
  88. package/dist/src/compiled/@workflow/core/workflow/abort-controller.d.ts +1 -1
  89. package/dist/src/compiled/@workflow/core/workflow/set-attributes.d.ts +1 -1
  90. package/dist/src/compiled/@workflow/core/workflow/world-init-stub.d.ts +1 -1
  91. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  92. package/dist/src/compiled/@workflow/errors/index.d.ts +18 -18
  93. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  94. package/dist/src/compiled/@workflow/world/analytics.d.ts +3 -2
  95. package/dist/src/compiled/@workflow/world/attributes-validation.d.ts +28 -0
  96. package/dist/src/compiled/@workflow/world/attributes.d.ts +8 -107
  97. package/dist/src/compiled/@workflow/world/env-config.d.ts +5 -5
  98. package/dist/src/compiled/@workflow/world/event-metadata.d.ts +132 -0
  99. package/dist/src/compiled/@workflow/world/events.d.ts +42 -96
  100. package/dist/src/compiled/@workflow/world/hooks.d.ts +12 -11
  101. package/dist/src/compiled/@workflow/world/index.d.ts +3 -3
  102. package/dist/src/compiled/@workflow/world/interfaces.d.ts +94 -39
  103. package/dist/src/compiled/@workflow/world/queue.d.ts +29 -22
  104. package/dist/src/compiled/@workflow/world/runs.d.ts +20 -0
  105. package/dist/src/compiled/@workflow/world/slot-identity.d.ts +3 -3
  106. package/dist/src/compiled/@workflow/world/spec-version.d.ts +82 -15
  107. package/dist/src/compiled/@workflow/world/ulid.d.ts +2 -2
  108. package/dist/src/compiled/@workflow/world-local/index.js +5 -5
  109. package/dist/src/compiled/@workflow/world-vercel/index.js +12 -12
  110. package/dist/src/compiled/_chunks/workflow/{attribute-changes-DXbpwBdw.js → attribute-changes-BwAadFfB.js} +3 -3
  111. package/dist/src/compiled/_chunks/workflow/debug-log-CVPstO1D.js +1 -0
  112. package/dist/src/compiled/_chunks/workflow/dist-CgbVZs5l.js +40 -0
  113. package/dist/src/compiled/_chunks/workflow/dist-DjojkP5e.js +3 -0
  114. package/dist/src/compiled/_chunks/workflow/frames-CZ9eHShe.js +3 -0
  115. package/dist/src/compiled/_chunks/workflow/global-singleton-BNinwFrL.js +1 -0
  116. package/dist/src/compiled/_chunks/workflow/private-CZFMABEf.js +1 -0
  117. package/dist/src/compiled/_chunks/workflow/resume-hook-BToMtPbH.js +1 -0
  118. package/dist/src/compiled/_chunks/workflow/run-DzyAoGh4.js +1 -0
  119. package/dist/src/compiled/_chunks/workflow/sleep-3_A5uOp-.js +1 -0
  120. package/dist/src/compiled/_chunks/workflow/undici-DfxNX5og.js +95 -0
  121. package/dist/src/compiled/_chunks/workflow/wait-until-BtySPYD0.js +15 -0
  122. package/dist/src/compiled/_chunks/workflow/ws-transport-PnVVxT0R.js +1 -0
  123. package/dist/src/eve-channel/index.js +1 -1
  124. package/dist/src/execution/agent-handle-dispatch.js +1 -1
  125. package/dist/src/execution/continuation-conflict-step.d.ts +10 -0
  126. package/dist/src/execution/continuation-conflict-step.js +1 -0
  127. package/dist/src/execution/delegated-parent-notification.js +1 -1
  128. package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +7 -29
  129. package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
  130. package/dist/src/execution/dispatch-runtime-actions-start.d.ts +33 -0
  131. package/dist/src/execution/dispatch-runtime-actions-start.js +1 -0
  132. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  133. package/dist/src/execution/dispatch-turn-step.js +1 -1
  134. package/dist/src/execution/dynamic-connections.js +1 -1
  135. package/dist/src/execution/inline-turn.js +1 -1
  136. package/dist/src/execution/next-driver-action.d.ts +5 -4
  137. package/dist/src/execution/proxied-deliver-step.js +1 -1
  138. package/dist/src/execution/runtime-errors.d.ts +0 -12
  139. package/dist/src/execution/runtime-errors.js +1 -1
  140. package/dist/src/execution/session-timeout-steps.js +1 -1
  141. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  142. package/dist/src/execution/stable-workflow-names.d.ts +2 -2
  143. package/dist/src/execution/subagent-start-local.js +1 -1
  144. package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
  145. package/dist/src/execution/tasks/parent/run-parent.js +1 -1
  146. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  147. package/dist/src/execution/tool-run/start.js +1 -1
  148. package/dist/src/execution/tools/subagent/local.js +1 -1
  149. package/dist/src/execution/turn-workflow.js +1 -1
  150. package/dist/src/execution/workflow-entry.d.ts +5 -1
  151. package/dist/src/execution/workflow-entry.js +1 -1
  152. package/dist/src/execution/workflow-runtime.d.ts +12 -12
  153. package/dist/src/execution/workflow-runtime.js +1 -1
  154. package/dist/src/execution/workflow-steps.js +1 -1
  155. package/dist/src/harness/tool-loop.js +1 -1
  156. package/dist/src/internal/application/package.js +1 -1
  157. package/dist/src/internal/workflow/development-world-client.js +1 -1
  158. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  159. package/dist/src/public/channels/slack/slackChannel.d.ts +7 -1
  160. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  161. package/dist/src/setup/flows/registry.js +1 -1
  162. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  163. package/dist/src/setup/scaffold/create/project.js +1 -1
  164. package/docs/channels/custom.mdx +4 -0
  165. package/docs/channels/eve.mdx +12 -8
  166. package/docs/channels/mcp.mdx +4 -1
  167. package/docs/guides/instrumentation.md +1 -1
  168. package/docs/install-integrations.mdx +2 -0
  169. package/docs/instructions.mdx +1 -1
  170. package/docs/memory/custom-provider.md +214 -0
  171. package/docs/memory/file.md +129 -0
  172. package/docs/memory/meta.json +5 -0
  173. package/docs/memory/overview.mdx +282 -0
  174. package/docs/patterns/multi-tenant-memory.md +12 -20
  175. package/package.json +8 -8
  176. package/dist/src/compiled/_chunks/workflow/dist-CqvWKNQv.js +0 -3
  177. package/dist/src/compiled/_chunks/workflow/dist-Dk0aQqFO.js +0 -40
  178. package/dist/src/compiled/_chunks/workflow/dist-DpYyXbJv.js +0 -1
  179. package/dist/src/compiled/_chunks/workflow/env-config-L94XftKz.js +0 -1
  180. package/dist/src/compiled/_chunks/workflow/frames-Dl2Hcma4.js +0 -3
  181. package/dist/src/compiled/_chunks/workflow/private-CuQ4HTFC.js +0 -1
  182. package/dist/src/compiled/_chunks/workflow/resume-hook-E-Nkx8q_.js +0 -1
  183. package/dist/src/compiled/_chunks/workflow/run-cIeex2KF.js +0 -1
  184. package/dist/src/compiled/_chunks/workflow/sleep-CxFsdxB_.js +0 -1
  185. package/dist/src/compiled/_chunks/workflow/spec-version-DBUVfF_R.js +0 -1
  186. package/dist/src/compiled/_chunks/workflow/undici-DznrXKcM.js +0 -95
  187. package/dist/src/compiled/_chunks/workflow/wait-until-BZHmJCAW.js +0 -15
  188. package/dist/src/compiled/_chunks/workflow/ws-transport-Ct6yyRWZ.js +0 -1
  189. package/docs/memory.md +0 -408
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.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{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.48.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,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.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{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.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{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.49.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,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,n){let r=parseChatGptModelSelection(e);return r===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(r)}),\n${reasoningTemplateLine(n)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,n){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(n.model)!==void 0?renderAgentTemplate(n.model,n.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,n.appName).replaceAll(`__EVE_INIT_MODEL__`,n.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(n.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(n.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(n.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(n.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,n.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,n.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,n.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,n.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,n.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,n.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__",
@@ -82,6 +82,10 @@ part of the authored channel API.
82
82
 
83
83
  Channel operations are dynamic: every call targets whichever session currently
84
84
  owns the address. Only `send()` can create a session when the address is unowned.
85
+ Cold-start sends return their accepted candidate without waiting for address
86
+ ownership. If simultaneous sends race, eve forwards the losing candidate's
87
+ message to the winner; resolve the address after startup when you need a fixed
88
+ handle to the canonical owner.
85
89
 
86
90
  ```ts
87
91
  const source = from(threadId);
@@ -47,22 +47,26 @@ curl -X POST https://<deployment>/eve/v1/session \
47
47
  # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
48
48
  ```
49
49
 
50
- The `202` response means Workflow accepted the durable run. The command inbox may still be
51
- starting, so an immediate follow-up or control request can report that the session is not active.
52
- The event-stream client retries the brief window before the new run becomes readable.
50
+ The `202` response means Workflow accepted the durable run. The route does not wait for command
51
+ inbox or continuation-token ownership. The inbox may still be starting, so an immediate follow-up
52
+ or control request can report that the session is not active. The event-stream client retries the
53
+ brief window before the new run becomes readable.
53
54
 
54
55
  Authenticated callers that may retry a create request can pass their own `operationId` for
55
- create-once semantics. The same operation under the same authenticated principal returns the
56
- active session it already created instead of dispatching the input again. The first accepted
57
- payload wins; retries with different input still return that first session. Anonymous callers
58
- cannot use `operationId`, and operation ownership expires when the session is no longer resumable.
56
+ create-once semantics. Once the operation owner is active, the same operation under the same
57
+ authenticated principal returns that session instead of dispatching the input again. The create
58
+ route does not wait for a concurrently starting request to publish ownership: simultaneous
59
+ requests can receive different accepted candidate IDs, while only the candidate that claims the
60
+ operation runs its first turn. Retry the operation after startup when you need its canonical
61
+ session ID. Anonymous callers cannot use `operationId`, and operation ownership expires when the
62
+ session is no longer resumable.
59
63
 
60
64
  ```bash
61
65
  curl -X POST https://<deployment>/eve/v1/session \
62
66
  -H "Authorization: Bearer <token>" \
63
67
  -H "Content-Type: application/json" \
64
68
  -d '{"message":"What is the weather in Paris?","operationId":"order-4213-research"}'
65
- # {"ok":true,"sessionId":"wrun_A","status":"accepted"} — retries return the same sessionId
69
+ # {"ok":true,"sessionId":"wrun_A","status":"accepted"}
66
70
  ```
67
71
 
68
72
  The first request requires `message`. A follow-up request accepts exactly one of
@@ -171,7 +171,10 @@ MCP clients receive four tools:
171
171
  | `agent_update` | `{ invocationId, responses }` | Answer the complete pending human-input batch. |
172
172
  | `agent_cancel` | `{ invocationId }` | Request cooperative cancellation of non-terminal work. |
173
173
 
174
- `agent_start` creates one task-mode eve session and returns after durable acceptance. Keep its `invocationId`, then call `agent_get` until the invocation reaches a terminal state. While the status is `working`, wait at least `pollAfterMs` before polling again.
174
+ `agent_start` creates one task-mode eve session and returns after durable acceptance without
175
+ waiting for the session continuation hook to become readable. Keep its `invocationId`, then call
176
+ `agent_get` until the invocation reaches a terminal state. While the status is `working`, wait at
177
+ least `pollAfterMs` before polling again.
175
178
 
176
179
  The invocation response is discriminated by `status`:
177
180
 
@@ -58,7 +58,7 @@ You are responsible for ensuring any observability or eval provider is approved
58
58
 
59
59
  The third configurable surface, [runtime context events](#runtime-context), attaches per-model-call values to these spans.
60
60
 
61
- Built-in messaging channels classify their instrumentation metadata with an `audience`: `public`, `private`, or `unknown`. Slack public channels and Chat SDK workspace-visible threads are public; direct and private conversations are private; platform surfaces without enough visibility evidence remain unknown.
61
+ Built-in messaging channels classify their instrumentation metadata with an `audience`: `public`, `private`, or `unknown`. Slack public channels and Chat SDK workspace-visible threads are public; direct and private conversations are private; platform surfaces without enough visibility evidence remain unknown. Proactive Slack `receive` / `ctx.send` handoffs stay `unknown` unless the caller passes `audience` on the target, for example when a webhook or schedule already knows the destination channel is public.
62
62
 
63
63
  ## Channel delivery traces
64
64
 
@@ -26,6 +26,8 @@ Some integrations package several independently installable components. For exam
26
26
 
27
27
  When an official item declares an interactive setup flow or flows, eve asks whether to run them after installation and runs multiple flows in declaration order. Run the printed `eve add <item> --skip-install` command to resume a skipped or cancelled setup later; it reruns the selected components' declared flows from the beginning.
28
28
 
29
+ An official item may identify optional pnpm dependencies that have build scripts. Before installation, eve asks whether to skip those optional packages, allow their build scripts, or abort. Your choice updates `ignoredOptionalDependencies` or `allowBuilds` in the pnpm workspace that owns the project. Allow build scripts only when you trust the packages named in the prompt.
30
+
29
31
  ## Automate setup
30
32
 
31
33
  Use `eve add <item> --non-interactive` when a script or coding agent cannot answer terminal prompts. It prints NDJSON events and exits with a status you can branch on:
@@ -99,4 +99,4 @@ Where an eve agent communicates with people, you may be required to disclose tha
99
99
  - [Tools](./tools): typed actions, the next capability to add
100
100
  - [Context control](./concepts/context-control): all the levers for what the model sees
101
101
  - [Skills](./skills): on-demand procedures, the counterpart to always-on instructions
102
- - [Multi-tenant memory](./patterns/multi-tenant-memory): dynamic instructions that load per-tenant memories each turn
102
+ - [Memory](./memory): provider-backed context that outlives a session, recalled before each turn
@@ -0,0 +1,214 @@
1
+ ---
2
+ title: "Build a Memory Provider"
3
+ description: "Implement the recall, capture, and tools contract so any store or memory service can back an eve memory slot."
4
+ ---
5
+
6
+ A memory provider is an object with a `recall` handler and optional `capture`
7
+ and `tools` handlers. eve calls those handlers at fixed points in the agent
8
+ lifecycle and passes each one a locked scope key, the projected conversation,
9
+ and a stable operation ID. Anything that can read and write under that key can
10
+ be a provider. Package one as a library that exports a provider factory, or
11
+ write one directly inside an agent.
12
+
13
+ ```ts title="agent/lib/notes-memory.ts"
14
+ import { defineMemoryProvider } from "eve/memory";
15
+ import { defineTool } from "eve/tools";
16
+ import { z } from "zod";
17
+ import { notes } from "./notes-db";
18
+
19
+ export function notesMemory() {
20
+ return defineMemoryProvider({
21
+ recall: {
22
+ async "turn.started"(ctx) {
23
+ const rows = await notes.search({
24
+ partition: ctx.memory.scope.key,
25
+ query: ctx.turn.input,
26
+ limit: 5,
27
+ });
28
+ return {
29
+ messages: rows.map((row) => ({ id: row.id, content: row.text })),
30
+ };
31
+ },
32
+ },
33
+ capture: {
34
+ async "turn.completed"(ctx) {
35
+ await notes.ingest({
36
+ partition: ctx.memory.scope.key,
37
+ idempotencyKey: ctx.operationId,
38
+ messages: ctx.messages,
39
+ });
40
+ },
41
+ },
42
+ async tools(ctx) {
43
+ return {
44
+ forget: defineTool({
45
+ description: "Delete a remembered note by its ID.",
46
+ inputSchema: z.object({ id: z.string() }),
47
+ async execute({ id }) {
48
+ await notes.delete({ partition: ctx.memory.scope.key, id });
49
+ return { deleted: true };
50
+ },
51
+ }),
52
+ };
53
+ },
54
+ });
55
+ }
56
+ ```
57
+
58
+ Bind the provider to a slot like any other:
59
+
60
+ ```ts title="agent/memory/notes.ts"
61
+ import { defineMemory } from "eve/memory";
62
+ import { byPrincipal } from "eve/memory/scope";
63
+ import { notesMemory } from "../lib/notes-memory";
64
+
65
+ export default defineMemory({
66
+ description: "Notes the caller has asked the agent to remember.",
67
+ provider: notesMemory(),
68
+ scope: byPrincipal,
69
+ });
70
+ ```
71
+
72
+ The model sees the tool as `notes__forget`, and the slot description is
73
+ prepended to its description.
74
+
75
+ ## The provider contract
76
+
77
+ `defineMemoryProvider()` accepts three surfaces. Omit any handler the provider
78
+ does not need; `fileMemory()`, for example, implements recall and tools but no
79
+ capture.
80
+
81
+ | Surface | Handlers | Responsibility |
82
+ | --------- | ----------------------------------------------------- | -------------------------------------------------------- |
83
+ | `recall` | `"turn.started"` (required), `"compaction.completed"` | Return messages to place in model context |
84
+ | `capture` | `"turn.completed"`, `"compaction.requested"` | Observe settled history and write to the store |
85
+ | `tools` | one function | Return model-facing operations bound to the locked scope |
86
+
87
+ ### Operation context
88
+
89
+ Every handler receives a `MemoryOperationContext`:
90
+
91
+ | Field | Meaning |
92
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------- |
93
+ | `memory.scope.key` | Opaque, versioned digest of the namespace and scope. Use it as the partition key for every read and write. |
94
+ | `memory.scope.namespace` | The resolved namespace string |
95
+ | `memory.scope.value` | The resolved scope string or tuple |
96
+ | `memory.slot` | The path-derived slot name |
97
+ | `messages` | Projected conversation history for this phase |
98
+ | `operationId` | Stable per session, sequence, phase, and slot. Use it as an idempotency key. |
99
+ | `abortSignal` | Cancellation for the operation |
100
+ | `session` | Session ID, authentication, and other `SessionContext` fields |
101
+
102
+ Phase-specific fields:
103
+
104
+ - `turn.started` and `turn.completed` add `turn` with the turn `id`, `input`
105
+ messages, and `sequence`.
106
+ - `compaction.requested` adds `compaction.modelId` and
107
+ `compaction.usageInputTokens`; `turn` is `null` for standalone compaction.
108
+ - `compaction.completed` adds `compaction.modelId`; `turn` may be `null`.
109
+
110
+ `tools()` receives a `MemoryToolsContext` with the same `memory` and `turn`
111
+ fields plus the ordinary dynamic-resolve context.
112
+
113
+ ### Recall results
114
+
115
+ A recall handler returns `{ messages }`, `null`, or `undefined`. Each message
116
+ has `content` and an optional `id`:
117
+
118
+ ```ts
119
+ return {
120
+ messages: [
121
+ { id: "preferred-language", content: "The user prefers Spanish." },
122
+ { content: "A relevant note without a stable identity." },
123
+ ],
124
+ };
125
+ ```
126
+
127
+ eve adds each message to model context as a user-role message attributed to the
128
+ slot. Provider content is never promoted to system instructions.
129
+
130
+ Use a stable `id` for replaceable facts. A later message with the same ID in
131
+ the same slot, namespace, and scope supersedes the earlier one; identical
132
+ content is a no-op. Messages without an ID accumulate, even when their content
133
+ repeats. Omitting an earlier ID from a later result does not delete it; recall
134
+ cannot retract, only supersede.
135
+
136
+ ### Tools
137
+
138
+ `tools()` returns a map of `defineTool()` values or `null`. eve qualifies each
139
+ key as `<slot>__<key>`; the qualified name must start with a letter, contain
140
+ only letters, digits, underscores, or dashes, and be at most 64 characters.
141
+ Schemas, `approval`, `outputSchema`, and `toModelOutput` work as they do for
142
+ authored tools.
143
+
144
+ A tool closes over the locked scope for the current turn, so it cannot be
145
+ redirected to another tenant or caller by the model. eve keeps each tool
146
+ callback replayable after a process restart or redeployment.
147
+
148
+ ## Lifecycle
149
+
150
+ | Phase | Handler | `messages` contains |
151
+ | ---------------------- | --------------------------------- | ---------------------------------------------------------- |
152
+ | `turn.started` | `recall["turn.started"]` | History before recall; the new delivery is in `turn.input` |
153
+ | `turn.completed` | `capture["turn.completed"]` | Settled history after a successful turn |
154
+ | `compaction.requested` | `capture["compaction.requested"]` | History before the checkpoint changes |
155
+ | `compaction.completed` | `recall["compaction.completed"]` | The checkpoint plus canonical recalled records |
156
+
157
+ At turn start, eve resolves and locks the scope for every active slot before any
158
+ recall runs. All slots see the same pre-recall history, and eve commits their
159
+ validated results atomically.
160
+
161
+ During compaction, eve excludes recalled records from the summarizer, keeps the
162
+ latest value for each keyed record plus every unkeyed record, and then calls
163
+ `recall["compaction.completed"]` against the new checkpoint. This keeps
164
+ provider content attributable and prevents a summary from turning it into
165
+ ordinary conversation history. If raw superseded records exceed 512 entries or
166
+ 256 KiB, eve canonicalizes them without waiting for the normal token threshold;
167
+ this changes session history only, not the provider's store.
168
+
169
+ Calling `clear()` on a session removes its history, recalled records, locked
170
+ scopes, and replay bookkeeping. It does not touch the provider's store; a later
171
+ turn recalls the same data again.
172
+
173
+ ## Failure behavior
174
+
175
+ - A throwing or invalid `recall["turn.started"]` fails the turn before the
176
+ model call. No slot's recall results are committed.
177
+ - A throwing `capture["compaction.requested"]` leaves history unchanged.
178
+ - A throwing `recall["compaction.completed"]` fails an automatic turn. For
179
+ standalone compaction, eve logs the error and returns the session to waiting,
180
+ because the checkpoint has already been written.
181
+ - An invalid or throwing `tools()` result is logged and omitted for that turn.
182
+ - A throwing `capture["turn.completed"]` is logged after the response and does
183
+ not rewrite the completed turn.
184
+
185
+ ## Requirements
186
+
187
+ Providers must:
188
+
189
+ - Partition every read and write by `memory.scope.key`. For semantic
190
+ retrieval, include the key in the query itself, not as a filter after a
191
+ global search.
192
+ - Treat `operationId` as an idempotency key. eve may replay a handler with the
193
+ same ID; replaying a recall with a different result is an error.
194
+ - Enforce their own size and retention policies. eve does not truncate or
195
+ expire provider content.
196
+ - Treat recalled content as user-controlled data.
197
+
198
+ eve enforces these limits on the values it passes to and receives from a
199
+ provider:
200
+
201
+ | Value | Limit |
202
+ | -------------------------------------- | ----------------- |
203
+ | Namespace | 1,024 UTF-8 bytes |
204
+ | Each scope component | 1,024 UTF-8 bytes |
205
+ | Scope tuple | 16 components |
206
+ | Combined canonical namespace and scope | 4,096 bytes |
207
+ | Recall message `id` | 1,024 UTF-8 bytes |
208
+
209
+ ## What to read next
210
+
211
+ - [Memory overview](/docs/memory): slots, scope, namespace, and visibility.
212
+ - [File memory](./file): the built-in provider as a reference implementation.
213
+ - [Dynamic capabilities](../guides/dynamic-capabilities): the dynamic-tool lifecycle provider tools run through.
214
+ - [Default harness](../concepts/default-harness): compaction in the built-in loop.
@@ -0,0 +1,129 @@
1
+ ---
2
+ title: "File Memory"
3
+ description: "Configure the built-in fileMemory() provider: a bounded, model-maintained document per scope with save and remove tools."
4
+ ---
5
+
6
+ `fileMemory()` from `eve/memory/file` is the memory provider built into eve.
7
+ It keeps one small document per resolved scope, recalls that document before
8
+ each turn and after compaction, and gives the model two tools to maintain it.
9
+ Use it when a short list of durable facts and preferences is enough; use
10
+ [another provider](/docs/memory#choose-a-provider) when you need semantic
11
+ retrieval or automatic capture.
12
+
13
+ ```ts title="agent/memory/profile.ts"
14
+ import { defineMemory } from "eve/memory";
15
+ import { byPrincipal } from "eve/memory/scope";
16
+ import { fileMemory } from "eve/memory/file";
17
+
18
+ export default defineMemory({
19
+ description: "Remember stable facts and preferences about the caller.",
20
+ provider: fileMemory(),
21
+ scope: byPrincipal,
22
+ });
23
+ ```
24
+
25
+ ## How it behaves
26
+
27
+ The provider implements recall and tools but no automatic capture. The model
28
+ decides when to call `profile__save_memory` and `profile__remove_memory`, where
29
+ `profile` is the slot name. The slot `description` is prepended to both tool
30
+ descriptions.
31
+
32
+ Each saved entry receives a permanent numeric index that the model uses to
33
+ remove it later. The provider recalls the whole document as one message with a
34
+ stable ID, so an updated or emptied document replaces the earlier recalled copy
35
+ rather than accumulating beside it.
36
+
37
+ The provider rejects writes that exceed its limits instead of truncating or
38
+ evicting older entries:
39
+
40
+ | Limit | Value |
41
+ | ---------------- | ------------------------------------------------ |
42
+ | Recalled message | `maxCharacters`, default 4,000 |
43
+ | One entry | 2,048 UTF-8 bytes after whitespace normalization |
44
+ | Stored document | 65,536 bytes |
45
+
46
+ `maxCharacters` caps the exact recalled message, including its heading and
47
+ removal guidance:
48
+
49
+ ```ts
50
+ provider: fileMemory({ maxCharacters: 8_000 });
51
+ ```
52
+
53
+ Saving text identical to an existing entry is a no-op. Concurrent writes to the
54
+ same document use optimistic versioning and retry on conflict.
55
+
56
+ ## Storage backends
57
+
58
+ The document lives in a backend, not in the agent's sandbox filesystem. With no
59
+ `backend` option, `fileMemory()` selects one lazily on first use:
60
+
61
+ | Environment | Backend |
62
+ | ----------------------------------------------------------------- | ---------------------------------------- |
63
+ | Vercel with Blob credentials (token, or attached store with OIDC) | Private Vercel Blob |
64
+ | Vercel without Blob configuration | Error asking you to attach a Blob store |
65
+ | `eve dev` | Shared process-local in-memory storage |
66
+ | Every other environment | Error asking you for an explicit backend |
67
+
68
+ `NODE_ENV=development` alone does not select in-memory storage, and a Blob
69
+ token outside Vercel does not select Blob.
70
+
71
+ ### In-memory
72
+
73
+ Pass a fresh in-memory backend for tests or throwaway environments. It loses
74
+ its contents when the backend instance or process is replaced:
75
+
76
+ ```ts
77
+ import { fileMemory, inMemory } from "eve/memory/file";
78
+
79
+ provider: fileMemory({ backend: inMemory() });
80
+ ```
81
+
82
+ ### Vercel Blob
83
+
84
+ Use `vercelBlob()` from `eve/memory/file/vercel` to configure credentials or an
85
+ object prefix explicitly instead of relying on environment detection:
86
+
87
+ ```ts
88
+ import { fileMemory } from "eve/memory/file";
89
+ import { vercelBlob } from "eve/memory/file/vercel";
90
+
91
+ provider: fileMemory({
92
+ backend: vercelBlob({ prefix: "eve/memory/support-agent" }),
93
+ });
94
+ ```
95
+
96
+ `vercelBlob()` accepts `token`, `oidcToken`, `storeId`, and `prefix`. The
97
+ default prefix is `eve/memory/file`; documents are stored privately under
98
+ `<prefix>/<scope key>/MEMORY.md`.
99
+
100
+ ### Custom backend
101
+
102
+ Implement `MemoryDocumentBackend` from `eve/memory/file` to keep the document in
103
+ another store:
104
+
105
+ ```ts
106
+ import { MemoryDocumentConflictError, type MemoryDocumentBackend } from "eve/memory/file";
107
+
108
+ export function kvBackend(store: KvStore): MemoryDocumentBackend {
109
+ return {
110
+ async read({ key }) {
111
+ const row = await store.get(key);
112
+ return row ? { content: row.content, version: row.version } : null;
113
+ },
114
+ async write({ key, content, expectedVersion }) {
115
+ const ok = await store.compareAndSet(key, content, expectedVersion);
116
+ if (!ok) throw new MemoryDocumentConflictError(key);
117
+ return { content, version: await store.version(key) };
118
+ },
119
+ };
120
+ }
121
+ ```
122
+
123
+ `write()` replaces the complete document and must throw
124
+ `MemoryDocumentConflictError` when `expectedVersion` no longer matches. An
125
+ `expectedVersion` of `null` means the document must not exist yet.
126
+
127
+ A backend changes only where the document is stored. It does not change file
128
+ memory's recall format or tools. When you need different retrieval, capture, or
129
+ tools, [build a memory provider](./custom-provider) instead.
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Memory",
3
+ "defaultOpen": false,
4
+ "pages": ["overview", "file", "custom-provider"]
5
+ }