@voria/cli 0.0.2
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.
- package/README.md +439 -0
- package/bin/voria +730 -0
- package/docs/ARCHITECTURE.md +419 -0
- package/docs/CHANGELOG.md +189 -0
- package/docs/CONTRIBUTING.md +447 -0
- package/docs/DESIGN_DECISIONS.md +380 -0
- package/docs/DEVELOPMENT.md +535 -0
- package/docs/EXAMPLES.md +434 -0
- package/docs/INSTALL.md +335 -0
- package/docs/IPC_PROTOCOL.md +310 -0
- package/docs/LLM_INTEGRATION.md +416 -0
- package/docs/MODULES.md +470 -0
- package/docs/PERFORMANCE.md +346 -0
- package/docs/PLUGINS.md +432 -0
- package/docs/QUICKSTART.md +184 -0
- package/docs/README.md +133 -0
- package/docs/ROADMAP.md +346 -0
- package/docs/SECURITY.md +334 -0
- package/docs/TROUBLESHOOTING.md +565 -0
- package/docs/USER_GUIDE.md +700 -0
- package/package.json +63 -0
- package/python/voria/__init__.py +8 -0
- package/python/voria/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/__pycache__/engine.cpython-312.pyc +0 -0
- package/python/voria/core/__init__.py +1 -0
- package/python/voria/core/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/__pycache__/setup.cpython-312.pyc +0 -0
- package/python/voria/core/agent/__init__.py +9 -0
- package/python/voria/core/agent/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/agent/__pycache__/loop.cpython-312.pyc +0 -0
- package/python/voria/core/agent/loop.py +343 -0
- package/python/voria/core/executor/__init__.py +19 -0
- package/python/voria/core/executor/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/executor/__pycache__/executor.cpython-312.pyc +0 -0
- package/python/voria/core/executor/executor.py +431 -0
- package/python/voria/core/github/__init__.py +33 -0
- package/python/voria/core/github/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/github/__pycache__/client.cpython-312.pyc +0 -0
- package/python/voria/core/github/client.py +438 -0
- package/python/voria/core/llm/__init__.py +55 -0
- package/python/voria/core/llm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/base.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/claude_provider.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/gemini_provider.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/modal_provider.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/model_discovery.cpython-312.pyc +0 -0
- package/python/voria/core/llm/__pycache__/openai_provider.cpython-312.pyc +0 -0
- package/python/voria/core/llm/base.py +152 -0
- package/python/voria/core/llm/claude_provider.py +188 -0
- package/python/voria/core/llm/gemini_provider.py +148 -0
- package/python/voria/core/llm/modal_provider.py +228 -0
- package/python/voria/core/llm/model_discovery.py +289 -0
- package/python/voria/core/llm/openai_provider.py +146 -0
- package/python/voria/core/patcher/__init__.py +9 -0
- package/python/voria/core/patcher/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/patcher/__pycache__/patcher.cpython-312.pyc +0 -0
- package/python/voria/core/patcher/patcher.py +375 -0
- package/python/voria/core/planner/__init__.py +1 -0
- package/python/voria/core/setup.py +201 -0
- package/python/voria/core/token_manager/__init__.py +29 -0
- package/python/voria/core/token_manager/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/voria/core/token_manager/__pycache__/manager.cpython-312.pyc +0 -0
- package/python/voria/core/token_manager/manager.py +241 -0
- package/python/voria/engine.py +1185 -0
- package/python/voria/plugins/__init__.py +1 -0
- package/python/voria/plugins/python/__init__.py +1 -0
- package/python/voria/plugins/typescript/__init__.py +1 -0
package/docs/INSTALL.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Installation Guide
|
|
2
|
+
|
|
3
|
+
Complete instructions for installing and using voria.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
### For Global CLI Tool (Recommended)
|
|
8
|
+
- **Node.js 16+** - Get from [https://nodejs.org](https://nodejs.org)
|
|
9
|
+
- **npm 8+** - Comes with Node.js
|
|
10
|
+
- **Git** - For version control
|
|
11
|
+
|
|
12
|
+
### For Development/Contributing
|
|
13
|
+
- **Rust 1.70+** - Get from [https://rustup.rs](https://rustup.rs)
|
|
14
|
+
- **Python 3.9+** - Get from [https://python.org](https://python.org)
|
|
15
|
+
- **10+ GB disk space** - For dependencies and build artifacts
|
|
16
|
+
|
|
17
|
+
### Optional (for specific features)
|
|
18
|
+
- **pytest** - For Python test execution support
|
|
19
|
+
- **Docker** - For sandboxed test runs
|
|
20
|
+
- **GraphQL client** - For GitHub Enterprise
|
|
21
|
+
|
|
22
|
+
## Quick Install (Recommended)
|
|
23
|
+
|
|
24
|
+
### Using npm (Easiest)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Install globally
|
|
28
|
+
npm install -g @srizdebnath/voria
|
|
29
|
+
|
|
30
|
+
# Verify installation
|
|
31
|
+
voria --version # Should show v0.0.1
|
|
32
|
+
|
|
33
|
+
# Initialize in your project
|
|
34
|
+
cd your-project
|
|
35
|
+
voria --init
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**That's it!** voria is now ready to use.
|
|
39
|
+
|
|
40
|
+
## 🔧 Alternative: Manual Installation from Source
|
|
41
|
+
|
|
42
|
+
### Step 1: Clone Repository
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/Srizdebnath/voria.git
|
|
46
|
+
cd voria
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Step 2: Create Python Virtual Environment
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Create virtual environment
|
|
53
|
+
python3 -m venv venv
|
|
54
|
+
source venv/bin/activate
|
|
55
|
+
|
|
56
|
+
# On Windows: venv\Scripts\activate
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 3: Install Python Package
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cd python
|
|
63
|
+
pip install -e ".[dev]"
|
|
64
|
+
cd ..
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**What gets installed:**
|
|
68
|
+
- httpx 0.24.0 - Async HTTP client
|
|
69
|
+
- aiofiles 23.0 - Async file operations
|
|
70
|
+
- pydantic 2.0+ - Data validation
|
|
71
|
+
- pytest 7.4+ - Testing framework (optional)
|
|
72
|
+
- black - Code formatter (optional)
|
|
73
|
+
- mypy - Type checker (optional)
|
|
74
|
+
|
|
75
|
+
### Step 4: Verify Installation
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Test the installation
|
|
79
|
+
voria --help
|
|
80
|
+
|
|
81
|
+
# Setup your LLM provider
|
|
82
|
+
voria setup-modal
|
|
83
|
+
|
|
84
|
+
# Setup GitHub access
|
|
85
|
+
voria set-github-token
|
|
86
|
+
|
|
87
|
+
# List issues from a repository
|
|
88
|
+
voria list-issues owner/repo
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Expected output:
|
|
92
|
+
```
|
|
93
|
+
⚡ voria - AI-Powered Bug Fixing
|
|
94
|
+
|
|
95
|
+
Usage: voria [OPTIONS] <COMMAND>
|
|
96
|
+
|
|
97
|
+
Commands:
|
|
98
|
+
setup-modal Setup Modal API configuration
|
|
99
|
+
set-github-token Set GitHub Personal Access Token
|
|
100
|
+
list-issues List issues from a GitHub repository
|
|
101
|
+
fix Fix a specific GitHub issue
|
|
102
|
+
plan Plan how to fix an issue
|
|
103
|
+
issue Run full agent loop on an issue
|
|
104
|
+
apply Apply an existing plan
|
|
105
|
+
help Print this message or the help of the given subcommand(s)
|
|
106
|
+
|
|
107
|
+
Options:
|
|
108
|
+
-v, --verbose Verbose logging
|
|
109
|
+
-c, --config <CONFIG> Configuration file path
|
|
110
|
+
-h, --help Print help
|
|
111
|
+
-V, --version Print version
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Configure LLM Providers
|
|
115
|
+
|
|
116
|
+
voria requires at least one LLM provider. Set up using `voria setup-modal`:
|
|
117
|
+
|
|
118
|
+
### Interactive Setup (Recommended)
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# In your project directory
|
|
122
|
+
voria --init
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This will guide you through:
|
|
126
|
+
1. ✅ Choose LLM provider (Modal, OpenAI, Gemini, Claude)
|
|
127
|
+
2. ✅ Enter API key
|
|
128
|
+
3. ✅ Set daily budget
|
|
129
|
+
4. ✅ Select test framework
|
|
130
|
+
5. ✅ Save configuration to `.voria.json`
|
|
131
|
+
|
|
132
|
+
### Manual Configuration
|
|
133
|
+
|
|
134
|
+
Edit `~/.voria/config.json` (created after `voria --init`):
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"provider": "openai",
|
|
139
|
+
"api_key": "sk-...",
|
|
140
|
+
"model": "gpt-5.4"
|
|
141
|
+
},
|
|
142
|
+
"modal": {
|
|
143
|
+
"api_key": "token-...",
|
|
144
|
+
"model": "zai-org/GLM-5.1-FP8"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Option C: Environment Variables
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# OpenAI
|
|
154
|
+
export OPENAI_API_KEY="sk-..."
|
|
155
|
+
|
|
156
|
+
# Modal
|
|
157
|
+
export MODAL_API_KEY="token-..."
|
|
158
|
+
|
|
159
|
+
# Google Gemini
|
|
160
|
+
export GOOGLE_API_KEY="..."
|
|
161
|
+
|
|
162
|
+
# Anthropic Claude
|
|
163
|
+
export ANTHROPIC_API_KEY="..."
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## System-Wide Installation
|
|
167
|
+
|
|
168
|
+
### Install to PATH
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Copy binary to system path
|
|
172
|
+
sudo cp target/release/voria /usr/local/bin/
|
|
173
|
+
|
|
174
|
+
# Now run from anywhere
|
|
175
|
+
voria --version
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Create Shell Alias
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Add to ~/.bashrc or ~/.zshrc
|
|
182
|
+
alias voria="~/path/to/voria/target/release/voria"
|
|
183
|
+
|
|
184
|
+
# Reload shell
|
|
185
|
+
source ~/.bashrc
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 🐳 Docker Installation
|
|
189
|
+
|
|
190
|
+
```dockerfile
|
|
191
|
+
FROM rust:1.70 as builder
|
|
192
|
+
WORKDIR /app
|
|
193
|
+
COPY . .
|
|
194
|
+
RUN cd rust && cargo build --release
|
|
195
|
+
|
|
196
|
+
FROM python:3.11
|
|
197
|
+
COPY --from=builder /app/target/release/voria /usr/local/bin/
|
|
198
|
+
COPY python /app/python
|
|
199
|
+
WORKDIR /app
|
|
200
|
+
RUN pip install -e python/
|
|
201
|
+
ENTRYPOINT ["voria"]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Build and run:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
docker build -t voria .
|
|
208
|
+
docker run -it voria --version
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Post-Installation Verification
|
|
212
|
+
|
|
213
|
+
### Check All Components
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# ✅ Check Rust CLI
|
|
217
|
+
./target/release/voria --version
|
|
218
|
+
./target/release/voria --help
|
|
219
|
+
|
|
220
|
+
# ✅ Check Python engine
|
|
221
|
+
python3 -c "import voria; print('Python OK')"
|
|
222
|
+
|
|
223
|
+
# ✅ Check NDJSON protocol
|
|
224
|
+
echo '{"command":"plan","issue_id":1}' | python3 -m voria.engine | head -1
|
|
225
|
+
|
|
226
|
+
# ✅ Check end-to-end
|
|
227
|
+
./target/release/voria plan 1
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Run Test Suite
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Python tests
|
|
234
|
+
cd python
|
|
235
|
+
pytest -v
|
|
236
|
+
|
|
237
|
+
# Rust tests
|
|
238
|
+
cd ../rust
|
|
239
|
+
cargo test
|
|
240
|
+
|
|
241
|
+
# Full integration
|
|
242
|
+
cd ..
|
|
243
|
+
python3 test_voria_cli.py
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Development Installation
|
|
247
|
+
|
|
248
|
+
If you plan to contribute:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Install with dev dependencies
|
|
252
|
+
cd python
|
|
253
|
+
pip install -e ".[dev]"
|
|
254
|
+
|
|
255
|
+
# Install development tools
|
|
256
|
+
pip install black pyright pytest-cov
|
|
257
|
+
|
|
258
|
+
# Format code
|
|
259
|
+
black .
|
|
260
|
+
|
|
261
|
+
# Type check
|
|
262
|
+
pyright .
|
|
263
|
+
|
|
264
|
+
# Run all tests
|
|
265
|
+
pytest -v
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Troubleshooting Installation
|
|
269
|
+
|
|
270
|
+
### "cargo not found"
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Install Rust
|
|
274
|
+
curl --proto '=https' --tlsvv0.0.1 -sSf https://sh.rustup.rs | sh
|
|
275
|
+
source $HOME/.cargo/env
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### "Python version too old"
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Check version
|
|
282
|
+
python3 --version
|
|
283
|
+
|
|
284
|
+
# Update with your package manager
|
|
285
|
+
brew install python3 # macOS
|
|
286
|
+
apt install python3.11 # Ubuntu
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### "Port already in use"
|
|
290
|
+
|
|
291
|
+
voria uses stdin/stdout, not network ports, so this shouldn't occur. If you see it:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Kill any hanging Python processes
|
|
295
|
+
pkill -f "python.*voria"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### "NDJSON protocol error"
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Clear any cached state
|
|
302
|
+
rm -rf ~/.voria/
|
|
303
|
+
|
|
304
|
+
# Reinstall
|
|
305
|
+
cd python && pip install -e . --force-reinstall
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Installation Checklist
|
|
309
|
+
|
|
310
|
+
- [ ] Rust compiled successfully
|
|
311
|
+
- [ ] Python virtual environment created
|
|
312
|
+
- [ ] Python dependencies installed
|
|
313
|
+
- [ ] `voria --version` works
|
|
314
|
+
- [ ] `voria plan 1` works
|
|
315
|
+
- [ ] LLM provider configured
|
|
316
|
+
- [ ] All tests passing
|
|
317
|
+
- [ ] Configuration file created
|
|
318
|
+
|
|
319
|
+
## Next Steps
|
|
320
|
+
|
|
321
|
+
1. Read [QUICKSTART.md](QUICKSTART.md) to run your first command
|
|
322
|
+
2. Check [USER_GUIDE.md](USER_GUIDE.md) for detailed usage
|
|
323
|
+
3. See [EXAMPLES.md](EXAMPLES.md) for real-world scenarios
|
|
324
|
+
4. Join the community on GitHub
|
|
325
|
+
|
|
326
|
+
## Need Help?
|
|
327
|
+
|
|
328
|
+
- Check [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
|
|
329
|
+
- Read [DEVELOPMENT.md](DEVELOPMENT.md)
|
|
330
|
+
- Search [GitHub Issues](https://github.com/Srizdebnath/voria/issues)
|
|
331
|
+
- Open a new issue
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
**Installation Complete!** Continue with [QUICKSTART.md](QUICKSTART.md) 🚀
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# IPC Protocol Specification
|
|
2
|
+
|
|
3
|
+
Complete specification of voria's NDJSON-based inter-process communication protocol.
|
|
4
|
+
|
|
5
|
+
## Protocol Overview
|
|
6
|
+
|
|
7
|
+
voria uses **NDJSON** (Newline-Delimited JSON) for communication between Rust CLI and Python engine.
|
|
8
|
+
|
|
9
|
+
## Format Rules (MANDATORY)
|
|
10
|
+
|
|
11
|
+
1. **One JSON object per line** - no line wrapping
|
|
12
|
+
2. **Newline terminator** - exactly `\n` after each JSON object
|
|
13
|
+
3. **No multi-line JSON** - protocol messages must fit on single line
|
|
14
|
+
4. **Flush after write** - must call `flush()` immediately after writing
|
|
15
|
+
5. **Line-by-line reading** - read one complete line at a time
|
|
16
|
+
|
|
17
|
+
### Example
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
{"command":"plan","issue_id":1}\n
|
|
21
|
+
{"status":"success","action":"stop","message":"Done"}\n
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
NOT acceptable:
|
|
25
|
+
```
|
|
26
|
+
{"command":"plan",
|
|
27
|
+
"issue_id":1}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Stdout/Stderr Discipline
|
|
31
|
+
|
|
32
|
+
### Python Side
|
|
33
|
+
|
|
34
|
+
**stdout** (ONLY protocol messages):
|
|
35
|
+
```python
|
|
36
|
+
response = {"status": "success", "action": "stop", "message": "Done"}
|
|
37
|
+
print(json.dumps(response)) # Automatic \n added
|
|
38
|
+
sys.stdout.flush() # CRITICAL!
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**stderr** (logs and debug info):
|
|
42
|
+
```python
|
|
43
|
+
logger.info("Processing issue...") # Goes to stderr
|
|
44
|
+
logger.debug("Token count: 1000") # Goes to stderr
|
|
45
|
+
print(f"Debug: {value}", file=sys.stderr) # Goes to stderr
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Rust Side
|
|
49
|
+
|
|
50
|
+
**Reads**: Only from stdout (line-by-line JSON parsing)
|
|
51
|
+
**Pipes**: stderr directly to user console
|
|
52
|
+
|
|
53
|
+
## Message Types
|
|
54
|
+
|
|
55
|
+
### Request (Rust → Python)
|
|
56
|
+
|
|
57
|
+
Sent by Rust CLI to invoke Python processing.
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"command": "plan|issue|apply|graph|test_results",
|
|
62
|
+
"issue_id": 123,
|
|
63
|
+
"repo_path": "/path/to/repo",
|
|
64
|
+
"iteration": 1,
|
|
65
|
+
"extra_field": "optional"
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Fields**:
|
|
70
|
+
- `command` (required): The action to perform
|
|
71
|
+
- `issue_id` (optional): GitHub issue number
|
|
72
|
+
- `repo_path` (optional): Local repository path
|
|
73
|
+
- `iteration` (optional): Loop iteration count (1-5)
|
|
74
|
+
|
|
75
|
+
**Command Types**:
|
|
76
|
+
- `plan`: Analyze issue without code changes
|
|
77
|
+
- `issue`: Start full agent loop
|
|
78
|
+
- `apply`: Execute a previously generated plan
|
|
79
|
+
- `graph`: Generate dependency graph
|
|
80
|
+
- `test_results`: Callback with test results
|
|
81
|
+
|
|
82
|
+
### Response (Python → Rust)
|
|
83
|
+
|
|
84
|
+
Sent by Python engine to Rust CLI after processing.
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"status": "success|pending|error",
|
|
89
|
+
"action": "apply_patch|run_tests|continue|stop",
|
|
90
|
+
"message": "Human-readable status message",
|
|
91
|
+
"patch": "... unified diff format ...",
|
|
92
|
+
"logs": "... multi-line debug output ...",
|
|
93
|
+
"token_usage": {
|
|
94
|
+
"used": 1000,
|
|
95
|
+
"max": 4000,
|
|
96
|
+
"cost": 0.05
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Fields**:
|
|
102
|
+
- `status` (required): Success, pending work, or error
|
|
103
|
+
- `action` (required): What Rust should do next
|
|
104
|
+
- `message` (required): Human-readable message
|
|
105
|
+
- `patch` (optional): Unified diff format patch
|
|
106
|
+
- `logs` (optional): Multi-line debug logs
|
|
107
|
+
- `token_usage` (optional): LLM token accounting
|
|
108
|
+
|
|
109
|
+
**Status Values**:
|
|
110
|
+
- `success`: Action completed successfully
|
|
111
|
+
- `pending`: Action in progress, expect more messages
|
|
112
|
+
- `error`: Action failed with error
|
|
113
|
+
|
|
114
|
+
**Action Values**:
|
|
115
|
+
- `apply_patch`: Apply the patch to filesystem
|
|
116
|
+
- `run_tests`: Execute test suite
|
|
117
|
+
- `continue`: Continue to next iteration
|
|
118
|
+
- `stop`: Stop processing, issue is done
|
|
119
|
+
|
|
120
|
+
### Callback (Rust → Python)
|
|
121
|
+
|
|
122
|
+
Sent by Rust to inform Python of execution results.
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"command": "test_results",
|
|
127
|
+
"test_status": "passed|failed",
|
|
128
|
+
"test_logs": "... test output ...",
|
|
129
|
+
"error": "... error message if failed ..."
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Fields**:
|
|
134
|
+
- `command` (required): `test_results`
|
|
135
|
+
- `test_status` (required): passed or failed
|
|
136
|
+
- `test_logs` (optional): Test suite output
|
|
137
|
+
- `error` (optional): Error message if failed
|
|
138
|
+
|
|
139
|
+
## Protocol Flow Examples
|
|
140
|
+
|
|
141
|
+
### Example 1: Simple Plan Request
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
RUST → PYTHON:
|
|
145
|
+
{"command":"plan","issue_id":1,"iteration":1}
|
|
146
|
+
|
|
147
|
+
PYTHON → RUST:
|
|
148
|
+
{"status":"success","action":"stop","message":"Plan generated for issue #1"}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Example 2: Full Agent Loop
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
RUST → PYTHON:
|
|
155
|
+
{"command":"issue","issue_id":123,"repo_path":"/home/user/repo"}
|
|
156
|
+
|
|
157
|
+
PYTHON → RUST:
|
|
158
|
+
{"status":"pending","action":"apply_patch","message":"Generated patch","patch":"--- a/src/main.py\n+++ b/src/main.py\n@@ -1,3 +1,3 @@\n..."}
|
|
159
|
+
|
|
160
|
+
RUST applies patch, runs tests
|
|
161
|
+
|
|
162
|
+
RUST → PYTHON:
|
|
163
|
+
{"command":"test_results","test_status":"failed","test_logs":"..."}
|
|
164
|
+
|
|
165
|
+
PYTHON → RUST:
|
|
166
|
+
{"status":"pending","action":"continue","message":"Tests failed, refining..."}
|
|
167
|
+
|
|
168
|
+
... (iterations) ...
|
|
169
|
+
|
|
170
|
+
PYTHON → RUST:
|
|
171
|
+
{"status":"success","action":"stop","message":"Issue resolved!"}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Example 3: Error Handling
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
RUST → PYTHON:
|
|
178
|
+
{"command":"plan","issue_id":1}
|
|
179
|
+
|
|
180
|
+
PYTHON → RUST:
|
|
181
|
+
{"status":"error","action":"stop","message":"Failed to fetch issue: API key missing","logs":"...traceback..."}
|
|
182
|
+
|
|
183
|
+
RUST displays error and exits
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Encoding
|
|
187
|
+
|
|
188
|
+
- **Character Encoding**: UTF-8
|
|
189
|
+
- **JSON Spec**: RFC 7159
|
|
190
|
+
- **Line Terminator**: LF (`\n`) on Unix/Linux/macOS, CRLF (`\r\n`) OK but LF preferred
|
|
191
|
+
|
|
192
|
+
## Timeout Behavior
|
|
193
|
+
|
|
194
|
+
### Rust Timeout Detection
|
|
195
|
+
|
|
196
|
+
If no response received for 30 seconds:
|
|
197
|
+
|
|
198
|
+
1. Log timeout message
|
|
199
|
+
2. Kill Python subprocess
|
|
200
|
+
3. Restart Python engine
|
|
201
|
+
4. Retry last request once
|
|
202
|
+
5. If still no response after 30s → exit with error
|
|
203
|
+
|
|
204
|
+
### Python Timeout Prevention
|
|
205
|
+
|
|
206
|
+
Python should send a response within reasonable time (< 5s for most operations).
|
|
207
|
+
|
|
208
|
+
For long operations:
|
|
209
|
+
- Send periodic `pending` messages
|
|
210
|
+
- Or implement streaming (future enhancement)
|
|
211
|
+
|
|
212
|
+
## Error Handling
|
|
213
|
+
|
|
214
|
+
### Python Errors
|
|
215
|
+
|
|
216
|
+
If Python encounters an error processing a request:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"status": "error",
|
|
221
|
+
"action": "stop",
|
|
222
|
+
"message": "Description of what failed",
|
|
223
|
+
"logs": "... traceback to stderr ..."
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Rust Errors
|
|
228
|
+
|
|
229
|
+
If Rust encounters an error:
|
|
230
|
+
|
|
231
|
+
1. Log the error
|
|
232
|
+
2. Skip to next command
|
|
233
|
+
3. Or restart Python if critical
|
|
234
|
+
|
|
235
|
+
### JSON Parse Errors
|
|
236
|
+
|
|
237
|
+
If either side receives invalid JSON:
|
|
238
|
+
|
|
239
|
+
1. Log the error to stderr
|
|
240
|
+
2. Send error response if possible
|
|
241
|
+
3. Or abort current operation
|
|
242
|
+
|
|
243
|
+
## Performance Guidelines
|
|
244
|
+
|
|
245
|
+
- **Parse Speed**: NDJSON parsing should be < 1ms per message
|
|
246
|
+
- **Flush Timing**: Flush within 100ms of write
|
|
247
|
+
- **Message Size**: Keep messages < 1MB (practical limit)
|
|
248
|
+
- **Latency**: Aim for < 100ms roundtrip for simple operations
|
|
249
|
+
|
|
250
|
+
## Versioning
|
|
251
|
+
|
|
252
|
+
Current protocol version: **1.0**
|
|
253
|
+
|
|
254
|
+
Protocol changes require coordination between Rust and Python versions.
|
|
255
|
+
|
|
256
|
+
## Testing
|
|
257
|
+
|
|
258
|
+
### Manual Test (Python Engine)
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
echo '{"command":"plan","issue_id":1}' | python3 -m voria.engine
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Expected output:
|
|
265
|
+
```
|
|
266
|
+
{"status":"success","action":"stop","message":"Plan generated for issue #1"}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Manual Test (Full CLI)
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
./target/debug/voria -v plan 1
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Expected behavior:
|
|
276
|
+
- [i] Planning fix for issue #1
|
|
277
|
+
- [✓] Plan generated for issue #1
|
|
278
|
+
- Process exits cleanly
|
|
279
|
+
|
|
280
|
+
## Debugging
|
|
281
|
+
|
|
282
|
+
Enable verbose logging:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
RUST_LOG=debug ./target/debug/voria plan 1
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
This shows:
|
|
289
|
+
- JSON being sent to Python
|
|
290
|
+
- JSON being received from Python
|
|
291
|
+
- Timing information
|
|
292
|
+
- Process lifecycle events
|
|
293
|
+
|
|
294
|
+
View Python logs:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
./target/debug/voria -v plan 1 2>&1 | grep -E "\[DEBUG\]|\[INFO\]"
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Backward Compatibility
|
|
301
|
+
|
|
302
|
+
Currently no versioning mechanism. Once protocol is stable, add version field:
|
|
303
|
+
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"version": "1.0",
|
|
307
|
+
"command": "...",
|
|
308
|
+
...
|
|
309
|
+
}
|
|
310
|
+
```
|