Self-editing agent on Gemini 3.5 Flash. Three-tier markdown memory (system / active / archive), per-user isolation, web UI + CLI.
pip install -r requirements.txt
$env:GEMINI_API_KEY = "..."
Web server (multi-user, mock login):
uvicorn server:app --host 127.0.0.1 --port 8000
Open http://127.0.0.1:8000 → pick a mock user → chat.
CLI (single user per process):
$env:AGENT_USER_ID = "alice"
python agent.py
- Read frontmatter of every skill under
data/users/<user_id>/skills/. - Gemini picks relevant skills from non-system tiers.
- System tier always loads. Active picks load whole-body. Archive picks load chosen
##sections. - Gemini answers (google_search grounding available).
- Reflect call returns skill edits — applied to disk.
- Turn appended to
sessions/<session_id>.jsonl. - On
/api/session/end(or Ctrl-C in CLI) → session summarized into a new active skill.
data/users/<user_id>/
skills/
system/*.md # always loaded (identity, response style, hard rules)
*.md # active tier, frontmatter-matched
archive/*.md # archive tier, section-retrieved by ## heading
sessions/
<session_id>.jsonl # one turn per line
---
name: skill-name
description: One-line description used for matching against prompts
---
Body. For archive-tier, structure with ## sections for granular retrieval.mock_users.json lists allowed user ids. Login POSTs to /api/login which sets a signed cookie. current_user dependency in server.py re-validates the cookie on every request.
Single seam for Google OAuth: replace /api/login with the OAuth callback. Cookie payload shape ({"user_id": "..."}) and current_user dependency stay identical. Nothing else in the codebase touches identity.
Mock login has no password — bind to 127.0.0.1 only.
GEMINI_API_KEYorGOOGLE_API_KEY— required.AGENT_USER_ID— CLI only. Must exist inmock_users.json.SECRET_KEY— optional. Auto-generated at.secret_keyif absent.AGENT_DEBUG=1— prints raw LLM JSON from reflect/session calls.
| Method | Path | Body / Notes |
|---|---|---|
| GET | /api/users |
Public. Mock account list. |
| POST | /api/login |
{user_id} → sets cookie. |
| POST | /api/logout |
Clears cookie. |
| GET | /api/me |
Current user. |
| POST | /api/chat |
{session_id?, message} |
| POST | /api/session/end |
{session_id} → writes skill. |
| GET | /api/sessions |
List user's sessions. |
| GET | /api/skills |
List user's skills. |
| DELETE | /api/skill/{name} |
Remove a skill. |