Building agents with code.
README.md

Memory #

Track: Phase 1

Goal #

Create or open an agent that retains identity or conversation state across a disconnect / second turn, then show that prior context still affects the later reply.

Success criteria #

  • Turn 1 establishes a memorable fact or persona.
  • After ending the first connection (or starting a new turn on a durable id), turn 2 refers to that fact without re-sending the full history from the client.
  • The second reply clearly depends on the retained state.

Assert (smoke) #

AGENT_LAB_RESULT {"v":1,"scenario":"memory","ok":true,"checks":{"durable_id":true,"fact_recalled":true,"reconnect":true}} Missing keys → AGENT_LAB_SKIP with scenario":"memory".

Check id Required Pass when
durable_id yes Non-empty durable session/agent/thread id used across turns
fact_recalled yes Turn-2 reply contains the planted fact (Orchid for the suggested prompt)
reconnect yes Connection/process truly ended before turn 2 (true only after dispose/exit/resume path)

Observe-only: richer “depends on state” beyond the fact substring (v1 uses fact_recalled as proxy).

Constraints #

  • Persistence mechanism is up to the stack (server memory blocks, checkpointer + thread id, durable instance state, session resume, etc.).
  • In-process variables that disappear when the script exits do not count.
  • No Modal. Do not invent Decisions clients or undocumented APIs.
  • Soft-pedal employer Managed platforms as first fills — prefer stacks with a documented durable session/thread/resume API.

Prompt (suggested) #

  1. Remember that the project codename is Orchid.
  2. (reconnect / new session on same agent) What is the project codename?

Mental model #

Memory is durable identity + true reconnect: turn 1 plants a fact under a stable session/agent/thread id; the process or connection ends; turn 2 resumes that id without the client replaying the full history, and the reply still contains the fact. In-process variables, module globals, or “keep the same messages[] array in RAM” die with the process and do not count — reconnect must reflect dispose/exit/resume. Failure looks like a two-turn chat in one process that never dropped the connection, or a client that re-sends the planted fact on turn 2.

What excellent looks like #

  • Capture a durable id after turn 1; dispose or exit; resume by id for turn 2; assert Orchid in the second reply.
  • Document the stack primitive in the folder README (conversation id, session.resume, checkpointer thread_id, Durable Object state, etc.).
  • Preferred stacks when Eng fills: TypeScript — Letta resumeSession, openai-agents Conversations session, claude-agent-sdk options.resume, LangGraph checkpointer; leave raw Messages/Responses gap unless a documented Conversations-style API is wired. Do not invent APIs.

Implementations #

Status badges match ../GAPS.md: verified = tripwire PASS; linked — pending keys+PASS = path present, not done; gap / stub unchanged. Do not treat linked as verified.

Folder Path Status Notes
claude/ — gap (raw Messages has no durable store)
openai/ — gap (raw Responses history is client-managed unless Conversations API — not wired here)
gemini/ — gap
letta/ index.ts verified createSession → dispose → resumeSession(agentId)
eve/ — gap (durable sessions are a product pitch)
langchain/ index.py linked — pending keys+PASS SqliteSaver + thread_id (file-backed)
openai-agents/ index.ts linked — pending keys+PASS OpenAIConversationsSession + reconnect by conversationId
claude-agent-sdk/ index.ts linked — pending keys+PASS Capture session_id → options.resume
notion-agent/ index.ts linked — pending keys+PASS Continue with session_id (TS)
gemini-managed/ index.ts linked — pending keys+PASS previous_interaction_id + environment (TS)
claude-managed/ index.ts linked — pending keys+PASS Two turns on the same session id (TS)
cloudflare-agents/ index.ts → MemoryAgent in index.ts linked — pending keys+PASS this.setState / DO instance name