Files
tatlock/docs/orchestration-scenarios.md
jpmschweitzerandClaude Opus 4.6 a3c7fcf8c3 refactor: consolidate project structure and clean up documentation
- Move docs to docs/ (philosophy, roadmap, orchestration scenarios,
  claude integration, testing improvements)
- Strip completed phases from roadmap and claude integration docs
- Move dependencies from requirements*.txt into pyproject.toml
- Move pytest config from pytest.ini into pyproject.toml
- Add Makefile replacing wakeup.sh (setup, run, test, lint, etc.)
- Add CI test gate in Gitea Actions workflow
- Consolidate caches into .cache/ (pytest, mypy, ruff)
- Consolidate build output into build/ (coverage, logs)
- Update Dockerfile for pyproject.toml install
- Update cross-references in README, AGENTS.md, CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 20:44:25 +01:00

36 KiB

Orchestration Scenarios and Tool Flows

This document outlines example scenarios of varying complexity to illustrate the desired orchestration patterns between Tatlock (Butler/Coordinator), expert agents (The Librarian, Housekeeper, Biographer), and the user.

Architecture Overview

Two-Phase Execution Model

Tatlock operates in two distinct phases to maintain consistent butler personality:

flowchart TB
    subgraph Phase1["Phase 1: Coordination"]
        direction TB
        U[User Request] --> S[Steward]
        S -->|"Analyzes & routes"| T1[Tatlock Orchestration]
        T1 -->|"delegate_to_*"| E1[Expert Agents]
        T1 -->|"tool calls"| TC[tatlock_core Tools]
        E1 -->|"structured results"| R1[Results Collection]
        TC -->|"tool outputs"| R1
    end

    subgraph Phase2["Phase 2: Synthesis"]
        direction TB
        R1 --> T2[Tatlock Synthesis]
        T2 -->|"butler-toned response"| U2[User Response]
    end

    style Phase1 fill:#1a1a2e,stroke:#4a4a6a
    style Phase2 fill:#16213e,stroke:#4a4a6a

Component Flow

flowchart LR
    subgraph Steward
        S1[Request Analysis]
        S2[Query Enrichment]
        S3[Capability Routing]
    end

    subgraph Tatlock
        T1[Phase 1: Orchestrate]
        T2[Phase 2: Synthesize]
    end

    subgraph Experts
        L[Librarian]
        H[Housekeeper]
        B[Biographer]
    end

    subgraph External
        LD[library-desk]
        HA[Home Assistant]
        DB[user-db]
    end

    S1 --> S2 --> S3 --> T1
    T1 --> L & H & B
    L --> LD
    H --> HA
    B --> DB
    L & H & B --> T2
    T2 --> Response

Key Principles:

  1. Steward sees everything - Has access to all capability descriptions to make informed routing decisions
  2. Query enrichment - Steward auto-fills user context (location, timezone) when not specified
  3. Two-phase execution - Coordination (tool calls) separated from synthesis (butler response)
  4. Expert agents are tools - Tatlock calls delegate_to_librarian(task), not hybrid_search() directly
  5. Each expert owns their tools - Librarian has wiki tools, Housekeeper has device tools, Biographer has memory tools
  6. Think slugs for transparency - Deterministic butler-perspective messages during expert delegation
  7. Results flow up - Phase 2 synthesizes all expert responses into coherent butler answer

Scenario 1: Weather Check (With Query Enrichment)

User: "What's the weather like?"

Complexity Analysis

This seemingly simple request is now streamlined by query enrichment:

  1. Steward enrichment - Auto-fills location from user profile
  2. Weather data fetch - Search for weather at enriched location
sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant TC as tatlock_core

    U->>S: "What's the weather like?"
    S->>S: Prefetch memory context
    Note over S: location=Amsterdam<br/>timezone=Europe/Amsterdam
    S->>T: Enriched query + routing
    T->>TC: search_web("weather Amsterdam")
    TC-->>T: "12°C, light rain"
    T->>U: Butler-toned response

Flow

1. Steward Analysis
   → Pre-fetch: memory_context = {profile: {location: "Amsterdam"}}
   → Enriched query: "What's the weather like?\n\n[User Context: location=Amsterdam]"
   → Capabilities needed: tatlock_core (web search)
   → Complexity: simple

2. Phase 1: Tatlock Orchestration
   → Calls: search_web("current weather Amsterdam Netherlands")
   → Receives: "Amsterdam: 12°C, light rain, humidity 78%"
   → Results: {tool_outputs: {search_web: "12°C, light rain..."}}

