# Improve Think Tool Usage

> **Status: partially implemented.** Fix B (simplify required params to just
> `thought`) and C (improved tool description) were shipped. The schema was later
> further revised to replace `is_revision` with a discriminated `mode` parameter
> and add tolerant coercion. Fix A (directive system prompt) was shipped. Fix D
> (loop nudges) was not implemented.

The agent rarely uses the `think` tool. Three root causes and four fixes.

## Why the model doesn't use it

### 1. System prompt is too gentle

The workflow section says "Plan with `think`. For non-trivial tasks..." — a single buried bullet point that reads as a suggestion. Models jump straight to action tools (read_file, edit_file) because those produce visible progress.

### 2. Tool schema is overly complex

The `think` tool has 8 parameters, 4 required (`thought`, `thought_number`, `total_thoughts`, `next_thought_needed`). Compare to Anthropic's recommended think tool: one `thought` string. High parameter ceremony makes the tool feel heavyweight. Models avoid it.

The revision/branching features (`is_revision`, `revises_thought`, `branch_from_thought`, `branch_id`) add more friction. Models won't use branching unless specifically prompted.

### 3. Description doesn't explain the payoff

The description says *what* it does but not *why* the model should bother. The `note` parameter — the most useful feature for persisting findings across context compaction — is buried as an optional param with no emphasis.

## Fixes

### A. Make the system prompt more directive (high impact, easy)

In `system_prompt.txt`, change the workflow section to make thinking non-optional for certain scenarios:

```
# Workflow

1. **Explore first.** Read files and list directories to understand the codebase before making changes.
2. **Think before you act.** ALWAYS use the `think` tool before:
   - Starting a multi-step task (plan your approach)
   - Debugging (track hypotheses and eliminate them systematically)
   - Making a decision between alternatives
   - After reading code, before editing it (verify you understand the change)
   Use `note` to save key findings — they survive context compaction.
3. **Implement incrementally.** One logical change at a time. After each change, re-read the file to verify.
4. **Recover from errors.** If a tool call fails, use `think` to diagnose the issue before trying again.
```

### B. Simplify the tool interface (high impact, moderate effort)

Make `thought_number`, `total_thoughts`, and `next_thought_needed` optional with sensible defaults (auto-increment, estimate 3, true). Reduces required parameters to just `thought`. The model can still provide the others for structured multi-step reasoning, but the barrier to entry drops.

Files touched: `tools.py` (schema), `thinking.py` (defaults in `process()`).

**Defaulting behavior:**
- `thought_number`: auto-increment from `len(self.history) + 1`
- `total_thoughts`: carry forward from last entry, or 3 if first call
- `next_thought_needed`: default `true`

**Required test coverage:**
- Schema-compat: calls that still pass all four fields work identically (no regressions in `test_think.py`)
- Defaulting: calls with only `thought` produce correct auto-incremented numbering
- Mixed: a sequence where some calls provide explicit numbers and some rely on defaults
- Revision/branch: existing revision and branch tests still pass (these depend on `thought_number` being recorded correctly, so auto-increment must match)
- Integration: `dispatch("think", {"thought": "..."}, ...)` returns valid JSON with correct fields

### C. Improve the tool description (moderate impact, easy)

Replace the dry functional description with one that sells the tool:

```python
"description": (
    "Think step-by-step before acting. This is your scratchpad for reasoning — "
    "use it to plan, debug, weigh alternatives, or track what you've learned. "
    "Using think before complex actions leads to better outcomes. "
    "Pass a `note` to save important findings to disk — these persist even when "
    "older messages are dropped during context compaction."
),
```

### D. Add nudges in the agent loop (moderate impact, moderate effort)

In `agent.py`, inject a soft reminder if the model hasn't used `think` yet and goes straight to a mutating tool.

**Trigger rules:**
- Fires when the model's tool call is `edit_file` or `write_file` AND `think` has not been called in the current `run_agent_loop()` invocation (tracked via a simple boolean flag).
- `run_command` is excluded — too many invocations are read-only (`ls`, `rg`, `git log`, etc.) and would over-trigger. Can be reconsidered later if needed.
- Does NOT fire for read-only tools (`read_file`, `list_files`, `grep`, `fetch_url`) — those are exploratory and don't need a plan.

**Suppression rules:**
- At most once per `run_agent_loop()` invocation. After the nudge fires once, the flag flips and it never fires again for that loop. This avoids prompt noise on multi-edit tasks.
- Does not fire if the conversation already contains a `think` tool result in the current turn sequence (the model already thought earlier).

**Implementation:** append the nudge as a user-role message *after* all tool results for the current turn, in the same place existing interventions are injected (see the repeated-error and guardrail messages in `agent.py`). This preserves the assistant→tool-result message sequencing that the API expects. The nudge is a soft hint, not a blocker — the tool call executes normally and the model sees the nudge on its next turn.

## Success metrics

- **Think call rate:** percentage of agent runs where `think` is called at least once. Target: >50% of multi-turn runs (currently near 0%).
- **Note save rate:** percentage of think calls that include a `note`. Indicates the model understands the persistence value. Target: >20% of think calls.
- **Measurement:** add counters to `ThinkingState` (`think_calls`, `note_attempts`, `note_saves`) independent of verbose logging. Emit a one-line summary to stderr at the end of `run_agent_loop()` (always, not gated on `--verbose`), e.g. `"think: 3 calls, 1 note saved"`. This makes metrics available in all runs without requiring verbose mode.
- **Qualitative:** spot-check agent transcripts for whether think calls precede complex edits and whether the reasoning is coherent (not just filler to satisfy the prompt).

## Suggested order

1. A (system prompt) + C (tool description) — quick, highest expected impact
2. B (simplify required params) — next tier, with full test coverage before merging
3. D (loop nudges) — if the above isn't enough, with the trigger/suppression rules above
