# AGENTS.md — pi-everos-memory

A pi extension package that exposes EverOS long-term memory as model-callable tools.

## Module map

- `src/index.ts` — extension entry; default export registers tools.
- `src/tools.ts` — 9 tools (typebox params, `pi.registerTool`):
  user memory `memory_search` / `memory_add` / `memory_profile` / `memory_episodes` / `memory_foresight` / `memory_delete`;
  agent memory `agent_skills` / `agent_cases` / `agent_record`.
- `src/everos.ts` — EverOS REST client over `fetch` (search, get, add+flush, agent add+flush, delete) plus multimodal upload (`/object/sign` + S3 presigned POST via `uploadLocalFiles`).
- `src/api.ts` — `ApiDialect`: per-version paths and field names. v1 is the default and the only dialect verified against the cloud; v2 is wired from the published OpenAPI and opt-in via `EVEROS_API_VERSION=v2`. Never hardcode a path in `everos.ts`.
- `src/config.ts` — constants (`USER_ID=wu`, method, base URL, flush backoff) and `loadApiKey()` (env or `.env` walk-up).
- `src/prompts.ts` — `MEMORY_PROMPT_GUIDELINES`: per-tool guideline bullets, attached to each tool individually. pi flattens active tools' guidelines into the system prompt without cross-tool dedup, so a single shared array would repeat ~9x.
- `test/` — manifest + unit tests (`node --import tsx --test`).

## Conventions

- Pure TypeScript; no Python/native deps. Cloud-only EverOS.
- pi bundles `@earendil-works/pi-coding-agent`, `@earendil-works/pi-ai`, `typebox` at runtime; they are optional peer deps.
- Recording is agent-judged (LLM calls `memory_add`), not automatic.
- **`add` is async (HTTP 202, queued).** A flush issued right after it sees an empty buffer and returns `status: "no_extraction"`, so the write yields nothing. `flushUntilExtracted` retries on that status with a widening backoff (~32s budget; extraction usually lands within ~20s) and reports `extracted` / `flush_attempts` to the caller. Never flush once and assume success.
- **The cloud silently ignores unknown request fields** (a made-up param still returns 200), so HTTP 200 does not prove a parameter is supported. Verify new params by their effect, not the status code.
- `memory_delete` single mode uses the **MemCell id** (= search result `parent_id`), not episode/atomic_fact ids; returns 204. Search is eventually consistent (deleted items linger briefly); `/memories/get` is canonical. No interactive confirmation. Both modes cover the user track only — a session batch delete leaves that session's `agent_case`/`agent_skill` behind, and deleting those by id returns 204 without removing them (verified 2026-07-25).
- Prefer correcting facts via `memory_add` (consolidation supersedes); delete only to truly remove.
- `memory_search` exposes `method`/`radius`/`include_original_data`; `memory_add` takes `attachments` (local paths → `/object/sign` → S3 → `ContentItem` on the latest user message, image/pdf/doc/txt/html/eml/mp3/wav); `agent_record` supports real `tool_calls`/`tool` steps (OpenAI format).
- `agent_skills`/`agent_cases` take an optional `query`: with it they run a relevance-ranked `memory_types: ["agent_memory"]` search (both tracks come back under `data.agent_memory.{skills,cases}`), without it they list recent items via `/get`. Agent-track search was broken server-side until EverOS 1.1.2.
- `foresight`/`eventlog` are documented memory types but the cloud search/get API still rejects them (HTTP 422, re-verified 2026-07-25); `memory_foresight` therefore falls back to episodic+profile semantic search with `current_time`.
- Cloud-only endpoints: Knowledge (documents/topics/search) and OME reflection `trigger` exist in the open-source server but 404 on the cloud, so self-hosting is the only way to reach them today.
- Run `npm run verify` (typecheck + tests) before committing.
