Knowledge¶
This page covers the read-only endpoints that surface what a persona keeps on disk: her conversation history, her readable knowledge (memory files and instructions), her calendar, a full diagnostic snapshot, her exported diary, and the media files she's produced.
Every route here takes the persona's id as a path param. All of them work whether she's running or stopped — they read her persisted files, not a live agent. They return 404 when no persona with that id exists on disk.
Conversation¶
Read the persona's stored conversation history — the running transcript she reads each beat.
GET /api/persona/{persona_id}/conversation
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
Response¶
200 — the raw conversation log, read line-for-line from her conversation.jsonl:
{
"messages": [
{
"role": "person",
"content": "Morning market context — risk-off across majors.",
"channel": { "type": "web", "name": "31c8fd99-a63d-4e3c-84d8-317f710b6069" },
"time": "2026-06-04T08:01:53.655812+02:00"
},
{
"role": "assistant",
"content": "Noted. I'll fold that into today's call.",
"channel": { "type": "web", "name": "31c8fd99-a63d-4e3c-84d8-317f710b6069" },
"time": "2026-06-04T08:02:10.114229+02:00"
}
]
}
Each entry is whatever was persisted, returned untouched. In practice every record carries role, content, channel (a {type, name} object, or null for internal turns), and time (ISO 8601). role is the on-disk value — person for your words, assistant for hers — not the wire user/assistant split. Older records may omit fields the writer didn't set; read defensively.
Errors¶
| Status | Meaning |
|---|---|
404 |
No persona with that id, or her conversation file can't be read. detail carries the reason. |
Example¶
Knowledge¶
Read everything the persona keeps in human-readable form, in one shape: her memory files (what she's learned about you and herself) and her instruction catalog (every instruction she can load — see Vocabulary).
GET /api/persona/{persona_id}/knowledge
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
Response¶
200:
{
"memory": {
"person": "# Morteza\n\nCreator of Eternego. Prefers terse, direct answers...",
"traits": "# Traits I've seen in Morteza\n\nDecisive, allergic to fluff...",
"persona-trait": "# How I show up with Morteza\n\nI keep it concrete...",
"wishes": "# Wishes\n\n- Ship the morning market call reliably...",
"struggles": "# Open struggles\n\n- Slow local beats on this hardware...",
"permissions": "# Permissions\n\n- Free to post to x.com; ask before emailing..."
},
"instruction": [
{
"intention": "Any type of conversation, there is nothing to do but talk",
"body": "Just talk. Listen, reply, stay yourself...",
"source": "builtin"
},
{
"intention": "Sweeping x.com",
"body": "A sweep is a structured check of mentions...",
"source": "custom"
}
]
}
memory is a {key: markdown_body} map. The keys are person, traits, persona-trait, wishes, struggles, permissions. Empty files are omitted, so a fresh persona returns fewer keys (or {}) — don't assume all six are present.
instruction is the full catalog as a flat list, each entry carrying:
| Field | Type | Description |
|---|---|---|
intention |
string | The instruction's title — the H1 of its file, the kind of moment it covers. |
body |
string | The path — the steps she follows once the instruction is loaded. |
source |
string | builtin (ships with Eternego) or custom (written by this persona, living in her meanings/ directory — her instructions on disk). |
Bodies are returned verbatim — secrets included
An instruction's body is the file's literal text. If a persona has written credentials into one of her own instructions (an API key, an OAuth secret), they appear here in the clear. This response is not masked. Treat it as sensitive.
Errors¶
| Status | Meaning |
|---|---|
404 |
No persona with that id. |
400 |
Found, but her knowledge couldn't be read ("Could not read knowledge."). |
Example¶
curl -s http://localhost:5000/api/persona/31c8fd99-a63d-4e3c-84d8-317f710b6069/knowledge | jq '.memory | keys'
Calendar¶
Read what the persona keeps in her calendar between two dates — past events she's archived (history/) and future events she's scheduled (destiny/). This is a view of her files, not a calendar engine: recurring items aren't projected, only what's actually on disk is returned.
GET /api/persona/{persona_id}/calendar?start=<iso>&end=<iso>
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
Query params¶
| Param | Type | Required | Description |
|---|---|---|---|
start |
string (ISO 8601) | yes | Window start, inclusive. Parsed with datetime.fromisoformat — accepts a date (2026-06-01) or a full timestamp (2026-06-01T00:00:00). |
end |
string (ISO 8601) | yes | Window end, exclusive. Same format. |
Events are kept when start <= event_time < end.
Response¶
200 — the window echoed back, plus the two halves grouped by subtype:
{
"start": "2026-06-01",
"end": "2026-07-01",
"history": {
"conversation": [
{ "time": "2026-06-04T00:01:04.528143+02:00", "body": "Talked through the morning market call..." }
],
"schedule": [],
"reminder": []
},
"destiny": {
"schedule": [
{ "time": "2026-06-04T08:00:00", "body": "Run the morning news + market context search.", "recurrence": "daily" }
],
"reminder": []
}
}
history— past events. Keys are alwaysconversation,schedule,reminder. Each entry:time(ISO 8601 — for conversations, the precise timestamp from herbriefing.mdindex; otherwise derived from the filename) andbody(the file's markdown).destiny— future events. Keys are alwaysschedule,reminder. Each entry:time,body, andrecurrence(the value of arecurrence:line in the file, lower-cased — e.g."daily","weekly"— ornullif none).recurrenceis informational only; nothing is projected from it.
A subtype with no matching events in the window is an empty list [], never absent.
Errors¶
| Status | Meaning |
|---|---|
404 |
No persona with that id. |
400 |
start/end aren't valid ISO dates ("start and end must be ISO dates"), or the calendar couldn't be read ("Could not read calendar."). |
Example¶
curl -s "http://localhost:5000/api/persona/6c17c83c-3158-450d-8e43-0e7efea717c1/calendar?start=2026-06-01&end=2026-07-01"
Diagnose¶
A full diagnostic snapshot — her vital status, her last persisted mind state, and a 24-hour uptime grid — all read from disk. This is what the Status panel renders; it works while she's stopped.
GET /api/persona/{persona_id}/diagnose
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
Response¶
200:
{
"status": "active",
"mind": {
"messages": [
{ "content": "...", "channel": { "type": "web", "name": "..." }, "prompt": { "role": "user", "content": "...", "cache_point": false }, "media": null, "id": "..." }
],
"archive": [],
"context": "Carrying: the morning market call is the day's anchor."
},
"uptime": {
"rows": [
{
"from": "2026-06-04T07:00:00",
"to": "2026-06-04T08:00:00",
"cells": [
{ "at": "2026-06-04T07:59:00", "tick": true, "fault": false, "providers": [], "signals": [] }
]
}
]
}
}
| Field | Type | Description |
|---|---|---|
status |
string | Her vital state — one of active, hibernate, sick (see Vocabulary). |
mind |
object | Her latest persisted mind state, echoed raw from her memory.json — messages (the running transcript, each entry the full stored record: content, channel, a nested prompt with the wire role, media, id), archive (older turns rolled out of the active window), and context (her carried summary). {} if none has been written yet. Ephemeral plan/instruction state is not persisted here, so it never appears. |
uptime |
object | A { "rows": [...] } grid: 24 rows × 60 minute-cells, most recent first. Each cell carries at (the minute), tick (did a beat run), fault (did a fault fire), providers (faulting providers, if any), and signals (signals captured that minute). Derived from her raw health log. |
Errors¶
| Status | Meaning |
|---|---|
404 |
No persona with that id. |
400 |
Found, but the diagnostic couldn't be assembled. detail carries the reason. |
Example¶
curl -s http://localhost:5000/api/persona/6c17c83c-3158-450d-8e43-0e7efea717c1/diagnose | jq '{status, rows: (.uptime.rows | length)}'
Export¶
Download the persona's encrypted diary — the single file needed to move her to another machine. Decrypting it requires her recovery phrase.
GET /api/persona/{persona_id}/export
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
Response¶
200 — the diary file as a binary download (Content-Type: application/octet-stream), filename <persona_id>.diary.
The file is ~/.eternego/diary/<id>/<id>.diary. It is written by her nightly sleep ritual, so it does not exist until she has slept at least once.
Errors¶
| Status | Meaning |
|---|---|
404 |
No diary file yet ("No diary file yet — wait until the persona's first nightly sleep."). Send her to sleep once, or wait for her nightly ritual, then retry. |
Example¶
Media¶
Fetch a media file the persona has produced or received — the image she drew, the voice clip she spoke. Filenames arrive over the WebSocket as a url field on chat_image / chat_audio events; this is the endpoint that serves the bytes.
GET /api/persona/{persona_id}/media/{filename}
| Path param | Type | Description |
|---|---|---|
persona_id |
string | Her UUID. |
filename |
string | The file's name inside her media directory (~/.eternego/personas/<id>/home/media/). |
Response¶
200 — the file's bytes as a FileResponse, with the content type inferred from its extension.
The lookup is sandboxed to her media directory: the resolved path must sit inside it and must be a real file. Anything else — a traversal attempt, a missing file — is a flat 404.
Errors¶
| Status | Meaning |
|---|---|
404 |
The file isn't in her media directory, or doesn't exist ("File not found."). |
Example¶
curl -s -o reply.png http://localhost:5000/api/persona/9ecfd82b-ec47-4644-8941-02ecfb7e6205/media/reply.png
Related¶
- Perception — the write side: send her text, voice, and files.
- WebSockets — where
chat_image/chat_audiourls come from. - Her files — what these endpoints read, on disk.
- The panel — Status, Calendar, Memory & instructions — the screens these routes sit behind.
- Vocabulary —
instruction,intention,path, the threestatusvalues,diary,recovery phrase.