# Personal Subagents The personal lead agents (Shawn, Nate, Hypatia, Marcus, Watson, Bourdain, David, Cousteau, Garth, Cristiano) delegate certain repeatable tasks to a shared **subagent** — minimal personality, narrow scope, called as a tool. Subagents don't own graph nodes and don't have character bibles. Subagents are runtime processes defined under `iolaus/agents/` (personal-team variants) or `kottos/agents/` (engineering originals, reused), exposed as MCP tools via StreamableHTTP. The canonical prompt text lives in `prompts/personal/subagents/` — copies in the runtime code should match. Mikael has a stronger editorial voice than the other subagents (Scandinavian newsroom skepticism, refusal to launder claims from low-credibility outlets) but is still a narrow-scope tool — no graph nodes, no character bible, invoked by leads as a sub-tool. ## Catalog ### research **Purpose:** Answer a question by searching the public web, Robert's Neo4j memory, and the Mnemosyne document library in parallel — then judging what came back and verifying it against live pages where it matters. **Composition:** `fast.parallel` of four sub-agents: - `web_search` — argos; reports blocked/empty/JS-shell results rather than papering over them - `memory_lookup` — neo4j (read-only) - `doc_lookup` — mnemosyne (read-only); passes `library_type` when the domain is clear - `synthesizer` — the researcher: reads all three reports, escalates to **dolores** for a real browser when a source is blocked, a URL looks guessed, or a load-bearing claim needs a live check **Tools:** argos, neo4j_cypher, mnemosyne, dolores, time **When to delegate:** - A question where being wrong has a cost — the answer gets verified, not just retrieved - "What do I already know about X, and what's actually true about it now?" - Anything whose answer goes stale: prices, availability, dates, current status - When the lead wants memory-aware research without burning its own context **When NOT to delegate:** - Quick web lookups where memory isn't relevant — use Argos directly - Pure graph queries where the web isn't needed — query Neo4j directly - Operating a browser as the goal itself (a form, a flow, a screenshot) — use `dolores` **Prompt:** [prompts/personal/subagents/research.md](../../prompts/personal/subagents/research.md) **Runtime:** `kottos/agents/research.py` (personal-team variant, copied with tweaks from engineering's research subagent — the memory_lookup sub-agent's prompt is scoped to personal-domain node types instead of engineering's) --- ### dolores **Purpose:** Operate a real web browser. Dolores drives a headed Chromium on the RDP desktop host via Playwright — she reads live pages, fills forms, works through multi-step flows, and returns screenshots. **Composition:** single `fast.agent`. **Tools:** playwright **When to delegate:** - A task that genuinely requires a browser: a form to fill, a login flow, a multi-step navigation - A page Argos can't render — JS-heavy, client-rendered, cookie-walled - When the *visual itself* is the deliverable ("what does this page look like") **When NOT to delegate:** - Finding an answer — that's `research`, which will call Dolores itself when a source needs verifying - Anything the cached snippet already answers **Sizing the task:** one page and one question at a time. She has no view of the caller's goal, so a task spanning several sites — or one whose later steps depend on what earlier ones turn up — comes back thin or wrong. Chain the steps from the calling side instead. **Prompt:** [prompts/personal/subagents/dolores.md](../../prompts/personal/subagents/dolores.md) **Runtime:** `iolaus/agents/dolores.py` — port 24054 --- ### mikael **Purpose:** Produce topic-driven, source-verified news briefings. Reads from a curated topic list and applies a strict source policy (preferred sources seeded into queries; avoided sources excluded with `-site:` *and* post-filtered by hostname). **Composition:** Single `fast.agent` (not a `fast.parallel`). The agent itself does the search → fetch → image lookup → summarize loop. **Tools:** argos (`search_web`, `fetch_webpage`, `search_images`), time, mnemosyne **When to delegate:** - "What's the latest on X?" — current events on a single topic, with sources and timestamps - Daily / morning briefings across the configured topic list - Any task where Robert needs *what is currently being reported* (with attribution and recency), not just background knowledge - Lead agents that need news context for their domain — e.g. Cristiano on a transfer story, David on an arts/culture story, Garth on a markets development — when the question is "what's being reported right now" **When NOT to delegate:** - Historical / background questions where the answer doesn't depend on the last 24h — use Argos directly or ask the domain lead - Topic deep-dives that need analysis, not headlines — the domain lead is the right answer (don't ask Mikael "what should I think about X") - Anything Robert wants stored — Mikael is read-only and explicitly does not write to Neo4j; the calling lead is responsible for persisting what matters **Configuration:** Driven by the top-level `news:` block in `iolaus/fastagent.config.yaml` — topics, preferred sources, avoided sources, default lookback window, max items per topic. Edits take effect on Iolaus restart, no code changes needed. **Source policy:** Mikael will never summarize or cite an avoided source, even if another outlet syndicates the claim. If only an avoided source has a story, the story is "unreported" until a credible outlet picks it up. **Prompt:** Embedded in [iolaus/agents/mikael.py](https://git.helu.ca/r/iolaus/src/branch/main/agents/mikael.py) (no separate canonical file in `prompts/personal/subagents/` yet — the in-code instruction interpolates the `news:` config block at startup, which is awkward to mirror as static markdown). **Runtime:** `iolaus/agents/mikael.py` (exposed as the `news` MCP tool on port 24053). Unlike `research`, there is no engineering-team variant — news briefing is a personal-team-only capability. --- ## Conventions **Source of truth:** koios is the master. The prompt text in `prompts/personal/subagents/` is canonical; runtime `.py` files should load from or match these prompts. When iterating, edit koios first and propagate. **Personality:** Subagents have minimal personality. Their identity is their role — "you are a web search specialist," "you are a memory specialist." No named character. The voice comes from the calling lead, not from the subagent. **Cross-team reuse:** The `research` subagent exists in three variants — engineering, work, and personal — each with its `memory_lookup` sub-agent's prompt scoped to that team's node types. This is **copy with tweaks** rather than a single shared file. The duplication is cheap; the per-team specificity makes the memory_lookup query more accurate. **Graph ownership:** Subagents do not own node types and do not write to the graph. The `memory_lookup` sub-agent is explicitly read-only. If a subagent's output suggests Robert's memory should be updated ("the web says X but your notes say Y; you might want to update your notes"), the calling lead agent is responsible for the write — not the subagent.