korgex 0.6.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.
@@ -0,0 +1,701 @@
1
+ Metadata-Version: 2.4
2
+ Name: korgex
3
+ Version: 0.6.1
4
+ Summary: Autonomous AI coding agent — provider-agnostic, MCP-native, plan-first
5
+ Author: New1Direction
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/New1Direction/Korgex
8
+ Project-URL: Repository, https://github.com/New1Direction/Korgex
9
+ Project-URL: Issues, https://github.com/New1Direction/Korgex/issues
10
+ Keywords: ai,agent,coding,llm,claude,openai,mcp,anthropic
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Software Development :: Code Generators
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: anthropic>=0.40.0
27
+ Requires-Dist: openai>=1.0.0
28
+ Requires-Dist: rich>=13.0.0
29
+ Requires-Dist: fastapi>=0.100.0
30
+ Requires-Dist: uvicorn>=0.20.0
31
+ Requires-Dist: websockets>=11.0
32
+ Requires-Dist: httpx>=0.24.0
33
+ Requires-Dist: pyyaml>=6.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest<9.0.0,>=8.0.0; extra == "dev"
36
+ Requires-Dist: ruff<1.0.0,>=0.1.0; extra == "dev"
37
+ Requires-Dist: build<2.0.0,>=1.0.0; extra == "dev"
38
+ Requires-Dist: twine<7.0.0,>=5.0.0; extra == "dev"
39
+ Dynamic: license-file
40
+
41
+ # korgex
42
+
43
+ **Autonomous coding agent. Provider-agnostic. MCP-native. Plan-first.**
44
+
45
+ A terminal-native AI engineer that reads your codebase, edits files, runs commands, and ships work. Speaks both Anthropic and OpenAI tool-use protocols. Connects to any MCP server. Streams output live to your terminal. Open source, MIT-licensed, no vendor lock-in.
46
+
47
+ ```bash
48
+ $ korgex "add a /healthz endpoint that returns 200 with uptime"
49
+ ➤ Read(file_path=/app/routes.py)
50
+ ➤ Edit(file_path=/app/routes.py, old_string=..., new_string=...)
51
+ ➤ Bash(command=pytest tests/test_routes.py -q)
52
+ ✓ Added GET /healthz returning {"status": "ok", "uptime_seconds": ...}
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Table of Contents
58
+
59
+ - [Install](#install)
60
+ - [Quickstart](#quickstart)
61
+ - [How it works](#how-it-works)
62
+ - [Verifiable cognition](#verifiable-cognition)
63
+ - [CLI reference](#cli-reference)
64
+ - [Tools](#tools)
65
+ - [Environment variables](#environment-variables)
66
+ - [Multi-model routing](#multi-model-routing)
67
+ - [MCP integration](#mcp-integration)
68
+ - [Streaming TUI](#streaming-tui)
69
+ - [VS Code sidecar](#vs-code-sidecar)
70
+ - [Dashboard API](#dashboard-api)
71
+ - [Architecture](#architecture)
72
+ - [Project structure](#project-structure)
73
+ - [Development](#development)
74
+ - [Testing](#testing)
75
+ - [Building & releasing](#building--releasing)
76
+ - [Troubleshooting](#troubleshooting)
77
+ - [Known limitations](#known-limitations)
78
+ - [License](#license)
79
+
80
+ ---
81
+
82
+ ## Install
83
+
84
+ ### From GitHub Release (recommended today)
85
+
86
+ ```bash
87
+ pip install https://github.com/New1Direction/korgex/releases/download/v0.6.1/korgex-0.6.1-py3-none-any.whl
88
+ ```
89
+
90
+ ### From source
91
+
92
+ ```bash
93
+ git clone https://github.com/New1Direction/korgex.git
94
+ cd korgex
95
+ pip install -e .
96
+ ```
97
+
98
+ ### From `git+https` (latest `main`)
99
+
100
+ ```bash
101
+ pip install git+https://github.com/New1Direction/korgex.git
102
+ ```
103
+
104
+ ### From PyPI
105
+
106
+ Planned. Until then use one of the above.
107
+
108
+ ---
109
+
110
+ ## Quickstart
111
+
112
+ ```bash
113
+ # 1. Set an API key — either provider works
114
+ export ANTHROPIC_API_KEY="sk-ant-..."
115
+ # or
116
+ export OPENAI_API_KEY="sk-proj-..."
117
+ # or via OpenRouter (OpenAI-compatible, many models)
118
+ export KORGEX_API_KEY="sk-or-v1-..."
119
+ export KORGEX_API_URL="https://openrouter.ai/api/v1"
120
+
121
+ # 2. Run the agent on a naked prompt
122
+ korgex "fix the failing test in tests/test_auth.py"
123
+
124
+ # 3. Or pick a specific model / mode
125
+ korgex --model claude-sonnet-4-6 "refactor src/handler.py"
126
+ korgex --mode plan "design a rate limiter for the API"
127
+ korgex --quiet "list the python files in src/"
128
+ ```
129
+
130
+ ---
131
+
132
+ ## How it works
133
+
134
+ ```
135
+ ┌──────────────────────────────────────────────────────────────────┐
136
+ │ KORGEX AGENT LOOP │
137
+ │ │
138
+ │ user prompt │
139
+ │ │ │
140
+ │ ▼ │
141
+ │ ┌─────────────────────────┐ │
142
+ │ │ KorgexAgent.run_task() │ │
143
+ │ └─────────────────────────┘ │
144
+ │ │ │
145
+ │ ▼ │
146
+ │ ┌──────────────────────────────────────────────────────────┐ │
147
+ │ │ for i in range(max_iter): │ │
148
+ │ │ response = LLM.send(messages, tools) │ │
149
+ │ │ if no tool_calls → return final text │ │
150
+ │ │ for call in tool_calls: │ │
151
+ │ │ result = route_tool_call(name, args) │ │
152
+ │ │ messages.append(tool_result) │ │
153
+ │ └──────────────────────────────────────────────────────────┘ │
154
+ │ │ │
155
+ │ ▼ │
156
+ │ ┌─────────────────────────────────────────┐ │
157
+ │ │ Provider branching │ │
158
+ │ │ - "claude" in model → Anthropic SDK │ │
159
+ │ │ - else → OpenAI SDK (works for │ │
160
+ │ │ OpenAI, OpenRouter, Ollama, etc.) │ │
161
+ │ └─────────────────────────────────────────┘ │
162
+ │ │ │
163
+ │ ▼ │
164
+ │ ┌─────────────────────────────────────────┐ │
165
+ │ │ Tool routing (src/tool_abstraction.py) │ │
166
+ │ │ - 12 Claude-Code-style user tools │ │
167
+ │ │ - Adapter layer → Jules-style handlers │ │
168
+ │ │ - MCP-sourced tools → MCP manager │ │
169
+ │ └─────────────────────────────────────────┘ │
170
+ └──────────────────────────────────────────────────────────────────┘
171
+ ```
172
+
173
+ The agent is provider-agnostic by design: tool schemas are translated per provider (`{name, description, input_schema}` for Anthropic, `{type: "function", function: {...}}` for OpenAI), responses are normalized into a common shape, and tool results are formatted in whichever message structure the provider expects.
174
+
175
+ ---
176
+
177
+ ## Verifiable cognition
178
+
179
+ What sets korgex apart: every run is recorded to a **tamper-evident causal ledger**, not an opaque log. Each event is hash-linked (`prev_hash`/`entry_hash`) to the previous one, so a whole session can be cryptographically proven intact — any edit, deletion, reorder, or splice is detected and localized to the offending event.
180
+
181
+ ```bash
182
+ # Prove a recorded run was not altered after the fact
183
+ korgex verify .korg/journal.jsonl
184
+ # ✓ ledger intact — 7 events, hash-chain verified (exit 0; exit 1 + the bad seq_id if tampered)
185
+
186
+ # Set KORG_LEDGER_HMAC_KEY to make the chain tamper-PROOF, not just tamper-evident
187
+ export KORG_LEDGER_HMAC_KEY=…
188
+ ```
189
+
190
+ On top of the chain, korgex tracks **memory drift**: a remembered fact is anchored to a sha256 baseline of its source, so when the source moves on the staleness is an exact signal — and the keep/refresh/discard reconcile decision is itself recorded to the ledger.
191
+
192
+ ```bash
193
+ # Scan persistent memories for drift against their recorded source baselines
194
+ korgex drift
195
+ # ✗ memory DRIFT — 1 drifted … reconcile is recorded to the ledger (exit 0 if none, 1 if drift)
196
+ ```
197
+
198
+ See [Self-Coding Bench](docs/self-coding-bench.md) for live reliability data across five models.
199
+
200
+ ---
201
+
202
+ ## CLI reference
203
+
204
+ ```
205
+ $ korgex --help
206
+
207
+ usage: korgex [-h] SUBCOMMAND ...
208
+
209
+ korgex — autonomous coding agent. Pass a naked prompt to run the agent,
210
+ or use a subcommand.
211
+
212
+ positional arguments:
213
+ SUBCOMMAND
214
+ serve Start dashboard + open VS Code with the sidecar.
215
+ dashboard Start the web dashboard only.
216
+ init Install Python deps + compile the VS Code extension.
217
+ status Check if the backend is running.
218
+ stop Stop the running backend.
219
+ install-extension
220
+ Install the .vsix into VS Code.
221
+ verify Prove the cognition ledger is intact (hash-chain proof).
222
+ drift Scan memories for drift vs their source baselines.
223
+ ```
224
+
225
+ ### Naked-prompt invocation (the default)
226
+
227
+ Any non-subcommand argument is treated as a prompt:
228
+
229
+ ```bash
230
+ korgex "create a hello.txt with the text 'hi'"
231
+ korgex --mode plan "redesign the data model"
232
+ korgex --model gpt-4o "write the test for this fix"
233
+ korgex --quiet "list all functions called from main()"
234
+ ```
235
+
236
+ ### Flags
237
+
238
+ | Flag | Purpose |
239
+ |---|---|
240
+ | `--model MODEL` | Override the model (e.g. `claude-sonnet-4-6`, `gpt-4o`, `openai/gpt-4o-mini`). Always wins over `--mode`. |
241
+ | `--mode {plan,execute,explore,review,debug,research}` | Mode-based model selection (see [Multi-model routing](#multi-model-routing)). |
242
+ | `--mcp` | Load MCP servers from `mcp.json` at startup. |
243
+ | `--quiet` / `-q` | Disable the streaming TUI. Only the final result text prints. Use this in pipes, scripts, CI. |
244
+ | `--resume` | Not yet implemented — exits with code 2 so scripts don't silently lose state. |
245
+
246
+ ### Subcommands
247
+
248
+ | Subcommand | Behavior |
249
+ |---|---|
250
+ | `korgex serve` | Starts the FastAPI dashboard on `localhost:8090` and opens VS Code with the sidecar. |
251
+ | `korgex dashboard` | Starts the dashboard only (no editor). |
252
+ | `korgex init` | One-shot setup: pip-installs deps, npm-installs + compiles the VS Code extension. |
253
+ | `korgex status` | Reports whether the background backend is running. |
254
+ | `korgex stop` | Terminates the background backend (SIGTERM, then SIGKILL if needed). |
255
+ | `korgex install-extension` | Installs the compiled `.vsix` into your local VS Code. |
256
+ | `korgex verify [journal]` | Verify the ledger's hash-chain is intact — proves the recorded run wasn't edited, deleted, reordered, or spliced (exit 0/1, CI-friendly). |
257
+ | `korgex drift` | Scan persistent memories for drift against their recorded source baselines (exit 0/1). |
258
+
259
+ ---
260
+
261
+ ## Tools
262
+
263
+ The agent sees ~12 high-level tools (Claude-Code style), each with a deep description that includes usage guidance, edge cases, and anti-patterns:
264
+
265
+ | Tool | Purpose |
266
+ |---|---|
267
+ | **Read** | Read a file from disk, optionally with line offset/limit. |
268
+ | **Write** | Create a new file or overwrite an existing one with full content. |
269
+ | **Edit** | Surgical string replacement in an existing file. Auto-converted to SEARCH/REPLACE block internally. |
270
+ | **Bash** | Execute a shell command with timeout. |
271
+ | **Grep** | Search file contents by regex (uses ripgrep where available). |
272
+ | **Glob** | List files matching a pattern. |
273
+ | **Agent** | Delegate a sub-task to a specialized sub-agent. |
274
+ | **AskUserQuestion** | Ask the user a clarifying question with optional multiple-choice. |
275
+ | **TaskCreate** | Track multi-step work via a task list. |
276
+ | **Skill** | Invoke an installed skill by name. |
277
+ | **ToolSearch** | Discover tools at runtime by keyword. |
278
+
279
+ Under the hood these route to 49+ internal handlers (file ops, git, GitHub API, sandbox execution, web fetch, dependency analysis, profiler, etc.) — see `src/tools_impl.py`.
280
+
281
+ ---
282
+
283
+ ## Environment variables
284
+
285
+ | Variable | Purpose | Default |
286
+ |---|---|---|
287
+ | `ANTHROPIC_API_KEY` | Used when the model name contains "claude" or starts with "anthropic/". | — |
288
+ | `OPENAI_API_KEY` | Used for any non-Anthropic model. | — |
289
+ | `KORGEX_API_KEY` | Generic fallback if a provider-specific key isn't set. Useful for OpenRouter. | — |
290
+ | `KORGEX_API_URL` | Base URL for OpenAI-compatible endpoints (set for OpenRouter, Ollama, etc.). | `https://api.openai.com/v1` |
291
+ | `KORGEX_MODEL` | Default model when neither `--model` nor `--mode` is given. | `claude-sonnet-4-6` |
292
+ | `KORGEX_MAX_ITERATIONS` | Maximum agent loop iterations before giving up. | `30` |
293
+ | `KORGEX_MCP` | Set to `1` to auto-load MCP servers from `mcp.json` (equivalent to `--mcp`). | unset |
294
+ | `KORGEX_SANDBOX` | `modal` \| `docker` \| `direct` \| `auto`. Controls bash sandbox isolation. | `auto` |
295
+ | `KORGEX_PROVIDER` | Force the transport (`openai` \| `anthropic`), overriding model-id autodetect — e.g. drive `anthropic/*` or `google/*` models through OpenRouter. | autodetect |
296
+ | `KORG_JOURNAL_PATH` | Path to the durable JSONL ledger journal; content-addressed blobs are written beside it. | `.korg/journal.jsonl` |
297
+ | `KORG_LEDGER_HMAC_KEY` | If set, the ledger hash-chain is HMAC-keyed — tamper-*proof*, not just tamper-evident. | unset |
298
+
299
+ Provider-detection rule: if the model id contains `"claude"` or starts with `"anthropic/"`, the agent uses the Anthropic SDK. Otherwise it uses the OpenAI SDK (which works against OpenAI, OpenRouter, Ollama, DeepSeek, vLLM, and anything else that speaks OpenAI's chat-completions protocol). Set `KORGEX_PROVIDER=openai` to force the OpenAI-compatible transport even for a `claude`/`anthropic/` model id — e.g. to drive Claude through OpenRouter.
300
+
301
+ ---
302
+
303
+ ## Multi-model routing
304
+
305
+ `--mode` picks a model appropriate for the work type:
306
+
307
+ | Mode | Model | Generation params |
308
+ |---|---|---|
309
+ | `plan` | Opus 4.7 | `max_tokens=64000`, `thinking={budget_tokens: 20000}`, `temperature=0.7` |
310
+ | `execute` | Sonnet 4.6 | `max_tokens=64000`, `temperature=0.3` |
311
+ | `explore` | Opus 4.7 | `max_tokens=32000`, `temperature=0.5` |
312
+ | `review` | Sonnet 4.6 | `max_tokens=16000`, `temperature=0.3` |
313
+ | `debug` | Haiku 4.5 | `max_tokens=16000`, `temperature=0.2` |
314
+ | `research` | Opus 4.7 | `max_tokens=32000`, `temperature=0.7` |
315
+
316
+ Explicit `--model` always wins over `--mode`. Default (neither set) is Sonnet 4.6.
317
+
318
+ ```bash
319
+ korgex --mode plan "architect a multi-tenant billing system"
320
+ korgex --mode debug "trace why this 500 is happening"
321
+ korgex --mode execute "implement the plan we just made"
322
+ ```
323
+
324
+ ---
325
+
326
+ ## MCP integration
327
+
328
+ korgex includes a native MCP (Model Context Protocol) client. Any MCP server in your `mcp.json` becomes part of the agent's tool surface.
329
+
330
+ ### As an MCP server (verify / audit / import from any host)
331
+
332
+ korgex also *is* an MCP server — `korgex mcp-server` exposes the verifiable-cognition substrate over JSON-RPC/stdio so any MCP host (Claude Desktop, Cursor, …) can call:
333
+
334
+ - **`korg_verify`** — prove a korg-ledger journal is tamper-evident-intact;
335
+ - **`korg_audit`** — audit the host agent's own Claude Code logs (import + verify), zero-config;
336
+ - **`korg_import`** — import a vendor session transcript into a verifiable chained ledger.
337
+
338
+ Wire it into your host's MCP config:
339
+
340
+ ```json
341
+ { "mcpServers": { "korg-ledger": { "command": "korgex", "args": ["mcp-server"] } } }
342
+ ```
343
+
344
+ ### Configure
345
+
346
+ Place an `mcp.json` in your repo root (matches the VS Code convention):
347
+
348
+ ```json
349
+ {
350
+ "mcpServers": {
351
+ "github": {
352
+ "command": "npx",
353
+ "args": ["-y", "@modelcontextprotocol/server-github"],
354
+ "env": {
355
+ "GITHUB_TOKEN": "ghp_..."
356
+ }
357
+ },
358
+ "filesystem": {
359
+ "command": "npx",
360
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
361
+ }
362
+ }
363
+ }
364
+ ```
365
+
366
+ ### Use
367
+
368
+ ```bash
369
+ korgex --mcp "create a GitHub issue summarizing today's bug"
370
+ ```
371
+
372
+ The agent discovers each server's tools at startup, registers them into the user-facing tool list, and routes calls back to the originating server. Server failures are logged and skipped — they never crash the agent.
373
+
374
+ ---
375
+
376
+ ## Streaming TUI
377
+
378
+ When stdout is a TTY, the agent streams output live via [Rich](https://rich.readthedocs.io/):
379
+
380
+ - **Thinking blocks** render in dimmed italic gray (Anthropic only)
381
+ - **Text** streams character-by-character
382
+ - **Tool calls** show a transient spinner: `⠋ Read(file_path=src/foo.py)`
383
+ - **Diffs** for Edit/Write on critical files prompt `[y/N]` confirmation
384
+ - **Ctrl+C** sends a graceful interrupt; double Ctrl+C force-kills
385
+
386
+ Streaming auto-disables when stdout is piped (e.g. `korgex "..." | tee log`), in CI, or with `--quiet`.
387
+
388
+ OpenAI/OpenRouter streaming works just like Anthropic: text deltas pipe through the same renderer, tool-call deltas are accumulated across chunks into a complete tool call.
389
+
390
+ ---
391
+
392
+ ## VS Code sidecar
393
+
394
+ `korgex-vscode/` contains a TypeScript extension that adds four commands (Cmd+Shift+P → "korgex"):
395
+
396
+ | Command | Action |
397
+ |---|---|
398
+ | `korgex: Refactor Current File` | POSTs to `/api/swarm/refactor` |
399
+ | `korgex: Run TDD Healer on Current File` | POSTs to `/api/swarm/heal` |
400
+ | `korgex: Profile Test Suite` | POSTs to `/api/swarm/profile` |
401
+ | `korgex: Open the Swarm Dashboard` | Opens `http://localhost:8090/dashboard` |
402
+
403
+ To install:
404
+
405
+ ```bash
406
+ korgex init # compiles the .vsix
407
+ korgex install-extension # installs it into your local VS Code
408
+ ```
409
+
410
+ The extension connects to `http://localhost:8090` by default, which matches the dashboard port. Adjust via the VS Code setting `korgex.backendUrl` if you change the port.
411
+
412
+ ---
413
+
414
+ ## Dashboard API
415
+
416
+ `korgex serve` (or `korgex dashboard`) starts a FastAPI server on `:8090` with these endpoints:
417
+
418
+ | Route | Method | Purpose |
419
+ |---|---|---|
420
+ | `/` | GET | HTML dashboard |
421
+ | `/health` | GET | `{status: "ok"}` for liveness checks |
422
+ | `/api/state` | GET | Current dashboard state (current task, plan, logs) |
423
+ | `/api/new-task` | POST `{description}` | Start a new agent task in a background thread |
424
+ | `/api/approve-plan` | POST | Approve a pending plan |
425
+ | `/api/send-feedback` | POST `{feedback}` | Send mid-task feedback to the agent |
426
+ | `/api/swarm/refactor` | POST `{filepath}` | Spin a one-shot agent that refactors the given file |
427
+ | `/api/swarm/heal` | POST `{filepath, command}` | Spin a one-shot agent that fixes failing tests |
428
+ | `/api/swarm/profile` | POST `{command}` | Run `cProfile` via `PerformanceProfiler` and return top-N slowest functions |
429
+ | `/ws/logs` | WebSocket | Live log stream |
430
+
431
+ All swarm endpoints are synchronous (FastAPI thread-pools them) and return JSON: `{success, output, ...}` or `{success: false, error}` if a key is missing or the agent crashes.
432
+
433
+ ---
434
+
435
+ ## Architecture
436
+
437
+ ### Tool routing — Claude-Code-style → Jules-style
438
+
439
+ ```
440
+ User tool call (LLM-visible): Internal handler (in src/tools_impl.py):
441
+ ───────────────────────────── ────────────────────────────────────────
442
+ Read(file_path=...) → tool_read_file(filepath=..., context=...)
443
+ Write(file_path=..., ...) → tool_write_file(filepath=..., ...)
444
+ Edit(file_path, old, new) → tool_replace_with_git_merge_diff(
445
+ filepath=...,
446
+ merge_diff="<<<<<<< SEARCH\n...")
447
+ Bash(command=...) → tool_run_in_bash_session(command=...)
448
+ ```
449
+
450
+ The router (`src/tool_abstraction.py`):
451
+
452
+ - Looks up the user-facing tool name in `_TOOL_ROUTING`
453
+ - Applies a `param_map` (rename kwargs like `file_path → filepath`)
454
+ - Or applies a custom `adapter` for structural transforms (Edit → SEARCH/REPLACE)
455
+ - Filters out kwargs the handler doesn't accept (so schema fields like `Read.offset` don't crash handlers that haven't grown them yet)
456
+ - Auto-injects `context={'repo_root': cwd}`
457
+ - Catches exceptions and returns `{"error": ...}` so a single tool failure never kills the agent loop
458
+
459
+ MCP-sourced tools bypass `_TOOL_ROUTING` and dispatch through `MCPServerManager.call_tool()` instead.
460
+
461
+ ### Provider branching
462
+
463
+ ```
464
+ KorgexAgent(model="claude-sonnet-4-6") → provider="anthropic"
465
+ KorgexAgent(model="anthropic/claude-...")→ provider="anthropic" (OpenRouter)
466
+ KorgexAgent(model="gpt-4o") → provider="openai"
467
+ KorgexAgent(model="openai/gpt-4o-mini") → provider="openai" (OpenRouter)
468
+ KorgexAgent(model="llama3:8b") → provider="openai" (Ollama)
469
+ ```
470
+
471
+ Each provider gets:
472
+ - Its own tool-schema shape
473
+ - Its own request method (`messages.create` vs `chat.completions.create`)
474
+ - Its own streaming chunk parser
475
+ - Its own assistant/tool-result message format
476
+
477
+ ### Plan-first system prompt
478
+
479
+ The default system prompt directs the agent to plan, verify, diagnose-before-changing, and never modify build artifacts. See `SYSTEM_PROMPT` in `src/agent.py`.
480
+
481
+ ---
482
+
483
+ ## Project structure
484
+
485
+ ```
486
+ korgex/
487
+ ├── src/
488
+ │ ├── agent.py # KorgexAgent class — main loop, provider branching, streaming
489
+ │ ├── cli.py # argparse dispatch (naked-prompt + subcommands)
490
+ │ ├── tool_abstraction.py # USER_TOOLS registry + router + MCP integration
491
+ │ ├── tools_impl.py # ~49 internal handlers (tool_read_file, tool_bash, ...)
492
+ │ ├── tool_base.py # Legacy Jules-style tool registry (still in use)
493
+ │ ├── interactive.py # Streaming TUI: Rich-based renderer, spinner, interrupt handler
494
+ │ ├── model_router.py # Mode → model mapping (plan/execute/debug/...)
495
+ │ ├── mcp_client.py # Native MCP client (stdio JSON-RPC 2.0)
496
+ │ ├── dashboard.py # FastAPI dashboard + /api/swarm/* endpoints
497
+ │ ├── sandbox.py # Docker / Modal / direct subprocess sandbox
498
+ │ ├── swarm.py # Multi-agent swarm orchestration
499
+ │ ├── self_healing.py # TDD self-healing loop
500
+ │ ├── profiler.py # cProfile-based perf profiler
501
+ │ ├── dependency_graph.py # AST-based import/symbol graph
502
+ │ ├── context_compression.py# AST minimization for large files
503
+ │ ├── diff_engine.py # SEARCH/REPLACE diff parser
504
+ │ ├── github_api.py # GitHub PR / issue helpers
505
+ │ ├── memory.py # Cross-session memory (planned)
506
+ │ ├── vision.py # Image attachment handling
507
+ │ └── ...
508
+ ├── korgex-vscode/ # VS Code sidecar extension (TypeScript)
509
+ │ ├── src/extension.ts # 4 registered commands
510
+ │ ├── korgex-sidecar.vsix # Compiled artifact (after `korgex init`)
511
+ │ └── package.json
512
+ ├── tests/
513
+ │ └── test_bridge.py # 27 tests covering router, providers, MCP, streaming, dashboard
514
+ ├── docs/ # CLI reference, comparison, getting-started
515
+ ├── scripts/ # Build helpers (package-vsix.sh, MCP conformance test)
516
+ ├── packages/
517
+ │ └── mcp-native-client/ # Standalone reusable MCP client package
518
+ ├── dist/ # Built wheels and sdists
519
+ ├── mcp.json # Default MCP server config
520
+ ├── pyproject.toml # Package metadata
521
+ └── requirements.txt # Pinned runtime deps
522
+ ```
523
+
524
+ ---
525
+
526
+ ## Development
527
+
528
+ ### Setup
529
+
530
+ ```bash
531
+ git clone https://github.com/New1Direction/korgex.git
532
+ cd korgex
533
+
534
+ # Create venv (uv recommended; falls back to python -m venv if you don't have uv)
535
+ uv venv .venv
536
+ source .venv/bin/activate
537
+
538
+ # Install with dev extras (pytest, twine, build, ruff)
539
+ uv pip install -e ".[dev]"
540
+
541
+ # Or with plain pip
542
+ pip install -e ".[dev]"
543
+ ```
544
+
545
+ ### Run the agent in editable mode
546
+
547
+ After `pip install -e .`, `korgex` is on your PATH and reflects live source edits:
548
+
549
+ ```bash
550
+ export ANTHROPIC_API_KEY=sk-ant-...
551
+ korgex "explain what src/agent.py does"
552
+ ```
553
+
554
+ ### Code style
555
+
556
+ The project uses [ruff](https://docs.astral.sh/ruff/):
557
+
558
+ ```bash
559
+ ruff check src/
560
+ ruff format src/
561
+ ```
562
+
563
+ ---
564
+
565
+ ## Testing
566
+
567
+ ```bash
568
+ # Run the full test suite
569
+ pytest tests/ -v
570
+
571
+ # Run a specific test
572
+ pytest tests/test_bridge.py::test_write_routes_to_disk -v
573
+
574
+ # With coverage
575
+ pytest tests/ --cov=src --cov-report=term-missing
576
+ ```
577
+
578
+ ### What the tests cover (27 cases)
579
+
580
+ - **Router** (5): Read/Write/Edit route to handlers and produce filesystem effects; unknown tools return errors gracefully; the Edit adapter constructs valid SEARCH/REPLACE blocks; unsupported kwargs (Read.offset/limit) are filtered, not crashed.
581
+ - **Provider schemas** (4): Anthropic and OpenAI tool-schema shapes are correct; OpenRouter `anthropic/...` IDs are detected; missing API keys raise `RuntimeError` cleanly.
582
+ - **Mode routing** (5): `--mode plan` picks Opus, `--mode execute` picks Sonnet, `--mode debug` picks Haiku, explicit `--model` overrides, default falls back to Sonnet.
583
+ - **MCP** (3): MCP tools register into `USER_TOOLS` correctly; the router dispatches them to the MCP manager; full connect→discover→call→disconnect round-trip against a real stub subprocess.
584
+ - **Streaming** (5): Interactive mode auto-detects TTY; sessions are lazily constructed; OpenAI streaming accumulates text + multi-chunk tool calls into the right shape; text-only responses pass through.
585
+ - **Dashboard** (5): `/health` returns ok; swarm endpoints reject missing args with 400; swarm endpoints return clean JSON errors when no API key is set.
586
+
587
+ No live LLM calls in the test suite — everything is unit-tested.
588
+
589
+ ---
590
+
591
+ ## Building & releasing
592
+
593
+ ### Build the wheel and sdist
594
+
595
+ ```bash
596
+ rm -rf dist build
597
+ python -m build
598
+ # → dist/korgex-X.Y.Z-py3-none-any.whl
599
+ # → dist/korgex-X.Y.Z.tar.gz
600
+
601
+ # Validate PyPI metadata
602
+ python -m twine check dist/*
603
+ ```
604
+
605
+ ### Cut a GitHub Release
606
+
607
+ ```bash
608
+ gh release create vX.Y.Z \
609
+ dist/korgex-X.Y.Z-py3-none-any.whl \
610
+ dist/korgex-X.Y.Z.tar.gz \
611
+ --title "korgex X.Y.Z" \
612
+ --notes "Release notes here"
613
+ ```
614
+
615
+ ### Publish to PyPI
616
+
617
+ ```bash
618
+ python -m twine upload dist/*
619
+ # username: __token__
620
+ # password: pypi-... (token from https://pypi.org/manage/account/token/)
621
+ ```
622
+
623
+ For the first upload of a new package, use an "Entire account" scoped token. After the package exists on PyPI, project-scoped tokens work.
624
+
625
+ ---
626
+
627
+ ## Troubleshooting
628
+
629
+ ### `korgex: No API key found`
630
+
631
+ Set one of `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `KORGEX_API_KEY` (with `KORGEX_API_URL` for non-OpenAI endpoints).
632
+
633
+ ### `ModuleNotFoundError: No module named 'anthropic'` (or `openai`, or `rich`)
634
+
635
+ The dependency wasn't installed. Either:
636
+
637
+ ```bash
638
+ pip install -e . # picks up everything from pyproject.toml
639
+ # or
640
+ pip install anthropic openai rich
641
+ ```
642
+
643
+ ### Agent loops forever on tool calls
644
+
645
+ The default `KORGEX_MAX_ITERATIONS` is 30. If the agent genuinely can't finish:
646
+
647
+ ```bash
648
+ export KORGEX_MAX_ITERATIONS=10 # cap it harder
649
+ korgex --quiet "..." # see only the final state
650
+ ```
651
+
652
+ ### `--mcp` takes a long time to start
653
+
654
+ The MCP client connects to each server synchronously at startup and waits up to 60s per server for the handshake. If your `mcp.json` references unreachable servers (missing `GITHUB_TOKEN`, `npx` not installed, network blocked), each one times out before being skipped. Remove unreachable entries from `mcp.json`, or reduce the per-server `timeout` value.
655
+
656
+ ### Streaming TUI swallows my prompt's output
657
+
658
+ `korgex "..."` streams to stdout. If you need machine-readable output (e.g. piping to `jq`), use `--quiet`:
659
+
660
+ ```bash
661
+ korgex --quiet "..." | tee transcript.txt
662
+ ```
663
+
664
+ ### `403 Forbidden` from `twine upload`
665
+
666
+ For a brand-new package on PyPI, you need an **"Entire account"** scoped token, not a project-scoped one. Project-scoped tokens can't create a package they don't yet own. Re-create the token at https://pypi.org/manage/account/token/ with the wider scope, upload, then narrow the token for future releases.
667
+
668
+ ### VS Code extension commands do nothing
669
+
670
+ The extension POSTs to `http://localhost:8090/api/swarm/*` by default (matches the dashboard). Make sure:
671
+ 1. The backend is running: `korgex serve` or `korgex dashboard`
672
+ 2. The `korgex.backendUrl` setting in VS Code matches the port korgex is listening on (default `8090` on both sides)
673
+
674
+ ---
675
+
676
+ ## Known limitations
677
+
678
+ These exist today; PRs welcome.
679
+
680
+ - **OpenAI streaming has fewer rendered events than Anthropic.** Anthropic emits thinking blocks, content-block-start/stop, and message-delta usage events; OpenAI emits only text and tool-call chunks. The TUI renders both correctly but is richer for Anthropic.
681
+ - **`--resume` is not yet implemented.** Exits with code 2 rather than silently starting fresh, so scripts and CI that rely on it fail loudly.
682
+ - **Memory module is a stub.** `src/memory.py` exists but isn't wired into the agent loop.
683
+ - **Swarm endpoints share the agent's single-context loop.** They don't actually run sub-agents in parallel sandboxes (the `swarm.py` module supports it, but the `/api/swarm/*` endpoints don't use it yet).
684
+ - **TDD self-healing requires explicit invocation.** It's not yet triggered automatically on test failure.
685
+ - **Dashboard authentication is not implemented.** Don't expose port 8090 publicly without putting a reverse proxy with auth in front of it.
686
+ - **Dependency-graph and AST-compression tools (`src/dependency_graph.py`, `src/context_compression.py`) are not yet bridged into `USER_TOOLS`.** They're callable directly but not exposed to the agent.
687
+
688
+ ---
689
+
690
+ ## License
691
+
692
+ MIT — see [LICENSE](LICENSE).
693
+
694
+ ---
695
+
696
+ ## Related projects
697
+
698
+ - **[korg](https://github.com/New1Direction/korg)** — deterministic cognitive runtime for AI agents (Rust). korgex v0.3.0+ records every tool call into a korg ledger via the `korg_bridge` PyO3 extension; the ledger is what korg-tui rewinds and korgchat builds on.
699
+ - **[korgchat](https://github.com/New1Direction/korgchat)** — chat product built on the same ledger; runs in the same `.korg/journal.json` as a korgex agent run, so you can interleave chat and autonomous edits.
700
+ - **[thumper](https://github.com/New1Direction/thumper)** — local execution + recovery substrate that runs under korgex; pre-warmed sandbox pools, persistent LSP, sub-second compile-error healing.
701
+ - **[Model Context Protocol](https://modelcontextprotocol.io/)** — the open MCP standard korgex implements.