Skip to content

feat(eve): memory - add portable file memory - #1703

Open
AndrewBarba wants to merge 1 commit into
barba/first-class-memoryfrom
barba/user-memory-vercel-blob
Open

feat(eve): memory - add portable file memory#1703
AndrewBarba wants to merge 1 commit into
barba/first-class-memoryfrom
barba/user-memory-vercel-blob

Conversation

@AndrewBarba

@AndrewBarba AndrewBarba commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Related to #1510. Stacked on #1700.

Adds eve's first built-in file-memory provider and keeps persistence portable behind a narrow, versioned-document backend contract.

  • Adds scope-neutral fileMemory() from eve/memory/file. The authored memory scope determines whether a file belongs to a principal, workspace, or another trusted partition.
  • Exposes two minimal model operations: save_memory(text) adds one memory and returns its index, while forget_memory(index) removes one indexed memory. The model never recreates the full memory set.
  • Stores canonical index: memory text lines in MEMORY.md and recalls those indexes with the memories. New entries use the current highest index plus one; forgetting an entry never rewrites surviving indexes or fills gaps.
  • Bounds files with memoryLimit, which defaults to 100 memories. Only new, distinct saves consume the limit. At capacity, the model-visible tool error directs the model to forget an outdated memory by index and retry the save.
  • eve owns single-line normalization, exact deduplication, and preservation of unrelated entries. It reapplies individual save and forget operations after conditional-write conflicts, so concurrent model calls merge without exposing the backing document to the model.
  • Adds MemoryDocumentBackend, MemoryDocumentConflictError, process-local inMemory() storage, and private vercelBlob() storage with deterministic paths and ETag-based writes. KV stores, object stores, or database rows can implement the same contract.
  • Selects Vercel Blob automatically when deployed on Vercel and process-local memory elsewhere, with lazy process-lifetime selection. The vendored server-side Blob client adds no runtime dependency.

The main review points are the scope-neutral file abstraction, stable indexed tool contract, count-based limit and recovery path, conditional conflict retries, and default Vercel selection.

Validation

  • pnpm fmt
  • pnpm lint
  • pnpm typecheck (33 workspace tasks)
  • pnpm guard:invariants
  • pnpm docs:check (82 documents, 263 imports, 357 code blocks)
  • pnpm --filter eve build:compiled
  • pnpm build
  • pnpm --filter eve exec vitest run --config vitest.unit.config.ts src/public/memory/file (17 tests)
  • pnpm --filter eve exec vitest run --config vitest.integration.config.ts src/execution/file-memory.integration.test.ts (1 test)
  • pnpm --filter eve exec vitest run --config vitest.scenario.config.ts test/scenarios/file-memory-provider.scenario.test.ts (1 test)

The scenario installs the built package and imports fileMemory, inMemory, and vercelBlob through eve/memory/file. Vercel Blob behavior is covered through its mocked SDK contract; no live Blob credentials were used locally.

Checklist

  • I linked an issue with prior discussion confirming this change is wanted
  • I ran the relevant checks from CONTRIBUTING.md
  • I added tests and documentation where relevant
  • I added a changeset if this touches the published eve package
  • DCO sign-off passes for every commit (git commit --signoff)

@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
eve-docs Ready Ready Preview Aug 6, 2026 6:39pm
eve-docs-4759 Ready Ready Preview, v0 Aug 6, 2026 6:39pm

@AndrewBarba AndrewBarba changed the title feat(eve): add user memory provider feat(eve): memory - add portable user provider Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Bundle + Package Summary: apps/fixtures/weather-agent

Key takeaways

  • Package delta: install footprint 72.06 MB -> 72.53 MB (+469.9 kB ⚠️).

Delta vs barba/first-class-memory (fa212b2)

