Skip to content

feat: run Data on a self-hosted Letta agent instead of a Zo persona - #10

Merged
EthanThatOneKid merged 1 commit into
mainfrom
letta-cutover
Sep 25, 2026
Merged

EthanThatOneKid merged 1 commit into
mainfrom
letta-cutover

Conversation

@EthanThatOneKid

Copy link
Copy Markdown
Contributor

Closes the third open item in #9: Data stops being a Zo persona and becomes the first self-hosted Letta agent on the Zo host.

What changes

  • Brain. channels/http/ turns a question into one headless turn of the local agent (letta --backend local --agent <id> -p <question> --output-format json) and reuses the conversation_id it returns for the next question on the same session. Continuity no longer needs a Cloud round trip.
  • Prompt stays in one place. agent/instructions.md is still the source of truth; scripts/sync-persona.ts (npm run sync-persona, --dry-run supported) renders it into the agent's memory as system/persona.md and commits it. Covered by lib/sync-persona.test.ts.
  • Provider key. The Letta harness reads only the canonical name, so the service exports DATA_OPENROUTER_API_KEY as OPENROUTER_API_KEY at startup.
  • Serialized turns. The local backend is a file-backed store, so two turns must never interleave; they queue in order.
  • Rollback. DATA_BRAIN=zo answers from the persona again. Both paths share framing and session bookkeeping, and /health now reports the brain, the agent id, and the resolved CLI path.

Verification

Run from a service-like environment — env -i with only HOME, PATH, the secret file, and DATA_LETTA_BIN:

  • /health → brain: letta, lettaBin: /usr/bin/letta, agent id reported.
  • A cited answer named channels/http/index.ts lines 356-357 (POST /ask) and readJsonBody lines 289-300; both checked against the file by hand.
  • A second question on the same session continued the conversation (same conversation_id, contextual answer).
  • The agent's memory repo holds system/persona.md seeded from agent/instructions.md (commit 190caa4), and a live turn answered "who are you" in Data's voice with its read-only boundary.
  • npm run typecheck clean; npm test 17/17.

Data's brain becomes a self-hosted Letta agent (Letta Code 0.33.1,
`--backend local`) on the Zo host, whose memory is a local git repository of
markdown. `channels/http/` now turns a question into one headless turn of that
agent and reuses the `conversation_id` it returns for the next question on the
same session, so continuity survives without a Cloud round trip.

- `agent/instructions.md` stays the source of truth; `scripts/sync-persona.ts`
  renders it into the agent's memory as `system/persona.md` and commits it, so
  the prompt cannot drift silently.
- The agent reads its provider key under its canonical name only, so the service
  exports `DATA_OPENROUTER_API_KEY` as `OPENROUTER_API_KEY` at startup.
- Turns are serialized: the local backend is a file-backed store, so two
  concurrent turns must never interleave.
- `DATA_BRAIN=zo` restores the persona path as the rollback, and `/health` now
  reports the brain, the agent id, and the resolved CLI path.

Verified from a service-like environment (`env -i` with `HOME`, `PATH`, and the
secret file): `/health` reports `brain: letta`, a cited answer named
`channels/http/index.ts` lines 356-357 and `readJsonBody` 289-300 — both checked
by hand — and a second question on the same session continued the conversation.

Refs #9
@wazoocomputer

wazoocomputer Bot commented Sep 25, 2026

Copy link
Copy Markdown

This pull request, "feat: run Data on a self-hosted Letta agent instead of a Zo persona" (#10), transitions the Data agent from a Zo persona to a self-hosted Letta agent. This change is driven by the goal to run Data on a local agent, improving continuity and streamlining prompt management. The core changes involve updating how Data's "brain" processes questions, centralizing the agent's prompt, and adapting to the new Letta-based execution environment.

Here's a breakdown of the changes:

File Path Change Type Summary
.gitignore modified Adds .letta/ to gitignore to exclude runtime state.
AGENTS.md modified Updates documentation to reflect the new self-hosted Letta agent architecture and prompt management.
README.md modified Updates the main README to describe Data's new identity as a self-hosted Letta agent and how it runs.
agent/README.md modified Clarifies how Data's prompt is managed within the self-hosted Letta agent.
channels/discord/README.md modified Updates description to align with the new brain architecture.
channels/http/README.md modified Details the new data-http service, its endpoints, and environment variables for the Letta agent.
channels/http/index.ts modified Implements the core logic for routing questions to the self-hosted Letta agent, including conversation management and environment variable handling.
lib/sync-persona.test.ts added Adds tests for the sync-persona script.
lib/sync-persona.ts added Implements the sync-persona script for seeding the agent's memory.
package.json modified Updates dependencies or scripts.
scripts/sync-persona.ts added Adds a script to synchronize the agent's persona.
services/README.md modified Minor update to services documentation.
services/http-api.md modified Updates documentation for the HTTP API to reflect the new architecture.

Reviewers should start by examining channels/http/index.ts to understand how questions are now routed to the self-hosted Letta agent and how conversations are managed.

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.

1 participant