Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Breaking Changes

- **F083**: Conversation mode redesigned as an interactive user-driven loop — removes all automated multi-turn fields (`max_turns`, `max_context_tokens`, `strategy`, `stop_condition`, `inject_context`) and the `initial_prompt` agent field. Workflows using these fields now fail YAML parsing silently (fields ignored); update them as follows:
- `initial_prompt: X` → use `prompt: X` (serves as the first user message in conversation mode)
- `conversation.max_turns`, `conversation.max_context_tokens`, `conversation.strategy`, `conversation.stop_condition`, `conversation.inject_context` → remove all five; the user now drives turn count and exit by typing into stdin (empty line, `exit`, or `quit`)
- `mode: conversation` now requires a terminal (reads from stdin) and the `ConversationManager` adds a `StdinInputReader` wiring `os.Stdin`/`os.Stdout`; headless/CI usage must pipe stdin (e.g., `echo "" | awf run ...`)
- Only `conversation.continue_from` is preserved, for cross-step session resume
- New `StopReasonUserExit` replaces the removed `StopReasonCondition`, `StopReasonMaxTurns`, `StopReasonMaxTokens` constants
- **F083**: `conversation:` sub-struct now usable in `mode: single` (the default) to opt a step into session tracking — a plain agent step with `conversation: {}` runs `provider.ExecuteConversation` once (no interactive loop), establishing a session that downstream steps can resume via `continue_from`; without the sub-struct, `mode: single` behaves exactly as before (no session, no tracking); this changes the semantic of `conversation:` from "conversation mode only" to "session tracking marker"
- **F081**: Codex model validation is stricter — only models with prefixes `gpt-`, `codex-`, or o-series pattern (e.g., `o1`, `o3-mini`) are accepted; workflows using non-OpenAI models (e.g., `code-davinci`, `text-davinci`) will fail validation; update YAML to use valid OpenAI model names or switch to a different provider
- **F079**: Stored `ConversationState.SessionID` values from prior runs are invalidated for Gemini and Codex — old sentinel values (`"latest"`, `"last"`, `codex-*` prefixed IDs) do not match any real session and cause resume to skip (safe fallback to stateless mode); no migration needed, conversations restart cleanly on first run after upgrade
- **F078**: CLI provider invocation flags updated to match current binary APIs — Claude and Gemini `output_format: json` now maps to `--output-format stream-json` (was `--output-format json`); Codex invocation changed from `codex --prompt "<prompt>" --quiet` to `codex exec --json "<prompt>"`; `quiet` option removed from Codex (silently ignored); Codex conversation resume changed from `codex resume <id> --prompt "<prompt>"` to `codex resume <id> --json "<prompt>"`; workflows using `output_format: json` require no YAML changes (mapping is automatic); workflows using `quiet: true` for Codex should remove the option (no-op)
Expand Down
103 changes: 50 additions & 53 deletions docs/user-guide/agent-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,83 +731,80 @@ handle_json_error:

## Multi-Turn Conversations

There are two approaches for multi-turn conversations:
AWF offers three approaches for multi-turn interactions, from stateless to fully session-tracked.

### Chaining Steps (Manual State Passing)
### 1. State Passing (Chained Steps, Stateless)

For simple multi-turn workflows, chain agent steps with state passing:
Chain agent steps via template interpolation. Each agent call is stateless — the provider has no memory of prior steps — but the next prompt carries the prior step's output as text. Cheapest and simplest.

```yaml
name: code-review-conversation
version: "1.0.0"
initial_review:
type: agent
provider: claude
prompt: |
Review this code for issues:
{{.inputs.code}}
on_success: follow_up

inputs:
- name: code
type: string
required: true
follow_up:
type: agent
provider: claude
prompt: |
Based on your previous analysis:
{{.states.initial_review.Output}}

states:
initial: initial_review
Can you elaborate on performance concerns?
on_success: done
```

initial_review:
type: agent
provider: claude
prompt: |
Review this code for issues:
{{.inputs.code}}
on_success: ask_about_performance
Use this when the prior output is small and the agent doesn't need implicit memory of prior conversation turns.

ask_about_performance:
type: agent
provider: claude
prompt: |
Based on your previous analysis:
{{.states.initial_review.Output}}
### 2. Cross-Step Session Tracking

Can you elaborate on performance concerns?
on_success: suggest_improvements
Add a `conversation:` sub-struct to an agent step (still `mode: single`, the default) to have AWF call `provider.ExecuteConversation` — one turn only, but the provider's session ID is captured. A later step with `conversation: {continue_from: prior_step}` clones that session state and resumes the actual provider-side conversation.

suggest_improvements:
type: agent
provider: claude
prompt: |
Based on the previous discussion, suggest 3 specific improvements to:
{{.inputs.code}}
on_success: done
```yaml
seed:
type: agent
provider: claude
system_prompt: "You are a memory test assistant."
prompt: |
Remember this secret: BANANA42.
Reply "stored".
conversation: {} # opt into session tracking
on_success: recall

done:
type: terminal
recall:
type: agent
provider: claude
prompt: "What was the secret?"
conversation:
continue_from: seed # resume seed's session
on_success: done
```

Each step can reference previous agent outputs and build on the conversation without maintaining session state.
No interactive loop, no stdin. Each step runs exactly one agent turn. The provider retains the conversation between steps via its native session store (`claude -r`, `gemini --resume`, `codex resume`, `opencode -s`).

Use this when the agent needs implicit memory of earlier turns or when prior context is large and you want to avoid re-sending it in each prompt.

### Conversation Mode (Built-In Multi-Turn)
### 3. Interactive Conversation Mode

For iterative refinement within a single step, use **conversation mode** with automatic context window management:
`mode: conversation` spawns a live user-driven chat loop: the agent replies, AWF prompts for your next message via stdin, and the loop continues until you submit an empty line, `exit`, or `quit`.

```yaml
refine_code:
chat:
type: agent
provider: claude
mode: conversation
system_prompt: "You are a code reviewer. Iterate until code is approved."
initial_prompt: |
Review this code:
{{.inputs.code}}
conversation:
max_turns: 10
max_context_tokens: 100000
stop_condition: "response contains 'APPROVED'"
system_prompt: "You are a concise technical assistant."
prompt: "{{.inputs.topic}}"
timeout: 600
on_success: done
```

**Key differences:**
- **Automatic turn management** — No need to manually chain steps
- **Context window handling** — Automatically truncates old turns when token limit approached
- **Stop conditions** — Exit conversation early when specific condition met
- **Single step** — Simpler workflows for iterative refinement
Requires a TTY. Use this for human-in-the-loop clarification sessions or iterative prompting driven by a user.

See [Conversation Mode Guide](conversation-steps.md) for detailed documentation, examples, and best practices.
See [Conversation Mode & Session Tracking](conversation-steps.md) for the complete reference, including `continue_from` rules, cross-provider limitations, and observability fields.

## Error Handling

Expand Down
Loading
Loading