Area Metric Baseline Current Delta
Package Packed tarball 7.66 MB 7.81 MB +144.0 kB ⚠️
Package Unpacked publish size 28.72 MB 29.19 MB +469.9 kB ⚠️
Package Installed footprint 72.06 MB 72.53 MB +469.9 kB ⚠️
Package Published files 3047 3066 +19
Package Installed files 6748 6767 +19
Runtime Unique function payloads 2 2 0
Runtime Total function bytes 17.02 MB 17.02 MB -40 B ✅
Runtime Public routes 13 13 0
Changed function payloads vs barba/first-class-memory (fa212b2) (2)
Function Status Baseline Current Delta Route changes
functions/__server.func changed 8.51 MB 8.51 MB -20 B ✅ none
functions/.well-known/workflow/v1/flow.func changed 8.51 MB 8.51 MB -20 B ✅ none

eve init install

Metric Baseline Current Delta
Installed footprint 110.47 MB 110.94 MB +469.9 kB ⚠️
Installed packages 121 121 0
dependencies 4 4 0
devDependencies 2 2 0
Dependency package bytes 43.15 MB 43.62 MB +469.9 kB ⚠️
devDependency package bytes 5.04 MB 5.04 MB 0 B ➖
Build Metadata
  • Preset: vercel
  • Nitro: nitro@3.0.260610-beta
  • Output directory: apps/fixtures/weather-agent/.vercel/output
  • Build metadata timestamp: 2026-08-06T03:15:17.609Z
  • Route aliases: 13 public, 1 internal (14 total aliases)
  • Vercel routes in config: 16
  • Severity legend: 🔴 dominant/large, 🟠 notable, 🟡 watch, ⚪ small
Package Drill-Down

Package Details

  • Package: eve@0.30.8
  • Package directory: packages/eve
  • Tarball: 7.81 MB (eve-0.30.8.tgz)
  • Unpacked payload: 29.19 MB across 3066 published files
  • Installed footprint: 72.53 MB across 6767 installed files
  • Installed root package: 27.84 MB
  • Installed dependencies: 44.70 MB
  • Runtime dependencies: 2
  • Peer dependencies: 5 (4 optional)

Installed footprint is measured from an isolated temporary npm install of the packed tarball.

Heavy installed dependencies

  • eve: 27.84 MB (38.4%)
  • @rolldown/binding-linux-x64-gnu: 19.35 MB (26.7%)
  • ai: 6.61 MB (9.1%)
  • zod: 5.07 MB (7.0%)
  • undici: 3.50 MB (4.8%)
