Memory Gateway

The Memory Gateway gives chat turns access to long-term memory stored in the entelecheia scepter / Philia memory service. On each chat turn Arona queries the service for memories relevant to the conversation, injects them into the prompt as a system section, and — after a completed reply — writes the turn back as an episode so future conversations can recall it.

It is a WebSocket JSON-RPC client to Philia (Sync.ConnectHandshake, Sync.MemoryQueryRequest, Sync.MemoryStoreRequest, Sync.MemoryDeleteRequest). Connections are established lazily, dropped on any error and re-established on the next call; every failure degrades silently and never blocks the chat path.

Configuration

The gateway is controlled by three environment variables:

VariableMeaning
ARONA_MEMORY_URLWebSocket URL of the scepter / Philia service, e.g. ws://192.0.2.10:8424/ws.
ARONA_MEMORY_TOKENToken for the memory service.
ARONA_MEMORY_WRITEBACKWhether completed turns are written back. Default on; set false to disable (parsed as a strict boolean — 0 is not accepted).

Both ARONA_MEMORY_URL and ARONA_MEMORY_TOKEN must be set and non-empty, otherwise the gateway is disabled: recall and writeback are skipped entirely and every request reports disabled. The token is sent both as a ?token= query parameter on the WebSocket upgrade and inside the Sync.ConnectHandshake request.

env
1
2
3
ARONA_MEMORY_URL=ws://192.0.2.10:8424/ws
ARONA_MEMORY_TOKEN=CHANGE_ME
ARONA_MEMORY_WRITEBACK=false

See Configuration for the full environment reference.

Recall injection

With the gateway enabled, every chat turn — REST non-streaming /v1/chat/completions, REST streaming (SSE), and RPC chat.send — queries the memory service before the request is forwarded:

The recall runs before conversation persistence and upstream forwarding; a slow or failing memory service adds no latency guarantee beyond its own 10-second RPC timeout and cannot fail the request.

Writeback

After a completed assistant reply, the turn is written back to the memory service as an episode node. The episode text is a heuristic transcript of the turn — User: <user content>\nAssistant: <assistant content> (either side omitted when empty; both empty skips the writeback). Writeback is fire-and-forget: it runs in a spawned task, never blocks the chat response, and its failures are only logged inside the memory client. (On the REST streaming path, writeback additionally requires a conversation to be attached to the request; the non-streaming REST and RPC paths write back regardless.)

Per-request control

Both the REST chat request body and the RPC chat.send params accept an optional memory field to override the server configuration per call:

json
1
{ "model": "", "messages": [], "memory": false }

The override affects recall; writeback follows only ARONA_MEMORY_WRITEBACK plus the gateway being enabled.

Header states

REST responses carry the turn's memory state in the X-Arona-Memory response header; the RPC chat.send response echoes the same value in a memory field of its result. Possible states:

ValueMeaning
enabledMemory was requested, the gateway is configured, recall succeeded and at least one memory was injected.
disabledGateway not configured, or memory: false on the request, or no user message to query, or recall succeeded but returned no relevant memories (nothing to inject).
offlineMemory was requested and the gateway is configured, but the recall call failed (connection refused, RPC error or timeout).
http
1
2
HTTP/1.1 200 OK
X-Arona-Memory: enabled

Failure semantics

Everything degrades explicitly, in the same direction — chat always runs:

There is no mode in which a memory outage fails or delays a chat request beyond the client's own bounded timeouts.

RPC surface

Two management methods are exposed on the JSON-RPC surface (both require a JWT; see JSON-RPC API):

memory.status — snapshot of the gateway:

json
1
2
3
4
5
6
7
8
9
{
  "enabled": true,
  "writeback": true,
  "events": [
    { "kind": "recall", "detail": "…query…", "at": "2026-01-01T00:00:00.000Z" },
    { "kind": "writeback", "detail": "…node id…", "at": "" },
    { "kind": "error", "detail": "", "at": "" }
  ]
}

events is an in-memory ring buffer of recent activity — recall, writeback, delete and error events, newest first, up to the requested count (the status handler requests the last 50; the buffer itself is capped at 100). It is not a durable audit log — it resets on restart.

memory.delete — prune a stored node by id:

json
1
{ "node_id": "" }

Returns { "deleted": true | false }. Fails with an error when node_id is missing or when the memory service is not configured.

Related