augment-sdk 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- augment/__init__.py +30 -0
- augment/acp/__init__.py +11 -0
- augment/acp/claude_code_client.py +365 -0
- augment/acp/client.py +640 -0
- augment/acp/test_client_e2e.py +472 -0
- augment/agent.py +1139 -0
- augment/exceptions.py +92 -0
- augment/function_tools.py +265 -0
- augment/listener.py +186 -0
- augment/listener_adapter.py +83 -0
- augment/prompt_formatter.py +343 -0
- augment_sdk-0.1.1.dist-info/METADATA +841 -0
- augment_sdk-0.1.1.dist-info/RECORD +17 -0
- augment_sdk-0.1.1.dist-info/WHEEL +5 -0
- augment_sdk-0.1.1.dist-info/entry_points.txt +2 -0
- augment_sdk-0.1.1.dist-info/licenses/LICENSE +22 -0
- augment_sdk-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,841 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: augment-sdk
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Python SDK for building AI-powered coding workflows with the Augment CLI agent
|
|
5
|
+
Author-email: Augment Code <support@augmentcode.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://augmentcode.com
|
|
8
|
+
Project-URL: Repository, https://github.com/augmentcode/augment-sdk-python
|
|
9
|
+
Project-URL: Documentation, https://docs.augmentcode.com
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/augmentcode/augment-sdk-python/issues
|
|
11
|
+
Project-URL: Source Code, https://github.com/augmentcode/augment-sdk-python
|
|
12
|
+
Keywords: augment,ai,coding,agent,sdk,automation,llm,code-generation
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: agent-client-protocol>=0.4.5
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
28
|
+
Requires-Dist: pytest-timeout>=2.1.0; extra == "test"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# Augment Python SDK
|
|
38
|
+
|
|
39
|
+
[](https://badge.fury.io/py/augment-sdk)
|
|
40
|
+
[](https://pypi.org/project/augment-sdk/)
|
|
41
|
+
[](https://opensource.org/licenses/MIT)
|
|
42
|
+
|
|
43
|
+
A Python SDK for interacting with the Augment CLI agent (auggie) programmatically. Build AI-powered coding workflows with type-safe responses, function calling, and real-time event streaming.
|
|
44
|
+
|
|
45
|
+
## What is Augment?
|
|
46
|
+
|
|
47
|
+
Augment is an AI-powered coding assistant that helps developers write, refactor, and understand code. The Augment Python SDK allows you to programmatically interact with the Augment CLI agent, enabling you to:
|
|
48
|
+
|
|
49
|
+
- Automate complex coding workflows
|
|
50
|
+
- Build custom AI-powered development tools
|
|
51
|
+
- Integrate AI assistance into your existing Python applications
|
|
52
|
+
- Create structured, type-safe interactions with AI coding agents
|
|
53
|
+
|
|
54
|
+
## Features
|
|
55
|
+
|
|
56
|
+
- **Simple API**: Clean, intuitive interface for agent interactions
|
|
57
|
+
- **Typed Results**: Get structured data back from the agent with full type safety
|
|
58
|
+
- **Type Inference**: Let the agent choose the appropriate type from a list of options
|
|
59
|
+
- **Function Calling**: Provide Python functions the agent can call during execution
|
|
60
|
+
- **Success Criteria**: Iteratively verify and correct work against quality standards
|
|
61
|
+
- **Event Listeners**: Monitor agent activity with AgentListener interface
|
|
62
|
+
- **Automatic Retries**: Parsing failures are automatically retried with feedback to the agent
|
|
63
|
+
- **Session Management**: Maintain conversation continuity with context managers
|
|
64
|
+
- **Model Selection**: Choose which AI model to use
|
|
65
|
+
- **Message Access**: Get the agent's reasoning via `agent.last_model_answer`
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
Install from PyPI:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install augment-sdk
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Prerequisites
|
|
76
|
+
|
|
77
|
+
- Python 3.8 or higher
|
|
78
|
+
- Augment CLI (`auggie`) installed and available in PATH
|
|
79
|
+
- Install with: `npm install -g @augmentcode/auggie@prerelease`
|
|
80
|
+
- Access to an Augment workspace
|
|
81
|
+
|
|
82
|
+
### Optional Dependencies
|
|
83
|
+
|
|
84
|
+
For development and testing:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Install with test dependencies
|
|
88
|
+
pip install augment-sdk[test]
|
|
89
|
+
|
|
90
|
+
# Install with development dependencies
|
|
91
|
+
pip install augment-sdk[dev]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
For detailed installation instructions, including platform-specific guides and troubleshooting, see [INSTALL.md](https://github.com/augmentcode/augment-sdk-python/blob/main/INSTALL.md).
|
|
95
|
+
|
|
96
|
+
## Quick Start
|
|
97
|
+
|
|
98
|
+
### Basic Usage
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from augment import Agent
|
|
102
|
+
|
|
103
|
+
# Create an agent
|
|
104
|
+
agent = Agent()
|
|
105
|
+
|
|
106
|
+
# Automatic type inference (agent chooses the best type)
|
|
107
|
+
result, inferred_type = agent.run("What is 15 + 27?")
|
|
108
|
+
print(f"Answer: {result} (type: {inferred_type.__name__})") # Answer: 42 (type: int)
|
|
109
|
+
|
|
110
|
+
# Explicit typed response
|
|
111
|
+
result = agent.run("What is 15 + 27?", return_type=int)
|
|
112
|
+
print(f"Answer: {result}") # Answer: 42
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Session Management
|
|
116
|
+
|
|
117
|
+
**By default, each call is independent:**
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from augment import Agent
|
|
121
|
+
|
|
122
|
+
agent = Agent()
|
|
123
|
+
|
|
124
|
+
# Each call creates a fresh session
|
|
125
|
+
agent.run("Create a function called add_numbers")
|
|
126
|
+
agent.run("Test that function") # ❌ Won't remember add_numbers!
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Use session context manager for conversation continuity:**
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
agent = Agent()
|
|
133
|
+
|
|
134
|
+
# Calls within a session share context
|
|
135
|
+
with agent.session() as session:
|
|
136
|
+
session.run("Create a function called add_numbers")
|
|
137
|
+
session.run("Test that function") # ✅ Remembers add_numbers!
|
|
138
|
+
session.run("Add error handling") # ✅ Still remembers!
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Model Selection
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
# List available models
|
|
145
|
+
from augment import Agent
|
|
146
|
+
|
|
147
|
+
models = Agent.get_available_models()
|
|
148
|
+
for model in models:
|
|
149
|
+
print(f"{model.name} [{model.id}]")
|
|
150
|
+
print(f" {model.description}")
|
|
151
|
+
|
|
152
|
+
# Use specific AI model
|
|
153
|
+
agent = Agent(model="sonnet4.5")
|
|
154
|
+
|
|
155
|
+
# Or with workspace and model
|
|
156
|
+
agent = Agent(
|
|
157
|
+
workspace_root="/path/to/project",
|
|
158
|
+
model="gpt5-codex"
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Automatic Type Inference
|
|
163
|
+
|
|
164
|
+
When you don't specify a `return_type`, the agent automatically infers the best type from common types (int, float, bool, str, list, dict):
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# Agent automatically determines the type
|
|
168
|
+
result, inferred_type = agent.run("What is 2 + 2?")
|
|
169
|
+
print(f"Result: {result}, Type: {inferred_type.__name__}") # Result: 4, Type: int
|
|
170
|
+
|
|
171
|
+
result, inferred_type = agent.run("List the primary colors")
|
|
172
|
+
print(f"Result: {result}, Type: {inferred_type.__name__}") # Result: ['red', 'blue', 'yellow'], Type: list
|
|
173
|
+
|
|
174
|
+
result, inferred_type = agent.run("Is Python statically typed?")
|
|
175
|
+
print(f"Result: {result}, Type: {inferred_type.__name__}") # Result: False, Type: bool
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Typed Results
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from dataclasses import dataclass
|
|
182
|
+
from enum import Enum
|
|
183
|
+
|
|
184
|
+
@dataclass
|
|
185
|
+
class Task:
|
|
186
|
+
title: str
|
|
187
|
+
priority: str
|
|
188
|
+
estimated_hours: int
|
|
189
|
+
|
|
190
|
+
class Priority(Enum):
|
|
191
|
+
LOW = "low"
|
|
192
|
+
MEDIUM = "medium"
|
|
193
|
+
HIGH = "high"
|
|
194
|
+
|
|
195
|
+
# Get structured data back with explicit type
|
|
196
|
+
task = agent.run("Create a task: 'Fix login bug', high priority, 8 hours", return_type=Task)
|
|
197
|
+
print(f"Task: {task.title}, Priority: {task.priority}")
|
|
198
|
+
|
|
199
|
+
# Works with lists of objects too
|
|
200
|
+
tasks = agent.run("Create 3 example tasks", return_type=list[Task])
|
|
201
|
+
for task in tasks:
|
|
202
|
+
print(f"- {task.title}")
|
|
203
|
+
|
|
204
|
+
# Access the agent's reasoning
|
|
205
|
+
print(f"Agent's explanation: {agent.last_model_answer}")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Function Calling
|
|
209
|
+
|
|
210
|
+
Provide Python functions that the agent can call during execution:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
def get_weather(location: str, unit: str = "celsius") -> dict:
|
|
214
|
+
"""
|
|
215
|
+
Get the current weather for a location.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
location: City name or coordinates
|
|
219
|
+
unit: Temperature unit (celsius or fahrenheit)
|
|
220
|
+
"""
|
|
221
|
+
# Your implementation here
|
|
222
|
+
return {"temp": 22, "condition": "sunny"}
|
|
223
|
+
|
|
224
|
+
def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
|
|
225
|
+
"""
|
|
226
|
+
Calculate distance between two coordinates.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
lat1: Latitude of first point
|
|
230
|
+
lon1: Longitude of first point
|
|
231
|
+
lat2: Latitude of second point
|
|
232
|
+
lon2: Longitude of second point
|
|
233
|
+
"""
|
|
234
|
+
# Your implementation here
|
|
235
|
+
return 100.5
|
|
236
|
+
|
|
237
|
+
# Agent can call these functions as needed
|
|
238
|
+
result = agent.run(
|
|
239
|
+
"What's the weather in San Francisco and how far is it from Los Angeles?",
|
|
240
|
+
return_type=str,
|
|
241
|
+
functions=[get_weather, calculate_distance]
|
|
242
|
+
)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Requirements for functions:**
|
|
246
|
+
- Must have type hints for parameters
|
|
247
|
+
- Should have docstrings with parameter descriptions
|
|
248
|
+
- The agent will automatically call them when needed
|
|
249
|
+
|
|
250
|
+
### Event Listeners
|
|
251
|
+
|
|
252
|
+
Monitor what the agent is doing with the `AgentListener` interface. The listener receives events from the underlying ACP (Agent Client Protocol) layer, including tool calls, agent messages, and function calls:
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
from augment import Agent, AgentListener, LoggingAgentListener
|
|
256
|
+
|
|
257
|
+
# Use the built-in logging listener
|
|
258
|
+
listener = LoggingAgentListener(verbose=True)
|
|
259
|
+
agent = Agent(listener=listener)
|
|
260
|
+
|
|
261
|
+
result = agent.run(
|
|
262
|
+
"What's the weather in San Francisco?",
|
|
263
|
+
return_type=dict,
|
|
264
|
+
functions=[get_weather]
|
|
265
|
+
)
|
|
266
|
+
# Prints: 📞 Calling function: get_weather(location=San Francisco)
|
|
267
|
+
# ✅ Function get_weather returned: {'temp': 72, ...}
|
|
268
|
+
|
|
269
|
+
# Or create a custom listener
|
|
270
|
+
class MyListener(AgentListener):
|
|
271
|
+
def on_function_call(self, function_name: str, arguments: dict) -> None:
|
|
272
|
+
print(f"Agent is calling {function_name}")
|
|
273
|
+
|
|
274
|
+
def on_function_result(self, function_name: str, result, error=None) -> None:
|
|
275
|
+
if error:
|
|
276
|
+
print(f"Function failed: {error}")
|
|
277
|
+
else:
|
|
278
|
+
print(f"Function returned: {result}")
|
|
279
|
+
|
|
280
|
+
agent = Agent(listener=MyListener())
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Available listener methods:**
|
|
284
|
+
- `on_agent_message(message)` - Agent sends a message
|
|
285
|
+
- `on_function_call(function_name, arguments)` - Agent calls a function
|
|
286
|
+
- `on_function_result(function_name, result, error)` - Function returns
|
|
287
|
+
- `on_tool_call(tool_call_id, title, kind, status)` - Agent uses a tool (view, edit, etc.)
|
|
288
|
+
- `on_tool_response(tool_call_id, status, content)` - Tool responds
|
|
289
|
+
- `on_agent_thought(text)` - Agent shares internal reasoning
|
|
290
|
+
|
|
291
|
+
All methods are optional - only implement the ones you need.
|
|
292
|
+
|
|
293
|
+
### Automatic Retries for Parsing Failures
|
|
294
|
+
|
|
295
|
+
When requesting typed results, the agent automatically retries if parsing fails:
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
# If the agent's response can't be parsed, it will automatically retry
|
|
299
|
+
# up to max_retries times (default: 3)
|
|
300
|
+
result = agent.run("What is 2 + 2?", return_type=int)
|
|
301
|
+
|
|
302
|
+
# Customize retry behavior
|
|
303
|
+
result = agent.run(
|
|
304
|
+
"Parse this complex data",
|
|
305
|
+
return_type=MyDataClass,
|
|
306
|
+
max_retries=5 # Try up to 5 times
|
|
307
|
+
)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**How it works:**
|
|
311
|
+
1. Agent sends the instruction
|
|
312
|
+
2. If parsing fails, agent is told about the error and asked to fix the output
|
|
313
|
+
3. This continues until success or max_retries is exhausted
|
|
314
|
+
4. The retry happens in the same session, so the agent has full context
|
|
315
|
+
|
|
316
|
+
### Success Criteria
|
|
317
|
+
|
|
318
|
+
Ensure the agent iteratively verifies and corrects its work against quality standards:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
# Agent will iteratively work and verify until all criteria are met
|
|
322
|
+
agent.run(
|
|
323
|
+
"Create a Python function to calculate fibonacci numbers",
|
|
324
|
+
success_criteria=[
|
|
325
|
+
"Function has type hints for all parameters and return value",
|
|
326
|
+
"Function has a comprehensive docstring with examples",
|
|
327
|
+
"Function handles edge cases (n=0, n=1, negative numbers)",
|
|
328
|
+
"Code follows PEP 8 style guidelines",
|
|
329
|
+
],
|
|
330
|
+
max_verification_rounds=3 # Optional: control max iterations (default: 3)
|
|
331
|
+
)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**How it works (iterative loop):**
|
|
335
|
+
1. Agent works on the task
|
|
336
|
+
2. Agent verifies all success criteria
|
|
337
|
+
3. If all criteria met → Done! ✅
|
|
338
|
+
4. If not all met → Agent receives specific feedback about what's wrong
|
|
339
|
+
5. Agent fixes the identified issues
|
|
340
|
+
6. Go back to step 2
|
|
341
|
+
7. Repeat until all criteria met or max_verification_rounds reached
|
|
342
|
+
|
|
343
|
+
**Benefits:**
|
|
344
|
+
- Ensures quality standards are automatically met
|
|
345
|
+
- Agent receives **structured feedback** on what needs fixing
|
|
346
|
+
- Iterative improvement - agent can make multiple passes
|
|
347
|
+
- Reduces need for manual review
|
|
348
|
+
- Works great for code generation, documentation, and refactoring tasks
|
|
349
|
+
|
|
350
|
+
**Exception handling:**
|
|
351
|
+
If criteria are not met after `max_verification_rounds`, an `AugmentVerificationError` is raised with details about unmet criteria and specific issues.
|
|
352
|
+
|
|
353
|
+
**See also:** [Success Criteria Documentation](docs/SUCCESS_CRITERIA_LOOP.md) for detailed examples and best practices.
|
|
354
|
+
|
|
355
|
+
## Supported Types
|
|
356
|
+
|
|
357
|
+
**Automatic type inference** (when no `return_type` specified):
|
|
358
|
+
- `int`, `float`, `bool`, `str`, `list`, `dict`
|
|
359
|
+
|
|
360
|
+
**Explicit types** (when `return_type` is specified):
|
|
361
|
+
- **Built-in types**: `int`, `float`, `str`, `bool`, `list`, `dict`
|
|
362
|
+
- **Dataclasses**: Any Python dataclass
|
|
363
|
+
- **Enums**: Python enums
|
|
364
|
+
- **Generic types**: `list[SomeClass]`, `list[int]`, etc.
|
|
365
|
+
|
|
366
|
+
## API Reference
|
|
367
|
+
|
|
368
|
+
### Agent Class
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
class Agent:
|
|
372
|
+
def __init__(
|
|
373
|
+
self,
|
|
374
|
+
workspace_root: Optional[Union[str, Path]] = None,
|
|
375
|
+
model: Optional[str] = None,
|
|
376
|
+
):
|
|
377
|
+
"""
|
|
378
|
+
Initialize an agent instance.
|
|
379
|
+
|
|
380
|
+
Args:
|
|
381
|
+
workspace_root: Path to workspace root (defaults to current directory)
|
|
382
|
+
model: AI model to use (e.g., "claude-3-5-sonnet-latest")
|
|
383
|
+
"""
|
|
384
|
+
|
|
385
|
+
def run(
|
|
386
|
+
self,
|
|
387
|
+
instruction: str,
|
|
388
|
+
return_type: Type[T] = None,
|
|
389
|
+
timeout: Optional[int] = None,
|
|
390
|
+
max_retries: int = 3,
|
|
391
|
+
) -> Union[T, tuple[T, Type[T]]]:
|
|
392
|
+
"""
|
|
393
|
+
Execute an instruction and return response.
|
|
394
|
+
|
|
395
|
+
If return_type is None, automatically infers the type and returns (result, type).
|
|
396
|
+
If return_type is specified, returns the parsed result of that type.
|
|
397
|
+
"""
|
|
398
|
+
|
|
399
|
+
def session(self, session_id: Optional[str] = None) -> Agent:
|
|
400
|
+
"""Create a session context for conversation continuity."""
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Session Usage Patterns
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
# Single task with multiple related steps
|
|
407
|
+
with agent.session() as session:
|
|
408
|
+
session.run("Create the main function")
|
|
409
|
+
session.run("Add error handling")
|
|
410
|
+
session.run("Write comprehensive tests")
|
|
411
|
+
|
|
412
|
+
# Continue the same task automatically
|
|
413
|
+
with agent.session() as session: # Resumes last session
|
|
414
|
+
session.run("Add more features to the function")
|
|
415
|
+
|
|
416
|
+
# Work on different concerns with explicit session IDs
|
|
417
|
+
with agent.session("backend-work") as backend:
|
|
418
|
+
backend.run("Create API endpoints")
|
|
419
|
+
|
|
420
|
+
with agent.session("frontend-work") as frontend:
|
|
421
|
+
frontend.run("Create React components")
|
|
422
|
+
|
|
423
|
+
# Return to backend work
|
|
424
|
+
with agent.session("backend-work") as backend:
|
|
425
|
+
backend.run("Add authentication to the API")
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Testing with Mock Clients
|
|
429
|
+
|
|
430
|
+
For testing purposes, you can provide your own ACPClient implementation to the Agent:
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
from augment import Agent
|
|
434
|
+
from augment.acp import ACPClient
|
|
435
|
+
|
|
436
|
+
class MockACPClient(ACPClient):
|
|
437
|
+
"""A mock client for testing."""
|
|
438
|
+
|
|
439
|
+
def __init__(self):
|
|
440
|
+
self._running = False
|
|
441
|
+
|
|
442
|
+
def start(self) -> None:
|
|
443
|
+
self._running = True
|
|
444
|
+
|
|
445
|
+
def stop(self) -> None:
|
|
446
|
+
self._running = False
|
|
447
|
+
|
|
448
|
+
def send_message(self, message: str, timeout: float = 30.0) -> str:
|
|
449
|
+
# Return mock responses for testing
|
|
450
|
+
return "Mock response"
|
|
451
|
+
|
|
452
|
+
def clear_context(self) -> None:
|
|
453
|
+
pass
|
|
454
|
+
|
|
455
|
+
@property
|
|
456
|
+
def is_running(self) -> bool:
|
|
457
|
+
return self._running
|
|
458
|
+
|
|
459
|
+
# Use the mock client in tests
|
|
460
|
+
mock_client = MockACPClient()
|
|
461
|
+
agent = Agent(acp_client=mock_client)
|
|
462
|
+
|
|
463
|
+
# Now agent.run() will use your mock client
|
|
464
|
+
response = agent.run("Test instruction")
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
This is useful for:
|
|
468
|
+
- Unit testing code that uses the Agent without calling the real CLI
|
|
469
|
+
- Controlling responses for predictable testing
|
|
470
|
+
- Faster test execution
|
|
471
|
+
- Testing without authentication or network access
|
|
472
|
+
|
|
473
|
+
## Prompt to Code Converter
|
|
474
|
+
|
|
475
|
+
Convert complex prompts into structured SDK programs with the `prompt_to_code.py` tool:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
# Convert a prompt file to an SDK program
|
|
479
|
+
python prompt_to_code.py my_prompt.txt
|
|
480
|
+
|
|
481
|
+
# With custom output file
|
|
482
|
+
python prompt_to_code.py my_prompt.txt --output my_workflow.py
|
|
483
|
+
|
|
484
|
+
# With custom model
|
|
485
|
+
python prompt_to_code.py my_prompt.txt --model claude-3-5-sonnet-latest
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Why convert prompts to SDK programs?**
|
|
489
|
+
- ✅ Better control over workflow execution
|
|
490
|
+
- ✅ Type safety with Python's type system
|
|
491
|
+
- ✅ Debugging capabilities with standard Python tools
|
|
492
|
+
- ✅ Reusability - run the same workflow multiple times
|
|
493
|
+
- ✅ Maintainability - easier to modify and extend
|
|
494
|
+
|
|
495
|
+
**Example:** Given a prompt like:
|
|
496
|
+
```
|
|
497
|
+
Analyze all Python files in src/, identify security issues,
|
|
498
|
+
create a report, and generate fixes for critical issues.
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
The tool generates a complete Python program with:
|
|
502
|
+
- Proper imports and dataclasses
|
|
503
|
+
- Session management for context
|
|
504
|
+
- Typed results for decision-making
|
|
505
|
+
- Loops for iteration
|
|
506
|
+
- Error handling
|
|
507
|
+
|
|
508
|
+
See [`docs/PROMPT_TO_CODE.md`](docs/PROMPT_TO_CODE.md) for detailed documentation.
|
|
509
|
+
|
|
510
|
+
## Examples
|
|
511
|
+
|
|
512
|
+
See the `examples/` directory for more usage examples:
|
|
513
|
+
- `examples/basic_usage.py` - Basic agent usage
|
|
514
|
+
- `examples/session_usage.py` - Session management examples
|
|
515
|
+
- `examples/list_prs.py` - Working with GitHub PRs
|
|
516
|
+
- `examples/list_models.py` - List available AI models
|
|
517
|
+
- `examples/mock_client_example.py` - Using a mock ACP client for testing
|
|
518
|
+
- `examples/event_listener_demo.py` - Interactive demo of event listeners
|
|
519
|
+
- `examples/example_prompt.txt` - Example prompt for the prompt-to-code converter
|
|
520
|
+
|
|
521
|
+
## Event Listeners
|
|
522
|
+
|
|
523
|
+
The SDK supports real-time event listeners to observe what the agent is doing:
|
|
524
|
+
|
|
525
|
+
```python
|
|
526
|
+
from augment import Agent
|
|
527
|
+
from augment.acp import AgentEventListener
|
|
528
|
+
|
|
529
|
+
class MyListener(AgentEventListener):
|
|
530
|
+
def on_agent_message_chunk(self, text: str) -> None:
|
|
531
|
+
"""Called when agent sends response chunks (streaming)."""
|
|
532
|
+
print(f"{text}", end="", flush=True)
|
|
533
|
+
|
|
534
|
+
def on_agent_message(self, message: str) -> None:
|
|
535
|
+
"""Called when agent finishes sending complete message."""
|
|
536
|
+
print(f"\n[Complete: {len(message)} chars]")
|
|
537
|
+
|
|
538
|
+
def on_tool_call(self, tool_call_id, title, kind=None, status=None):
|
|
539
|
+
"""Called when agent makes a tool call (read file, edit, etc.)."""
|
|
540
|
+
print(f"\n🔧 Using tool: {title}")
|
|
541
|
+
|
|
542
|
+
def on_tool_response(self, tool_call_id, status=None, content=None):
|
|
543
|
+
"""Called when tool responds."""
|
|
544
|
+
if status == "completed":
|
|
545
|
+
print("✅ Done!")
|
|
546
|
+
|
|
547
|
+
def on_agent_thought(self, text: str) -> None:
|
|
548
|
+
"""Called when agent shares its reasoning."""
|
|
549
|
+
print(f"💭 Thinking: {text}")
|
|
550
|
+
|
|
551
|
+
# Use the listener
|
|
552
|
+
listener = MyListener()
|
|
553
|
+
agent = Agent(listener=listener)
|
|
554
|
+
response = agent.run("Read the README and summarize it")
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**For detailed explanation of all events, see:** [`docs/AGENT_EVENT_LISTENER.md`](docs/AGENT_EVENT_LISTENER.md)
|
|
558
|
+
|
|
559
|
+
## API Reference
|
|
560
|
+
|
|
561
|
+
### Agent.get_available_models()
|
|
562
|
+
|
|
563
|
+
Get the list of available AI models for your account.
|
|
564
|
+
|
|
565
|
+
```python
|
|
566
|
+
from augment import Agent, Model
|
|
567
|
+
|
|
568
|
+
models = Agent.get_available_models()
|
|
569
|
+
# Returns: List[Model]
|
|
570
|
+
|
|
571
|
+
# Each Model has:
|
|
572
|
+
# - id: str # Model identifier (e.g., "sonnet4.5")
|
|
573
|
+
# - name: str # Human-readable name (e.g., "Claude Sonnet 4.5")
|
|
574
|
+
# - description: str # Additional info (e.g., "Anthropic Claude Sonnet 4.5, 200k context")
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**Example:**
|
|
578
|
+
```python
|
|
579
|
+
models = Agent.get_available_models()
|
|
580
|
+
for model in models:
|
|
581
|
+
print(f"{model.name} [{model.id}]")
|
|
582
|
+
if model.description:
|
|
583
|
+
print(f" {model.description}")
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## Error Handling
|
|
587
|
+
|
|
588
|
+
```python
|
|
589
|
+
from augment.exceptions import AugmentCLIError, AugmentParseError
|
|
590
|
+
|
|
591
|
+
try:
|
|
592
|
+
result = agent.run("What is the color blue?", return_type=int)
|
|
593
|
+
except AugmentParseError as e:
|
|
594
|
+
print(f"Could not parse as int: {e}")
|
|
595
|
+
except AugmentCLIError as e:
|
|
596
|
+
print(f"CLI error: {e}")
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Key Features
|
|
600
|
+
|
|
601
|
+
### Session Management
|
|
602
|
+
|
|
603
|
+
The Agent class uses the ACP (Agent Client Protocol) client internally for better performance. By default, each `run()` call creates a fresh session. Use the `session()` context manager to maintain conversation continuity:
|
|
604
|
+
|
|
605
|
+
```python
|
|
606
|
+
from augment import Agent
|
|
607
|
+
|
|
608
|
+
agent = Agent()
|
|
609
|
+
|
|
610
|
+
# Use session context for conversation continuity
|
|
611
|
+
with agent.session() as session:
|
|
612
|
+
session.run("Create a function")
|
|
613
|
+
session.run("Test it") # Remembers the function!
|
|
614
|
+
session.run("Optimize it") # Still remembers!
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Real-Time Streaming (Optional)
|
|
618
|
+
|
|
619
|
+
You can optionally provide an event listener to receive real-time updates:
|
|
620
|
+
|
|
621
|
+
```python
|
|
622
|
+
from augment import Agent
|
|
623
|
+
from augment.acp import AgentEventListener
|
|
624
|
+
|
|
625
|
+
class MyListener(AgentEventListener):
|
|
626
|
+
def on_agent_message_chunk(self, text: str):
|
|
627
|
+
print(text, end="", flush=True)
|
|
628
|
+
|
|
629
|
+
agent = Agent(listener=MyListener())
|
|
630
|
+
agent.run("Create a hello world function") # See real-time output!
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
## Testing
|
|
634
|
+
|
|
635
|
+
The SDK includes fast unit tests, quick e2e sanity checks, and comprehensive slow tests.
|
|
636
|
+
|
|
637
|
+
### Running Tests
|
|
638
|
+
|
|
639
|
+
**Run fast tests + quick sanity checks (default):**
|
|
640
|
+
```bash
|
|
641
|
+
pytest
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
This runs:
|
|
645
|
+
- All unit tests (tests in `tests/` directory) which use mocks - complete in milliseconds
|
|
646
|
+
- Quick e2e sanity checks (3 tests: start/stop, simple math query, context manager) - complete in a few seconds
|
|
647
|
+
|
|
648
|
+
Total time: ~5-10 seconds
|
|
649
|
+
|
|
650
|
+
**Run all tests including slow ones:**
|
|
651
|
+
```bash
|
|
652
|
+
pytest -m ""
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
This runs all 50 tests including slow integration/e2e tests that make extensive real calls to the auggie CLI. These tests can take several minutes.
|
|
656
|
+
|
|
657
|
+
**Run only slow tests:**
|
|
658
|
+
```bash
|
|
659
|
+
pytest -m slow
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
**Run with verbose output:**
|
|
663
|
+
```bash
|
|
664
|
+
pytest -v
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### Test Organization
|
|
668
|
+
|
|
669
|
+
**Fast unit tests (always run):**
|
|
670
|
+
- `tests/test_agent.py` - Unit tests for Agent class (uses mocks)
|
|
671
|
+
- `tests/test_exceptions.py` - Exception handling tests
|
|
672
|
+
- `tests/test_utils.py` - Utility function tests (uses mocks)
|
|
673
|
+
|
|
674
|
+
**Quick e2e sanity checks (always run):**
|
|
675
|
+
- `augment/acp/test_client_e2e.py::test_start_and_stop` - Basic client lifecycle
|
|
676
|
+
- `augment/acp/test_client_e2e.py::test_simple_math_query` - Single simple query
|
|
677
|
+
- `augment/acp/test_client_e2e.py::test_context_manager` - Context manager usage
|
|
678
|
+
|
|
679
|
+
**Slow comprehensive tests (marked with @pytest.mark.slow):**
|
|
680
|
+
- `test_sdk.py` - Integration tests for basic SDK functionality
|
|
681
|
+
- `test_e2e_session.py` - End-to-end session management tests
|
|
682
|
+
- `augment/acp/test_client_e2e.py` - Most ACP client integration tests
|
|
683
|
+
|
|
684
|
+
## ACP Client (Advanced)
|
|
685
|
+
|
|
686
|
+
The SDK includes ACP (Agent Client Protocol) clients for more advanced use cases. ACP clients maintain a long-running connection to agents, providing better performance and real-time streaming of responses.
|
|
687
|
+
|
|
688
|
+
**Key Difference:** Unlike the `Agent` class which spawns a new process per request, ACP clients maintain a **single persistent session**. All messages sent to the client automatically share context - no need for explicit session management!
|
|
689
|
+
|
|
690
|
+
### Available ACP Clients
|
|
691
|
+
|
|
692
|
+
1. **`AuggieACPClient`** - For Augment CLI (default)
|
|
693
|
+
2. **`ClaudeCodeACPClient`** - For Claude Code via Anthropic's API
|
|
694
|
+
|
|
695
|
+
### Augment CLI (AuggieACPClient)
|
|
696
|
+
|
|
697
|
+
```python
|
|
698
|
+
from augment.acp import AuggieACPClient
|
|
699
|
+
|
|
700
|
+
# Create client with model and workspace configuration
|
|
701
|
+
client = AuggieACPClient(
|
|
702
|
+
model="claude-3-5-sonnet-latest",
|
|
703
|
+
workspace_root="/path/to/workspace"
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
# Start the agent (creates a persistent session)
|
|
707
|
+
client.start()
|
|
708
|
+
|
|
709
|
+
# Send messages - they all share the same session context!
|
|
710
|
+
response1 = client.send_message("Create a function called add_numbers")
|
|
711
|
+
print(response1)
|
|
712
|
+
|
|
713
|
+
response2 = client.send_message("Now test that function") # Remembers add_numbers!
|
|
714
|
+
print(response2)
|
|
715
|
+
|
|
716
|
+
# Stop the agent
|
|
717
|
+
client.stop()
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### Claude Code (ClaudeCodeACPClient)
|
|
721
|
+
|
|
722
|
+
Use Claude Code directly via Anthropic's API:
|
|
723
|
+
|
|
724
|
+
```python
|
|
725
|
+
from augment.acp import ClaudeCodeACPClient
|
|
726
|
+
|
|
727
|
+
# Requires: npm install -g @zed-industries/claude-code-acp
|
|
728
|
+
# And: export ANTHROPIC_API_KEY=...
|
|
729
|
+
|
|
730
|
+
client = ClaudeCodeACPClient(
|
|
731
|
+
model="claude-3-5-sonnet-latest",
|
|
732
|
+
workspace_root="/path/to/workspace"
|
|
733
|
+
)
|
|
734
|
+
|
|
735
|
+
client.start()
|
|
736
|
+
response = client.send_message("Write a Python function to calculate fibonacci")
|
|
737
|
+
print(response)
|
|
738
|
+
client.stop()
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
See [Claude Code Client Documentation](docs/CLAUDE_CODE_CLIENT.md) for details.
|
|
742
|
+
|
|
743
|
+
### ACP with Context Manager
|
|
744
|
+
|
|
745
|
+
```python
|
|
746
|
+
from augment.acp import AuggieACPClient
|
|
747
|
+
|
|
748
|
+
# Automatically starts and stops
|
|
749
|
+
with AuggieACPClient(model="claude-3-5-sonnet-latest") as client:
|
|
750
|
+
response = client.send_message("What is 2 + 2?")
|
|
751
|
+
print(response)
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
### ACP with Event Listener
|
|
755
|
+
|
|
756
|
+
```python
|
|
757
|
+
from augment.acp import AuggieACPClient, AgentEventListener
|
|
758
|
+
|
|
759
|
+
class MyListener(AgentEventListener):
|
|
760
|
+
def on_agent_message_chunk(self, text: str):
|
|
761
|
+
print(f"Agent: {text}", end="", flush=True)
|
|
762
|
+
|
|
763
|
+
def on_tool_call(self, tool_name: str, tool_input: dict):
|
|
764
|
+
print(f"\n[Tool: {tool_name}]")
|
|
765
|
+
|
|
766
|
+
client = AuggieACPClient(
|
|
767
|
+
model="claude-3-5-sonnet-latest",
|
|
768
|
+
listener=MyListener()
|
|
769
|
+
)
|
|
770
|
+
client.start()
|
|
771
|
+
response = client.send_message("Create a hello world function")
|
|
772
|
+
client.stop()
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### ACP Client Parameters
|
|
776
|
+
|
|
777
|
+
- `cli_path`: Path to the Augment CLI (optional, auto-detected)
|
|
778
|
+
- `listener`: Event listener for real-time updates (optional)
|
|
779
|
+
- `model`: AI model to use (e.g., "claude-3-5-sonnet-latest", "gpt-4o")
|
|
780
|
+
- `workspace_root`: Workspace root directory (optional, defaults to current directory)
|
|
781
|
+
|
|
782
|
+
### Agent vs ACP Client Comparison
|
|
783
|
+
|
|
784
|
+
**When to use `Agent` (subprocess-based):**
|
|
785
|
+
- Simple one-off requests
|
|
786
|
+
- Don't need real-time streaming
|
|
787
|
+
- Want explicit session control
|
|
788
|
+
|
|
789
|
+
**When to use `AuggieACPClient` (long-running):**
|
|
790
|
+
- Multiple related requests
|
|
791
|
+
- Want automatic session continuity
|
|
792
|
+
- Need real-time streaming and events
|
|
793
|
+
- Better performance (no subprocess overhead)
|
|
794
|
+
|
|
795
|
+
```python
|
|
796
|
+
# Agent - each call is independent by default
|
|
797
|
+
agent = Agent()
|
|
798
|
+
agent.run("Create a function")
|
|
799
|
+
agent.run("Test it") # ❌ Doesn't remember the function
|
|
800
|
+
|
|
801
|
+
# Agent - need explicit session for context
|
|
802
|
+
with agent.session() as session:
|
|
803
|
+
session.run("Create a function")
|
|
804
|
+
session.run("Test it") # ✅ Remembers the function
|
|
805
|
+
|
|
806
|
+
# ACP Client - automatic session continuity
|
|
807
|
+
client = AuggieACPClient()
|
|
808
|
+
client.start()
|
|
809
|
+
client.send_message("Create a function")
|
|
810
|
+
client.send_message("Test it") # ✅ Automatically remembers!
|
|
811
|
+
client.stop()
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
See `augment/acp/example_usage.py` for more examples.
|
|
815
|
+
|
|
816
|
+
## Requirements
|
|
817
|
+
|
|
818
|
+
- Python 3.8 or higher
|
|
819
|
+
- Augment CLI (`auggie`) installed and available in PATH
|
|
820
|
+
- Install with: `npm install -g @augmentcode/auggie@prerelease`
|
|
821
|
+
- Access to an Augment workspace
|
|
822
|
+
|
|
823
|
+
## Contributing
|
|
824
|
+
|
|
825
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
826
|
+
|
|
827
|
+
## Support
|
|
828
|
+
|
|
829
|
+
- **Documentation**: [https://docs.augmentcode.com](https://docs.augmentcode.com)
|
|
830
|
+
- **GitHub Issues**: [https://github.com/augmentcode/augment-sdk-python/issues](https://github.com/augmentcode/augment-sdk-python/issues)
|
|
831
|
+
- **Website**: [https://augmentcode.com](https://augmentcode.com)
|
|
832
|
+
|
|
833
|
+
## License
|
|
834
|
+
|
|
835
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
836
|
+
|
|
837
|
+
## Links
|
|
838
|
+
|
|
839
|
+
- **PyPI**: [https://pypi.org/project/augment-sdk/](https://pypi.org/project/augment-sdk/)
|
|
840
|
+
- **GitHub**: [https://github.com/augmentcode/augment-sdk-python](https://github.com/augmentcode/augment-sdk-python)
|
|
841
|
+
- **Documentation**: [https://docs.augmentcode.com](https://docs.augmentcode.com)
|