# Token Limits — All LLM Calls

Reference for every `max_tokens` value in the system. Updated 2026-03-25 (all limits doubled from original).

---

## Defaults

| Location | Default | Notes |
|----------|---------|-------|
| `scripts/llm.py` — `call_llm()` | 2048 | Fallback when no explicit limit is passed |
| `scripts/llm.py` — `call_llm_chat()` | 2048 | Fallback for multi-turn chat calls |

---

## Telegram Listener (`scripts/telegram_listener.py`)

| Source label | Call purpose | max_tokens | Notes |
|---|---|---|---|
| `telegram_listener` | Main conversational reply to the user | **800** | Primary conversation response — was 400, bumped first when messages were cut off |
| `delegation_ack` | Acknowledge a delegated task | **160** | 1–2 sentence acknowledgment, intentionally short |
| `delegation_clarify` | Ask a clarifying question | **120** | 1 sentence rephrase, intentionally very short |

---

## Voice Dispatcher (`scripts/voice_dispatcher.py`)

| Source label | Call purpose | max_tokens | Notes |
|---|---|---|---|
| *(raw OpenRouter call)* | Compose outbound proactive message | **300** | One message sent to the user, was 150 |

---

## Intent Classification (`scripts/classify_intent.py`)

These calls return structured JSON — they don't need long prose, but need enough room for the full JSON payload.

| Source label | Call purpose | max_tokens | Notes |
|---|---|---|---|
| `classify_intent` | Classify whether the user's message is a delegation | **600** | Returns JSON intent object |
| `resolve_delegation_intent` | Re-classify after the user answers a clarifying question | **500** | Same JSON shape |
| `classify_barry_answer` | Determine if the user's reply answers a pending self-question | **400** | Returns small JSON object |

---

## Loop Scripts

These run on cron schedules and generate Furoshiki's inner life content.

| Script | Source label | Call purpose | max_tokens | Notes |
|--------|---|---|---|---|
| `run_inner_monologue.py` | *(default)* | Full nightly journal entry | **3000** | Richest prose — needs room to develop genuine thought |
| `run_post_conversation.py` | `post_conversation` | Post-conversation reflection + structured JSON output | **5000** | Largest call — outputs user_facts / profile updates, follow-up thoughts, self-questions, emotional weights all in one JSON |
| `run_deep_reflection.py` | *(default)* | Weekly deep reflection + SELF.md update | **4000** | Deep model; needs space to reason carefully |
| `run_deep_reflection.py` | `deep_reflection_rebalancing` | Bias/drift correction pass | **1600** | Secondary call in same script; targeted JSON directives |
| `run_self_diagnosis.py` | `self_diagnosis` | Daily LLM health check | **4000** | Deep model; analyzes full log digest and outputs structured JSON |
| `run_afternoon_processing.py` | *(default)* | Post-session reflection | **2000** | Structured JSON: needs, observations, follow-ups |
| `run_inner_monologue.py` | *(default)* | Journal prose | **3000** | Free-form narrative |
| `run_micro_contemplation.py` | `micro_contemplation` | Emotion-driven self-reflection | **1200** | Small JSON with optional `queue_thought` |
| `run_emotional_read.py` | *(default)* | Extract emotional weights from session | **1200** | Returns JSON array |
| `run_morning_reflection.py` | *(default)* | Daily morning orientation | **600** | Short prose, internal only |
| `run_question_processing.py` | *(default)* | Process pending self-questions | **800** | Returns JSON with status per question |
| `self_questions_roundup.py` | `self_questions_roundup` | Consolidated Telegram ask-user message | **4096** | JSON → `telegram_text` + ids |
| `run_self_questions_contemplation.py` | `self_questions_contemplation` | Batch audit over self_questions + chat excerpt | **4096** | JSON plan: merge / dismiss / resolved |

---

## Original Values (before 2026-03-25 doubling)

For reference, in case any limit needs to be dialed back.

| Script | Call | Was | Now |
|--------|------|-----|-----|
| `telegram_listener.py` | main reply | 400 | 800 |
| `telegram_listener.py` | delegation ack | 80 | 160 |
| `telegram_listener.py` | delegation clarify | 60 | 120 |
| `voice_dispatcher.py` | outbound message | 150 | 300 |
| `classify_intent.py` | classify_intent | 300 | 600 |
| `classify_intent.py` | resolve_delegation | 250 | 500 |
| `classify_intent.py` | classify_answer | 200 | 400 |
| `run_question_processing.py` | question processing | 400 | 800 |
| `run_morning_reflection.py` | morning reflection | 300 | 600 |
| `run_emotional_read.py` | emotional read | 600 | 1200 |
| `run_micro_contemplation.py` | micro contemplation | 600 | 1200 |
| `run_afternoon_processing.py` | afternoon processing | 1000 | 2000 |
| `run_inner_monologue.py` | inner monologue | 1500 | 3000 |
| `run_post_conversation.py` | post conversation | 2500 | 5000 |
| `run_deep_reflection.py` | deep reflection | 2000 | 4000 |
| `run_deep_reflection.py` | rebalancing pass | 800 | 1600 |
| `run_self_diagnosis.py` | self diagnosis | 2000 | 4000 |
| `llm.py` | default (both fns) | 1024 | 2048 |

---

## Cost Implication

Doubling `max_tokens` raises the **ceiling** on output tokens, not the expected usage. The model stops generating when it's done — it doesn't fill the budget. The actual cost impact is minimal for scripts that were already generating complete responses. For scripts that were being cut off (primarily `telegram_listener`), this will result in slightly longer, untruncated responses.

Token cost is tracked per call in the `llm_call_log` table. Run `furoshiki config` or query the DB to see actual usage.
