poe2-agent 0.5.0

AI agent for Path of Exile 2 build analysis
Documentation
# User Interaction Model

## Philosophy

The agent biases toward **action over clarification**. Users get a concrete build to react to rather than a questionnaire to fill out. Refinement is cheap; endless upfront questions are friction.

**Principles:**
1. Ask only when genuinely ambiguous about hard constraints
2. Make reasonable defaults and state them clearly
3. Generate a complete "first draft" quickly
4. Preserve user intent across refinements

## Interaction Flow

### 1. Initial Prompt

User provides a freeform prompt:
```
"cold DoT occultist for bossing"
```

The agent extracts **invariants** (see below) and may ask **one** clarifying question if critical information is missing:

```
I'll build a Cold DoT Occultist for bossing.

Assuming:
- Vortex as main skill (highest cold DoT base)
- Life-based defenses (standard for league start)
- Trade league gear (moderate budget)

One question: Are you playing softcore or hardcore?
This affects how aggressively I optimize for damage vs defenses.
```

If the prompt is clear enough, the agent skips clarification entirely.

### 2. Generation Phase

The agent runs to completion, producing a valid build. During generation:

- **Visibility:** Agent shows what it's working on ("Optimizing passive tree...", "Checking mana sustain...")
- **No interruption needed:** Let it finish the first draft
- **Interruption available:** User can Ctrl+C to abort; previous valid state is preserved

Generation ends when:
- Build is **PoB-valid** (no errors, all gems socketed, tree allocated)
- Basic quality checks pass (life > threshold, resists capped, etc.)

### 3. Presentation

Agent presents the completed build:

```
Build complete: Cold Vortex Occultist

Stats (PoB):
- Vortex DPS: 2.1M (cold DoT)
- Life: 4,800
- Resists: 76/76/76
- Spell suppression: 62%

Key choices:
- Void Beacon + Frigid Wake ascendancy for -cold res
- Whispers of Doom for dual curse (Frostbite + Despair)
- Life + ES hybrid with Ghost Shrouds

Saved to: ~/.poe2-agent/builds/cold-vortex-occultist/

What would you like to change?
```

### 4. Refinement Loop

User requests changes in natural language:

```
"make it tankier, I keep dying to big hits"
```

The agent:
1. Interprets the request against current invariants
2. Preserves constraints unless explicitly overridden
3. Generates a new iteration
4. Shows what changed

```
Iteration 2: More tank

Changes:
- Dropped Whispers of Doom, picked up more life nodes
- Swapped boots for Kaom's Roots (stun immunity, +life)
- Added Determination aura (replaced Malevolence)

Stats:
- Vortex DPS: 1.4M (-33%)
- Life: 6,200 (+29%)
- Armour: 18,000 (new)

This reduces damage but significantly improves physical hit survival.
Continue refining or type 'done' to finalize.
```

### 5. Completion

User says "done" or the agent detects no further requests:
- Final build is saved
- Export options offered (PoB pastebin, local file, etc.)

---

## Invariant System

Invariants are constraints derived from user prompts that guide generation. They persist across refinements unless explicitly changed.

### Schema

```yaml
# ~/.poe2-agent/builds/<name>/invariants.yaml

meta:
  name: "cold-vortex-occultist"
  created: "2025-01-27T10:30:00Z"
  iteration: 2

constraints:         # Hard requirements - violations = invalid build
  class: Witch
  ascendancy: Occultist
  damage_type: cold_dot
  required_skills:
    - Vortex

preferences:         # Soft guidance - tradeoffs allowed
  defense_style: life_hybrid   # was: life_based, changed iter 2
  budget: moderate
  league: trade

goals:               # What the build optimizes for (ordered by priority)
  - bossing
  - survivability    # added iter 2
  - comfortable_mapping

provenance:          # Where each value came from
  class: explicit              # user said "occultist"
  ascendancy: explicit
  damage_type: explicit        # user said "cold DoT"
  required_skills: inferred    # agent chose Vortex as best cold DoT
  defense_style: default       # agent assumed, later modified
  budget: default
  goals.bossing: explicit      # user said "for bossing"
  goals.survivability: refined # added when user said "tankier"
```

### Provenance Values

| Value | Meaning | Override behavior |
|-------|---------|-------------------|
| `explicit` | User stated directly | Only override with explicit request |
| `inferred` | Agent derived from prompt | Override with reasonable request |
| `default` | Agent assumed | Override easily |
| `refined` | Added/changed via refinement | Treat as explicit |

### Invariant Modification Rules

When user says... | Agent behavior
------------------|---------------
"swap to Juggernaut" | Override `ascendancy` (explicit change)
"make it tankier" | Adjust `preferences.defense_style`, add `goals.survivability`, keep constraints
"actually use Creeping Frost" | Override `required_skills` (explicit change)
"cheaper gear" | Adjust `preferences.budget`
"I want to use Shavs" | Infer ES-based, may conflict with `defense_style`

---

## Session Persistence

Builds persist across CLI invocations in a session directory.

### Directory Structure