3. Phase 2: Tatlock Synthesis
   → Input: user message, tool results, enriched context
   → Output: Butler-toned response

4. Response
   "Currently 12°C with light rain in Amsterdam, sir. You might want
   to grab an umbrella if you're heading out."

Steward Note Format

📋 Steward's Analysis
========================================
Complexity: SIMPLE
Recommended tools: tatlock_core
----------------------------------------
User Context:
  • location: Amsterdam
  • timezone: Europe/Amsterdam
  • preferences: temperature_unit=celsius
========================================

Alternative Flow: Location Specified

If user specifies location, no enrichment occurs:

User: "What's the weather in London?"

Steward Analysis:
   → Location specified in query ("in London")
   → No enrichment needed
   → Direct routing to tatlock_core

Scenario 2: Adjust Temperature Based on Weather (Conditional with Housekeeper)

User: "Check the weather and if it's cold, turn up the heating"

Complexity Analysis

This requires:

  1. Query enrichment - Location auto-filled from profile
  2. Weather fetch - Get current outdoor temperature
  3. Conditional evaluation - Is it "cold"? (requires threshold judgment)
  4. Housekeeper delegation - Adjust heating if condition met
sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant TC as tatlock_core
    participant H as Housekeeper
    participant HA as Home Assistant

    U->>S: "Check weather, if cold turn up heating"
    S->>S: Enrich with location
    S->>T: Route to tatlock_core + housekeeper

    rect rgb(40, 40, 60)
        Note over T: Phase 1: Orchestration
        T->>TC: search_web("weather Amsterdam")
        TC-->>T: "8°C, cloudy"
        T->>T: Evaluate: 8°C < 15°C = cold
        T-->>U: <think>I'm instructing the household staff now, sir.</think>
        T->>H: delegate_to_housekeeper(task)
        H->>HA: climate.set_temperature(21)
        HA-->>H: Success
        H-->>T: "Thermostat set to 21°C"
        T-->>U: <think>The household has been configured as requested.</think>
    end

    rect rgb(30, 50, 70)
        Note over T: Phase 2: Synthesis
        T->>U: Butler-toned response
    end

Flow with Think Slugs

1. Steward Analysis
   → Enriched query: [User Context: location=Amsterdam]
   → Capabilities needed: tatlock_core, housekeeper
   → Complexity: moderate (conditional)

2. Phase 1: Tatlock Orchestration
   → Calls: search_web("current weather Amsterdam")
   → Receives: "8°C, cloudy, wind 15km/h"
   → Evaluates: 8°C is cold (< 15°C threshold)

   → Emits think slug (streamed to user):
     <think>I'm instructing the household staff now, sir.</think>

   → Calls: delegate_to_housekeeper(
       task="Set thermostat to 21°C - cold weather detected (8°C outside)"
     )
   → Housekeeper executes: climate.set_temperature(entity_id, 21)
   → Returns: {success: true, output: "Thermostat set to 21°C"}

   → Emits think slug (streamed to user):
     <think>The household has been configured as requested.</think>

   → Results: {
       tool_outputs: {search_web: "8°C..."},
       expert_results: {housekeeper: "Thermostat set to 21°C"}
     }

3. Phase 2: Tatlock Synthesis
   → Input: user message, weather data, housekeeper result
   → Output: Butler-toned response

4. Response
   "It's rather brisk outside at 8°C, sir. I've taken the liberty of raising
   the heating to a comfortable 21°C. The house should warm up shortly."

Think Slug Mapping (Housekeeper)

Action Type Phase Message
CONTROL start <think>I'm instructing the household staff now, sir.</think>
CONTROL success <think>The household has been configured as requested.</think>
CONTROL error <think>I'm afraid the staff reports an issue with that request.</think>
RETRIEVE start <think>Allow me to inquire with the household staff.</think>
RETRIEVE success <think>The staff reports the current status, sir.</think>

Alternative Flow: Not Cold

Weather returns: "Current temperature: 18°C, partly sunny"

Phase 1 Evaluation:
   → 18°C is not cold (>= 15°C)
   → No housekeeper delegation needed
   → Results: {tool_outputs: {search_web: "18°C..."}, expert_results: {}}

Phase 2 Synthesis:
   "It's a pleasant 18°C outside, sir - not particularly cold.
   I don't believe the heating requires adjustment, but do let
   me know if you'd like it warmer regardless."

