diff --git a/examples/python-sdk/README.md b/examples/python-sdk/README.md
index 3c0b316..d87982c 100644
--- a/examples/python-sdk/README.md
+++ b/examples/python-sdk/README.md
@@ -1,7 +1,24 @@
-# Augment SDK Examples
+# Augment Python SDK Examples
This directory contains examples demonstrating how to use the Augment Python SDK.
+## Quick Links
+
+- **[User Examples](user_examples/)** - Numbered tutorial examples (01-09) with a comprehensive [user guide](user_examples/user_guide.md)
+- **[Documentation](docs/)** - Detailed guides on specific features
+- **Basic Examples** - See below for standalone example scripts
+
+## Installation
+
+```bash
+pip install auggie-sdk
+```
+
+Make sure you have the Auggie CLI installed:
+```bash
+auggie --version
+```
+
## Basic Examples
### `basic_usage.py`
@@ -16,7 +33,7 @@ Demonstrates fundamental SDK features:
**Run it:**
```bash
-python examples/basic_usage.py
+python basic_usage.py
```
### `session_usage.py`
@@ -28,16 +45,15 @@ Shows how to use sessions for conversation continuity:
**Run it:**
```bash
-python examples/session_usage.py
+python session_usage.py
```
-### `list_prs.py` / `list_prs_2.py`
-Examples of working with GitHub PRs using the SDK.
+### `list_prs.py`
+Example of working with GitHub PRs using the SDK.
-**Run them:**
+**Run it:**
```bash
-python examples/list_prs.py
-python examples/list_prs_2.py
+python list_prs.py
```
## ACP Client Examples
@@ -51,33 +67,13 @@ Demonstrates the AuggieACPClient for persistent sessions with the Augment CLI:
**Run it:**
```bash
-python examples/acp_example_usage.py
-```
-
-### Claude Code Client Tests
-
-For ClaudeCodeACPClient examples and testing, see the **real E2E tests**:
-
-**Location:** `tests/test_claude_code_client_e2e.py`
-
-**Prerequisites:**
-```bash
-npm install -g @zed-industries/claude-code-acp
-export ANTHROPIC_API_KEY=...
+python acp_example_usage.py
```
-**Run tests:**
-```bash
-# Quick tests (~30 seconds)
-pytest tests/test_claude_code_client_e2e.py
+### Claude Code Client
-# All tests including slow ones (~5-10 minutes)
-pytest tests/test_claude_code_client_e2e.py -m ""
-```
-
-**Documentation:**
-- [Claude Code Client Guide](../docs/CLAUDE_CODE_CLIENT.md)
-- [Testing Guide](../tests/README_CLAUDE_CODE_TESTS.md)
+For ClaudeCodeACPClient documentation, see:
+- [Claude Code Client Guide](docs/CLAUDE_CODE_CLIENT.md)
## Prompt-to-SDK Conversion
@@ -104,22 +100,7 @@ Finally:
- Create fix suggestions for top 3
```
-**Convert it to SDK code:**
-```bash
-# In TUI mode
-/prompt-to-sdk examples/example_complex_prompt.txt
-
-# From command line
-auggie command prompt-to-sdk examples/example_complex_prompt.txt
-```
-
-### `demo_prompt_to_sdk.sh`
-Interactive demo script that shows the prompt-to-sdk conversion process.
-
-**Run it:**
-```bash
-./examples/demo_prompt_to_sdk.sh
-```
+See [README_PROMPT_TO_CODE.md](README_PROMPT_TO_CODE.md) for more details on prompt-to-code conversion.
## Workflow Patterns
@@ -252,28 +233,35 @@ All examples can be run directly:
```bash
# Run a specific example
-python examples/basic_usage.py
+python basic_usage.py
# Run with custom workspace
-python examples/basic_usage.py --workspace /path/to/workspace
+python basic_usage.py --workspace /path/to/workspace
# Run with different model
-python examples/basic_usage.py --model gpt-4o
+python basic_usage.py --model gpt-4o
```
## Documentation
-- **SDK README**: `../README.md`
-- **Prompt-to-SDK Guide**: `../PROMPT_TO_SDK_GUIDE.md`
-- **Slash Command Summary**: `../SLASH_COMMAND_SUMMARY.md`
+For more comprehensive documentation, see the [docs](docs/) directory:
+- [Agent Event Listener](docs/AGENT_EVENT_LISTENER.md)
+- [Architecture](docs/ARCHITECTURE.md)
+- [Automatic Type Inference](docs/AUTOMATIC_TYPE_INFERENCE.md)
+- [Claude Code Client](docs/CLAUDE_CODE_CLIENT.md)
+- [Function Calling](docs/FUNCTION_CALLING.md)
+- [Prompt to Code](docs/PROMPT_TO_CODE.md)
+- [Session Continuity](docs/SESSION_CONTINUITY.md)
+
+Also check out the [user_examples](user_examples/) directory for more examples and the [user guide](user_examples/user_guide.md).
## Getting Help
If you encounter issues:
-1. Check that the SDK is installed: `pip install -e .`
+1. Check that the SDK is installed: `pip install auggie-sdk`
2. Verify auggie CLI is available: `auggie --version`
3. Check the workspace path is correct
4. Review error messages for specific issues
-For more help, see the main SDK documentation.
+For more help, see the documentation in the [docs](docs/) directory.
diff --git a/examples/python-sdk/docs/AGENT_EVENT_LISTENER.md b/examples/python-sdk/docs/AGENT_EVENT_LISTENER.md
new file mode 100644
index 0000000..cf2040e
--- /dev/null
+++ b/examples/python-sdk/docs/AGENT_EVENT_LISTENER.md
@@ -0,0 +1,291 @@
+# AgentEventListener Interface Explained
+
+The `AgentEventListener` interface allows you to receive real-time notifications about what the agent is doing while it processes your request. This is useful for:
+- Building UIs that show progress
+- Logging agent activity
+- Debugging agent behavior
+- Providing user feedback during long-running operations
+
+## Overview
+
+When you send a message to the agent (e.g., "Create a function to add two numbers"), the agent goes through several steps:
+
+1. **Thinking** - The agent reasons about what to do
+2. **Tool Calls** - The agent uses tools (read files, write files, run commands, etc.)
+3. **Responding** - The agent sends back a message with the results
+
+The `AgentEventListener` lets you observe all of these steps in real-time as they happen.
+
+## The Five Event Types
+
+### 1. `on_agent_message_chunk(text: str)`
+
+**What it is:** Chunks of the agent's response message as it's being streamed.
+
+**When it's called:** Multiple times as the agent streams its response text to you.
+
+**Example scenario:**
+```
+You ask: "What is 2 + 2?"
+
+The agent responds: "The answer is 4."
+
+Your listener receives:
+ on_agent_message_chunk("The ")
+ on_agent_message_chunk("answer ")
+ on_agent_message_chunk("is ")
+ on_agent_message_chunk("4.")
+ on_agent_message("The answer is 4.") # Complete message at the end
+```
+
+**Why it's chunked:** The agent streams its response in real-time rather than waiting to generate the entire message. This allows you to show progress to users immediately.
+
+**Use cases:**
+- Display the agent's response as it's being typed (like ChatGPT)
+- Show a progress indicator while waiting for the full response
+- Build up the complete message incrementally
+
+### 2. `on_agent_thought(text: str)`
+
+**What it is:** The agent's internal reasoning/thinking process.
+
+**When it's called:** When the agent is thinking about what to do next, before it takes action.
+
+**Example scenario:**
+```
+You ask: "Read the README file and summarize it"
+
+Your listener receives:
+ on_agent_thought("I need to first read the README.md file using the view tool")
+ on_agent_thought("Then I'll analyze the content and create a summary")
+```
+
+**Why it's useful:** Helps you understand the agent's decision-making process. This is like seeing the agent "think out loud."
+
+**Use cases:**
+- Debug why the agent chose a particular approach
+- Show users what the agent is planning to do
+- Log the agent's reasoning for audit purposes
+
+### 3. `on_tool_call(tool_call_id, title, kind, status)`
+
+**What it is:** Notification that the agent is making a tool call.
+
+**When it's called:** When the agent begins executing a tool (reading a file, editing code, running a command, etc.)
+
+**Parameters:**
+- `tool_call_id`: Unique ID for this specific tool call (e.g., "tc_123")
+- `title`: Human-readable description (e.g., "view", "str-replace-editor", "launch-process")
+- `kind`: Category of tool (e.g., "read", "edit", "delete", "execute")
+- `status`: Current status (e.g., "pending", "in_progress")
+
+**Example scenario:**
+```
+You ask: "Read the file test.py and fix any errors"
+
+Your listener receives:
+ on_tool_call(
+ tool_call_id="tc_001",
+ title="view",
+ kind="read",
+ status="pending"
+ )
+```
+
+**Use cases:**
+- Show "Reading file..." or "Editing file..." messages to users
+- Track which tools the agent is using
+- Display a progress indicator for long-running operations
+
+### 4. `on_tool_response(tool_call_id, status, content)`
+
+**What it is:** Response from a tool call.
+
+**When it's called:** When a tool responds with results.
+
+**Parameters:**
+- `tool_call_id`: The ID from the corresponding `on_tool_call`
+- `status`: Response status (e.g., "completed", "failed")
+- `content`: Results or additional information from the tool
+
+**Example scenario:**
+```
+Continuing from above...
+
+Your listener receives:
+ on_tool_response(
+ tool_call_id="tc_001",
+ status="completed",
+ content={"file_content": "def test():\n pass"}
+ )
+```
+
+**Use cases:**
+- Update progress indicators
+- Show tool results to users
+- Detect when operations complete or fail
+
+### 5. `on_agent_message(message: str)`
+
+**What it is:** The complete agent message after all chunks have been sent.
+
+**When it's called:** Once, after the agent finishes streaming its complete response.
+
+**Example scenario:**
+```
+After receiving all the chunks:
+ on_agent_message_chunk("The ")
+ on_agent_message_chunk("answer ")
+ on_agent_message_chunk("is ")
+ on_agent_message_chunk("4.")
+
+You receive:
+ on_agent_message("The answer is 4.")
+```
+
+**Use cases:**
+- Log the complete message
+- Process the full response (e.g., parse it, save it)
+- Update UI with final message
+- Trigger actions based on complete response
+
+## Complete Example
+
+Here's a complete example showing all events in action:
+
+```python
+from auggie_sdk import Auggie
+from auggie_sdk.acp import AgentEventListener
+
+class MyListener(AgentEventListener):
+ def on_agent_message_chunk(self, text: str) -> None:
+ print(f"[CHUNK] {text}", end="", flush=True)
+
+ def on_agent_message(self, message: str) -> None:
+ print(f"\n[COMPLETE MESSAGE] {message}")
+
+ def on_tool_call(self, tool_call_id: str, title: str,
+ kind: str = None, status: str = None) -> None:
+ print(f"\n[TOOL CALL] {title} (kind={kind}, status={status})")
+
+ def on_tool_response(self, tool_call_id: str,
+ status: str = None, content: Any = None) -> None:
+ print(f"[TOOL RESPONSE] status={status}")
+
+ def on_agent_thought(self, text: str) -> None:
+ print(f"[THINKING] {text}")
+
+# Use the listener
+listener = MyListener()
+agent = Auggie(listener=listener)
+
+response = agent.run("Read the file test.py and count the lines")
+```
+
+**Output might look like:**
+```
+[THINKING] I need to read the test.py file first
+[TOOL CALL] view (kind=read, status=pending)
+[TOOL RESPONSE] status=completed
+[CHUNK] The file test.py has
+[CHUNK] 42 lines
+[CHUNK] .
+[COMPLETE MESSAGE] The file test.py has 42 lines.
+```
+
+## Event Flow Diagram
+
+```
+User sends message: "Create a function"
+ ↓
+[THINKING] "I'll create a new file..."
+ ↓
+[TOOL CALL] save-file (kind=create)
+ ↓
+[TOOL RESPONSE] status=completed
+ ↓
+[AGENT MESSAGE CHUNK] "I've created "
+[AGENT MESSAGE CHUNK] "the function "
+[AGENT MESSAGE CHUNK] "for you."
+ ↓
+[AGENT MESSAGE] "I've created the function for you."
+```
+
+## Important Notes
+
+1. **Chunks vs Complete Messages**: `on_agent_message_chunk` is called multiple times with small chunks. `on_agent_message` is called once with the complete message at the end.
+
+2. **Optional Methods**: `on_agent_thought` and `on_agent_message` are NOT abstract, so you don't have to implement them if you don't need them.
+
+3. **Tool Call Pairing**: Each `on_tool_call` will have one or more corresponding `on_tool_response` calls with the same `tool_call_id`.
+
+4. **Thread Safety**: If you're updating a UI, make sure your listener methods are thread-safe.
+
+5. **Performance**: Keep your listener methods fast - they're called synchronously and will block the agent if they take too long.
+
+## Common Patterns
+
+### Pattern 1: Accumulate Full Message
+```python
+class MessageAccumulator(AgentEventListener):
+ def __init__(self):
+ self.message_chunks = []
+
+ def on_agent_message_chunk(self, text: str) -> None:
+ self.message_chunks.append(text)
+
+ def on_agent_message(self, message: str) -> None:
+ # Or just use the complete message directly!
+ print(f"Complete message: {message}")
+
+ # ... implement other required methods ...
+```
+
+### Pattern 2: Track Tool Usage
+```python
+class ToolTracker(AgentEventListener):
+ def __init__(self):
+ self.tools_used = []
+
+ def on_tool_call(self, tool_call_id, title, kind=None, status=None):
+ self.tools_used.append({
+ "id": tool_call_id,
+ "name": title,
+ "kind": kind,
+ "start_time": time.time()
+ })
+
+ # ... implement other required methods ...
+```
+
+### Pattern 3: Progress UI
+```python
+class ProgressListener(AgentEventListener):
+ def on_tool_call(self, tool_call_id, title, kind=None, status=None):
+ print(f"⏳ {title}...")
+
+ def on_tool_response(self, tool_call_id, status=None, content=None):
+ if status == "completed":
+ print(f"✅ Done!")
+ elif status == "failed":
+ print(f"❌ Failed!")
+
+ # ... implement other required methods ...
+```
+
+## Quick Reference Table
+
+| Event | When Called | How Many Times | Purpose |
+|-------|-------------|----------------|---------|
+| `on_agent_message_chunk` | Agent is streaming response | Many (chunks) | Get response text in real-time |
+| `on_agent_message` | Agent finishes response | Once | Get complete message |
+| `on_agent_thought` | Agent is thinking | 0 or more | See agent's reasoning |
+| `on_tool_call` | Agent makes a tool call | Once per tool | Know what tool is being used |
+| `on_tool_response` | Tool responds | 1+ per tool | Get tool results |
+
+## See Also
+
+- `examples/event_listener_demo.py` - Interactive demo showing all events
+- `examples/` directory for more working examples
+- `augment/acp/test_client_e2e.py` for test examples using listeners
+
diff --git a/examples/python-sdk/docs/ARCHITECTURE.md b/examples/python-sdk/docs/ARCHITECTURE.md
new file mode 100644
index 0000000..7a9d209
--- /dev/null
+++ b/examples/python-sdk/docs/ARCHITECTURE.md
@@ -0,0 +1,268 @@
+# Augment Python SDK Architecture
+
+## Overview
+
+The Augment Python SDK is organized into two distinct layers:
+
+1. **Protocol Layer** - Pure ACP (Agent Client Protocol) implementation
+2. **SDK Layer** - Augment-specific convenience features and utilities
+
+This separation ensures the protocol client remains reusable and spec-compliant, while the SDK layer provides user-friendly features.
+
+## Architecture Diagram
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ User Code │
+└─────────────────────────────────────────────────────────────────┘
+ │
+ ├─────────────────┬─────────────────┐
+ ↓ ↓ ↓
+┌──────────────────────────────────┐ ┌──────────────────────────────────┐
+│ SDK Layer (Optional) │ │ Protocol Layer (Core) │
+├──────────────────────────────────┤ ├──────────────────────────────────┤
+│ │ │ │
+│ Agent (subprocess-based) │ │ AuggieACPClient │
+│ - run(return_type=int) │ │ - start() │
+│ - Typed returns │ │ - send_message() → str │
+│ - Session management │ │ - stop() │
+│ - CLI subprocess spawning │ │ - Pure ACP protocol │
+│ │ │ - Event listeners │
+│ AgentACP (future) │ │ - Long-running process │
+│ - run(return_type=int) │ │ │
+│ - Typed returns │ │ Model/workspace config: │
+│ - Uses AuggieACPClient ────────────→│ - model parameter │
+│ - Agent-compatible API │ │ - workspace_root parameter │
+│ │ │ - Passed as CLI args │
+└──────────────────────────────────┘ └──────────────────────────────────┘
+ │
+ ↓
+ ┌──────────────────────────────────┐
+ │ Augment CLI (ACP mode) │
+ │ - Runs with --acp flag │
+ │ - Implements ACP protocol │
+ │ - Long-running process │
+ └──────────────────────────────────┘
+```
+
+## Layer Responsibilities
+
+### Protocol Layer: `AuggieACPClient`
+
+**Purpose:** Pure implementation of the ACP (Agent Client Protocol) specification.
+
+**Responsibilities:**
+- ✅ Spawn CLI in ACP mode
+- ✅ Implement ACP protocol (initialize, newSession, prompt, etc.)
+- ✅ Handle bidirectional JSON-RPC communication
+- ✅ Stream responses via event listeners
+- ✅ Manage process lifecycle
+- ✅ Pass configuration via CLI arguments (model, workspace_root)
+
+**NOT Responsible For:**
+- ❌ Typed return values (not in ACP spec)
+- ❌ Augment-specific features
+- ❌ Convenience wrappers
+- ❌ Response parsing beyond protocol requirements
+
+**API:**
+```python
+from auggie_sdk.acp import AuggieACPClient
+
+client = AuggieACPClient(
+ model="claude-3-5-sonnet-latest", # CLI arg
+ workspace_root="/path/to/workspace", # CLI arg
+ listener=MyEventListener() # ACP feature
+)
+
+client.start() # ACP: initialize + newSession
+response = client.send_message("...") # ACP: prompt → returns str
+client.clear_context() # ACP: clear
+client.stop() # Cleanup
+```
+
+### SDK Layer: `Agent` and `AgentACP`
+
+**Purpose:** User-friendly API with Augment-specific features.
+
+**Responsibilities:**
+- ✅ Typed return values (int, str, bool, list, dict, dataclass, enum)
+- ✅ Convenient API for common use cases
+- ✅ Session management (for subprocess-based `Agent`)
+- ✅ Response parsing and validation
+- ✅ Error handling and retries
+- ✅ Augment-specific conventions
+
+**Current Implementation:**
+
+#### `Agent` (subprocess-based)
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie(
+ workspace_root="/path/to/workspace",
+ model="claude-3-5-sonnet-latest"
+)
+
+# Typed returns - SDK feature
+result = agent.run("What is 2 + 2?", return_type=int)
+print(result) # 4 (int, not str)
+
+# Session management - SDK feature
+with agent.session() as session:
+ session.run("Create a function")
+ session.run("Test it") # Remembers context
+```
+
+#### `AgentACP` (future - ACP-based)
+```python
+from auggie_sdk import AgentACP
+
+agent = AgentACP(
+ workspace_root="/path/to/workspace",
+ model="claude-3-5-sonnet-latest"
+)
+
+# Same API as Agent, but uses ACP client internally
+result = agent.run("What is 2 + 2?", return_type=int)
+print(result) # 4 (int, not str)
+
+# No session management needed - automatic!
+agent.run("Create a function")
+agent.run("Test it") # Automatically remembers context
+```
+
+## Feature Mapping
+
+| Feature | Protocol Layer | SDK Layer | Notes |
+|---------|---------------|-----------|-------|
+| **Model selection** | ✅ CLI arg | ✅ Constructor param | Passed to CLI via `--model` |
+| **Workspace root** | ✅ CLI arg | ✅ Constructor param | Passed to CLI via `--workspace-root` |
+| **Send message** | ✅ `send_message()` | ✅ `run()` | Protocol returns str, SDK can parse |
+| **Typed returns** | ❌ Not in spec | ✅ `run(return_type=T)` | SDK-level feature |
+| **Event streaming** | ✅ Event listeners | ⚠️ Optional | Protocol feature, SDK can expose |
+| **Session continuity** | ✅ Automatic | ✅ Automatic (ACP) / Manual (subprocess) | Long-running vs subprocess |
+| **Context clearing** | ✅ `clear_context()` | ✅ Exposed | Protocol feature |
+| **Timeout** | ✅ Per-message | ✅ Per-request | Both support |
+
+## Design Principles
+
+### 1. Separation of Concerns
+
+**Protocol Layer:**
+- Implements ACP specification exactly
+- No Augment-specific features
+- Reusable by other projects
+- Minimal dependencies
+
+**SDK Layer:**
+- Augment-specific conveniences
+- User-friendly API
+- Can use protocol layer or subprocess
+- Rich feature set
+
+### 2. Configuration via CLI Arguments
+
+The ACP client passes configuration to the CLI via command-line arguments rather than protocol messages:
+
+```python
+# Model and workspace are CLI arguments
+cli_args = ["node", "augment.mjs", "--acp", "--model", "claude-3-5-sonnet-latest", "--workspace-root", "/path"]
+
+# NOT protocol parameters
+# NewSessionRequest only has: cwd, mcpServers
+```
+
+**Why:**
+- Model selection happens at CLI initialization
+- Workspace root affects CLI behavior globally
+- Keeps protocol simple and focused
+- Matches how CLI is designed
+
+### 3. Long-Running Session Model
+
+The ACP client maintains a single persistent session:
+
+```python
+client.start() # Creates ONE session
+client.send_message("A") # Same session
+client.send_message("B") # Same session
+client.send_message("C") # Same session
+client.stop() # Ends session
+```
+
+**Benefits:**
+- Automatic context continuity
+- No session resume needed
+- Better performance (no subprocess overhead)
+- Real-time streaming
+
+**Contrast with subprocess model:**
+```python
+agent.run("A") # New process, new session
+agent.run("B") # New process, new session - NO CONTEXT
+
+with agent.session() as session:
+ session.run("A") # Process with session ID
+ session.run("B") # New process, resumes session - HAS CONTEXT
+```
+
+## Migration Path
+
+### Current State
+- ✅ `Agent` - Subprocess-based, full-featured
+- ✅ `AuggieACPClient` - Protocol layer, model/workspace support
+
+### Future State
+- ✅ `Agent` - Keep for simple use cases
+- ✅ `AuggieACPClient` - Protocol layer (stable)
+- 🔄 `AgentACP` - SDK wrapper using ACP client (to be implemented)
+
+### When to Use Each
+
+**Use `Agent` (subprocess) when:**
+- Simple one-off requests
+- Don't need real-time streaming
+- Want simplest API
+- Explicit session control preferred
+
+**Use `AuggieACPClient` (protocol) when:**
+- Building custom integrations
+- Need full control over ACP protocol
+- Want event-driven architecture
+- Building tools/libraries
+
+**Use `AgentACP` (future) when:**
+- Multiple related requests
+- Want typed returns + automatic sessions
+- Need better performance than subprocess
+- Want Agent-compatible API with ACP benefits
+
+## Implementation Status
+
+### ✅ Complete
+- [x] `AuggieACPClient` with model and workspace_root parameters
+- [x] CLI argument passing for configuration
+- [x] Automatic session continuity
+- [x] Event listener support
+- [x] Documentation and examples
+
+### 🔄 Future (Optional)
+- [ ] `AgentACP` wrapper class
+- [ ] Typed return values in SDK layer
+- [ ] Migration guide from `Agent` to `AgentACP`
+- [ ] Performance benchmarks
+
+### ❌ Not Planned
+- Typed returns in `AuggieACPClient` (belongs in SDK layer)
+- Session resume in ACP client (not needed - long-running)
+- Protocol extensions for Augment-specific features (use CLI args)
+
+## Summary
+
+The architecture cleanly separates protocol implementation from SDK conveniences:
+
+- **`AuggieACPClient`** = Pure ACP protocol, reusable, spec-compliant
+- **`Agent`/`AgentACP`** = User-friendly SDK with typed returns and conveniences
+
+This design keeps the protocol layer clean while providing rich features in the SDK layer.
diff --git a/examples/python-sdk/docs/AUTOMATIC_TYPE_INFERENCE.md b/examples/python-sdk/docs/AUTOMATIC_TYPE_INFERENCE.md
new file mode 100644
index 0000000..dd8bc1a
--- /dev/null
+++ b/examples/python-sdk/docs/AUTOMATIC_TYPE_INFERENCE.md
@@ -0,0 +1,190 @@
+# Automatic Type Inference
+
+## Summary
+
+The Agent class now automatically infers the type of responses when no `return_type` is specified. This makes the SDK more intelligent and user-friendly by eliminating the need to explicitly specify types for common use cases.
+
+## Changes Made
+
+### 1. Removed `infer_type` Parameter
+
+**Before:**
+```python
+# Explicit type inference with infer_type parameter
+result, chosen_type = agent.run("What is 2 + 2?", infer_type=[int, str, bool])
+```
+
+**After:**
+```python
+# Automatic type inference (no parameter needed)
+result, chosen_type = agent.run("What is 2 + 2?")
+```
+
+### 2. New Default Behavior
+
+When `return_type` is not specified, the agent automatically:
+1. Infers the best type from a default set of common types
+2. Returns a tuple of `(result, inferred_type)`
+
+**Default inference types:**
+- `int`
+- `float`
+- `bool`
+- `str`
+- `list`
+- `dict`
+
+### 3. Updated API
+
+**`Agent.run()` signature:**
+```python
+def run(
+ self,
+ instruction: str,
+ return_type: Type[T] = None, # infer_type parameter removed
+ timeout: Optional[int] = None,
+ max_retries: int = 3,
+) -> Union[T, tuple[T, Type[T]]]:
+```
+
+**Return values:**
+- If `return_type` is specified: Returns parsed result of that type
+- If `return_type` is None: Returns tuple of `(result, inferred_type)`
+
+## Examples
+
+### Automatic Type Inference
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# Agent automatically determines the type
+result, inferred_type = agent.run("What is 2 + 2?")
+print(f"Result: {result}, Type: {inferred_type.__name__}")
+# Output: Result: 4, Type: int
+
+result, inferred_type = agent.run("List the primary colors")
+print(f"Result: {result}, Type: {inferred_type.__name__}")
+# Output: Result: ['red', 'blue', 'yellow'], Type: list
+
+result, inferred_type = agent.run("Is Python statically typed?")
+print(f"Result: {result}, Type: {inferred_type.__name__}")
+# Output: Result: False, Type: bool
+```
+
+### Explicit Type Specification
+
+```python
+# Still works as before - specify exact type
+result = agent.run("What is 2 + 2?", return_type=int)
+print(f"Result: {result}") # Result: 4
+
+# Works with complex types
+from dataclasses import dataclass
+
+@dataclass
+class Task:
+ title: str
+ priority: str
+
+task = agent.run("Create a task", return_type=Task)
+print(f"Task: {task.title}")
+```
+
+## Implementation Details
+
+### Core Changes
+
+1. **Added `DEFAULT_INFERENCE_TYPES` constant** in `augment/agent.py`:
+ ```python
+ DEFAULT_INFERENCE_TYPES = [int, float, bool, str, list, dict]
+ ```
+
+2. **Modified `run()` method** to use automatic type inference when `return_type` is None:
+ ```python
+ if return_type is None:
+ # Type inference mode with default types
+ return self._run_with_type_inference(
+ client,
+ instruction,
+ DEFAULT_INFERENCE_TYPES,
+ effective_timeout,
+ max_retries,
+ )
+ ```
+
+3. **Removed `infer_type` parameter** from the `run()` method signature
+
+4. **Updated return type annotation** to reflect the new behavior:
+ ```python
+ -> Union[T, tuple[T, Type[T]]]
+ ```
+
+### Test Updates
+
+- Updated all tests that call `agent.run()` without `return_type` to expect tuple returns
+- Added helper function `make_type_inference_response()` for creating mock responses
+- Renamed tests from `test_run_type_inference_*` to `test_run_automatic_type_inference_*`
+- All 49 unit tests passing
+
+### Documentation Updates
+
+- Updated README.md with automatic type inference examples
+- Added dedicated section explaining the feature
+- Updated API reference
+- Updated examples in `examples/basic_usage.py`
+
+## Benefits
+
+1. **Simpler API**: No need to specify `infer_type` parameter
+2. **More Intelligent**: Agent automatically chooses the best type
+3. **Backward Compatible**: Explicit `return_type` still works as before
+4. **Better UX**: Natural behavior - when you don't specify a type, the agent figures it out
+
+## Migration Guide
+
+### If you were using `infer_type`:
+
+**Before:**
+```python
+result, chosen_type = agent.run("What is 2 + 2?", infer_type=[int, str, bool])
+```
+
+**After:**
+```python
+# Just remove the infer_type parameter
+result, chosen_type = agent.run("What is 2 + 2?")
+```
+
+### If you were calling `run()` without any type:
+
+**Before:**
+```python
+response = agent.run("Hello") # Returns string
+```
+
+**After:**
+```python
+result, inferred_type = agent.run("Hello") # Returns tuple
+# Or unpack just the result if you don't need the type
+result, _ = agent.run("Hello")
+```
+
+## Files Modified
+
+1. `augment/agent.py` - Core implementation
+2. `tests/test_agent.py` - Test updates
+3. `README.md` - Documentation
+4. `examples/basic_usage.py` - Example updates
+5. `pyproject.toml` - Fixed duplicate `[project.optional-dependencies]` section
+
+## Testing
+
+All tests pass:
+```bash
+cd experimental/guy/auggie_sdk
+python3 -m pytest tests/test_agent.py -v
+# 49 passed in 0.16s
+```
diff --git a/examples/python-sdk/docs/CLAUDE_CODE_CLIENT.md b/examples/python-sdk/docs/CLAUDE_CODE_CLIENT.md
new file mode 100644
index 0000000..393f084
--- /dev/null
+++ b/examples/python-sdk/docs/CLAUDE_CODE_CLIENT.md
@@ -0,0 +1,287 @@
+# Claude Code ACP Client
+
+The `ClaudeCodeACPClient` provides a Python interface to interact with [Claude Code](https://www.anthropic.com/claude-code) via the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/).
+
+This client uses Zed's open-source ACP adapter ([`@zed-industries/claude-code-acp`](https://github.com/zed-industries/claude-code-acp)) to communicate with Claude Code through the standardized ACP protocol.
+
+## Prerequisites
+
+### 1. Install the ACP Adapter
+
+The adapter is a Node.js package that wraps the Claude Code SDK to speak ACP:
+
+```bash
+npm install -g @zed-industries/claude-code-acp
+```
+
+### 2. Set Your API Key
+
+You need an Anthropic API key to use Claude Code:
+
+```bash
+export ANTHROPIC_API_KEY=...
+```
+
+You can get an API key from [Anthropic's Console](https://console.anthropic.com/).
+
+## Basic Usage
+
+### Simple Example
+
+```python
+from auggie_sdk.acp import ClaudeCodeACPClient
+
+# Create client (uses ANTHROPIC_API_KEY from environment)
+client = ClaudeCodeACPClient()
+
+# Start the agent
+client.start()
+
+# Send a message
+response = client.send_message("What is 2 + 2?")
+print(response)
+
+# Stop the agent
+client.stop()
+```
+
+### With Context Manager
+
+```python
+from auggie_sdk.acp import ClaudeCodeACPClient
+
+with ClaudeCodeACPClient() as client:
+ response = client.send_message("Write a hello world function in Python")
+ print(response)
+```
+
+### With Event Listener
+
+```python
+from auggie_sdk.acp import ClaudeCodeACPClient, AgentEventListener
+
+class MyListener(AgentEventListener):
+ def on_agent_message_chunk(self, text: str) -> None:
+ print(text, end="", flush=True)
+
+ def on_tool_call(self, tool_call_id: str, title: str, kind: str = None, status: str = None) -> None:
+ print(f"\n[Tool: {title}]")
+
+client = ClaudeCodeACPClient(listener=MyListener())
+client.start()
+response = client.send_message("Create a Python function to calculate fibonacci numbers")
+client.stop()
+```
+
+## Configuration Options
+
+### API Key
+
+You can provide the API key in three ways:
+
+1. **Environment variable** (recommended):
+ ```bash
+ export ANTHROPIC_API_KEY=...
+ ```
+
+2. **Constructor argument**:
+ ```python
+ client = ClaudeCodeACPClient(api_key="...")
+ ```
+
+3. **Programmatically**:
+ ```python
+ import os
+ os.environ["ANTHROPIC_API_KEY"] = "..."
+ client = ClaudeCodeACPClient()
+ ```
+
+### Model Selection
+
+Specify which Claude model to use:
+
+```python
+client = ClaudeCodeACPClient(
+ model="claude-3-5-sonnet-latest"
+)
+```
+
+Available models:
+- `claude-3-5-sonnet-latest` (default)
+- `claude-3-opus-latest`
+- `claude-3-haiku-latest`
+
+### Workspace Root
+
+Set the working directory for the agent:
+
+```python
+client = ClaudeCodeACPClient(
+ workspace_root="/path/to/your/project"
+)
+```
+
+### Custom Adapter Path
+
+If you installed the adapter locally or want to use a specific version:
+
+```python
+client = ClaudeCodeACPClient(
+ adapter_path="/path/to/claude-code-acp"
+)
+```
+
+## Session Continuity
+
+Messages sent to the same client instance share context automatically:
+
+```python
+client = ClaudeCodeACPClient()
+client.start()
+
+# First message
+client.send_message("My favorite color is blue")
+
+# Second message - remembers the context
+response = client.send_message("What is my favorite color?")
+print(response) # Will mention "blue"
+
+client.stop()
+```
+
+To clear the context and start fresh:
+
+```python
+client.clear_context() # Restarts the agent with a new session
+```
+
+## Features Supported
+
+The Claude Code ACP adapter supports all major Claude Code features:
+
+- ✅ **Context @-mentions** - Reference files and code
+- ✅ **Images** - Send images for analysis
+- ✅ **Tool calls** - File operations, terminal commands, etc.
+- ✅ **Permission requests** - Interactive approval for sensitive operations
+- ✅ **Edit review** - Review and approve code changes
+- ✅ **TODO lists** - Track tasks and progress
+- ✅ **Interactive terminals** - Run commands and see output
+- ✅ **Slash commands** - Custom commands for specialized tasks
+- ✅ **MCP servers** - Connect to Model Context Protocol servers
+
+## Error Handling
+
+```python
+from auggie_sdk.acp import ClaudeCodeACPClient
+
+try:
+ client = ClaudeCodeACPClient()
+ client.start()
+ response = client.send_message("Hello!")
+ client.stop()
+except ValueError as e:
+ print(f"Configuration error: {e}")
+except RuntimeError as e:
+ print(f"Runtime error: {e}")
+except TimeoutError as e:
+ print(f"Timeout: {e}")
+```
+
+Common errors:
+
+- **`ValueError: ANTHROPIC_API_KEY must be provided`** - Set your API key
+- **`RuntimeError: npx not found`** - Install Node.js
+- **`TimeoutError: Claude Code agent failed to start`** - Install the adapter with `npm install -g @zed-industries/claude-code-acp`
+
+## Testing
+
+Run the E2E tests to verify everything works:
+
+```bash
+# Quick tests (~30 seconds)
+pytest tests/test_claude_code_client_e2e.py
+
+# All tests including slow ones (~5-10 minutes)
+pytest tests/test_claude_code_client_e2e.py -m ""
+
+# Specific test
+pytest tests/test_claude_code_client_e2e.py::test_simple_math_query -v
+```
+
+See [Testing Guide](../tests/README_CLAUDE_CODE_TESTS.md) for details.
+
+## Comparison with AuggieACPClient
+
+| Feature | ClaudeCodeACPClient | AuggieACPClient |
+|---------|---------------------|-----------------|
+| Backend | Claude Code (Anthropic) | Augment CLI |
+| API Key | Anthropic API key | Augment credentials |
+| Installation | npm package | Built-in CLI |
+| Models | Claude 3.x family | Multiple providers |
+| Features | Full Claude Code features | Augment-specific features |
+
+## Architecture
+
+```
+Python Code
+ ↓
+ClaudeCodeACPClient (Python)
+ ↓
+agent-client-protocol (Python package)
+ ↓
+ACP Protocol (stdio)
+ ↓
+@zed-industries/claude-code-acp (Node.js adapter)
+ ↓
+Claude Agent SDK (TypeScript)
+ ↓
+Claude Code
+ ↓
+Anthropic API
+```
+
+## Troubleshooting
+
+### Adapter not found
+
+```
+RuntimeError: npx not found
+```
+
+**Solution**: Install Node.js from [nodejs.org](https://nodejs.org/)
+
+### Agent fails to start
+
+```
+TimeoutError: Claude Code agent failed to start within 30 seconds
+```
+
+**Solution**: Install the adapter:
+```bash
+npm install -g @zed-industries/claude-code-acp
+```
+
+### API key errors
+
+```
+ValueError: ANTHROPIC_API_KEY must be provided
+```
+
+**Solution**: Set your API key:
+```bash
+export ANTHROPIC_API_KEY=...
+```
+
+### Process exits immediately
+
+Check the error message for details. Common causes:
+- Invalid API key
+- Network issues
+- Adapter version mismatch
+
+## References
+
+- [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code)
+- [Agent Client Protocol](https://agentclientprotocol.com/)
+- [Zed's ACP Adapter](https://github.com/zed-industries/claude-code-acp)
+- [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-python)
diff --git a/examples/python-sdk/docs/FUNCTION_CALLING.md b/examples/python-sdk/docs/FUNCTION_CALLING.md
new file mode 100644
index 0000000..fc68ae1
--- /dev/null
+++ b/examples/python-sdk/docs/FUNCTION_CALLING.md
@@ -0,0 +1,263 @@
+# Function Calling Feature
+
+## Overview
+
+The Augment Python SDK now supports **function calling**, allowing you to provide Python functions that the agent can invoke during execution. This enables the agent to interact with external systems, perform calculations, fetch data, and more.
+
+## Implementation Summary
+
+### What Was Added
+
+1. **Function Schema Generation** (`augment/function_tools.py`)
+ - Converts Python functions with type hints to JSON schemas
+ - Extracts parameter descriptions from docstrings
+ - Supports Google-style and NumPy-style docstrings
+ - Handles optional parameters, default values, and various Python types
+
+2. **Agent Integration** (`augment/agent.py`)
+ - Added `functions` parameter to `Agent.run()` method
+ - Function schemas are added to the instruction prompt
+ - Integrated into normal code path (no separate function calling flow)
+ - Added `_handle_function_calls()` helper to process function calls in responses
+ - Added `_parse_function_calls()` to extract function calls from agent responses
+ - Automatic function execution and result passing back to agent
+
+3. **Documentation**
+ - Updated README.md with function calling examples
+ - Updated examples/README.md with proper usage
+ - Updated .augment/commands/prompt-to-sdk.md
+
+4. **Examples and Tests**
+ - Created `examples/function_calling_example.py` with comprehensive examples
+ - Created `examples/simple_function_test.py` for quick testing
+ - Created `test_function_calling.py` with unit tests
+
+## How It Works
+
+### 1. Function Definition
+
+Define Python functions with type hints and docstrings:
+
+```python
+def get_weather(location: str, unit: str = "celsius") -> dict:
+ """
+ Get the current weather for a location.
+
+ Args:
+ location: City name or coordinates
+ unit: Temperature unit (celsius or fahrenheit)
+ """
+ # Your implementation
+ return {"temp": 22, "condition": "sunny"}
+```
+
+### 2. Pass Functions to Agent
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+result = agent.run(
+ "What's the weather in San Francisco?",
+ return_type=dict,
+ functions=[get_weather]
+)
+```
+
+### 3. Agent Workflow
+
+1. Function schemas are added to the instruction prompt
+2. Agent receives instruction and can call functions as needed
+3. If agent calls a function, it returns:
+ ```
+
+ {
+ "name": "get_weather",
+ "arguments": {"location": "San Francisco", "unit": "celsius"}
+ }
+
+ ```
+4. SDK parses the function call and executes the function
+5. SDK sends results back to agent in the same conversation
+6. Agent continues with the response (can call more functions if needed)
+7. Final response is parsed according to `return_type`
+
+This all happens in the normal code path - function calling is integrated seamlessly.
+
+## Function Requirements
+
+For functions to work properly with the agent:
+
+1. **Type Hints**: All parameters should have type hints
+ ```python
+ def my_func(param1: str, param2: int) -> dict:
+ ```
+
+2. **Docstrings**: Include parameter descriptions in docstring
+ ```python
+ """
+ Function description.
+
+ Args:
+ param1: Description of param1
+ param2: Description of param2
+ """
+ ```
+
+3. **Return Type**: Specify return type hint
+ ```python
+ def my_func(...) -> dict:
+ ```
+
+## Supported Types
+
+The schema generator supports:
+- Basic types: `str`, `int`, `float`, `bool`
+- Collections: `list`, `dict`, `List[T]`, `Dict[K, V]`
+- Optional types: `Optional[T]`
+- Union types: `Union[T1, T2]`
+- Any type: `Any`
+
+## Examples
+
+### Simple Calculation
+
+```python
+def add_numbers(a: int, b: int) -> int:
+ """Add two numbers."""
+ return a + b
+
+result = agent.run(
+ "What is 15 + 27?",
+ return_type=int,
+ functions=[add_numbers]
+)
+```
+
+### Multiple Functions
+
+```python
+def multiply(a: int, b: int) -> int:
+ """Multiply two numbers."""
+ return a * b
+
+def divide(a: int, b: int) -> float:
+ """Divide two numbers."""
+ return a / b
+
+result = agent.run(
+ "Calculate (10 * 5) / 2",
+ return_type=float,
+ functions=[multiply, divide]
+)
+```
+
+### Complex Workflow
+
+```python
+def fetch_data(source: str) -> list:
+ """Fetch data from a source."""
+ return [{"id": 1, "value": 100}, {"id": 2, "value": 200}]
+
+def process_data(data: list) -> dict:
+ """Process the fetched data."""
+ total = sum(item["value"] for item in data)
+ return {"count": len(data), "total": total}
+
+result = agent.run(
+ "Fetch data from 'api' and process it",
+ return_type=dict,
+ functions=[fetch_data, process_data]
+)
+```
+
+## Error Handling
+
+If a function raises an exception, the error is caught and returned to the agent:
+
+```python
+def failing_function(x: int) -> int:
+ """A function that might fail."""
+ if x < 0:
+ raise ValueError("x must be positive")
+ return x * 2
+
+# Agent will receive error message and can handle it
+result = agent.run(
+ "Call failing_function with x=-5",
+ return_type=str,
+ functions=[failing_function]
+)
+```
+
+## Limitations
+
+1. **Maximum Rounds**: Function calling is limited to 5 rounds to prevent infinite loops
+2. **Function Signature**: Functions must be callable with keyword arguments
+3. **Serialization**: Function arguments and return values must be JSON-serializable
+4. **No Nested Calls**: Functions cannot call other provided functions directly
+
+## Testing
+
+Run the tests:
+
+```bash
+# Unit tests
+cd experimental/guy/auggie_sdk
+python3 -m pytest test_function_calling.py
+
+# Simple integration test
+python3 examples/simple_function_test.py
+
+# Full examples
+python3 examples/function_calling_example.py
+```
+
+## Implementation Details
+
+### Function Schema Format
+
+Functions are converted to this schema format:
+
+```json
+{
+ "name": "function_name",
+ "description": "Function description from docstring",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "param1": {
+ "type": "string",
+ "description": "Parameter description"
+ }
+ },
+ "required": ["param1"]
+ }
+}
+```
+
+### Agent Protocol
+
+The agent uses XML tags to indicate function calls:
+
+```xml
+
+{
+ "name": "function_name",
+ "arguments": {"param": "value"}
+}
+
+```
+
+Multiple function calls can be made in a single response.
+
+## Future Enhancements
+
+Potential improvements:
+- Support for async functions
+- Streaming function results
+- Function call history/logging
+- Better error recovery
+- Function call validation before execution
+- Support for more complex type hints (TypedDict, Literal, etc.)
diff --git a/examples/python-sdk/docs/PROMPT_TO_CODE.md b/examples/python-sdk/docs/PROMPT_TO_CODE.md
new file mode 100644
index 0000000..cb18947
--- /dev/null
+++ b/examples/python-sdk/docs/PROMPT_TO_CODE.md
@@ -0,0 +1,281 @@
+# Prompt to Code Converter
+
+The `prompt_to_code.py` tool converts complex, multi-stage prompts into well-structured Python programs using the Augment SDK. This allows you to express complex workflows with conditions, loops, and multiple stages as code rather than a single monolithic prompt.
+
+## Why Convert Prompts to SDK Programs?
+
+Complex prompts often involve:
+- **Sequential stages** that build on each other
+- **Conditional logic** based on intermediate results
+- **Loops** over collections of items
+- **Data dependencies** between steps
+- **Validation** and error handling
+
+Converting these to SDK programs gives you:
+- ✅ **Better control** over workflow execution
+- ✅ **Type safety** with Python's type system
+- ✅ **Debugging** capabilities with standard Python tools
+- ✅ **Reusability** - run the same workflow multiple times
+- ✅ **Maintainability** - easier to modify and extend
+- ✅ **Visibility** - see exactly what's happening at each stage
+
+## Installation
+
+Make sure the Augment SDK is installed:
+
+```bash
+cd experimental/guy/auggie_sdk
+pip install -e .
+```
+
+## Usage
+
+### Basic Usage
+
+```bash
+python prompt_to_code.py
+```
+
+This will:
+1. Read your prompt from the file
+2. Analyze its structure
+3. Generate a Python program using the Augment SDK
+4. Save it to `generated_sdk_program.py` (or a numbered variant)
+
+### With Custom Output File
+
+```bash
+python prompt_to_code.py my_prompt.txt --output my_workflow.py
+```
+
+### With Custom Model
+
+```bash
+python prompt_to_code.py my_prompt.txt --model claude-3-5-sonnet-latest
+```
+
+### With Custom Workspace
+
+```bash
+python prompt_to_code.py my_prompt.txt --workspace /path/to/workspace
+```
+
+## Example
+
+Given a prompt file `example_prompt.txt`:
+
+```
+Analyze all Python files in the src/ directory, identify any security
+vulnerabilities or code quality issues, create a detailed report in
+markdown format, and if there are any critical security issues found,
+generate fix suggestions for each one with specific code changes needed.
+```
+
+Run the converter:
+
+```bash
+python prompt_to_code.py examples/example_prompt.txt
+```
+
+This generates a Python program like:
+
+```python
+#!/usr/bin/env python3
+"""
+Security analysis workflow for Python files.
+"""
+
+from auggie_sdk import Auggie
+from dataclasses import dataclass
+from typing import List
+
+@dataclass
+class SecurityIssue:
+ file: str
+ severity: str
+ description: str
+ line_number: int
+
+def main():
+ agent = Auggie(workspace_root=".", model="claude-3-5-sonnet-latest")
+
+ # Stage 1: Get list of Python files
+ files = agent("List all Python files in src/ directory", list[str])
+ print(f"Found {len(files)} Python files to analyze")
+
+ # Stage 2: Analyze each file for security issues
+ all_issues: List[SecurityIssue] = []
+ with agent.session() as session:
+ for file in files:
+ issues = session(
+ f"Analyze {file} for security vulnerabilities. "
+ f"Return a list of issues found.",
+ list[SecurityIssue]
+ )
+ all_issues.extend(issues)
+
+ print(f"Found {len(all_issues)} total security issues")
+
+ # Stage 3: Create report
+ agent(f"Create a security report in security_report.md summarizing "
+ f"the {len(all_issues)} issues found across {len(files)} files")
+
+ # Stage 4: Generate fixes for critical issues
+ critical_issues = [i for i in all_issues if i.severity == "critical"]
+
+ if critical_issues:
+ print(f"Found {len(critical_issues)} critical issues - generating fixes")
+ with agent.session() as session:
+ for issue in critical_issues:
+ session(
+ f"Create a fix for the critical security issue in {issue.file} "
+ f"at line {issue.line_number}: {issue.description}"
+ )
+ else:
+ print("No critical issues found!")
+
+if __name__ == "__main__":
+ main()
+```
+
+## How It Works
+
+The converter analyzes your prompt and identifies patterns:
+
+### 1. Sequential Stages with Context
+
+When steps build on each other, it uses sessions:
+
+```python
+with agent.session() as session:
+ session("Step 1: Create the base structure")
+ session("Step 2: Add features to what we just created")
+ session("Step 3: Test everything we built")
+```
+
+### 2. Conditional Logic
+
+When decisions are needed, it uses typed results:
+
+```python
+result = agent("Check if the file exists", bool)
+if result:
+ agent("Process the existing file")
+else:
+ agent("Create a new file first")
+```
+
+### 3. Loops/Iterations
+
+When operating on collections:
+
+```python
+files = agent("List all Python files in src/", list[str])
+for file in files:
+ agent(f"Review {file} for security issues")
+```
+
+### 4. Data Dependencies
+
+When steps need structured data from previous steps:
+
+```python
+@dataclass
+class FileInfo:
+ path: str
+ size: int
+ type: str
+
+files = agent("Analyze all config files", list[FileInfo])
+for file in files:
+ if file.size > 1000:
+ agent(f"Optimize {file.path} - it's {file.size} bytes")
+```
+
+### 5. Function Calling
+
+When the agent needs to interact with external systems:
+
+```python
+def run_tests(test_file: str) -> dict:
+ """Run tests and return results."""
+ # Your test execution logic
+ return {"passed": 10, "failed": 2, "file": test_file}
+
+result = agent.run(
+ "Run all tests and analyze failures",
+ return_type=dict,
+ functions=[run_tests]
+)
+```
+
+## Command-Line Options
+
+```
+usage: prompt_to_code.py [-h] [-o OUTPUT] [-m MODEL] [-w WORKSPACE] prompt_file
+
+Convert a complex prompt into an Augment SDK program
+
+positional arguments:
+ prompt_file Path to the file containing the prompt to convert
+
+optional arguments:
+ -h, --help show this help message and exit
+ -o OUTPUT, --output OUTPUT
+ Output file path for the generated program (default: auto-generated)
+ -m MODEL, --model MODEL
+ Model to use for conversion (default: claude-3-5-sonnet-latest)
+ -w WORKSPACE, --workspace WORKSPACE
+ Workspace root directory (default: current directory)
+```
+
+## Tips for Writing Good Prompts
+
+To get the best SDK programs, write prompts that clearly describe:
+
+1. **The stages** - What are the distinct steps?
+2. **The data flow** - What information passes between steps?
+3. **The conditions** - When should different actions be taken?
+4. **The iterations** - What collections need to be processed?
+5. **The outputs** - What should be created or returned?
+
+### Good Prompt Example
+
+```
+First, scan all TypeScript files in the components/ directory and identify
+which ones are missing unit tests. For each file without tests, create a
+comprehensive test file with at least 80% coverage. Then run all the new
+tests and if any fail, fix the issues. Finally, generate a summary report
+of test coverage improvements.
+```
+
+This clearly shows:
+- Sequential stages (scan → create tests → run tests → fix → report)
+- Iteration (for each file without tests)
+- Conditional logic (if any fail)
+- Data dependencies (which files need tests)
+
+### Less Ideal Prompt Example
+
+```
+Make the codebase better with tests and stuff.
+```
+
+This is too vague and doesn't provide enough structure for conversion.
+
+## After Generation
+
+Once you have your generated SDK program:
+
+1. **Review the code** - Make sure it matches your intent
+2. **Customize as needed** - Add error handling, logging, etc.
+3. **Test it** - Run it on a small subset first
+4. **Iterate** - Modify the program based on results
+5. **Reuse it** - Run the same workflow whenever needed
+
+## See Also
+
+- [Agent Documentation](./AGENT_EVENT_LISTENER.md)
+- [Session Continuity](./SESSION_CONTINUITY.md)
+- [Function Calling](./FUNCTION_CALLING.md)
+- [Type Inference](./AUTOMATIC_TYPE_INFERENCE.md)
diff --git a/examples/python-sdk/docs/SESSION_CONTINUITY.md b/examples/python-sdk/docs/SESSION_CONTINUITY.md
new file mode 100644
index 0000000..095913f
--- /dev/null
+++ b/examples/python-sdk/docs/SESSION_CONTINUITY.md
@@ -0,0 +1,268 @@
+# Session Continuity: Agent vs ACP Client
+
+## Key Insight
+
+**The ACP client does NOT need session resume functionality** because it maintains a **long-running process with a single persistent session**. All messages automatically share context.
+
+## Architecture Comparison
+
+### Agent Library (Subprocess-Based)
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Agent Library │
+├─────────────────────────────────────────────────────────────┤
+│ │
+│ agent.run("Create a function") │
+│ ↓ │
+│ ┌──────────────────────────────────┐ │
+│ │ Spawn CLI Process │ │
+│ │ Session ID: abc123 │ │
+│ │ Execute → Return → Exit │ │
+│ └──────────────────────────────────┘ │
+│ │
+│ agent.run("Test it") │
+│ ↓ │
+│ ┌──────────────────────────────────┐ │
+│ │ Spawn NEW CLI Process │ │
+│ │ Session ID: xyz789 ← NEW! │ │
+│ │ Execute → Return → Exit │ │
+│ └──────────────────────────────────┘ │
+│ │
+│ ❌ NO CONTEXT - Different sessions! │
+│ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+**Solution:** Explicit session management
+
+```python
+with agent.session() as session:
+ session.run("Create a function") # Session: abc123
+ session.run("Test it") # Session: abc123 (resumed)
+ # ✅ HAS CONTEXT - Same session!
+```
+
+### ACP Client (Long-Running)
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ ACP Client │
+├─────────────────────────────────────────────────────────────┤
+│ │
+│ client.start() │
+│ ↓ │
+│ ┌──────────────────────────────────┐ │
+│ │ Spawn CLI Process (ACP mode) │ │
+│ │ Session ID: abc123 │ │
+│ │ │ │
+│ │ ┌──────────────────────────────┐ │ │
+│ │ │ RUNNING... │ │ │
+│ │ │ │ │ │
+│ │ │ client.send_message(...) │ │ Session: abc123 │
+│ │ │ → Response │ │ │
+│ │ │ │ │ │
+│ │ │ client.send_message(...) │ │ Session: abc123 │
+│ │ │ → Response │ │ │
+│ │ │ │ │ │
+│ │ │ client.send_message(...) │ │ Session: abc123 │
+│ │ │ → Response │ │ │
+│ │ │ │ │ │
+│ │ └──────────────────────────────┘ │ │
+│ │ │ │
+│ └──────────────────────────────────┘ │
+│ ↓ │
+│ client.stop() │
+│ │
+│ ✅ AUTOMATIC CONTEXT - Same session throughout! │
+│ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+**No session management needed!** All messages go to the same session automatically.
+
+## Code Examples
+
+### Agent Library - Requires Session Management
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# ❌ NO CONTEXT - Each call is independent
+agent.run("Create a function called add_numbers")
+agent.run("Test that function") # Doesn't know about add_numbers!
+
+# ✅ WITH CONTEXT - Explicit session
+with agent.session() as session:
+ session.run("Create a function called add_numbers")
+ session.run("Test that function") # Knows about add_numbers!
+```
+
+### ACP Client - Automatic Session Continuity
+
+```python
+from auggie_sdk.acp import AuggieACPClient
+
+client = AuggieACPClient()
+client.start()
+
+# ✅ AUTOMATIC CONTEXT - All messages share session
+client.send_message("Create a function called add_numbers")
+client.send_message("Test that function") # Automatically knows about add_numbers!
+
+client.stop()
+```
+
+## Why This Matters
+
+### Performance
+
+**Agent Library:**
+- Spawns new process per request: ~500ms overhead
+- 10 requests = 10 processes = ~5 seconds overhead
+
+**ACP Client:**
+- One process for all requests: ~500ms overhead once
+- 10 requests = 1 process = ~500ms overhead total
+- **10x faster for multiple requests!**
+
+### User Experience
+
+**Agent Library:**
+```python
+# User must remember to use session context
+with agent.session() as session: # Easy to forget!
+ session.run("Step 1")
+ session.run("Step 2")
+```
+
+**ACP Client:**
+```python
+# Session continuity is automatic
+client.start()
+client.send_message("Step 1")
+client.send_message("Step 2") # Just works!
+client.stop()
+```
+
+### Real-Time Feedback
+
+**Agent Library:**
+- Waits for entire response before returning
+- No progress updates
+
+**ACP Client:**
+- Streams responses in real-time
+- Can show tool calls, thinking process, etc.
+- Better UX for long-running operations
+
+```python
+from auggie_sdk.acp import AuggieACPClient, AgentEventListener
+
+class MyListener(AgentEventListener):
+ def on_agent_message_chunk(self, text: str):
+ print(text, end="", flush=True) # Real-time output!
+
+ def on_tool_call(self, tool_name: str, tool_input: dict):
+ print(f"\n[Using tool: {tool_name}]")
+
+client = AuggieACPClient(listener=MyListener())
+client.start()
+client.send_message("Create a complex function") # See progress in real-time!
+client.stop()
+```
+
+## When to Use Each
+
+### Use Agent Library When:
+
+- ✅ Simple one-off requests
+- ✅ Don't need session continuity
+- ✅ Want simplest possible API
+- ✅ Don't need real-time streaming
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+result = agent.run("What is 2 + 2?", return_type=int)
+print(result) # 4
+```
+
+### Use ACP Client When:
+
+- ✅ Multiple related requests
+- ✅ Need automatic session continuity
+- ✅ Want real-time streaming
+- ✅ Need better performance
+- ✅ Want event-driven architecture
+
+```python
+from auggie_sdk.acp import AuggieACPClient
+
+client = AuggieACPClient(model="claude-3-5-sonnet-latest")
+client.start()
+
+# All these share context automatically
+client.send_message("Create a function")
+client.send_message("Test it")
+client.send_message("Now optimize it")
+
+client.stop()
+```
+
+## Migration Path
+
+If you're using `Agent` with sessions:
+
+```python
+# Before (Agent with session)
+from auggie_sdk import Auggie
+
+agent = Auggie(workspace_root="/path/to/workspace", model="claude-3-5-sonnet-latest")
+
+with agent.session() as session:
+ session.run("Create a function")
+ session.run("Test it")
+ session.run("Optimize it")
+```
+
+Migrate to ACP client:
+
+```python
+# After (ACP client - simpler!)
+from auggie_sdk.acp import AuggieACPClient
+
+client = AuggieACPClient(
+ workspace_root="/path/to/workspace",
+ model="claude-3-5-sonnet-latest"
+)
+
+client.start()
+client.send_message("Create a function")
+client.send_message("Test it")
+client.send_message("Optimize it")
+client.stop()
+
+# Or use context manager
+with AuggieACPClient(workspace_root="/path/to/workspace") as client:
+ client.send_message("Create a function")
+ client.send_message("Test it")
+ client.send_message("Optimize it")
+```
+
+## Summary
+
+| Feature | Agent Library | ACP Client |
+|---------|--------------|------------|
+| **Session Continuity** | Manual (with `session()`) | Automatic |
+| **Process Model** | New process per request | Long-running process |
+| **Performance** | ~500ms overhead per request | ~500ms overhead once |
+| **Real-time Streaming** | ❌ No | ✅ Yes |
+| **Event Listeners** | ❌ No | ✅ Yes |
+| **API Complexity** | Simple for one-off, complex for sessions | Consistent |
+| **Best For** | One-off requests | Multiple related requests |
+
+**Key Takeaway:** The ACP client's long-running architecture makes session resume unnecessary - it's a feature, not a bug! 🎉
diff --git a/examples/python-sdk/user_examples/01_quick_start.py b/examples/python-sdk/user_examples/01_quick_start.py
new file mode 100644
index 0000000..951f38f
--- /dev/null
+++ b/examples/python-sdk/user_examples/01_quick_start.py
@@ -0,0 +1,11 @@
+"""Quick Start Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+
+# Create an agent instance
+agent = Auggie()
+
+# Run a simple instruction
+response = agent.run("What is the capital of France?")
+print(response)
+# Output: Paris
diff --git a/examples/python-sdk/user_examples/02_event_listener_builtin.py b/examples/python-sdk/user_examples/02_event_listener_builtin.py
new file mode 100644
index 0000000..4c2fcaa
--- /dev/null
+++ b/examples/python-sdk/user_examples/02_event_listener_builtin.py
@@ -0,0 +1,13 @@
+"""Built-in Logger Example from user_guide.md"""
+
+from auggie_sdk import Agent, LoggingAgentListener
+
+# Use the built-in logger for easy debugging
+agent = Auggie(listener=LoggingAgentListener(verbose=True))
+
+result = agent.run("What is 2 + 2?")
+print(f"\nFinal result: {result}")
+# Output will include:
+# 🔧 Tool calls
+# 💭 Thinking messages
+# 💬 Agent messages
diff --git a/examples/python-sdk/user_examples/03_event_listener_custom.py b/examples/python-sdk/user_examples/03_event_listener_custom.py
new file mode 100644
index 0000000..11c68a3
--- /dev/null
+++ b/examples/python-sdk/user_examples/03_event_listener_custom.py
@@ -0,0 +1,34 @@
+"""Custom Listener Example from user_guide.md"""
+
+from auggie_sdk import Auggie, AgentListener
+from typing import Any, Optional
+
+
+class MyCustomListener(AgentListener):
+ def on_agent_thought(self, text: str):
+ """Called when the agent shares its internal reasoning."""
+ print(f"[Thinking] {text[:100]}...")
+
+ def on_tool_call(
+ self,
+ tool_call_id: str,
+ title: str,
+ kind: Optional[str] = None,
+ status: Optional[str] = None,
+ ):
+ """Called when the agent is about to execute a tool."""
+ print(f"[Tool Call] {title} (kind={kind}, status={status})")
+
+ def on_tool_response(
+ self, tool_call_id: str, status: Optional[str] = None, content: Any = None
+ ):
+ """Called when a tool execution completes."""
+ print(f"[Tool Result] status={status}, content={str(content)[:50]}...")
+
+ def on_agent_message(self, message: str):
+ """Called when the agent sends a complete message."""
+ print(f"[Agent Message] {message}")
+
+
+agent = Auggie(listener=MyCustomListener())
+agent.run("What is 5 * 5?")
diff --git a/examples/python-sdk/user_examples/04_session_management.py b/examples/python-sdk/user_examples/04_session_management.py
new file mode 100644
index 0000000..c040be7
--- /dev/null
+++ b/examples/python-sdk/user_examples/04_session_management.py
@@ -0,0 +1,16 @@
+"""Session Management Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# ❌ INCORRECT: These calls don't know about each other
+agent.run("Remember that my favorite color is blue")
+result1 = agent.run("What is my favorite color?") # Agent won't know
+print(f"Without session: {result1}")
+
+# ✅ CORRECT: Using a session for shared context
+with agent.session() as session:
+ session.run("Remember that my favorite color is blue")
+ response = session.run("What is my favorite color?")
+ print(f"With session: {response}") # Output: Blue
diff --git a/examples/python-sdk/user_examples/05_type_inference.py b/examples/python-sdk/user_examples/05_type_inference.py
new file mode 100644
index 0000000..24d2130
--- /dev/null
+++ b/examples/python-sdk/user_examples/05_type_inference.py
@@ -0,0 +1,15 @@
+"""Automatic Type Inference Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# Automatic type inference
+result = agent.run("What is 2 + 2?")
+print(f"Result: {result} (Type: {type(result).__name__})")
+# Output: Result: 4 (Type: int)
+
+# It handles complex types too
+result = agent.run("Return a list of the first 3 prime numbers")
+print(result)
+# Output: [2, 3, 5]
diff --git a/examples/python-sdk/user_examples/06_typed_returns.py b/examples/python-sdk/user_examples/06_typed_returns.py
new file mode 100644
index 0000000..a43427f
--- /dev/null
+++ b/examples/python-sdk/user_examples/06_typed_returns.py
@@ -0,0 +1,34 @@
+"""Explicit Type Specification Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+from dataclasses import dataclass
+from typing import List, Dict
+
+
+@dataclass
+class Task:
+ id: int
+ description: str
+ is_done: bool
+
+
+agent = Auggie()
+
+# Get a strongly-typed object back
+task = agent.run("Create a sample task for 'Buy groceries'", return_type=Task)
+print(f"Task {task.id}: {task.description} (Done: {task.is_done})")
+
+# Get a list of objects
+tasks = agent.run(
+ "Create 3 sample tasks for a weekend to-do list", return_type=List[Task]
+)
+for t in tasks:
+ print(f"- {t.description}")
+
+# Get a dictionary of simple types
+counts = agent.run(
+ "Count the number of vowels in 'hello world' and return as a dict",
+ return_type=Dict[str, int],
+)
+print(counts)
+# Output: {'e': 1, 'o': 2}
diff --git a/examples/python-sdk/user_examples/07_success_criteria.py b/examples/python-sdk/user_examples/07_success_criteria.py
new file mode 100644
index 0000000..7253b03
--- /dev/null
+++ b/examples/python-sdk/user_examples/07_success_criteria.py
@@ -0,0 +1,17 @@
+"""Success Criteria & Verification Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# The agent will verify its work meets the criteria
+result = agent.run(
+ "Write a Python function to calculate fibonacci numbers",
+ success_criteria=[
+ "Function has type hints",
+ "Function has a docstring",
+ "Function handles the base cases (0 and 1)",
+ ],
+ max_verification_rounds=3, # Optional: limit retry attempts (default: 3)
+)
+print(result)
diff --git a/examples/python-sdk/user_examples/08_function_tools.py b/examples/python-sdk/user_examples/08_function_tools.py
new file mode 100644
index 0000000..a522a40
--- /dev/null
+++ b/examples/python-sdk/user_examples/08_function_tools.py
@@ -0,0 +1,32 @@
+"""Function Tools Example from user_guide.md"""
+
+from auggie_sdk import Auggie
+import datetime
+
+
+def get_current_weather(location: str, unit: str = "celsius") -> dict:
+ """
+ Gets the weather for a given location.
+
+ Args:
+ location: The city and state, e.g. San Francisco, CA
+ unit: Temperature unit ('celsius' or 'fahrenheit')
+ """
+ # In a real app, you'd call a weather API here
+ return {"temp": 72, "unit": unit, "forecast": "sunny"}
+
+
+def get_time() -> str:
+ """Returns the current time."""
+ return datetime.datetime.now().strftime("%H:%M")
+
+
+agent = Auggie()
+
+# The agent will call the appropriate function(s) to answer the question
+response = agent.run(
+ "What's the weather like in NYC right now, and what time is it there?",
+ functions=[get_current_weather, get_time],
+)
+
+print(response)
diff --git a/examples/python-sdk/user_examples/09_remove_tools.py b/examples/python-sdk/user_examples/09_remove_tools.py
new file mode 100644
index 0000000..53edc4f
--- /dev/null
+++ b/examples/python-sdk/user_examples/09_remove_tools.py
@@ -0,0 +1,20 @@
+from typing import List
+
+from auggie_sdk import Auggie
+
+INTEGRATION_TOOLS = [
+ "github-api",
+ "linear",
+ "notion",
+ "glean",
+ "supabase",
+ "jira",
+ "confluence",
+ "slack",
+]
+
+agent = Auggie(removed_tools=INTEGRATION_TOOLS)
+
+response = agent.run("What are the tools you have available?")
+
+print(response)
diff --git a/examples/python-sdk/user_examples/README.md b/examples/python-sdk/user_examples/README.md
new file mode 100644
index 0000000..d838c35
--- /dev/null
+++ b/examples/python-sdk/user_examples/README.md
@@ -0,0 +1,30 @@
+# User Examples
+
+This directory contains executable examples and the comprehensive user guide for the Augment Python SDK.
+
+## 📖 User Guide
+
+See **[user_guide.md](user_guide.md)** for the complete documentation with detailed explanations, API reference, and usage patterns.
+
+## 🚀 Quick Start Examples
+
+1. **01_quick_start.py** - Basic agent usage
+2. **02_event_listener_builtin.py** - Using the built-in logging listener
+3. **03_event_listener_custom.py** - Creating a custom event listener
+4. **04_session_management.py** - Using sessions for conversational context
+5. **05_type_inference.py** - Automatic type inference
+6. **06_typed_returns.py** - Explicit type specification with dataclasses
+7. **07_success_criteria.py** - Using success criteria for verification
+8. **08_function_tools.py** - Giving the agent access to custom functions
+
+## Running Examples
+
+Run individual examples:
+```bash
+python 01_quick_start.py
+```
+
+Run all examples:
+```bash
+./run_all.sh
+```
diff --git a/examples/python-sdk/user_examples/run_all.sh b/examples/python-sdk/user_examples/run_all.sh
new file mode 100755
index 0000000..0094c5b
--- /dev/null
+++ b/examples/python-sdk/user_examples/run_all.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -e
+
+# Change to the directory where this script is located
+cd "$(dirname "$0")"
+
+echo "=========================================="
+echo "Running User Examples from USER_README.md"
+echo "=========================================="
+echo ""
+
+for script in *.py; do
+ if [ -f "$script" ]; then
+ echo "=========================================="
+ echo "Running: $script"
+ echo "=========================================="
+ python "$script"
+ echo ""
+ echo "✅ $script completed successfully"
+ echo ""
+ fi
+done
+
+echo "=========================================="
+echo "All examples completed successfully! ✅"
+echo "=========================================="
diff --git a/examples/python-sdk/user_examples/test_listener.py b/examples/python-sdk/user_examples/test_listener.py
new file mode 100644
index 0000000..404dae9
--- /dev/null
+++ b/examples/python-sdk/user_examples/test_listener.py
@@ -0,0 +1,40 @@
+"""Test if listener is being called"""
+
+from auggie_sdk import Agent, AgentListener
+from typing import Any, Optional
+
+
+class TestListener(AgentListener):
+ def __init__(self):
+ self.called = []
+
+ def on_agent_message(self, message: str):
+ print(f"✅ on_agent_message called: {message[:50]}")
+ self.called.append("on_agent_message")
+
+ def on_agent_thought(self, text: str):
+ print(f"✅ on_agent_thought called: {text[:50]}")
+ self.called.append("on_agent_thought")
+
+ def on_tool_call(
+ self,
+ tool_call_id: str,
+ title: str,
+ kind: Optional[str] = None,
+ status: Optional[str] = None,
+ ):
+ print(f"✅ on_tool_call called: {title}")
+ self.called.append("on_tool_call")
+
+ def on_tool_response(
+ self, tool_call_id: str, status: Optional[str] = None, content: Any = None
+ ):
+ print(f"✅ on_tool_response called: status={status}")
+ self.called.append("on_tool_response")
+
+
+listener = TestListener()
+agent = Auggie(listener=listener)
+result = agent.run("What is 2 + 2?")
+print(f"\nResult: {result}")
+print(f"Listener methods called: {listener.called}")
diff --git a/examples/python-sdk/user_examples/user_guide.md b/examples/python-sdk/user_examples/user_guide.md
new file mode 100644
index 0000000..3991de4
--- /dev/null
+++ b/examples/python-sdk/user_examples/user_guide.md
@@ -0,0 +1,250 @@
+# Auggie Python SDK
+
+A Python SDK for interacting with the Augment CLI agent (`auggie`) programmatically.
+
+## Prerequisites
+
+1. **Python**
+2. **Augment CLI (`auggie`)**: Must be installed and authenticated on your system.
+ * **Note:** The SDK currently requires the pre-release version of auggie
+ * Install: `npm install -g @augmentcode/auggie@prerelease`
+ * Login: `auggie auth login`
+
+## Installation
+
+Install the SDK from PyPI:
+
+```bash
+pip install auggie-sdk
+```
+
+## Quick Start
+
+```python
+from auggie_sdk import Auggie
+
+# Create an agent instance
+agent = Auggie()
+
+# Run a simple instruction
+response = agent.run("What is the capital of France?")
+print(response)
+# Output: Paris
+```
+
+---
+
+## Listening to Events
+
+To monitor the agent's internal actions (tool calls, thoughts, function executions), you can attach a listener.
+
+### Built-in Logger
+
+Use the built-in `LoggingAgentListener` for easy debugging to stdout:
+
+```python
+from auggie_sdk import Agent, LoggingAgentListener
+
+# Use the built-in logger for easy debugging
+agent = Auggie(listener=LoggingAgentListener(verbose=True))
+
+agent.run("Find the 'main' function in src/app.py and summarize it")
+# Output will now include:
+# 🔧 Tool: view (read)
+# 💭 Thinking: I need to read the file first...
+# 💬 Agent: The main function does...
+```
+
+### Custom Listener
+
+You can implement your own listener by subclassing `AgentListener`. This is useful for integrating with custom logging systems, UIs, or for programmatic reactions to agent events.
+
+```python
+from auggie_sdk import Agent, AgentListener
+from typing import Any, Optional
+
+class MyCustomListener(AgentListener):
+ def on_agent_thought(self, text: str):
+ """Called when the agent shares its internal reasoning."""
+ print(f"[Thinking] {text[:100]}...")
+
+ def on_tool_call(
+ self,
+ tool_call_id: str,
+ title: str,
+ kind: Optional[str] = None,
+ status: Optional[str] = None,
+ ):
+ """Called when the agent is about to execute a tool."""
+ print(f"[Tool Call] {title} (kind={kind}, status={status})")
+
+ def on_tool_response(
+ self, tool_call_id: str, status: Optional[str] = None, content: Any = None
+ ):
+ """Called when a tool execution completes."""
+ print(f"[Tool Result] status={status}, content={str(content)[:50]}...")
+
+ def on_agent_message(self, message: str):
+ """Called when the agent sends a complete message."""
+ print(f"[Agent Message] {message}")
+
+agent = Auggie(listener=MyCustomListener())
+agent.run("What is 5 * 5?")
+```
+
+---
+
+## Core Features
+
+### 1. Session Management
+
+By default, every `agent.run()` call is independent and has no memory of previous calls. Use a **session** to maintain conversational context.
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# ❌ INCORRECT: These calls don't know about each other
+agent.run("Remember that my favorite color is blue")
+agent.run("What is my favorite color?") # Agent won't know
+
+# ✅ CORRECT: Using a session for shared context
+with agent.session() as session:
+ session.run("Remember that my favorite color is blue")
+ response = session.run("What is my favorite color?")
+ print(response) # Output: Blue
+```
+
+### 2. Typed Returns
+
+The SDK provides flexible type handling for agent responses.
+
+#### Automatic Type Inference
+
+By default, the agent returns a string. You can let it automatically infer the best type (int, float, bool, list, dict, str):
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# Automatic type inference
+result = agent.run("What is 2 + 2?")
+print(f"Result: {result} (Type: {type(result).__name__})")
+# Output: Result: 4 (Type: int)
+
+# It handles complex types too
+result = agent.run("Return a list of the first 3 prime numbers")
+print(result)
+# Output: [2, 3, 5]
+```
+
+#### Explicit Type Specification
+
+For strict control, specify the exact `return_type` you expect. The SDK ensures the agent returns data in this format, automatically retrying if it fails initially.
+
+Supported types: `int`, `float`, `str`, `bool`, `list`, `dict`, `dataclasses`, and `Enum`s.
+Compound types are also supported, such as `List[int]`, `Dict[str, int]`, or `List[MyDataclass]`.
+
+```python
+from auggie_sdk import Auggie
+from dataclasses import dataclass
+from typing import List, Dict
+
+@dataclass
+class Task:
+ id: int
+ description: str
+ is_done: bool
+
+agent = Auggie()
+
+# Get a strongly-typed object back
+task = agent.run(
+ "Create a sample task for 'Buy groceries'",
+ return_type=Task
+)
+print(f"Task {task.id}: {task.description} (Done: {task.is_done})")
+
+# Get a list of objects
+tasks = agent.run(
+ "Create 3 sample tasks for a weekend to-do list",
+ return_type=List[Task]
+)
+for t in tasks:
+ print(f"- {t.description}")
+
+# Get a dictionary of simple types
+counts = agent.run(
+ "Count the number of vowels in 'hello world' and return as a dict",
+ return_type=Dict[str, int]
+)
+print(counts)
+# Output: {'e': 1, 'o': 2}
+```
+
+### 3. Success Criteria & Verification
+
+You can specify success criteria that the agent must meet. The agent will verify its work and automatically retry if the criteria aren't met.
+
+```python
+from auggie_sdk import Auggie
+
+agent = Auggie()
+
+# The agent will verify its work meets the criteria
+result = agent.run(
+ "Write a Python function to calculate fibonacci numbers",
+ success_criteria=[
+ "Function has type hints",
+ "Function has a docstring",
+ "Function handles the base cases (0 and 1)",
+ ],
+ max_verification_rounds=3 # Optional: limit retry attempts (default: 3)
+)
+print(result)
+```
+
+The agent will:
+1. Complete the task
+2. Verify the result against each criterion
+3. If any criterion fails, automatically fix the issues and retry
+4. Repeat until all criteria pass or max rounds reached
+
+If verification fails after max rounds, an `AugmentVerificationError` is raised with details about which criteria failed.
+
+### 4. Function Tools
+
+You can give the agent access to your own Python functions. It will call them intelligently to complete tasks.
+**Important**: Functions *must* have type hints and docstrings, as these are used to generate the tool definition for the agent.
+
+```python
+from auggie_sdk import Auggie
+import datetime
+
+def get_current_weather(location: str, unit: str = "celsius") -> dict:
+ """
+ Gets the weather for a given location.
+
+ Args:
+ location: The city and state, e.g. San Francisco, CA
+ unit: Temperature unit ('celsius' or 'fahrenheit')
+ """
+ # In a real app, you'd call a weather API here
+ return {"temp": 72, "unit": unit, "forecast": "sunny"}
+
+def get_time() -> str:
+ """Returns the current time."""
+ return datetime.datetime.now().strftime("%H:%M")
+
+agent = Auggie()
+
+# The agent will call the appropriate function(s) to answer the question
+response = agent.run(
+ "What's the weather like in NYC right now, and what time is it there?",
+ functions=[get_current_weather, get_time]
+)
+
+print(response)
+```