|
1 | 1 | # Agent Kit |
2 | 2 |
|
3 | | -Developer toolkit for building AI agents with OpenAI Responses API. |
| 3 | +Framework for building AI agents with OpenAI Responses API. |
4 | 4 |
|
5 | 5 | ## Features |
6 | 6 |
|
7 | | -- OpenAI Responses API with `previous_response_id` for conversation continuation |
8 | | -- YAML-based configuration and prompt templates |
9 | | -- Connection pooling with retry logic |
| 7 | +- Conversation continuation via `previous_response_id` (no message array juggling) |
10 | 8 | - Session management with automatic cleanup |
| 9 | +- YAML-based prompts and configuration |
| 10 | +- Connection pooling with retry logic |
11 | 11 | - Tool integration (web search, time utilities) |
12 | | -- Interactive console with rich terminal interface |
| 12 | +- Interactive console with slash commands |
13 | 13 |
|
14 | 14 | ## Quick Start |
15 | 15 |
|
16 | 16 | ```bash |
17 | | -# Install and setup |
18 | 17 | uv sync |
19 | 18 | uv run agent-kit init |
20 | 19 | export OPENAI_API_KEY="sk-..." |
21 | | - |
22 | | -# Run console |
23 | 20 | uv run agent-kit |
24 | | - |
25 | | -# Try commands |
26 | | -/hello Alice |
27 | 21 | ``` |
28 | 22 |
|
29 | | -## Programmatic Usage |
| 23 | +Try `/hello Alice` or ask questions in chat mode. |
30 | 24 |
|
31 | | -```python |
32 | | -from agent_kit.api import AgentAPI |
| 25 | +## Usage |
33 | 26 |
|
34 | | -api = AgentAPI() |
35 | | -session_id = await api.session_store.create_session() |
| 27 | +```python |
| 28 | +from agent_kit import SessionStore |
| 29 | +from agent_kit.agents.hello.agent import HelloAgent |
| 30 | +from agent_kit.config import get_openai_client |
36 | 31 |
|
37 | | -# Fresh conversation |
38 | | -greeting = await api.hello("Alice", session_id) |
| 32 | +# Create session |
| 33 | +session_store = SessionStore(get_openai_client()) |
| 34 | +session_id = await session_store.create_session() |
| 35 | +session = await session_store.get_session(session_id) |
39 | 36 |
|
40 | | -# Continued conversation (uses previous_response_id) |
41 | | -response = await api.chat("What's the weather?", session_id) |
42 | | -followup = await api.chat("How about tomorrow?", session_id) |
43 | | -``` |
| 37 | +# Use agent |
| 38 | +agent = await session.use_agent(HelloAgent) |
44 | 39 |
|
45 | | -## Architecture |
| 40 | +# Fresh conversation |
| 41 | +response = await agent.process("Greet Alice", continue_conversation=False) |
46 | 42 |
|
| 43 | +# Continue conversation (uses previous_response_id) |
| 44 | +followup = await agent.process("What's the weather?", continue_conversation=True) |
47 | 45 | ``` |
48 | | -agent_kit/ |
49 | | -├── agents/ # BaseAgent and implementations |
50 | | -├── api/ # AgentAPI, SessionStore, Console |
51 | | -├── clients/ # OpenAI client with pooling |
52 | | -├── config/ # YAML configuration system |
53 | | -├── prompts/ # Prompt template loader |
54 | | -├── utils/ # Tool definitions and utilities |
55 | | -└── data/ # Config and prompt templates |
56 | | -``` |
57 | | - |
58 | | -## Building Custom Agents |
59 | 46 |
|
60 | | -### 1. Define Models |
| 47 | +## Extending |
61 | 48 |
|
62 | | -```python |
63 | | -from pydantic import BaseModel |
64 | | - |
65 | | -class MyResponse(BaseModel): |
66 | | - model_config = {"extra": "forbid"} # Required for structured outputs |
67 | | - result: str |
68 | | -``` |
| 49 | +Agent-Kit is designed for extension. See `agent_kit/agents/hello/` for the complete pattern. |
69 | 50 |
|
70 | | -### 2. Implement Agent |
| 51 | +### Custom Agent |
71 | 52 |
|
72 | 53 | ```python |
73 | | -from agent_kit.agents.base_agent import BaseAgent |
74 | | -from agent_kit.utils.tools import get_tool_definitions, execute_tool |
| 54 | +from agent_kit import BaseAgent |
75 | 55 |
|
76 | 56 | class MyAgent(BaseAgent): |
77 | 57 | async def process(self, query: str, continue_conversation: bool = False) -> str: |
78 | | - prompts = self.render_prompt("myagent", "orchestrator") |
| 58 | + prompts = self.render_prompt("my_agent", "orchestrator") |
79 | 59 |
|
80 | 60 | response = await self.execute_tool_conversation( |
81 | 61 | instructions=prompts["instructions"], |
82 | 62 | initial_input=[{"role": "user", "content": query}], |
83 | 63 | tools=get_tool_definitions(), |
84 | 64 | tool_executor=execute_tool, |
85 | 65 | previous_response_id=self.last_response_id if continue_conversation else None, |
86 | | - response_format=MyResponse, # structured output |
87 | | - max_iterations=10 |
88 | 66 | ) |
89 | 67 |
|
90 | | - return response if isinstance(response, str) else response.result |
| 68 | + return response.output_text or "Error" |
91 | 69 | ``` |
92 | 70 |
|
93 | | -### 3. Create Prompt Template |
94 | | - |
95 | | -`data/prompts/myagent/orchestrator.yaml`: |
| 71 | +### Agent Structure |
96 | 72 |
|
97 | | -```yaml |
98 | | -agent: myagent |
99 | | -function: orchestrator |
100 | | -prompt: |
101 | | - instructions: | |
102 | | - # Role |
103 | | - You are a helpful assistant. |
104 | | -
|
105 | | - ## Available Tools |
106 | | - - `web_search`: Search the web |
107 | | - - `get_current_time`: Get current time |
108 | | -parameters: [] |
| 73 | +``` |
| 74 | +my_agents/analyzer/ |
| 75 | +├── agent.py # Implements BaseAgent |
| 76 | +├── tools.py # Tool definitions and executor |
| 77 | +├── console.py # Optional: slash commands |
| 78 | +├── config.yaml # Agent-specific config |
| 79 | +└── prompts/ |
| 80 | + └── orchestrator.yaml |
109 | 81 | ``` |
110 | 82 |
|
111 | | -### 4. Add to API |
| 83 | +### Console Commands |
112 | 84 |
|
113 | 85 | ```python |
114 | | -async def my_action(self, query: str, session_id: str) -> str: |
115 | | - session = self._get_session(session_id) |
116 | | - agent = session.get_or_create_agent(AgentType.MY_AGENT) |
117 | | - result = await agent.process(query, continue_conversation=True) |
118 | | - session.store_result(AgentType.MY_AGENT, result, query=query) |
119 | | - return result |
120 | | -``` |
| 86 | +from agent_kit.api.console.server import SlashCommands |
| 87 | +from rich.console import Console |
| 88 | + |
| 89 | +class MyCommands(SlashCommands): |
| 90 | + def __init__(self, console: Console): |
| 91 | + super().__init__(console) |
| 92 | + |
| 93 | + # Register commands |
| 94 | + self.register_command( |
| 95 | + "/analyze", |
| 96 | + self._handle_analyze, |
| 97 | + "Run analysis", |
| 98 | + "Analyze data\nUsage: /analyze <topic>" |
| 99 | + ) |
121 | 100 |
|
122 | | -## Configuration |
| 101 | + async def _handle_analyze(self, args: list[str]) -> None: |
| 102 | + # Your implementation |
| 103 | + pass |
123 | 104 |
|
124 | | -`~/.agent-kit/config.yaml`: |
| 105 | +# Run console |
| 106 | +await run_console(MyCommands) |
| 107 | +``` |
125 | 108 |
|
| 109 | +### Configuration |
| 110 | + |
| 111 | +Framework config (`~/.agent-kit/config.yaml`): |
126 | 112 | ```yaml |
127 | 113 | openai: |
128 | 114 | api_key: "${OPENAI_API_KEY}" |
129 | | - model: "gpt-5-nano" |
| 115 | + model: "gpt-4o" |
130 | 116 | pool_size: 8 |
131 | 117 |
|
132 | 118 | agents: |
133 | 119 | max_iterations: 20 |
134 | 120 | ``` |
135 | 121 |
|
136 | | -## Development |
137 | | - |
138 | | -```bash |
139 | | -# Lint and format |
140 | | -uv run ruff check . && uv run ruff format . |
| 122 | +Agent config (`~/.agent-kit/my_agent.yaml`): |
| 123 | +```yaml |
| 124 | +max_iterations: 15 |
| 125 | +``` |
141 | 126 |
|
142 | | -# Type check |
143 | | -uv run pyright |
| 127 | +Configs auto-loaded from: |
| 128 | +- `agent_kit/agents/{agent}/config.yaml` (package defaults) |
| 129 | +- `~/.agent-kit/{agent}.yaml` (user overrides) |
144 | 130 |
|
145 | | -# Test |
146 | | -uv run pytest |
| 131 | +## Development |
147 | 132 |
|
148 | | -# Run CI checks locally |
149 | | -make ci |
| 133 | +```bash |
| 134 | +uv run ruff check . && uv run ruff format . # Lint and format |
| 135 | +uv run pyright # Type check |
| 136 | +uv run pytest # Test |
| 137 | +make ci # Run all checks |
150 | 138 | ``` |
151 | 139 |
|
152 | | -## Key Patterns |
153 | | - |
154 | | -- **Conversation Continuation**: Uses `previous_response_id` instead of message arrays |
155 | | -- **Single Method Pattern**: One `process(query, continue_conversation)` method per agent |
156 | | -- **Connection Pooling**: Efficient OpenAI API usage with retry logic |
157 | | -- **YAML Prompts**: Markdown-formatted prompts with parameter injection |
158 | | -- **Tool-First Design**: Centralized tool definitions in `utils/tools.py` |
159 | | - |
160 | 140 | ## Requirements |
161 | 141 |
|
162 | 142 | - Python 3.13+ |
163 | 143 | - OpenAI API key |
164 | | -- `uv` package manager |
| 144 | +- uv package manager |
165 | 145 |
|
166 | 146 | ## License |
167 | 147 |
|
|
0 commit comments