crow-cli 0.1.0__tar.gz
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.
- crow_cli-0.1.0/.gitignore +3 -0
- crow_cli-0.1.0/.python-version +1 -0
- crow_cli-0.1.0/PKG-INFO +369 -0
- crow_cli-0.1.0/README.md +342 -0
- crow_cli-0.1.0/TODO.md +74 -0
- crow_cli-0.1.0/config/.env.example +7 -0
- crow_cli-0.1.0/config/compose.yaml +34 -0
- crow_cli-0.1.0/config/config.yaml +60 -0
- crow_cli-0.1.0/config/prompts/self_documentation.jinja2 +15 -0
- crow_cli-0.1.0/config/prompts/skill_knowledge_info.jinja2 +12 -0
- crow_cli-0.1.0/config/prompts/system_message_suffix.jinja2 +42 -0
- crow_cli-0.1.0/config/prompts/system_prompt.jinja2 +121 -0
- crow_cli-0.1.0/config/searxng/settings.yml +2799 -0
- crow_cli-0.1.0/examples/mc_escher_loop.py +49 -0
- crow_cli-0.1.0/examples/quick_test.py +75 -0
- crow_cli-0.1.0/pyproject.toml +56 -0
- crow_cli-0.1.0/run_tests.sh +6 -0
- crow_cli-0.1.0/src/crow_cli/__init__.py +1 -0
- crow_cli-0.1.0/src/crow_cli/agent/__init__.py +3 -0
- crow_cli-0.1.0/src/crow_cli/agent/compact.py +185 -0
- crow_cli-0.1.0/src/crow_cli/agent/configure.py +218 -0
- crow_cli-0.1.0/src/crow_cli/agent/context.py +103 -0
- crow_cli-0.1.0/src/crow_cli/agent/db.py +112 -0
- crow_cli-0.1.0/src/crow_cli/agent/llm.py +46 -0
- crow_cli-0.1.0/src/crow_cli/agent/logger.py +36 -0
- crow_cli-0.1.0/src/crow_cli/agent/main.py +599 -0
- crow_cli-0.1.0/src/crow_cli/agent/mcp_client.py +155 -0
- crow_cli-0.1.0/src/crow_cli/agent/prompt.py +162 -0
- crow_cli-0.1.0/src/crow_cli/agent/prompts/self_documentation.jinja2 +15 -0
- crow_cli-0.1.0/src/crow_cli/agent/prompts/skill_knowledge_info.jinja2 +12 -0
- crow_cli-0.1.0/src/crow_cli/agent/prompts/system_message_suffix.jinja2 +42 -0
- crow_cli-0.1.0/src/crow_cli/agent/prompts/system_prompt.jinja2 +121 -0
- crow_cli-0.1.0/src/crow_cli/agent/react.py +520 -0
- crow_cli-0.1.0/src/crow_cli/agent/session.py +309 -0
- crow_cli-0.1.0/src/crow_cli/agent/skills.py +9 -0
- crow_cli-0.1.0/src/crow_cli/agent/tools.py +517 -0
- crow_cli-0.1.0/src/crow_cli/cli/__init__.py +0 -0
- crow_cli-0.1.0/src/crow_cli/cli/init_cmd.py +418 -0
- crow_cli-0.1.0/src/crow_cli/cli/main.py +376 -0
- crow_cli-0.1.0/src/crow_cli/client/__init__.py +0 -0
- crow_cli-0.1.0/src/crow_cli/client/main.py +294 -0
- crow_cli-0.1.0/test_send_request_error_handling.py +195 -0
- crow_cli-0.1.0/tests/__init__.py +1 -0
- crow_cli-0.1.0/tests/conftest.py +112 -0
- crow_cli-0.1.0/tests/test_agent_init.py +82 -0
- crow_cli-0.1.0/tests/unit/test_session.py +336 -0
- crow_cli-0.1.0/uv.lock +1639 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
crow_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: crow-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Project-URL: Homepage, https://github.com/odellus/crow-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/odellus/crow-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/odellus/crow-cli/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/odellus/crow-cli#readme
|
|
9
|
+
Requires-Python: >=3.14
|
|
10
|
+
Requires-Dist: agent-client-protocol>=0.8.1
|
|
11
|
+
Requires-Dist: coolname>=2.2.0
|
|
12
|
+
Requires-Dist: directory-tree>=1.0.0
|
|
13
|
+
Requires-Dist: fastmcp>=2.14.5
|
|
14
|
+
Requires-Dist: httpx>=0.28.1
|
|
15
|
+
Requires-Dist: ipython>=9.10.0
|
|
16
|
+
Requires-Dist: jinja2>=3.1.6
|
|
17
|
+
Requires-Dist: json-schema-to-pydantic>=0.4.9
|
|
18
|
+
Requires-Dist: openai>=2.21.0
|
|
19
|
+
Requires-Dist: pandas>=3.0.1
|
|
20
|
+
Requires-Dist: psycopg2-binary>=2.9.11
|
|
21
|
+
Requires-Dist: pysqlite3>=0.6.0
|
|
22
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
23
|
+
Requires-Dist: rich>=14.3.3
|
|
24
|
+
Requires-Dist: sqlalchemy>=2.0.46
|
|
25
|
+
Requires-Dist: typer>=0.24.1
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# `crow-cli`
|
|
29
|
+
|
|
30
|
+
`crow-cli` is an [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) native agent implementation that serves as the core execution engine for the Crow agent framework.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Ensure you're in the correct project directory
|
|
36
|
+
cd /home/thomas/src/nid
|
|
37
|
+
uv venv
|
|
38
|
+
# Install dependencies using uv
|
|
39
|
+
uv --project /path/to/crow/crow-cli sync
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### Run as CLI Agent
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Activate the virtual environment (if not using --project)
|
|
48
|
+
# Run the agent
|
|
49
|
+
uv --project . crow-cli --help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Run Programmatically
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import asyncio
|
|
56
|
+
from crow_acp.agent import AcpAgent, agent_run
|
|
57
|
+
|
|
58
|
+
async def main():
|
|
59
|
+
await agent_run()
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
asyncio.run(main())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### Environment Variables
|
|
68
|
+
|
|
69
|
+
Create a `.env` file in your project root or set these environment variables:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# LLM Configuration
|
|
73
|
+
ZAI_API_KEY=your-api-key-here
|
|
74
|
+
ZAI_BASE_URL=https://api.zai.ai
|
|
75
|
+
|
|
76
|
+
# Database path (optional, defaults to ~/.crow/crow.db)
|
|
77
|
+
DATABASE_PATH=sqlite:~/.crow/crow.db
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### MCP Server Configuration
|
|
81
|
+
|
|
82
|
+
MCP servers are configured in `~/.crow/mcp.json`. The default configuration includes the built-in Crow MCP tools:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"mcpServers": {
|
|
87
|
+
"crow-mcp": {
|
|
88
|
+
"command": "uv",
|
|
89
|
+
"args": [
|
|
90
|
+
"--project",
|
|
91
|
+
"/home/thomas/src/nid/crow-mcp",
|
|
92
|
+
"run",
|
|
93
|
+
"python",
|
|
94
|
+
"-m",
|
|
95
|
+
"crow_mcp.server",
|
|
96
|
+
"--transport",
|
|
97
|
+
"stdio"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Features
|
|
105
|
+
|
|
106
|
+
### 1. ACP Protocol Native
|
|
107
|
+
- Implements all ACP agent endpoints (`initialize`, `new_session`, `load_session`, `prompt`, `cancel`)
|
|
108
|
+
- Full streaming support for token-by-token responses
|
|
109
|
+
- Session persistence to SQLite database
|
|
110
|
+
|
|
111
|
+
### 2. Multi-Session Support
|
|
112
|
+
- Handles multiple concurrent sessions with proper isolation
|
|
113
|
+
- Sessions persist across agent restarts
|
|
114
|
+
- Load existing sessions by ID
|
|
115
|
+
|
|
116
|
+
### 3. MCP Tool Integration
|
|
117
|
+
- Automatically discovers tools from connected MCP servers
|
|
118
|
+
- Supports both MCP and ACP-native tool execution
|
|
119
|
+
- Tool execution with progress updates
|
|
120
|
+
|
|
121
|
+
### 4. Streaming ReAct Loop
|
|
122
|
+
- Real-time streaming of thinking tokens (for reasoning models)
|
|
123
|
+
- Content token streaming
|
|
124
|
+
- Tool call progress updates (pending → in_progress → completed/failed)
|
|
125
|
+
|
|
126
|
+
### 5. Cancellation Support
|
|
127
|
+
- Immediate task cancellation via async events
|
|
128
|
+
- Persists partial state on cancellation
|
|
129
|
+
- Safe resource cleanup on cancel
|
|
130
|
+
|
|
131
|
+
### 6. ACP Terminal Support
|
|
132
|
+
When the ACP client supports terminals (`clientCapabilities.terminal: true`):
|
|
133
|
+
- Uses ACP-native terminals instead of MCP terminal calls
|
|
134
|
+
- Better terminal display in the client
|
|
135
|
+
- Live output streaming
|
|
136
|
+
- Proper terminal lifecycle management
|
|
137
|
+
|
|
138
|
+
## Built-in Tools
|
|
139
|
+
|
|
140
|
+
The agent automatically discovers and registers tools from connected MCP servers:
|
|
141
|
+
|
|
142
|
+
- `crow-mcp_terminal` - Execute shell commands in the workspace
|
|
143
|
+
- `crow-mcp_write` - Write content to files
|
|
144
|
+
- `crow-mcp_read` - Read files with line numbers
|
|
145
|
+
- `crow-mcp_edit` - Fuzzy string replacement in files
|
|
146
|
+
- `crow-mcp_web_search` - Search the web using a search engine
|
|
147
|
+
- `crow-mcp_web_fetch` - Fetch URL content as markdown
|
|
148
|
+
|
|
149
|
+
## Session Management
|
|
150
|
+
|
|
151
|
+
### Creating a New Session
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# When connecting via ACP, a new session is created automatically
|
|
155
|
+
# with the working directory and MCP servers provided by the client
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Loading an Existing Session
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
# Sessions persist to the database and can be loaded by ID
|
|
162
|
+
# The load_session endpoint handles this automatically
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Session Data Storage
|
|
166
|
+
|
|
167
|
+
Sessions are stored in SQLite with three main tables:
|
|
168
|
+
|
|
169
|
+
- **Prompt** - System prompt templates (Jinja2)
|
|
170
|
+
- **Session** - Session metadata (config, tools, model, cwd)
|
|
171
|
+
- **Event** - Conversation turns (messages, tool calls, results)
|
|
172
|
+
|
|
173
|
+
## Usage with ACP Clients
|
|
174
|
+
|
|
175
|
+
`crow-cli` is designed to work with any ACP-compatible client:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Example with ACP client that supports terminal and filesystem capabilities
|
|
179
|
+
# The agent will automatically use ACP-native features when available
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### ACP Client Capabilities
|
|
183
|
+
|
|
184
|
+
The agent automatically detects and uses client capabilities:
|
|
185
|
+
|
|
186
|
+
| Capability | When Enabled | Behavior |
|
|
187
|
+
|------------|--------------|----------|
|
|
188
|
+
| `terminal` | Client supports ACP terminals | Uses ACP-native terminals |
|
|
189
|
+
| `fs.write_text_file` | Client supports file writing | Uses ACP file write |
|
|
190
|
+
| `fs.read_text_file` | Client supports file reading | Uses ACP file read |
|
|
191
|
+
|
|
192
|
+
## Project Structure
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
crow-cli/
|
|
196
|
+
├── agent.py # AcpAgent class - ACP protocol + ReAct loop
|
|
197
|
+
├── session.py # Session management + persistence
|
|
198
|
+
├── db.py # SQLAlchemy database models
|
|
199
|
+
├── config.py # Configuration (LLM, MCP, database)
|
|
200
|
+
├── llm.py # LLM client configuration
|
|
201
|
+
├── mcp_client.py # MCP client creation + tool extraction
|
|
202
|
+
├── context.py # Context providers (directory tree, file fetching)
|
|
203
|
+
├── prompts/ # Jinja2 system prompt templates
|
|
204
|
+
│ ├── system_prompt.jinja2
|
|
205
|
+
│ ├── self_documentation.jinja2
|
|
206
|
+
│ ├── skill_knowledge_info.jinja2
|
|
207
|
+
│ └── system_message_suffix.jinja2
|
|
208
|
+
└── pyproject.toml # Project dependencies and entry point
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Development
|
|
212
|
+
|
|
213
|
+
### Running Tests
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# From the project root
|
|
217
|
+
uv run --project /home/thomas/src/nid pytest crow-cli/tests/
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Building
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Build the package
|
|
224
|
+
uv build --project /home/thomas/src/nid/crow-cli
|
|
225
|
+
|
|
226
|
+
# Install locally
|
|
227
|
+
pip install --force-reinstall ./crow-cli/dist/*.whl
|
|
228
|
+
```
|
|
229
|
+
### ReAct Loop Logic
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
233
|
+
│ REACT LOOP (Turn N) │
|
|
234
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
235
|
+
│
|
|
236
|
+
▼
|
|
237
|
+
┌───────────────────────────────┐
|
|
238
|
+
│ cancel_event.is_set()? │
|
|
239
|
+
└───────────────────────────────┘
|
|
240
|
+
│ │
|
|
241
|
+
YES NO
|
|
242
|
+
│ │
|
|
243
|
+
▼ ▼
|
|
244
|
+
┌──────────┐ ┌────────────────────────┐
|
|
245
|
+
│ RETURN │ │ send_request(LLM) │
|
|
246
|
+
└──────────┘ └────────────────────────┘
|
|
247
|
+
│
|
|
248
|
+
▼
|
|
249
|
+
┌──────────────────────────────┐
|
|
250
|
+
│ process_response() stream │
|
|
251
|
+
│ ┌────────────────────────┐ │
|
|
252
|
+
│ │ Yield: thinking/token │ │
|
|
253
|
+
│ │ Yield: content/token │ │
|
|
254
|
+
│ │ Yield: tool_args/token │ │
|
|
255
|
+
│ └────────────────────────┘ │
|
|
256
|
+
│ │ │
|
|
257
|
+
│ ▼ │
|
|
258
|
+
│ Collect in │
|
|
259
|
+
│ state_accumulator │
|
|
260
|
+
└──────────────────────────────┘
|
|
261
|
+
│
|
|
262
|
+
▼
|
|
263
|
+
┌──────────────────────────────┐
|
|
264
|
+
│ Cancelled during stream? │
|
|
265
|
+
└──────────────────────────────┘
|
|
266
|
+
┌────────┴────────┐
|
|
267
|
+
YES NO
|
|
268
|
+
│ │
|
|
269
|
+
▼ ▼
|
|
270
|
+
┌──────────────┐ ┌────────────────────────┐
|
|
271
|
+
│ Add partial │ │ Yield: final │
|
|
272
|
+
│ response │ │ (thinking, content, │
|
|
273
|
+
│ + results │ │ tool_call_inputs) │
|
|
274
|
+
│ Raise │ └────────────────────────┘
|
|
275
|
+
│ CancelledErr │ │
|
|
276
|
+
└──────────────┘ ▼
|
|
277
|
+
│ ┌────────────────────────┐
|
|
278
|
+
│ │ Log pre-tool usage │
|
|
279
|
+
▼ └────────────────────────┘
|
|
280
|
+
┌──────────┐ │
|
|
281
|
+
│ RETURN │ ┌────────────────────────┐
|
|
282
|
+
└──────────┘ │ tokens > threshold? │
|
|
283
|
+
│ └────────────────────────┘
|
|
284
|
+
┌──────────────────────────────┐ │ │
|
|
285
|
+
│ Turn Loop: for turn in │ YES NO
|
|
286
|
+
│ range(max_turns): │ │ │
|
|
287
|
+
└──────────────────────────────┘ ▼ ▼
|
|
288
|
+
│ ┌──────────────┐ ┌──────────┐
|
|
289
|
+
▼ │ COMPACT │ │ SKIP │
|
|
290
|
+
┌──────────────────────────┐ │ session() │ │ COMPACT│
|
|
291
|
+
│ process_response DONE │ └──────────────┘ └──────────┘
|
|
292
|
+
│ Extract: thinking │ │ │
|
|
293
|
+
│ content │ └────────┬───────┘
|
|
294
|
+
│ tool_call_inputs │ │
|
|
295
|
+
│ usage │ ▼
|
|
296
|
+
└──────────────────────────┘ ┌────────────────────────┐
|
|
297
|
+
│ │ Has tools to call? │
|
|
298
|
+
▼ └────────────────────────┘
|
|
299
|
+
┌──────────────────────────┐ │
|
|
300
|
+
│ Cancelled after stream? │ ┌────┴────┐
|
|
301
|
+
└──────────────────────────┘ YES NO
|
|
302
|
+
│ │ │
|
|
303
|
+
YES ▼ ▼
|
|
304
|
+
│ ┌──────────────┐ ┌──────────────┐
|
|
305
|
+
▼ │ EXECUTE │ │ NO TOOLS │
|
|
306
|
+
┌──────────────┐ │ TOOLS │ │ (final msg) │
|
|
307
|
+
│ Add partial │ └──────────────┘ └──────────────┘
|
|
308
|
+
│ response │ │ │
|
|
309
|
+
│ + tool │ │ │
|
|
310
|
+
│ results │ ▼ ▼
|
|
311
|
+
│ RETURN │ ┌──────────────┐ ┌──────────────┐
|
|
312
|
+
└──────────────┘ │ Add tools │ │ Add assistant│
|
|
313
|
+
│ to results │ │ response │
|
|
314
|
+
└──────────────┘ └──────────────┘
|
|
315
|
+
│ │ │
|
|
316
|
+
▼ ▼ ▼
|
|
317
|
+
┌──────────────────────────────────────────────────┐
|
|
318
|
+
│ Cancelled after tool execution? │
|
|
319
|
+
└──────────────────────────────────────────────────┘
|
|
320
|
+
│
|
|
321
|
+
┌────────┴────────┐
|
|
322
|
+
YES NO
|
|
323
|
+
│ │
|
|
324
|
+
▼ ▼
|
|
325
|
+
┌──────────────┐ ┌────────────────────────┐
|
|
326
|
+
│ Add partial │ │ Add assistant response │
|
|
327
|
+
│ response + │ │ + tool results │
|
|
328
|
+
│ tool results │ └────────────────────────┘
|
|
329
|
+
│ RETURN │ │
|
|
330
|
+
└──────────────┘ │
|
|
331
|
+
│
|
|
332
|
+
▼
|
|
333
|
+
┌────────────────────────┐
|
|
334
|
+
│ Turn N complete │
|
|
335
|
+
│ ───────────────────── │
|
|
336
|
+
│ Loop back to turn N+1 │
|
|
337
|
+
│ (or max_turns reached)│
|
|
338
|
+
└────────────────────────┘
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Troubleshooting
|
|
342
|
+
|
|
343
|
+
### Connection Issues
|
|
344
|
+
|
|
345
|
+
If the agent can't connect to MCP servers:
|
|
346
|
+
|
|
347
|
+
1. Verify MCP server config in `~/.crow/mcp.json`
|
|
348
|
+
2. Check that the MCP server path is correct
|
|
349
|
+
3. Ensure the server is executable
|
|
350
|
+
|
|
351
|
+
### Session Loading Failures
|
|
352
|
+
|
|
353
|
+
If sessions fail to load:
|
|
354
|
+
|
|
355
|
+
1. Check database exists: `ls ~/.crow/crow.db`
|
|
356
|
+
2. Verify database permissions: `chmod 644 ~/.crow/crow.db`
|
|
357
|
+
3. Check session ID exists in database
|
|
358
|
+
|
|
359
|
+
### Terminal Not Working
|
|
360
|
+
|
|
361
|
+
If ACP terminals aren't working:
|
|
362
|
+
|
|
363
|
+
1. Check client capabilities: `clientCapabilities.terminal` should be `true`
|
|
364
|
+
2. Verify MCP terminal fallback is configured
|
|
365
|
+
3. Check terminal command is valid in the workspace directory
|
|
366
|
+
|
|
367
|
+
## License
|
|
368
|
+
|
|
369
|
+
Apache-2.0
|