Scenario 3: Adjust Lights Based on Time (Housekeeper Scene Control)

User: "Set the lights appropriately for the time of day"

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant TC as tatlock_core
    participant H as Housekeeper
    participant HA as Home Assistant

    U->>S: "Set lights for time of day"
    S->>S: Enrich with timezone
    S->>T: Route to tatlock_core + housekeeper

    rect rgb(40, 40, 60)
        Note over T: Phase 1: Orchestration
        T->>TC: get_current_datetime()
        TC-->>T: "2024-12-11 21:45 Europe/Amsterdam"
        T->>T: Evaluate: 21:45 = evening
        T-->>U: <think>I'm instructing the household staff now, sir.</think>
        T->>H: delegate_to_housekeeper(task)
        H->>HA: scene.turn_on("evening_relaxation")
        HA-->>H: Scene activated
        H-->>T: "Scene activated: warm white 40%"
        T-->>U: <think>The household has been configured as requested.</think>
    end

    rect rgb(30, 50, 70)
        Note over T: Phase 2: Synthesis
        T->>U: Butler-toned response
    end

Flow

1. Steward Analysis
   → Enriched query: [User Context: timezone=Europe/Amsterdam]
   → Capabilities needed: tatlock_core, housekeeper
   → Complexity: moderate

2. Phase 1: Tatlock Orchestration
   → Calls: get_current_datetime()
   → Receives: "2024-12-11 21:45 Europe/Amsterdam"
   → Evaluates: 21:45 = evening, warm dim lighting appropriate

   → Emits: <think>I'm instructing the household staff now, sir.</think>

   → Calls: delegate_to_housekeeper(
       task="Activate evening lighting scene - it's 21:45"
     )
   → Housekeeper executes: scene.turn_on("evening_relaxation")
   → Returns: "Scene 'evening_relaxation' activated - warm white 40%"

   → Emits: <think>The household has been configured as requested.</think>

3. Phase 2: Tatlock Synthesis
   → Input: time context, scene activation result
   → Output: Butler-toned response with proactive offer

4. Response
   "It's quarter to ten in the evening, sir. I've set the lights to a warm,
   subdued glow - ideal for winding down. Shall I also draw the curtains?"

Housekeeper Task Format

Task: Activate evening lighting scene - it's 21:45
Context: User wants lights appropriate for time of day.
Action required: Activate scene suitable for late evening/wind-down.

Reference: "Set the lights appropriately for the time of day"

Scenario 4: Create a Reminder (Simple Expert Delegation)

User: "Remind me to call the dentist tomorrow at 2pm"

Flow

1. Steward Analysis
   → Capabilities needed: personal_assistant (reminders)
   → Complexity: simple

2. Tatlock Execution
   <think>Creating reminder for tomorrow afternoon...</think>
   → Calls: personal_assistant_agent(task)
   → PA executes: create_reminder(title, datetime, notification_time)
   → Receives: "Reminder created: ID 847"

3. Response
   "Very good, sir. I've set a reminder to call the dentist for tomorrow at
   2 o'clock in the afternoon. I'll notify you 15 minutes beforehand."

Intra-System Prompts

Tatlock → Personal Assistant Agent:

Task: Create a reminder for the user.
Details:
- Subject: Call the dentist
- When: Tomorrow at 14:00
- Notification: 15 minutes before (default)

Reference (user's original request): "Remind me to call the dentist tomorrow at 2pm"

Scenario 5: Schedule Recurring Automation (Complex, Multi-Expert)

User: "Schedule the lights to turn on at 09:00 every weekend day"

Flow

1. Steward Analysis
   → Capabilities needed: home_automation (scheduling)
   → Complexity: moderate
   → Note: Recurring schedule, weekend-only

2. Tatlock Execution
   <think>Setting up recurring weekend morning lighting schedule...</think>
   → Calls: home_automation_agent(task)
   → HA executes: create_schedule(trigger, days, action)
   → Receives: "Schedule created: ID wake_light_weekend"

3. Response
   "The weekend wake-up lighting is now scheduled, sir. Every Saturday and
   Sunday at 9 o'clock sharp, the lights will illuminate. Would you prefer
   a gradual sunrise simulation, or an immediate full brightness?"

Intra-System Prompts

Tatlock → Home Automation Agent:

Task: Create a recurring lighting schedule.
Details:
- Action: Turn on lights
- Time: 09:00
- Days: Saturday, Sunday (weekends only)
- Recurrence: Weekly

Reference (user's original request): "Schedule the lights to turn on at 09:00 every weekend day"

Scenario 6: Create Wiki Page About Topic (Librarian with Research)

User: "Create a wiki page about CI/CD"

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant L as Librarian
    participant LD as library-desk

    U->>S: "Create a wiki page about CI/CD"
    S->>T: Route to librarian (CREATE action)

    rect rgb(40, 40, 60)
        Note over T: Phase 1: Orchestration
        T-->>U: <think>I'm having the Librarian prepare a new entry.</think>
        T->>L: delegate_to_librarian(task)

        rect rgb(50, 50, 80)
            Note over L: Librarian Internal
            L->>LD: hybrid_search("CI/CD")
            LD-->>L: 12 sources found
            L->>LD: create_wiki_page(...)
            LD-->>L: Page created
        end

        L-->>T: Structured result
        T-->>U: <think>The new material has been properly catalogued, sir.</think>
    end

    rect rgb(30, 50, 70)
        Note over T: Phase 2: Synthesis
        T->>U: Butler-toned response
    end

Flow with Think Slugs

1. Steward Analysis
   → Capabilities needed: librarian
   → Complexity: complex
   → Action detected: CREATE (create, write, add keywords)

2. Phase 1: Tatlock Orchestration
   → Emits: <think>I'm having the Librarian prepare a new entry.</think>

   → Calls: delegate_to_librarian(
       task="Create a comprehensive wiki page about CI/CD"
     )

   → Librarian Internal Flow:
     - hybrid_search("CI/CD continuous integration deployment")
     - Synthesizes content from wiki, graph, and web sources
     - create_wiki_page(title, path, content, tags)

   → Returns: {
       success: true,
       output: "Page created: CI/CD, Path: /technology/cicd, Sources: 12"
     }

   → Emits: <think>The new material has been properly catalogued, sir.</think>

3. Phase 2: Tatlock Synthesis
   → Input: user request, librarian result with page details
   → Output: Butler-toned response with specifics

4. Response
   "The wiki page on CI/CD has been created, sir. The Librarian has compiled
   information from 12 sources, including our existing documentation on DevOps
   practices. The page is now available at /technology/cicd and has been
   cross-linked with related topics like Jenkins, GitHub Actions, and Docker."

Think Slug Mapping (Librarian)

Action Type Phase Message
CREATE start <think>I'm having the Librarian prepare a new entry.</think>
CREATE success <think>The new material has been properly catalogued, sir.</think>
CREATE error <think>I'm afraid there was difficulty filing the entry.</think>
RETRIEVE start <think>Allow me to consult the archives, sir.</think>
RETRIEVE success <think>The Librarian has compiled the relevant findings.</think>
RESEARCH start <think>I've dispatched the Librarian to conduct some fresh research.</think>
RESEARCH success <think>The Librarian has returned with findings, sir.</think>

Librarian Response Format

Task completed: Wiki page created

Page Details:
- Title: CI/CD (Continuous Integration/Continuous Deployment)
- Path: /technology/cicd
- Tags: technology, devops, automation, software-development

Research Summary:
- Wiki sources: 3 pages (DevOps Overview, Jenkins Setup, GitHub Actions Guide)
- Knowledge graph entities: 4 (linked to Docker, Kubernetes, Git, Testing)
- Web sources: 5 articles (current best practices, 2024 trends)
- Total sources synthesized: 12

Knowledge Graph Updates:
- Forward links created: 8 (to existing related pages)
- Backward links created: 3 (updated existing pages to reference new page)

Scenario 7: Update Stock Wiki with Evaluation Tracker (Complex, Multi-Tool Expert)

User: "Update the GOOG stock wiki page with a rolling evaluation tracker"

Flow

1. Steward Analysis
   → Capabilities needed: librarian
   → Complexity: complex
   → Specific action: search existing page, fetch current data, update page

2. Tatlock Execution
   <think>This requires finding the existing page, fetching current stock data,
   and updating with a new evaluation section. Delegating to The Librarian...</think>
   → Calls: librarian_agent(task)

3. Librarian Internal Flow - Step 1
   <think>First, locating the existing GOOG wiki page...</think>
   → search_wiki("GOOG stock Alphabet")
   → Receives: Page ID 234, path /investments/stocks/goog

4. Librarian Internal Flow - Step 2
   <think>Fetching current page content to preserve existing information...</think>
   → get_wiki_page(234)
   → Receives: Current page content

5. Librarian Internal Flow - Step 3
   <think>Researching current stock data and evaluation metrics...</think>
   → hybrid_search("GOOG Alphabet stock price evaluation 2024")
   → Receives: Current price, P/E ratio, analyst ratings, etc.

6. Librarian Internal Flow - Step 4
   <think>Updating page with new rolling evaluation section...</think>
   → update_wiki_page(234, content=updated_content)
   → Receives: Update confirmation

7. Tatlock Receives
   "Page updated: GOOG Stock Analysis
    Added section: Rolling Evaluation Tracker
    Data points added: Price history, P/E trend, Analyst consensus
    Last updated: 2024-12-11"

8. Response
   "The GOOG stock page has been updated, sir. I've added a rolling evaluation
   tracker with current metrics: the stock is trading at $178.32 with a P/E
   of 24.8, and analyst consensus remains 'Buy'. The tracker includes a
   90-day price trend and quarterly earnings history. Shall I set up
   automatic weekly updates?"

Intra-System Prompts

Tatlock → Librarian Agent:

Task: Update the GOOG (Alphabet) stock wiki page with a rolling evaluation tracker.
Context: User wants to add ongoing stock evaluation tracking to an existing page.

Actions required:
1. Find the existing GOOG stock wiki page
2. Read current page content (preserve existing information)
3. Research current stock data and evaluation metrics
4. Update the page with a new "Rolling Evaluation Tracker" section including:
   - Current price and change
   - Key ratios (P/E, P/B, etc.)
   - Analyst consensus
   - Price trend (30/60/90 day)
   - Recent earnings summary
5. Report back with update summary

Reference (user's original request): "Update the GOOG stock wiki page with a rolling evaluation tracker"

Librarian → Tatlock Response:

Task completed: Wiki page updated

Page Details:
- Title: GOOG - Alphabet Inc. Stock Analysis
- Path: /investments/stocks/goog
- Page ID: 234

Update Summary:
- New section added: "Rolling Evaluation Tracker"
- Existing content: Preserved (company overview, investment thesis)

Evaluation Data Added:
- Current Price: $178.32 (+1.2% today)
- P/E Ratio: 24.8 (vs sector avg 28.3)
- P/B Ratio: 6.2
- 52-Week Range: $120.21 - $191.75
- Analyst Consensus: Buy (24 buy, 8 hold, 2 sell)
- Price Trend: +15.3% (90-day)
- Last Earnings: Q3 2024 - Beat estimates by 8%

Sources:
- Web: 4 financial data sources
- Existing wiki: Investment strategy context

Suggested follow-up: Set up automated weekly data refresh?

Scenario 8: Complex Multi-Expert Coordination

User: "Check if there's anything about the new project deadline in my notes, if so create a reminder, and if the deadline is this week, also update the project wiki page with a status note"

Flow

1. Steward Analysis
   → Capabilities needed: librarian, personal_assistant
   → Complexity: complex
   → Note: Conditional multi-step, requires information passing between experts

2. Tatlock Execution - Step 1
   <think>First, searching for project deadline information in the wiki...</think>
   → Calls: librarian_agent(search_task)
   → Librarian: hybrid_search("new project deadline")
   → Returns: "Project Alpha deadline: December 15, 2024 (this Friday)"

3. Tatlock Evaluation
   <think>Found deadline: December 15. That's this week (Friday).
   Need to: 1) Create reminder, 2) Update project wiki page...</think>

4. Tatlock Execution - Step 2 (parallel if possible)
   <think>Creating reminder and updating wiki status...</think>

   → Calls: personal_assistant_agent(reminder_task)
   → PA: create_reminder("Project Alpha deadline", "2024-12-15 09:00")
   → Returns: "Reminder created for Dec 15 at 9am"

   → Calls: librarian_agent(update_task)
   → Librarian: search_wiki → get_wiki_page → update_wiki_page
   → Returns: "Project Alpha page updated with deadline status note"

5. Response
   "I've found the deadline in your notes, sir - Project Alpha is due this
   Friday, December 15th. I've set a reminder for 9 o'clock that morning,
   and I've updated the project wiki page with a status note indicating
   the imminent deadline. Is there anything else you need to prepare?"

Intra-System Prompts

Tatlock → Librarian Agent (Search):

Task: Search for information about a new project deadline.
Context: User wants to find deadline information from their notes/wiki.

Action required:
1. Search wiki and knowledge base for project deadline information
2. Return: Project name, deadline date, and any relevant context

Reference (user's original request): "Check if there's anything about the new project deadline in my notes..."

Tatlock → Personal Assistant Agent:

Task: Create a reminder for a project deadline.
Details:
- Subject: Project Alpha deadline
- When: December 15, 2024 at 09:00
- Priority: High (deadline is this week)
- Notification: Morning of the deadline

Reference: Creating reminder based on deadline found in user's notes.

Tatlock → Librarian Agent (Update):

Task: Update the Project Alpha wiki page with a deadline status note.
Context: Project deadline is December 15, 2024 (this Friday). User requested
a status update since the deadline is this week.

Action required:
1. Find the Project Alpha wiki page
2. Add a status note/banner indicating the imminent deadline
3. Optionally update any status fields

Reference: Part of user's request to track and highlight near-term deadlines.

Scenario 9: Simple Light Control (Direct Housekeeper Delegation)

User: "Turn on the living room lights"

This is a simple direct delegation scenario - no tool calls needed, just Housekeeper.

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant H as Housekeeper
    participant HA as Home Assistant

    U->>S: "Turn on the living room lights"
    S->>S: Detect: housekeeper only, CONTROL action
    S->>T: Direct delegation recommended

    T-->>U: <think>I'm instructing the household staff now, sir.</think>
    T->>H: delegate_to_housekeeper(task)
    H->>HA: light.turn_on("light.living_room")
    HA-->>H: Success
    H-->>T: "Living room lights turned on"
    T-->>U: <think>The household has been configured as requested.</think>

    Note over T: Phase 2: Synthesis
    T->>U: "Very good, sir. The living room lights are now on."

Flow

1. Steward Analysis
   → Capabilities needed: housekeeper
   → Action detected: CONTROL (turn on/off, set, toggle)
   → Complexity: simple
   → Direct delegation: Yes (single expert, no tools needed)

2. Direct Delegation (bypasses full orchestration)
   → Emits: <think>I'm instructing the household staff now, sir.</think>
   → Calls: delegate_to_housekeeper(task="Turn on the living room lights")
   → Housekeeper executes: light.turn_on("light.living_room")
   → Returns: {success: true, output: "Living room lights turned on"}
   → Emits: <think>The household has been configured as requested.</think>

3. Phase 2: Synthesis (still runs for butler tone)
   → Input: simple action result
   → Output: Concise butler acknowledgment

4. Response
   "Very good, sir. The living room lights are now on."

Scenario 10: Device Status Query (Housekeeper RETRIEVE)

User: "What devices are on in the bedroom?"

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant H as Housekeeper
    participant HA as Home Assistant

    U->>S: "What devices are on in the bedroom?"
    S->>T: Route to housekeeper (RETRIEVE action)

    T-->>U: <think>Allow me to inquire with the household staff.</think>
    T->>H: delegate_to_housekeeper(task)
    H->>HA: get_area_devices("bedroom", state="on")
    HA-->>H: Device list
    H-->>T: Structured result
    T-->>U: <think>The staff reports the current status, sir.</think>

    T->>U: Butler-toned response

Flow

1. Steward Analysis
   → Capabilities needed: housekeeper
   → Action detected: RETRIEVE (what, which, status, is)
   → Complexity: simple

2. Phase 1: Tatlock Orchestration
   → Emits: <think>Allow me to inquire with the household staff.</think>
   → Calls: delegate_to_housekeeper(task="List active devices in the bedroom")
   → Returns: {
       success: true,
       output: "Bedroom: Ceiling light (on, 75%), Bedside lamp (on, 30%)"
     }
   → Emits: <think>The staff reports the current status, sir.</think>

3. Phase 2: Tatlock Synthesis
   → Output: Butler-toned summary

4. Response
   "In the bedroom, sir, we have the ceiling light at 75% brightness
   and the bedside lamp at a gentle 30%. Would you like me to adjust
   either of them?"

Scenario 11: Biographer Memory Recording

User: "Remember that I prefer my coffee black"

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant B as Biographer
    participant DB as user-db

    U->>S: "Remember that I prefer my coffee black"
    S->>T: Route to biographer (RECORD action)

    T-->>U: <think>I've asked the Biographer to take note of this, sir.</think>
    T->>B: delegate_to_biographer(task)
    B->>DB: store_preference(category="food", key="coffee", value="black")
    DB-->>B: Stored
    B-->>T: "Preference recorded"
    T-->>U: <think>The household records have been updated accordingly.</think>

    T->>U: Butler-toned confirmation

Flow

1. Steward Analysis
   → Capabilities needed: biographer
   → Action detected: RECORD (remember, note, save, record)
   → Complexity: simple

2. Phase 1: Tatlock Orchestration
   → Emits: <think>I've asked the Biographer to take note of this, sir.</think>
   → Calls: delegate_to_biographer(task="Record preference: coffee black")
   → Returns: {success: true, output: "Preference recorded: coffee=black"}
   → Emits: <think>The household records have been updated accordingly.</think>

3. Phase 2: Tatlock Synthesis

4. Response
   "Noted, sir. I'll remember you prefer your coffee black."

Think Slug Mapping (Biographer)

Action Type Phase Message
RECORD start <think>I've asked the Biographer to take note of this, sir.</think>
RECORD success <think>The household records have been updated accordingly.</think>
RECORD error <think>I'm afraid there was difficulty recording the entry.</think>
RETRIEVE start <think>Let me consult the household records.</think>
RETRIEVE success <think>The Biographer has located the relevant information, sir.</think>

Scenario 12: Multi-Expert Morning Routine (Parallel Delegation)

User: "Good morning! What's the weather, and set the house for daytime"

This scenario demonstrates parallel expert delegation with multiple think slugs.

sequenceDiagram
    participant U as User
    participant S as Steward
    participant T as Tatlock
    participant TC as tatlock_core
    participant H as Housekeeper
    participant HA as Home Assistant

    U->>S: "Good morning! Weather + daytime settings"
    S->>S: Enrich with location, timezone
    S->>T: Route to tatlock_core + housekeeper

    rect rgb(40, 40, 60)
        Note over T: Phase 1: Parallel Orchestration
        par Weather Check
            T->>TC: search_web("weather Amsterdam")
            TC-->>T: "14°C, sunny"
        and Home Setup
            T-->>U: <think>I'm instructing the household staff now, sir.</think>
            T->>H: delegate_to_housekeeper(task)
            H->>HA: scene.turn_on("daytime")
            HA-->>H: Scene activated
            H-->>T: "Daytime scene activated"
            T-->>U: <think>The household has been configured as requested.</think>
        end
    end

    rect rgb(30, 50, 70)
        Note over T: Phase 2: Synthesis
        T->>U: Combined butler greeting
    end

Flow

1. Steward Analysis
   → Enriched query: [User Context: location=Amsterdam, timezone=Europe/Amsterdam]
   → Capabilities needed: tatlock_core, housekeeper
   → Complexity: moderate
   → Parallel execution possible: weather + home setup independent

2. Phase 1: Tatlock Orchestration (parallel)
   → Calls in parallel:
     - search_web("current weather Amsterdam")
     - delegate_to_housekeeper(task="Set house for daytime")

   → Think slugs emitted as housekeeper delegation starts:
     <think>I'm instructing the household staff now, sir.</think>

   → Results collected:
     {
       tool_outputs: {search_web: "14°C, sunny, light breeze"},
       expert_results: {housekeeper: "Daytime scene activated: blinds open, lights off"}
     }

   → Think slug on completion:
     <think>The household has been configured as requested.</think>

3. Phase 2: Tatlock Synthesis
   → Input: weather data, home status, morning context
   → Output: Warm morning greeting with combined info

4. Response
   "Good morning, sir. It's a lovely day outside - 14°C and sunny with a
   light breeze. I've opened the blinds and set the house for daytime.
   Is there anything else you'd like to start your day?"

Response Pattern Guidelines

Think Slugs (Deterministic, No LLM)

Think slugs are deterministic messages emitted during expert delegation. They are:

  • Generated from HOUSEHOLD_THINK_MESSAGES mapping (no LLM involved)
  • Based on expert name + detected action type
  • Written from butler's perspective, addressed to user
  • Streamed in real-time as experts are called
flowchart LR
    subgraph Detection
        T[Task Description] --> D[_detect_action_type]
        D --> AT[ActionType]
    end

    subgraph Lookup
        AT --> M[HOUSEHOLD_THINK_MESSAGES]
        E[Expert Name] --> M
        M --> MSG[Think Message]
    end

    subgraph Stream
        MSG --> S["<think>...</think>"]
        S --> U[User]
    end

Action Type Detection

Expert Keywords → Action Type
Librarian search, find, look up → RETRIEVE
Librarian web, online, research → RESEARCH
Librarian create, write, add → CREATE
Biographer remember, note, save → RECORD
Biographer what, recall, who → RETRIEVE
Housekeeper turn, set, activate, toggle → CONTROL
Housekeeper what, which, status, is → RETRIEVE

Complete Think Slug Reference

Expert Action Start Success Error
Librarian RETRIEVE Allow me to consult the archives, sir. The Librarian has compiled the relevant findings. I'm afraid the archives proved difficult to access.
Librarian RESEARCH I've dispatched the Librarian to conduct some fresh research. The Librarian has returned with findings, sir. The research proved inconclusive, I'm afraid.
Librarian CREATE I'm having the Librarian prepare a new entry. The new material has been properly catalogued, sir. I'm afraid there was difficulty filing the entry.
Biographer RETRIEVE Let me consult the household records. The Biographer has located the relevant information, sir. I'm unable to locate those particular records.
Biographer RECORD I've asked the Biographer to take note of this, sir. The household records have been updated accordingly. I'm afraid there was difficulty recording the entry.
Housekeeper RETRIEVE Allow me to inquire with the household staff. The staff reports the current status, sir. The household staff is momentarily unavailable, I'm afraid.
Housekeeper CONTROL I'm instructing the household staff now, sir. The household has been configured as requested. I'm afraid the staff reports an issue with that request.

Tatlock's Final Response Pattern (Phase 2 Synthesis)

Phase 2 synthesis ensures butler tone by receiving:

  • Original user message
  • All expert results
  • All tool outputs
  • Conversation history

Response structure:

  1. Acknowledge - Confirm understanding of the request
  2. Summarize actions - What was done, by whom (implicitly)
  3. Key details - Important information the user should know
  4. Proactive offer - Suggest related actions or follow-ups
  5. Butler voice - Formal but warm, with personality ("sir", formal language)

Expert Agent Response Pattern

  1. Task status - Completed/Partial/Failed
  2. Action summary - What was done
  3. Key data - Information Tatlock needs to synthesize
  4. Metadata - IDs, counts, timestamps for reference
  5. Suggestions - Optional follow-up actions

Error Handling Scenarios

Expert Agent Failure

Tatlock → Librarian: "Create wiki page about quantum computing"
Librarian → Tatlock: "Error: library-desk API unavailable (connection timeout)"

Tatlock Response:
"I'm afraid The Librarian is having some difficulty reaching the wiki
service at the moment, sir. I can attempt a basic web search on quantum
computing if you'd like, or we can try the wiki operation again in a
few minutes."

Partial Completion

User: "Create a reminder and add it to my calendar"

Tatlock → PA: Create reminder
PA → Tatlock: "Reminder created successfully"

Tatlock → Calendar: Add to calendar
Calendar → Tatlock: "Error: Calendar sync not configured"

Tatlock Response:
"I've created the reminder, sir, but I wasn't able to add it to your
calendar - it appears the calendar integration needs to be configured.
The reminder will still alert you at the scheduled time. Shall I help
set up the calendar connection?"

Summary: Key Design Principles

mindmap
  root((Tatlock))
    Orchestration
      Two-phase execution
      Phase 1: Tool calls
      Phase 2: Synthesis
    Experts
      Librarian
        Archives
        Research
        Wiki creation
      Housekeeper
        Device control
        Scenes
        Status queries
      Biographer
        Memory
        Preferences
        User context
    UX
      Think slugs
      Butler tone
      Proactive offers
    Context
      Query enrichment
      Steward routing
      History awareness

Core Principles

  1. Two-phase execution - Coordination (tool calls) separated from synthesis (butler response)
  2. Expert agents as tools - Tatlock calls delegate_to_*(), they return structured responses
  3. Deterministic think slugs - Butler-perspective messages during delegation (no LLM)
  4. Query enrichment - Steward auto-fills user context (location, timezone) when not specified
  5. Results flow up - Phase 2 synthesizes all expert responses into coherent butler answer
  6. Butler tone guaranteed - Phase 2 always produces formal, warm butler voice
  7. Errors handled gracefully - Butler explains issues and offers alternatives
  8. Proactive suggestions - Tatlock anticipates follow-up needs

Expert Responsibilities

Expert Domains External Service
Librarian Wiki, knowledge graph, web research library-desk
Housekeeper Lights, climate, scenes, device status Home Assistant
Biographer User memory, preferences, profile user-db

Action Types by Expert

Expert RETRIEVE RESEARCH CREATE CONTROL RECORD
Librarian
Housekeeper
Biographer