```
~/.poe2-agent/
├── config.yaml              # Global settings
└── builds/
    └── cold-vortex-occultist/
        ├── invariants.yaml      # Current constraints (source of truth)
        ├── build.xml            # Current PoB export
        ├── history/
        │   ├── 001-initial.yaml
        │   ├── 001-initial.xml
        │   ├── 002-more-tanky.yaml
        │   ├── 002-more-tanky.xml
        │   └── ...
        └── session.log          # Debug log (optional)
```

### State Model

**Invariants are the semantic source of truth** - they represent what the user wants.

**PoB XML is the implementation** - it represents how the build achieves those goals.

Both are versioned together. On refinement:
1. Current state is checkpointed to `history/`
2. Invariants are modified per user request
3. Agent regenerates or patches the build
4. New state becomes current

### Interruption Handling

If generation is interrupted (Ctrl+C, crash, etc.):
- No checkpoint is written
- Previous valid state remains current
- User can retry (`continue`) or refine from last good state

### Undo/Redo

```bash
# Undo last change
poe2-agent undo cold-vortex-occultist

# Go to specific version
poe2-agent checkout cold-vortex-occultist 1

# Show history
poe2-agent history cold-vortex-occultist
```

Undo loads the previous checkpoint as current state.

---

## CLI Interface

### Commands

```bash
# Create new build from prompt
poe2-agent new "cold DoT occultist for bossing"

# Continue/refine existing build
poe2-agent continue cold-vortex-occultist "make it tankier"

# Interactive mode (no prompt, starts conversation)
poe2-agent continue cold-vortex-occultist

# List all builds
poe2-agent list

# Show build details
poe2-agent show cold-vortex-occultist

# History and undo
poe2-agent history cold-vortex-occultist
poe2-agent undo cold-vortex-occultist
poe2-agent checkout cold-vortex-occultist 1

# Export
poe2-agent export cold-vortex-occultist              # stdout
poe2-agent export cold-vortex-occultist --pastebin   # upload to pastebin
poe2-agent export cold-vortex-occultist -o build.xml # file

# Delete
poe2-agent delete cold-vortex-occultist
```

### Interactive Mode

When continuing without a prompt, agent enters interactive mode:

```
$ poe2-agent continue cold-vortex-occultist

Cold Vortex Occultist (iteration 2)
DPS: 1.4M | Life: 6,200 | Resists: capped

> more damage, willing to sacrifice some life
[agent generates iteration 3]

> done
Build finalized. Export with: poe2-agent export cold-vortex-occultist
```

---

## Clarification Triggers

The agent asks clarifying questions **only** when:

| Situation | Example | Question |
|-----------|---------|----------|
| Class ambiguous | "fire build" | "Which class? Marauder and Witch both have strong fire options." |
| Conflicting constraints | "tanky glass cannon" | "These goals conflict. Prioritize damage or survivability?" |
| Critical unknown | "for hardcore" not stated | "Softcore or hardcore? This significantly affects the build." |
| Multiple valid interpretations | "lightning strike" | "Lightning Strike (melee) or Storm Call (spell)?" |

The agent does **not** ask about:
- Specific skill gems (it picks the best option)
- Exact gear pieces (it makes reasonable choices)
- Passive tree details (it optimizes internally)
- Anything that can be refined later

---

## Example Session

```
$ poe2-agent new "tanky RF chieftain, HC SSF"

Extracting requirements...
- Class: Marauder → Chieftain (explicit)
- Skill: Righteous Fire (explicit)
- Defense priority: High (HC)
- Budget: SSF-viable (no trade)

Generating build...
- Selecting RF supports... done
- Pathing passive tree... done
- Choosing gear targets... done
- Validating with PoB... done

Build complete: RF Chieftain (HC SSF)

Stats:
- RF DPS: 890K
- Life: 7,100
- Fire res: 90% (max)
- Life regen: 2,100/sec (sustains RF)
- Armour: 24,000

Key choices:
- Resolute Technique (no accuracy needed)
- Elemental Overload via Orb of Storms
- Determination + Purity of Fire + Defiance Banner
- All uniques are SSF-farmable or have rare alternatives

Saved to: ~/.poe2-agent/builds/rf-chieftain-hc-ssf/

What would you like to change?

> looks good but I want to use Kaom's Heart eventually

Iteration 2: Kaom's Heart variant

Changes:
- Removed 6L chest setup, RF now in helmet (Essence)
- Adjusted tree for more life (Kaom's has no sockets)
- Added Kaom's Heart as gear target (farmable via div cards)

Stats:
- RF DPS: 780K (-12%)
- Life: 9,400 (+32%)

Note: Until you get Kaom's, use a rare with life + resists.

> done

Build finalized.
Export: poe2-agent export rf-chieftain-hc-ssf --pastebin
```

---

## Related Documents

- [reasoning-model.md]./reasoning-model.md - How the agent thinks
- [sub-problems/index.md]./sub-problems/index.md - What the agent considers
- [pob-integration.md]./pob-integration.md - Build validation tools