Publish payload breakdown
Published file size
🔴 dist/src/compiled/shadcn-registry/index.js       [################........] 9.68 MB 33.2%
🟠 dist/src/compiled/@photon-ai/chat-adapter-ime... [####....................] 2.42 MB 8.3%
🟠 dist/src/compiled/experimental-ai-sdk-code-mo... [##......................] 1.51 MB 5.2%
🟡 dist/src/compiled/_chunks/node/undici-DWL_MYm... [#.......................] 502.4 kB 1.7%
🟡 dist/src/compiled/_chunks/workflow/undici-DWL... [#.......................] 502.4 kB 1.7%
🔴 Other published files                            [########################] 14.58 MB 49.9%
Installed footprint breakdown
Installed package size
🔴 eve                             [########################] 27.84 MB 38.4%
🔴 @rolldown/binding-linux-x64-gnu [#################.......] 19.35 MB 26.7%
🔴 ai                              [######..................] 6.61 MB 9.1%
🔴 zod                             [####....................] 5.07 MB 7.0%
🟠 undici                          [###.....................] 3.50 MB 4.8%
🟠 nitro                           [##......................] 2.41 MB 3.3%
🔴 Other installed packages        [#######.................] 7.76 MB 10.7%
Runtime dependencies (2)
Package Range Notes
nitro 3.0.260610-beta
undici 8.9.0
Peer dependencies (5)
Package Range Notes
@opentelemetry/api ^1.0.0 optional peer
ai catalog:
braintrust ^3.0.0 optional peer
just-bash ^3.0.0 optional peer
microsandbox ^0.5.0 optional peer
eve init install drill-down

eve init install details

  • Command: eve init my-agent
  • Package manager: npm
  • Installed footprint: 110.94 MB across 8643 installed files
  • Installed packages: 121 total (115 transitive-only)
  • dependencies: 4 direct packages totaling 43.62 MB
  • devDependencies: 2 direct packages totaling 5.04 MB
  • Other transitive package files: 62.29 MB

Installed footprint is measured from an isolated temporary eve init my-agent using the current packed eve tarball.

Heavy installed dependencies

  • @typescript/typescript-linux-x64: 27.95 MB (25.2%)
  • eve: 27.84 MB (25.1%)
  • @rolldown/binding-linux-x64-gnu: 19.35 MB (17.4%)
  • zod: 9.02 MB (8.1%)
  • ai: 6.61 MB (6.0%)
Installed footprint breakdown
Installed package size
🔴 @typescript/typescript-linux-x64 [########################] 27.95 MB 25.2%
🔴 eve                              [########################] 27.84 MB 25.1%
🔴 @rolldown/binding-linux-x64-gnu  [#################.......] 19.35 MB 17.4%
🔴 zod                              [########................] 9.02 MB 8.1%
🔴 ai                               [######..................] 6.61 MB 6.0%
🟠 undici                           [###.....................] 3.50 MB 3.2%
🔴 Other installed packages         [##############..........] 16.67 MB 15.0%
dependencies (4)
Package Range Installed size Share
@vercel/connect 0.4.3 141.0 kB 0.1%
ai ^7.0.38 6.61 MB 6.0%
eve file:eve-0.30.8.tgz 27.84 MB 25.1%
zod 4.4.3 9.02 MB 8.1%
devDependencies (2)
Package Range Installed size Share
@types/node 24.x 2.54 MB 2.3%
typescript 7.0.2 2.50 MB 2.3%
Function Drill-Down

Payload Size Graph

Unique function payload size and share of total
🔴 functions/.well-known/workflow/v1/flow.func     [########################] 8.51 MB 50.0%
🔴 functions/__server.func                         [########################] 8.51 MB 50.0%

Top Function Payloads

🟠 functions/.well-known/workflow/v1/flow.func • 1 public route • 8.51 MB
Metric Value
Public routes /.well-known/workflow/v1/flow
Runtime nodejs24.x
Handler index.mjs
Payload 8.51 MB
Function files 8.51 MB across 43 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 2.33 MB (27.3%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                       [#######################.] 2.33 MB 27.3%
🟠 _chunks/runtime-artifacts.mjs   [################........] 1.62 MB 19.0%
🟡 _libs/undici.mjs                [##########..............] 980.5 kB 11.5%
🟡 _chunks/sandbox.mjs             [########................] 769.0 kB 9.0%
🟡 _libs/@ai-sdk/gateway+[...].mjs [####....................] 432.8 kB 5.1%
🟠 Other bundled files             [########################] 2.38 MB 28.0%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x",
  "maxDuration": "max",
  "experimentalTriggers": [
    {
      "type": "queue/v2beta",
      "topic": "__eve776561746865722d6167656e74_wkf_workflow_*",
      "consumer": "default",
      "retryAfterSeconds": 5,
      "initialDelaySeconds": 0
    }
  ],
  "environment": {
    "WORKFLOW_PRECONDITION_GUARD": "1"
  }
}

🟠 functions/__server.func • 12 public routes, 1 internal alias • 8.51 MB
Metric Value
Public routes /
/eve/v1/callback/[token]
/eve/v1/connections/[name]/callback/[token]
/eve/v1/health
/eve/v1/info
/eve/v1/session
/eve/v1/session/[sessionId]
/eve/v1/session/[sessionId]/cancel
/eve/v1/session/[sessionId]/clear
/eve/v1/session/[sessionId]/compact
/eve/v1/session/[sessionId]/reset
/eve/v1/session/[sessionId]/stream
Internal aliases /__server
Runtime nodejs24.x
Handler index.mjs
Payload 8.51 MB
Function files 8.51 MB across 43 files
Traced dependencies 0 B
Signal 🟠 Bundled file index.mjs is 2.33 MB (27.3%)

🟠 🔎 Dependency Analysis

📦 Bundled files:

Bundled file size
🟠 index.mjs                       [#######################.] 2.33 MB 27.3%
🟠 _chunks/runtime-artifacts.mjs   [################........] 1.62 MB 19.0%
🟡 _libs/undici.mjs                [##########..............] 980.5 kB 11.5%
🟡 _chunks/sandbox.mjs             [########................] 769.0 kB 9.0%
🟡 _libs/@ai-sdk/gateway+[...].mjs [####....................] 432.8 kB 5.1%
🟠 Other bundled files             [########################] 2.38 MB 28.0%

🧾 Vercel Config

{
  "handler": "index.mjs",
  "launcherType": "Nodejs",
  "shouldAddHelpers": false,
  "supportsResponseStreaming": true,
  "runtime": "nodejs24.x"
}

Build Timing: e2e/fixtures/agent-tools-sandbox

This is an informational timing measurement inside eve build, from preflight through publication. Output-size measurement and profile writing are excluded.

Build mode: deployable Vercel build with sandbox template prewarm included.

  • Build pipeline: 1.86 s -> 1.85 s (-15.5 ms) vs barba/first-class-memory (fa212b2).
  • Timing is informational: shared GitHub runners are too variable for a hard timing budget.
Detailed phase timings vs `barba/first-class-memory (fa212b2)`
Phase Baseline Current Delta
extension.check 15.7 ms 0.8 ms -14.9 ms
project.resolve 3.5 ms 0.4 ms -3.1 ms
workspace.create 8.4 ms 0.5 ms -7.9 ms
host.prepare 268.1 ms 251.7 ms -16.4 ms
vercel.service-prefix.resolve 1.6 ms 1.5 ms -0.1 ms
nitro.create 223.7 ms 232.7 ms +9.0 ms
sandbox.prewarm 274.9 ms 249.4 ms -25.5 ms
nitro.cache.prepare 0.2 ms 0.2 ms 0.0 ms
nitro.prepare 0.6 ms 0.6 ms 0.0 ms
nitro.public-assets 0.6 ms 0.6 ms 0.0 ms
nitro.prerender 0.3 ms 0.4 ms +0.1 ms
nitro.bundle 1.00 s 1.05 s +49.3 ms
nitro.cache.write 0.3 ms 0.2 ms -0.1 ms
vercel.workflow-function.materialize 57.6 ms 38.0 ms -19.6 ms
agent-summary.emit 0.4 ms 0.4 ms 0.0 ms
nitro.close 0.1 ms 0.1 ms 0.0 ms
output.publish 2.3 ms 16.2 ms +13.9 ms
workspace.remove 1.3 ms 1.5 ms +0.2 ms

Comment thread docs/memory.md
provider: userMemory({
backend: vercelBlob({
prefix: "my-agent/memory/user",
token: process.env.BLOB_READ_WRITE_TOKEN,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this token? Let's recommend OIDC

};

return {
forget_memory: defineTool({

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove_memory is probably a better name here. more clear as the the effect

const entries = parseMemoryDocument(document?.content ?? "");
const existing = entries.find((entry) => entry.text === text);
if (existing !== undefined) return { index: existing.index };
if (entries.length >= input.memoryLimit) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why number of entries vs length? The latter enforces concise entries as well


return defineMemoryProvider({
events: {
async "turn.prepared"(_event, context) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use hook event names? i don't think turn.prepared exists

@ctgowrie

ctgowrie commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

e2e?

Signed-off-by: Andrew Barba <barba@hey.com>
@AndrewBarba
AndrewBarba force-pushed the barba/user-memory-vercel-blob branch from 36a476b to 3027fc1 Compare August 6, 2026 18:37
@AndrewBarba AndrewBarba changed the title feat(eve): memory - add portable user provider feat(eve): memory - add portable file memory Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants