Skip to content

feat(eve): memory provider for eve's first-class memory slots (v0.3.0) - #4735

Merged
benfrank241 merged 3 commits into
mainfrom
feat/eve-memory-provider
Sep 28, 2026
Merged

benfrank241 merged 3 commits into
mainfrom
feat/eve-memory-provider

Conversation

@benfrank241

Copy link
Copy Markdown
Member

Summary

Vercel asked us (on X) to migrate @vectorize-io/hindsight-eve to eve's new memory provider contract. This PR does that as v0.3.0.

hindsightMemory() now returns a MemoryProvider for one authored file:

// agent/memory/hindsight.ts
export default defineMemory({
  description: "Long-term memory about the current user.",
  provider: hindsightMemory(),
  scope: byPrincipal,
});

What the contract fixes vs. the v0.2 hooks/instructions approach:

  • Recall runs on the live user message (ctx.turn.input) — v0.2 had to use a fixed broad query because eve's instruction resolver couldn't see it.
  • One bank per locked scope (bankId = scope.key) — tenants are isolated as eve requires. A string bankId / HINDSIGHT_BANK_ID still pins a shared bank for single-user agents; a resolver names banks yourself.
  • Each turn's recall is one message with a stable id, so it supersedes the previous block instead of accumulating in history (incl. after compaction).
  • Captures use eve's operationId as document_id, so a replay replaces rather than duplicates.
  • <slot>__reflect tool exposed by default (tools: false to opt out).
  • A failed recall reports via onError and never fails the turn; recall on a not-yet-created bank (404) reads as empty.

The v0.2 entrypoints stay for one release as hindsightAutoRecall() / hindsightRetainHook() (deprecated). Dev dep → eve 0.66.2, peer → >=0.45.1. Docs page, README and gallery blurb updated.

Upstream regression found while verifying

eve 0.51.0+ never invokes capture["turn.completed"] for any provider — vercel/eve#2690 dropped the history argument from emitTurnEpilogue. Tracked in vercel/eve#3223 (p0), fix pending in vercel/eve#3465; I added a 0.66.2 confirmation there. README/docs carry a "Known issue" section with the interim (pin eve@0.50.0, or keep the deprecated retain hook alongside the provider).

Test plan

  • 59 unit tests (vitest), typecheck, tsup build, lockfile gate
  • Provider tests drive eve-shaped MemoryTurnStartedContext / MemoryTurnCompletedContext / MemoryToolsContext against a mocked fetch
  • Live e2e against Hindsight Cloud with a scaffolded eve agent (eve dev --no-ui, gpt-4.1): on eve 0.49.1, session 1 "use Python, full type hints, no comments" → captured; fresh session "Write me a throttle function." → typed, comment-free Python, "as per your preferences", zero tool calls. On 0.66.2 recall works and capture never fires (the upstream bug above).
  • /code-review — only failure is eslint for the control plane, which has no node_modules in the fresh worktree and isn't touched here

🤖 Generated with Claude Code

benfrank241 and others added 3 commits September 24, 2026 14:38
Vercel added a memory provider contract to eve (0.45.1: defineMemoryProvider
with recall / capture / tools handlers, bound to a slot via defineMemory) and
asked us to migrate. The v0.2 package hand-rolled the same shape on generic
hooks + dynamic instructions, with two known gaps that the contract closes:

- recall now runs on the live user message (ctx.turn.input) instead of a
  fixed broad query, because the instruction resolver could not see it
- every locked scope gets its own bank (bank id = scope.key), so tenants
  are isolated as eve requires; a string bankId / HINDSIGHT_BANK_ID still
  pins a single shared bank for single-user agents

hindsightMemory() now returns the provider for agent/memory/hindsight.ts.
Each turn's recall is one message with a stable id so it supersedes the
previous block rather than accumulating in history; captures use eve's
operationId as document_id so a replay replaces instead of duplicating;
a reflect tool (<slot>__reflect) is exposed by default. A failed recall
reports through onError and never fails the turn.

The v0.2 entrypoints stay one release as hindsightAutoRecall() /
hindsightRetainHook() (deprecated). Dev dep moves to eve 0.66.2, peer
range to >=0.45.1. 57 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rror

Retain creates a bank on first write, recall does not, so the very first
turn for a new scope logged a 404 through onError. HindsightHttpError now
carries the status and recall maps a 404 to no results.

Also documents the upstream regression found while verifying end to end:
eve 0.51.0+ never invokes capture["turn.completed"] for any provider
(vercel/eve#3223, fix in #3465). Verified the provider captures and
recalls correctly on eve 0.49.1.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@benfrank241
benfrank241 merged commit 295b53f into main Sep 28, 2026
97 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants