Back to StateLoop

Documentation

SPEC

StateLoop - Complete System Specification

1. Overview

StateLoop is a stateless agent orchestration system for coordinating AI agents in multi-party negotiations. Agents negotiate to reach consensus on decisions - from policy debates to project approaches to resource allocation.

1.1 Core Philosophy

The system implements a "stateless agent" pattern where:

  • Agents have no memory - All context is fetched fresh each turn
  • State lives in the system - SQLite database holds all state
  • Private agendas - Each agent only sees their own preferences
  • Hot-swappable - Agents can be stopped/started without losing progress
  • AI-driven setup - AI analyzes scenarios, determines appearances, identifies speakers

1.2 Key Benefits

BenefitDescription
ResilienceStop/restart agents without data loss
FlexibilitySwap agent implementations mid-negotiation
AuditabilityFull request log of all actions
PrivacyAgents don't see others' private instructions
SimplicityNo conversation history management needed

2. System Architecture

shell
┌─────────────────────────────────────────────────────────────────┐
│                         Web Browser                              │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                    Thronglet UI                          │    │
│  │  - 2D Canvas visualization                               │    │
│  │  - Conversation thread                                   │    │
│  │  - Case management                                       │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
                               │
                               │ HTTP/REST
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Express.js Server                           │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │   Routes     │  │   Services   │  │   Storage    │          │
│  │  (REST API)  │──│  (Business)  │──│  (SQLite)    │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                               │
                               │ HTTP (auto-play)
                               ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Claude API                                  │
│  - Generates agent responses                                     │
│  - Receives private agenda per agent                            │
└─────────────────────────────────────────────────────────────────┘

2.1 Technology Stack

ComponentTechnology
RuntimeNode.js 18+
LanguageTypeScript
DatabaseSQLite (better-sqlite3)
Web ServerExpress.js
FrontendVanilla JS + Canvas
AIClaude API (Anthropic)

3. Data Models

3.1 Case

The main entity representing a negotiation session.

typescript
interface Case {
  id: string;                    // e.g., "case-a4573814"
  scenario: string;              // Full case description text
  status: 'active' | 'resolved' | 'abandoned';
  currentTurn: string | null;    // Participant ID whose turn it is
  outcome: 'agreed' | 'failed' | 'abandoned' | null;
  selectedOptionId: string | null;
  resolutionSummary: string | null;
  createdAt: string;             // ISO timestamp
  updatedAt: string;
  resolvedAt: string | null;
}

3.2 Participant

An agent/person in the negotiation.

typescript
interface Participant {
  id: string;                    // e.g., "case-abc-person-0"
  caseId: string;
  name: string;                  // Display name, e.g., "Alice"
  preferences: string[];         // Public preferences (optional)
  constraints: string[];         // Public constraints (optional)
  isPayer: boolean;              // Whether this person is paying
}

3.3 Option

An option to be negotiated.

typescript
interface Option {
  id: string;                    // e.g., "case-abc-opt-1"
  caseId: string;
  name: string;
  category: string;
  priceRange: string;            // $, $$, $$$
  features: string[];
}

3.4 Message

A message in the conversation.

typescript
interface Message {
  id: string;
  caseId: string;
  author: string;                // Participant ID
  type: 'proposal' | 'counter' | 'accept' | 'reject' | 'message';
  content: string;
  optionId: string | null;       // For proposals
  timestamp: string;
  agentContext: string | null;   // Private agenda shown to agent (debug)
}

3.5 BossMessage

An instruction from the system operator.

typescript
interface BossMessage {
  id: string;
  caseId: string;
  content: string;
  targetAgent: string | null;    // null = all agents
  read: boolean;
  timestamp: string;
}


4. Case Description Format

Cases are created using a structured text format that defines agents, their private agendas, and negotiation options.

4.1 Format Specification

shell
PUBLIC INFO:
[Optional public scenario description visible to all]

AGENT: <Name>
AGENDA: [Private instructions only this agent sees]
[Additional lines of private context...]

AGENT: <Name2>
AGENDA: [Different private instructions...]

OPTIONS:
- <Option Name>: <Category>, <Price>, <Features>
- <Option Name2>: ...

4.2 Example

shell
PUBLIC INFO:
Scenario: Team decision on project approach.
Participants: Moderator, Alice, Bob

AGENT: Moderator
AGENDA: You introduce the case. Say "Welcome! You need to pick
an approach for the project. Alice, please start."

AGENT: Alice
AGENDA: You STRONGLY prefer the structured approach.
Budget is $40k max. You're willing to compromise but push for
Approach A first.

AGENT: Bob
AGENDA: You need flexibility. You prefer approaches that allow
for iteration. Try to get Approach B.

OPTIONS:
- Approach A: Structured, $$$, reliable, established process
- Approach B: Agile, $$, flexible, iterative development
- Approach C: Hybrid, $, balanced, combines both methods

4.3 Parsing Rules

  • AGENT: Name - Creates a new participant
  • Lines after AGENT: until next AGENT: or section marker = private agenda
  • PUBLIC INFO: section = visible to everyone (optional)
  • OPTIONS: section = list of choices to negotiate
  • Each - Name line creates an option entry
  • LOCATION: <location> - Sets the scenario location (optional)
  • SCENARIO: <title> - Sets the scenario title (optional)
  • AGENDA (<Role>): - Sets the agent's display role title
  • AGREEABILITY: <0-100> - Sets how quickly agent agrees (default: 50)
  • APPEARANCE: <type> - Sets professional appearance (nurse_scrubs, doctor_coat, etc.)
  • MAX_ROUNDS: <n> - Maximum rounds before timeout
  • 4.4 Location-Based Environments

    The system supports different visual backgrounds based on scenario location. Location can be specified explicitly or auto-detected from scenario keywords.

    Explicit Location:

    shell
    LOCATION: hospital
    
    PUBLIC INFO:
    A medical team discusses patient care options...

    Supported Locations:

    LocationDescriptionVisual Elements
    parkDefault outdoor settingGrass, trees, path
    hospitalMedical ward environmentBeds, nurse station, medical equipment
    libraryQuiet reading spaceBookshelves, reading tables, quiet atmosphere
    officeCorporate meeting roomConference table, chairs, whiteboard
    schoolClassroom settingBlackboard, student desks
    cafeCoffee shopCounter, tables, warm lighting
    Auto-Detection: The system analyzes scenario keywords to auto-detect appropriate location:
    • "hospital", "patient", "nurse", "doctor" → hospital
    • "library", "books", "reading" → library
    • "office", "meeting", "conference" → office
    • "school", "classroom", "student", "teacher" → school
    • "cafe", "coffee", "barista" → cafe
    Location Title Display: When a location is set, the canvas displays a title bar at the top showing:
    • Location name (e.g., "Hospital Ward")
    • Optional subtitle based on scenario context

    4.5 AI Setup Phase

    When a new case is created and auto-play is called for the first time (no messages yet), the system enters a Setup Phase where AI:

    4.5.1 Determines Agent Appearances

    AI analyzes each agent's personality and role to determine their visual appearance on the Thronglet map:

    bash
    POST /api/cases/:id/set-appearance
    {
      "agentName": "Alice",
      "appearance": {
        "accessory": "glasses",
        "bodyStyle": "normal",
        "color": "#3498db",
        "skinTone": "#ffcc80",
        "professionalRole": "nurse_scrubs"
      }
    }

    Appearance Options:

    PropertyOptions
    accessorynone, hat, glasses, bowtie, headphones, scarf, wheelchair
    bodyStylenormal, tall, short, wide, athletic
    shapeTypebox (default), cylinder, oval
    colorAny hex color for clothes
    skinToneAny hex color for skin
    gendermale, female
    voice{ pitch, rate, voiceType } for text-to-speech
    professionalRolenone, nurse_scrubs, doctor_coat, police_uniform, teacher, business_suit, healthcare_assistant
    Body Shape Types (3D Mode):
    ShapeDescription
    boxDefault isometric box shape with flat sides
    cylinderRounded cylindrical body with curved sides
    ovalEgg-shaped body, good for wide/stocky characters
    Body Style Dimensions:
    StyleWidthHeightDescription
    normal2535Standard proportions
    tall2245Taller, thinner build
    short2828Shorter, wider build
    wide3532Broad, stocky build
    athletic2640Taller with moderate width
    Professional Role Appearances: Agents can have professional uniforms that override default clothing:
    RoleDescription
    nurse_scrubsBlue or green medical scrubs
    doctor_coatWhite lab coat with stethoscope
    police_uniformDark blue uniform with badge
    teacherCardigan, smart casual attire
    business_suitFormal suit and tie
    healthcare_assistantLight blue uniform
    Diversity in Agent Appearances: The system supports diverse agent representations including:
    • Different genders (male/female)
    • Physical disabilities (wheelchair users)
    • Various skin tones
    • Multiple accessory styles
    • Professional uniforms
    Personality → Appearance Mapping:
    PersonalitySuggested Appearance
    Formal/Moderatorbowtie, tall, blue (#3498db), male
    Professionalglasses, normal, red (#e74c3c), female
    Wheelchair Userwheelchair, normal, orange (#f39c12), any gender
    Creative/Artisticscarf, normal, purple (#9b59b6), female
    Casual/Relaxedhat, wide, green (#27ae60), male
    Energeticheadphones, short, pink (#e91e63), female
    Medical Staffnurse_scrubs or doctor_coat, appropriate colors
    Law Enforcementpolice_uniform, dark blue
    Educatorteacher, cardigan style
    Corporatebusiness_suit, formal colors

    4.5.2 Identifies First Speaker

    The system automatically determines who speaks first based on currentTurn in the database. The setup prompt tells AI exactly who should make the opening move.

    4.5.3 Makes Opening Move

    AI submits the first message as the identified speaker, kicking off the negotiation.


    5. API Specification

    5.1 Endpoint Summary

    MethodEndpointDescription
    GET/apiAPI info and discovery
    GET/api/casesList all cases
    POST/api/casesCreate new case
    GET/api/cases/:idGet case details
    GET/api/cases/:id/historyGet conversation history for playback
    POST/api/cases/:id/runPre-run case to completion (simulation)
    POST/api/cases/:id/resetReset case (soft or full)
    GET/api/cases/:id/auto-playExecute turn for current agent
    GET/api/auto-playExecute turn on most recent active case
    POST/api/cases/:id/set-appearanceSet agent appearance (AI-determined)
    GET/api/cases/:id/next-taskGet task (manual mode)
    POST/api/cases/:id/submitSubmit response (manual mode)
    POST/api/cases/:id/resolveManually resolve case
    POST/api/cases/:id/reopenReopen resolved case (adds +10 rounds)
    POST/api/cases/:id/boss-messageSend operator message
    GET/api/scenariosList available scenario files
    GET/api/scenarios/:nameGet scenario file content
    POST/api/scenarios/:name/loadCreate case from scenario
    GET/api/logsView request logs
    POST/api/resetClear database

    Company/Building Endpoints

    MethodEndpointDescription
    GET/api/companiesList all companies
    POST/api/companiesCreate a company
    GET/api/companies/:idGet company with relations
    PUT/api/companies/:idUpdate company
    DELETE/api/companies/:idDelete company
    GET/api/companies/:id/auto-playGet AI setup prompt
    POST/api/companies/:id/setupAI bulk setup
    GET/api/companies/:id/buildingsList buildings
    POST/api/companies/:id/buildingsCreate building
    GET/api/companies/:id/buildings/:buildingIdGet building with rooms
    DELETE/api/companies/:id/buildings/:buildingIdDelete building
    GET/api/companies/:id/buildings/:buildingId/roomsList rooms
    POST/api/companies/:id/buildings/:buildingId/roomsCreate room
    GET/api/companies/:id/rooms/:roomIdGet room
    DELETE/api/companies/:id/rooms/:roomIdDelete room
    GET/api/companies/:id/policiesList policies
    POST/api/companies/:id/policiesCreate policy
    GET/api/companies/:id/policies/:policyIdGet policy
    DELETE/api/companies/:id/policies/:policyIdDelete policy
    GET/api/companies/:id/employeesList employees
    POST/api/companies/:id/employeesAdd employee
    GET/api/agents/:name/employmentGet agent's employments across companies
    GET/api/policy-categoriesList policy categories
    GET/api/cases/:id/agent-rolesGet agent roles for case
    POST/api/cases/:id/agent-rolesSet agent roles for case
    GET/api/cases/:id/companyGet company associated with case
    GET/api/cases/:id/policiesGet policies for case
    GET/api/cases/:id/policies/:policyIdGet specific policy for case

    Agent Profile Endpoints

    MethodEndpointDescription
    GET/api/agents/:name/profileGet agent's detailed profile
    PUT/api/agents/:name/profileCreate/update agent profile
    GET/api/agents/:name/character-descriptionGet natural language description
    GET/api/agents/:name/image-promptGet AI image generation prompt
    GET/api/agents/:name/historyGet agent's case participation history
    POST/api/agents/:name/historyAdd case history entry

    5.2 Auto-Play Endpoint (Primary)

    The main endpoint for advancing the negotiation.

    GET /api/cases/:id/auto-play or GET /api/auto-play

    What it does:

  • Identifies whose turn it is
  • Extracts that agent's private agenda from scenario
  • Builds prompt with conversation history
  • Returns plain text prompt for Claude
  • Response (text/plain):

    shell
    YOU ARE: Alice
    
    YOUR PRIVATE AGENDA (only you know this):
    You STRONGLY prefer Japanese food...
    
    OTHER PARTICIPANTS: Moderator, Bob
    (You do NOT know their private preferences)
    
    OPTIONS:
    - case-abc-opt-1: Approach A (Structured, $$$) - reliable, established
    
    CONVERSATION SO FAR:
    [Moderator] (message): Welcome! Please start...
    
    YOUR TASK:
    Respond as Alice. Negotiate based on your agenda.
    
    To respond, POST to: http://localhost:3000/api/cases/abc/submit
    {...}

    5.3 Submit Response

    POST /api/cases/:id/submit

    Request:

    json
    {
      "taskId": "task-xyz",
      "agentId": "case-abc-person-0",
      "agentContext": "Private agenda text (optional, for debug)",
      "response": {
        "type": "proposal",
        "thoughts": "This aligns with my goals",
        "content": "How about Approach A?",
        "optionId": "case-abc-opt-1",
        "documentUpdates": [
          { "document": "notes", "action": "append", "content": "Proposed Approach A" }
        ]
      }
    }

    Response Fields:

    • type - Required: proposal, counter, accept, reject, or message
    • content - Required: The spoken message
    • thoughts - Optional: Internal reasoning (shown in UI, not to other agents)
    • optionId - Required for proposal/counter types
    • documentUpdates - Optional: Array of document edits
    Response Types:
    • proposal - Suggest an option (requires optionId)
    • counter - Counter-proposal (requires optionId)
    • accept - Accept the last proposal (auto-resolves case)
    • reject - Reject without alternative
    • message - General comment
    Automatic Continuation:

    When case is still active, the submit response includes the NEXT agent's prompt, enabling continuous processing without user intervention:

    shell
    SUBMISSION ACCEPTED
    ===================
    Your message was recorded. Case is still active.
    
    NEXT TURN
    =========
    YOU ARE: Bob
    ...

    This allows Claude to automatically continue processing turns until the case resolves, without waiting for user input between turns.

    JSON Response (when Content-Type: application/json is set):

    json
    {
      "messageId": "msg-3",
      "caseStatus": "active",
      "nextTurn": "case-abc-person-1"
    }

    5.4 Auto-Resolution

    When an agent submits type: "accept":

  • System checks if there's a pending proposal
  • If the accepter is different from the proposer
  • Case automatically resolves with outcome: "agreed"
  • 5.5 History Endpoint

    GET /api/cases/:id/history

    Returns full conversation history optimized for playback:

    json
    {
      "caseId": "case-abc",
      "scenario": "...",
      "status": "resolved",
      "outcome": "agreed",
      "participants": [
        { "id": "...", "name": "Alice", "appearance": {...} }
      ],
      "options": [...],
      "timeline": [
        {
          "index": 0,
          "messageId": "msg-xyz",
          "speaker": "Alice",
          "speakerId": "case-abc-person-1",
          "type": "proposal",
          "content": "How about Zen?",
          "timestamp": "2024-01-01T12:00:00Z"
        }
      ],
      "totalMessages": 5
    }

    5.6 Run-to-Completion Endpoint

    POST /api/cases/:id/run

    Pre-runs a case to completion using simulated agent responses. Useful for:

    • Testing scenarios quickly
    • Pre-generating content for playback
    • Batch processing multiple negotiations
    Query Parameters:
    • maxRounds (optional): Maximum rounds before stopping (default: 20)
    Document Writing: The /run endpoint automatically writes to working documents as agents interact:
    • Proposals → Appends to script document with the proposed option
    • Accepts → Appends to decisions document with the agreed outcome
    • Early messages → Appends to notes document (first 3 messages per agent)
    This enables automatic content generation during simulation runs.

    Response:

    json
    {
      "status": "resolved",
      "outcome": "agreed",
      "rounds": 6,
      "messageCount": 6,
      "log": [
        "  [DOC] notes: append - Alice's opening position...",
        "[Alice] (message): I believe we should...",
        "  [DOC] script: append - [Alice's proposal: Option A]...",
        "[Alice] (proposal): I propose we go with Option A.",
        "  [DOC] decisions: append - AGREED: Option A...",
        "[Bob] (accept): Yes, let's do it."
      ],
      "historyUrl": "/api/cases/case-abc/history"
    }

    The log includes [DOC] entries showing document updates alongside agent messages.

    5.7 Working Documents

    Cases can have collaborative working documents that agents update during the negotiation:

    Document Types:

    • Input Documents - Read-only reference materials (character guides, style guides)
    • Working Documents - Collaborative documents agents can edit (scripts, notes, decisions)
    Document Update Actions:
    ActionDescription
    appendAdd content to end of document
    prependAdd content to beginning
    replaceReplace entire document content
    replace_sectionReplace a named section
    Example Document Update:

    json
    {
      "taskId": "task-abc",
      "agentId": "case-123-person-0",
      "response": {
        "type": "message",
        "content": "I've drafted the opening scene",
        "documentUpdates": [
          {
            "document": "script",
            "action": "append",
            "content": "INT. LOBBY - DAY\n\nBasil enters, practicing deep breaths..."
          }
        ]
      }
    }

    5.8 Swagger API Documentation

    Full interactive API documentation is available at:

    • Swagger UI: http://localhost:3000/api-docs
    • OpenAPI Spec: http://localhost:3000/swagger-generated.json (auto-generated)
    The Swagger documentation is auto-generated using swagger-autogen from inline comments in src/api/routes.ts. It includes:
    • All endpoints with request/response schemas
    • Example payloads for each operation
    • Schema definitions for all data types
    To regenerate documentation: npm run swagger:generate


    6. UI Specification (Thronglet)

    6.1 Layout

    shell
    ┌─────────────────────────────────────────────────────────────────┐
    │  Header: Logo, Case Selector, New Case, Reset, Audio, 2D/3D,    │
    │          Replay, Config, Theme Toggle                            │
    ├─────────────────────────────────┬───────────────────────────────┤
    │                                 │  Conversation Thread          │
    │    2D Canvas Map                │  - Chat-style messages        │
    │    - Agents (varied looks)      ├───────────────────────────────┤
    │    - Trees, Path                │  Agent Thoughts (collapsible) │
    │    - Options (when case         │  - Internal reasoning         │
    │      loaded)                    │  - Synced with speaker        │
    │    - Speech bubbles             ├───────────────────────────────┤
    │                                 │  Case Info Panel              │
    │                                 │  - Participant cards          │
    │                                 ├───────────────────────────────┤
    │                                 │  Boss Messages Panel          │
    ├─────────────────────────────────┴───────────────────────────────┤
    │  Agent Prompt Card - Curl command for auto-play                 │
    ├─────────────────────────────────────────────────────────────────┤
    │  Request Log - Collapsible API request history                  │
    └─────────────────────────────────────────────────────────────────┘

    6.1.1 Agent Thoughts Panel

    The Agent Thoughts panel displays the internal reasoning of each agent:

    • Location: Sidebar, below Conversation Thread
    • Collapsible: Click header to expand/collapse
    • Auto-expand: Opens automatically when new thoughts arrive
    • Synced: Shows thoughts from the currently speaking agent
    • Styling: Purple theme to distinguish from public speech
    This allows observers to see what agents are "thinking" separately from what they say publicly.

    6.2 Agent Visualization

    Visual Variety: Each agent has distinct features:

    • Body color (red, blue, purple, green, orange, teal, pink, cyan)
    • Accessory (none, hat, glasses, bowtie, headphones, scarf, wheelchair)
    • Gender representation (different voice types)
    • Skin tone diversity
    • Body style (normal, tall, short, wide)
    • Skin tone variation
    • Animation speed variation
    States:
    • Idle: Various behaviors (standing, wandering, checking phone, etc.)
    • Thinking: Orange indicator dot
    • Speaking: Speech bubble visible
    Collision Avoidance: Agents don't walk into:
    • Trees (50px radius)
    • Options (60px radius)
    • Canvas boundaries
    • Speech bubbles (move away)

    6.3 Idle Behaviors

    Agents perform random actions when idle:

    • Standing, looking, wandering
    • Checking phone, looking at watch
    • Stretching, waving, yawning
    • Tapping foot, scratching head
    • Crossing arms, humming
    • Pacing, jumping, sitting
    • Daydreaming, chitchat

    6.4 Options

    • Only drawn when a case is loaded
    • Icons appropriate to option type
    • Name labels below
    • Color states:
    - Normal: Brown - Proposed: Blue glow - Selected: Orange with checkmark

    6.5 Text-to-Speech and Audio System

    The UI supports text-to-speech for agent messages with a comprehensive audio system:

    Audio System Features:

    • Audio is enabled by default on page load
    • Toggle audio on/off via button in header
    • Each agent has a unique voice (pitch, rate, voice type)
    • Voice settings are determined during AI setup phase
    • Speech bubble stays visible for 15 seconds after audio ends
    • Polling pauses while speech is playing to avoid interruptions
    Voice Settings:
    PropertyRangeDescription
    pitch0.7 - 1.4Voice pitch (higher = higher voice)
    rate0.85 - 1.15Speech rate (higher = faster)
    voiceTypemale/femaleBrowser voice selection
    Message Queue with Speech Sync:
  • Messages are added to a queue as they arrive
  • One message is displayed at a time
  • If audio is enabled, the message is spoken aloud
  • Next message is processed only after speech completes
  • 500ms pause between messages for natural pacing
  • Polling for new messages pauses during speech playback
  • 6.6 Speaker Positioning

    When an agent speaks, the system automatically repositions agents for optimal visibility:

    Speaker Movement:

    • Speaking agent moves to a clear center-left position (35% across canvas, y=380)
    • Original position is stored so they can return after speaking
    • Movement is animated smoothly via the speaking_move idle action
    • Speaker's original position is restored when their message completes
    Other Agents Clear the Way:
    • Non-speaking agents automatically move away from the speech bubble area
    • Agents on the left of the speaker move further left
    • Agents on the right of the speaker move further right
    • All non-speakers move down slightly for clear visual separation
    • Movement uses the avoiding idle action with faster speed (2.0x)
    Positioning Logic:

    shell
    Speech Bubble Zone:
    ┌─────────────────────────────────────────────┐
    │                                             │
    │         ┌─────────────────┐                 │
    │         │  Speech Bubble  │                 │
    │         │     (320px)     │                 │
    │         └────────┬────────┘                 │
    │                  │                          │
    │              ╔═══╧═══╗                      │
    │              ║Speaker║  ← Moves to y=380    │
    │              ╚═══════╝                      │
    │   ○ ←──────              ──────→ ○          │
    │ Agent A                        Agent B      │
    │ (moves left)               (moves right)   │
    └─────────────────────────────────────────────┘

    Benefits:

    • Speaker is always clearly visible without overlap
    • Speech bubble doesn't obscure other agents
    • Conversation flow is visually clear
    • Agents return to natural positions between messages

    6.7 Interactive Features

    Agent Selection:

    • Click on agents in the canvas to select them
    • Click on participant cards in the side panel
    • Selected agent shows expanded details (ID, gender, accessory, voice)
    • Selection highlighted with colored border
    Zoom Controls:
    • "Zoom In" button activates focused view mode
    • When zoomed in, camera frames current speaker + previous 2 speakers
    • Dynamic zoom level adjusts to fit all 3 agents with padding
    • Smooth pan/zoom animation with camera lerping
    Reset & Replay:
    • "Reset & Replay" button in the map header
    • Soft reset: Clears messages, keeps agents and options
    • Full reset: Regenerates entire case setup
    • Automatically runs simulation after reset
    Idle Behavior:
    • Agents perform idle animations when not their turn
    • Chitchat disabled during active negotiations
    • Agents avoid walking into speech bubbles

    6.8 2D/3D View Toggle

    The canvas supports switching between two rendering modes:

    2D Mode:

    • Classic pixelated top-down view
    • Simpler rendering, lower resource usage
    • All accessories and professional roles supported
    3D Mode:
    • Isometric pseudo-3D rendering with depth
    • Body shapes (box, cylinder, oval) affect rendering
    • Enhanced visual appeal with shading and perspective
    • Location furniture rendered with 3D depth
    • Transparent backgrounds for furniture sprites
    Toggle Features:
    • Toggle button in the map header switches between modes
    • Mode preference persisted in localStorage
    • Smooth visual transition when switching
    • Both modes support all agent customization options

    6.9 Location Viewer (scenarios.html)

    The scenarios page includes an interactive location viewer for previewing scenario environments.

    Mouse-Based Rotation:

    • Click and drag horizontally to rotate the room view
    • Smooth, responsive rotation following mouse movement
    • True 3D rotation in isometric space (not 2D canvas rotation)
    4-Wall Visibility Culling:
    • Room has 4 walls (front, back, left, right)
    • Front wall is always culled to show room interior
    • Other walls are culled when rotation makes them face the viewer
    • Creates an intuitive "cutaway" view that always shows room contents
    Zoom Controls:
    • Zoom In (+): Increase scale for detail view
    • Zoom Out (-): Decrease scale for overview
    • Reset: Return to default zoom level

    7. Privacy Model

    7.1 Information Boundaries

    InformationAlice SeesBob Sees
    Alice's agendaYesNo
    Bob's agendaNoYes
    Option listYesYes
    Conversation historyYesYes
    Public scenario infoYesYes
    Other agents' namesYesYes

    7.2 Agenda Extraction

    The system extracts each agent's private agenda from the case description:

  • Find AGENT: <Name> block
  • Extract text until next AGENT: or section marker
  • Include only in that agent's prompt
  • Store with message for debugging (agentContext field)

  • 8. Resolution Logic

    8.1 Automatic Resolution

    When an accept message is submitted:

  • Find the last proposal/counter in conversation
  • Verify accepter != proposer
  • Update case status to "resolved"
  • Set outcome to "agreed"
  • Set selectedOptionId from the accepted proposal
  • 8.2 Manual Resolution

    Operators can resolve via:

    shell
    POST /api/cases/:id/resolve
    {
      "outcome": "agreed" | "failed" | "abandoned",
      "selectedOption": "opt-id",
      "summary": "Resolution notes"
    }


    9. Testing

    9.1 API Tests

    Located in /tests/api.test.ts (15 tests):

    Test SuiteTestsDescription
    POST /api/cases3Case creation, scenario parsing, validation
    GET /api/cases2List cases, return created cases
    GET /api/cases/:id2Case details, 404 handling
    POST /api/cases/:id/submit2Turn advancement, case resolution
    POST /api/cases/:id/auto-play2Auto-play processing, 404 handling
    GET /api/logs1Request log retrieval
    POST /api/reset1Database reset
    Scenario parsing1Option parsing from text
    Message validation1Submit field validation

    9.2 Running Tests

    bash
    npm test

    All tests use an in-memory SQLite database for isolation.


    10. Configuration

    10.1 Environment Variables

    VariableDefaultDescription
    PORT3000Server port
    DATABASE_PATH./stateloop.dbSQLite database location

    10.2 Server Setup

    bash
    # Install dependencies
    npm install
    
    # Run development server
    npm run dev
    
    # Run production
    npm start
    
    # Run tests
    npm test


    11. Example Workflow

    11.1 Creating a Case

  • Open UI at http://localhost:3000
  • Click "New Case"
  • Enter case description with AGENT sections
  • Submit to create case
  • 11.2 Running Negotiation

  • Copy curl command from Agent Prompt card
  • Execute to get agent's prompt
  • Feed prompt to Claude API
  • Submit Claude's response to the submit endpoint
  • Repeat until case resolves
  • 11.3 Using Auto-Play

    Simply call:

    bash
    curl "http://localhost:3000/api/auto-play"

    This returns a prompt for the current agent, ready to send to Claude.


    12. Files and Structure

    shell
    stateLoop/
    ├── src/
    │   ├── index.ts           # Entry point
    │   ├── api/
    │   │   └── routes.ts      # REST endpoints
    │   ├── services/
    │   │   ├── caseService.ts # Business logic
    │   │   └── taskService.ts # Task management
    │   ├── storage/
    │   │   └── sqlite.ts      # Database operations
    │   └── types/
    │       └── index.ts       # TypeScript interfaces
    ├── public/
    │   ├── index.html         # Main UI
    │   ├── css/
    │   │   └── styles.css     # Styling
    │   └── js/
    │       └── thronglet.js   # Canvas UI logic
    ├── scenarios/             # Pre-made scenario library
    │   └── *.txt              # Scenario definition files
    ├── tests/
    │   └── api.test.ts        # API tests
    ├── docs/
    │   ├── SPEC.md            # This document
    │   ├── requirements.md    # Requirements
    │   ├── api-design.md      # API details
    │   ├── data-models.md     # Data schemas
    │   └── ui-design.md       # UI specification
    ├── package.json
    └── tsconfig.json


    13. Scenarios Library

    13.1 Pre-made Scenarios

    The system includes a library of pre-made scenarios in the /scenarios directory.

    Accessing Scenarios:

    • Web UI: /scenarios.html page with tabs for Scenarios, Furniture, Locations
    • API: GET /api/scenarios lists available scenarios
    • Loading: POST /api/scenarios/:name/load creates a case from a scenario
    Scenario File Format: Scenarios are .txt files in the /scenarios directory following the standard case description format.

    Example Scenarios:

    NameDescriptionAgents
    hospital-hydrationHospital ward discussing patient hydration solutions9 (ACP, nurses, patients)
    spain-trip-gcseTeenagers negotiating a Spain trip with parents6 (Mrs. Patterson, Jake, Chloe, Marcus, Priya, Destiny)
    movie-nightRoommates deciding on a movie4 (Moderator, Chris, Pat, Morgan)
    wedding-planningTwo families planning a wedding5 (Sophie, James, Margaret, Richard, Claire)

    13.2 Furniture Catalog

    The furniture catalog (/public/data/furniture.json) provides location-appropriate furniture items:

    Categories:

    CategoryItems
    hospitalHospital bed, bedside table, nurse station, IV stand, wheelchair
    officeConference table, office chair, whiteboard, desk, filing cabinet
    libraryBookshelf, reading table, armchair, magazine rack, study carrel
    schoolBlackboard, teacher desk, student desk, globe, lockers
    cafeService counter, coffee machine, cafe table, bar stool, pastry case
    outdoorTree, park bench, lamp post, fountain, picnic table
    commonWindow, door, waste bin, fire extinguisher, notice board
    3D Furniture Rendering: Location furniture is rendered in 3D with the following improvements:
    • Transparent backgrounds for PNG furniture sprites
    • Proper depth sorting for layered rendering
    • Isometric perspective matching agent rendering
    • Shadow and lighting effects for visual consistency
    • Dynamic scaling based on canvas size

    13.3 Enhanced Simulation

    The /run endpoint uses intelligent response generation based on agent roles:

    AGREEABILITY Score (0-100):

    • Low (< 45): Skeptical, raises concerns, needs more discussion rounds
    • Medium (45-70): Open to discussion, will agree after reasonable debate
    • High (> 70): Agreeable, quick to accept proposals
    Role-Based Responses:
    RoleBehavior
    Facilitator/ACPOpens discussion, prompts quiet participants, guides to resolution
    PatientShares specific barriers from their agenda
    Skeptical NurseRaises practical workload concerns
    HCAShares domain knowledge about individual preferences
    Junior StaffEager to learn, asks for techniques
    Rounds Calculation: Rounds needed = (100 - agreeability) / 10 + 5

    Automatic Document Writing: When working documents exist (script, notes, decisions), the simulation automatically:

    EventDocumentAction
    Agent makes proposalscriptAppend proposal with option name
    Agent accepts proposaldecisionsAppend agreed decision
    Agent speaks (first 3 messages)notesAppend discussion point
    This enables the /run endpoint to generate complete collaborative documents during simulation.


    14. Agent Customizer (scenarios.html)

    The Scenarios page includes a comprehensive agent customizer for designing agent appearances.

    14.1 Customization Options

    PropertyOptionsDescription
    Age Groupchild, teen, adult, middle, elderlyAffects size and appearance details
    Gendermale, femaleAffects voice and style
    Body Stylenormal, tall, short, wide, athleticProportions and build
    Body Shape (3D)box, cylinder, oval3D rendering shape
    Skin Tone6 preset tones from light to darkDiversity representation
    Hair Colorblack, brown, auburn, blonde, gray, white, redHair appearance
    Clothing ColorColor pickerMain body color
    Accessorynone, hat, glasses, bowtie, headphones, scarfVisual additions
    Professional Rolenone, nurse_scrubs, doctor_coat, police_uniform, teacher, business_suit, healthcare_assistantUniform/outfit
    Mobilitystanding, wheelchair, walking_stick, zimmer_frameMovement aids

    14.1.1 Age Groups

    Age GroupScaleVisual Changes
    child70%Smaller proportions, rounder features
    teen85%Slightly smaller than adult
    adult100%Standard proportions
    middle100%Subtle aging details
    elderly95%Gray hair option, slight stoop

    14.1.2 Body Styles

    StyleWidthHeightDescription
    normal2535Standard proportions
    tall2245Taller, thinner build
    short2828Shorter, compact build
    wide3532Broad, stocky build
    athletic2640Taller with moderate width

    14.1.3 Body Shapes (3D Mode)

    ShapeDescriptionBest For
    boxDefault isometric box shape with flat facesMost characters
    cylinderRounded cylindrical body with curved sidesSofter, friendlier appearance
    ovalEgg-shaped elliptical bodyWide/stocky characters

    14.1.4 Skin Tone Presets

    The system provides 6 preset skin tones for diverse representation:

  • Light/Fair (#ffe0bd)
  • Light-Medium (#f5d0b0)
  • Medium (#d4a574)
  • Medium-Dark (#c68642)
  • Dark (#8d5524)
  • Deep (#5c3317)
  • 14.1.5 Hair Colors

    ColorHex Value
    black#1a1a1a
    brown#654321
    auburn#922724
    blonde#f0e68c
    gray#808080
    white#f5f5f5
    red#b22222

    14.1.6 Accessories

    AccessoryDescription
    noneNo accessory
    hatCap or hat on head
    glassesEyeglasses
    bowtieFormal bowtie
    headphonesOver-ear headphones
    scarfNeck scarf

    14.1.7 Professional Roles

    RoleVisual Description
    nurse_scrubsBlue or green medical scrubs
    doctor_coatWhite lab coat with stethoscope
    police_uniformDark blue uniform with badge
    teacherCardigan or blazer, smart casual
    business_suitFormal suit and tie
    healthcare_assistantLight blue uniform with name badge

    14.1.8 Mobility Options

    MobilityDescription
    standingDefault upright position
    wheelchairSeated in wheelchair
    walking_stickUsing a walking cane
    zimmer_frameUsing a walking frame/zimmer

    14.2 Live Preview

    The customizer includes:

    • Real-time 2D/3D preview canvas
    • JSON code output for copying to scenarios
    • Instant updates on any setting change

    14.3 Age-Based Adjustments

    AgeScaleVisual Changes
    child70%Smaller proportions
    teen85%Slightly smaller
    adult100%Standard
    middle100%Subtle wrinkles
    elderly95%Gray hair, wrinkles

    15. Implemented Features

  • Automatic Continuation - Submit responses include next agent's prompt, enabling Claude to process multiple turns automatically
  • Replay Mode - History endpoint and UI replay functionality for scrubbing through conversations
  • Agent Personas - Agent customizer with age, body, skin, hair, accessories, professional roles, and mobility options
  • Content-Type Aware Responses - JSON for programmatic access, text for human readability
  • 16. Future Enhancements

  • Claude API Auto-Call - Direct Claude API calls from auto-play endpoint
  • WebSocket Updates - Real-time UI updates without polling
  • Multi-Round Voting - Support voting mechanisms
  • Mobile UI - Responsive design for mobile devices
  • 16.1 Planned: Workflows

    Multi-stage workflows where output from one task feeds into the next:

    • Workflow Templates - YAML-defined reusable workflow patterns
    • Stage Chaining - Documents flow automatically between stages
    • Progress Tracking - Visual progress through workflow stages
    • Mermaid Diagrams - Auto-generated workflow visualizations
    See docs/api-design.md section "Process Flows / Workflows" for detailed API design.

    16.2 Planned: Goal-Driven Workflows

    AI-planned workflows based on high-level goals:

    • Goal Definition - Specify desired outcome and constraints
    • Auto-Planning - AI generates execution plan
    • Dynamic Stages - Stages created based on goal requirements

    16.3 Planned: Variability & Randomness

    Control agent behavior unpredictability:

    • Temperature - Overall randomness (0=deterministic, 1=creative)
    • Mood Swings - Moods evolve based on conversation
    • Quirks & Triggers - Per-agent behavioral tendencies
    • Chaos Levels - calm, normal, heated, chaotic
    See docs/api-design.md section "Variability & Randomness" for detailed API design.

    © 2026 Jonathan Leahy · v0.8.1-31-g196fa14