vamp-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.
Files changed (69) hide show
  1. vamp_cli-0.1.0/LICENSE +21 -0
  2. vamp_cli-0.1.0/PKG-INFO +317 -0
  3. vamp_cli-0.1.0/README.md +263 -0
  4. vamp_cli-0.1.0/pyproject.toml +53 -0
  5. vamp_cli-0.1.0/setup.cfg +4 -0
  6. vamp_cli-0.1.0/src/vamp_cli/__init__.py +0 -0
  7. vamp_cli-0.1.0/src/vamp_cli/agent/__init__.py +0 -0
  8. vamp_cli-0.1.0/src/vamp_cli/agent/context_sync.py +72 -0
  9. vamp_cli-0.1.0/src/vamp_cli/agent/graph.py +159 -0
  10. vamp_cli-0.1.0/src/vamp_cli/agent/instructions.py +18 -0
  11. vamp_cli-0.1.0/src/vamp_cli/agent/nodes.py +375 -0
  12. vamp_cli-0.1.0/src/vamp_cli/agent/roles.py +8 -0
  13. vamp_cli-0.1.0/src/vamp_cli/agent/runtime/__init__.py +0 -0
  14. vamp_cli-0.1.0/src/vamp_cli/agent/runtime/runtime.py +133 -0
  15. vamp_cli-0.1.0/src/vamp_cli/agent/state.py +55 -0
  16. vamp_cli-0.1.0/src/vamp_cli/agent/status.py +17 -0
  17. vamp_cli-0.1.0/src/vamp_cli/config/__init__.py +0 -0
  18. vamp_cli-0.1.0/src/vamp_cli/config/loader.py +152 -0
  19. vamp_cli-0.1.0/src/vamp_cli/config/schema.py +82 -0
  20. vamp_cli-0.1.0/src/vamp_cli/llm/__init__.py +0 -0
  21. vamp_cli-0.1.0/src/vamp_cli/llm/adapter.py +52 -0
  22. vamp_cli-0.1.0/src/vamp_cli/llm/adapter_registry.py +26 -0
  23. vamp_cli-0.1.0/src/vamp_cli/llm/debug_callbacks.py +18 -0
  24. vamp_cli-0.1.0/src/vamp_cli/llm/router.py +247 -0
  25. vamp_cli-0.1.0/src/vamp_cli/llm/usage.py +170 -0
  26. vamp_cli-0.1.0/src/vamp_cli/logging_setup/logging_setup.py +37 -0
  27. vamp_cli-0.1.0/src/vamp_cli/main.py +1023 -0
  28. vamp_cli-0.1.0/src/vamp_cli/persistence/__init__.py +29 -0
  29. vamp_cli-0.1.0/src/vamp_cli/persistence/compaction.py +372 -0
  30. vamp_cli-0.1.0/src/vamp_cli/persistence/emitter.py +371 -0
  31. vamp_cli-0.1.0/src/vamp_cli/persistence/event_log.py +303 -0
  32. vamp_cli-0.1.0/src/vamp_cli/persistence/fork.py +81 -0
  33. vamp_cli-0.1.0/src/vamp_cli/persistence/loader.py +616 -0
  34. vamp_cli-0.1.0/src/vamp_cli/persistence/transcript.py +160 -0
  35. vamp_cli-0.1.0/src/vamp_cli/prompts/prompts.py +182 -0
  36. vamp_cli-0.1.0/src/vamp_cli/sandbox/__init__.py +0 -0
  37. vamp_cli-0.1.0/src/vamp_cli/sandbox/base.py +22 -0
  38. vamp_cli-0.1.0/src/vamp_cli/sandbox/config.py +16 -0
  39. vamp_cli-0.1.0/src/vamp_cli/sandbox/docker.py +293 -0
  40. vamp_cli-0.1.0/src/vamp_cli/sandbox/manager.py +31 -0
  41. vamp_cli-0.1.0/src/vamp_cli/sandbox/result.py +14 -0
  42. vamp_cli-0.1.0/src/vamp_cli/sandbox/terminal.py +151 -0
  43. vamp_cli-0.1.0/src/vamp_cli/tools/__init__.py +0 -0
  44. vamp_cli-0.1.0/src/vamp_cli/tools/base.py +44 -0
  45. vamp_cli-0.1.0/src/vamp_cli/tools/diagnostic.py +120 -0
  46. vamp_cli-0.1.0/src/vamp_cli/tools/execute_cmd.py +16 -0
  47. vamp_cli-0.1.0/src/vamp_cli/tools/files.py +652 -0
  48. vamp_cli-0.1.0/src/vamp_cli/tools/registry.py +163 -0
  49. vamp_cli-0.1.0/src/vamp_cli/tools/tools_classes.py +622 -0
  50. vamp_cli-0.1.0/src/vamp_cli/utils/__init__.py +0 -0
  51. vamp_cli-0.1.0/src/vamp_cli/utils/error_codes.py +7 -0
  52. vamp_cli-0.1.0/src/vamp_cli/utils/ignore.py +36 -0
  53. vamp_cli-0.1.0/src/vamp_cli/utils/sha_256.py +32 -0
  54. vamp_cli-0.1.0/src/vamp_cli/utils/token_tracker.py +31 -0
  55. vamp_cli-0.1.0/src/vamp_cli/workspace/__init__.py +0 -0
  56. vamp_cli-0.1.0/src/vamp_cli/workspace/workspace.py +16 -0
  57. vamp_cli-0.1.0/src/vamp_cli.egg-info/PKG-INFO +317 -0
  58. vamp_cli-0.1.0/src/vamp_cli.egg-info/SOURCES.txt +67 -0
  59. vamp_cli-0.1.0/src/vamp_cli.egg-info/dependency_links.txt +1 -0
  60. vamp_cli-0.1.0/src/vamp_cli.egg-info/entry_points.txt +2 -0
  61. vamp_cli-0.1.0/src/vamp_cli.egg-info/requires.txt +14 -0
  62. vamp_cli-0.1.0/src/vamp_cli.egg-info/top_level.txt +1 -0
  63. vamp_cli-0.1.0/tests/test_list_dir.py +27 -0
  64. vamp_cli-0.1.0/tests/test_loader.py +23 -0
  65. vamp_cli-0.1.0/tests/test_model_fallbacks.py +81 -0
  66. vamp_cli-0.1.0/tests/test_persistence.py +30 -0
  67. vamp_cli-0.1.0/tests/test_registry_async.py +27 -0
  68. vamp_cli-0.1.0/tests/test_sandbox_roundtrip.py +51 -0
  69. vamp_cli-0.1.0/tests/test_system_verification.py +172 -0
vamp_cli-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Satyam Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,317 @@
1
+ Metadata-Version: 2.4
2
+ Name: vamp-cli
3
+ Version: 0.1.0
4
+ Summary: CLI coding agent.
5
+ Author-email: Satyam Kumar <satkr2208@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Satyam Kumar
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/satkr22/vamp-cli
29
+ Project-URL: Repository, https://github.com/satkr22/vamp-cli
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Developers
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.11
35
+ Classifier: Programming Language :: Python :: 3.12
36
+ Requires-Python: >=3.11
37
+ Description-Content-Type: text/markdown
38
+ License-File: LICENSE
39
+ Requires-Dist: pydantic
40
+ Requires-Dist: rich
41
+ Requires-Dist: typer
42
+ Requires-Dist: click
43
+ Requires-Dist: orjson
44
+ Requires-Dist: pytest
45
+ Requires-Dist: pyyaml
46
+ Requires-Dist: pathspec
47
+ Requires-Dist: prompt-toolkit
48
+ Requires-Dist: langchain-core
49
+ Requires-Dist: langgraph
50
+ Requires-Dist: langchain-litellm
51
+ Requires-Dist: langgraph-checkpoint-sqlite
52
+ Requires-Dist: aiosqlite
53
+ Dynamic: license-file
54
+
55
+ # VAMP-CLI
56
+
57
+ VAMP-CLI is an interactive coding agent for working in a local repository. It combines a planner, a coder, model fallbacks, workspace-aware file tools, and a Docker-backed command sandbox in one terminal application.
58
+
59
+ The agent can inspect and edit files, search a codebase, run commands, maintain a task list, and ask for confirmation before executing potentially dangerous operations.
60
+
61
+ > **Status:** VAMP-CLI is an early-stage project. The interfaces and default model configuration may change.
62
+
63
+ ## Highlights
64
+
65
+ - Interactive terminal UI launched with the `vamp` command.
66
+ - Two operating modes:
67
+ - **Normal mode**: work directly with the coding agent.
68
+ - **Plan mode**: have the planner produce a plan and approve it before implementation.
69
+ - Workspace-scoped file operations and searches.
70
+ - Docker sandbox for command execution, with CPU, memory, process, timeout, and workspace-boundary limits.
71
+ - Human-in-the-loop approval for plan execution and commands classified as dangerous.
72
+ - Configurable models, profiles, prompts, streaming, reasoning, and model fallbacks.
73
+ - Token usage tracking and LangGraph-based agent orchestration.
74
+ - **Session persistence**: all conversations are durably logged as append-only JSONL with per-session SQLite checkpoints.
75
+ - **Session resumption**: resume any past session exactly where it left off, including parked interrupts.
76
+ - **Session listing**: list all past sessions with timestamps and first-message previews.
77
+ - **Forking**: rewind to any past user message and branch off a new conversation path without deleting the original.
78
+ - **Branch switching**: view and switch between conversation branches within a session.
79
+ - **Conversation compaction**: automatically or manually summarize early turns to stay within model context limits.
80
+
81
+ ## Requirements
82
+
83
+ - Python 3.11 or newer
84
+ - Docker Engine or Docker Desktop, running and accessible to the current user
85
+ - An API key for each model configured in `src/vamp_cli/config/config.yaml`
86
+
87
+ The first run automatically builds the `vamp-sandbox:latest` image from [`src/vamp_cli/sandbox/Dockerfile`](src/vamp_cli/sandbox/Dockerfile) when it is not already available locally. The image includes Python, Node.js, Git, `ripgrep`, `fd`, and common build tools.
88
+
89
+ ## Installation
90
+
91
+ Create and activate a virtual environment, then install the project (all dependencies will be installed itself):
92
+
93
+ ```bash
94
+ python3 -m venv .venv
95
+ source .venv/bin/activate
96
+ python -m pip install --upgrade pip
97
+ python -m pip install -e .
98
+ ```
99
+
100
+ Confirm that Docker is available before starting the agent:
101
+
102
+ ```bash
103
+ docker info
104
+ ```
105
+
106
+ ## Configuration
107
+
108
+ Model and profile configuration lives in [`src/vamp_cli/config/config.yaml`](src/vamp_cli/config/config.yaml). API keys are read from environment variables named by each model's `api_key_env` field; keys are not read from YAML values directly.
109
+
110
+ The checked-in default configuration defines `qwen` and `openai`, so both variables must be present unless you edit the configuration to remove or replace one of those models:
111
+
112
+ ```bash
113
+ export DASHSCOPE_API_KEY="your-dashscope-key"
114
+ export OPENAI_API_KEY="your-openai-key"
115
+ ```
116
+
117
+ For a different provider, update the model's `model`, optional `api_base`, `api_key_env`, parameters, capabilities, and fallback list in the YAML file. Profiles select the model and the tools available to the planner or coder.
118
+
119
+ ## Running VAMP-CLI
120
+
121
+ Run it from the repository you want the agent to work on:
122
+
123
+ ```bash
124
+ vamp
125
+ ```
126
+
127
+ The current directory becomes the agent workspace and is mounted at `/workspace` inside the sandbox. On startup, VAMP-CLI prints an interactive prompt:
128
+
129
+ ```text
130
+ You:
131
+ ```
132
+
133
+ ### CLI Arguments
134
+
135
+ | Argument | Action |
136
+ | --- | --- |
137
+ | `--resume <id>` or `-r <id>` | Resume a previous session by its ID |
138
+ | `--list` or `-l` | List all past sessions |
139
+
140
+ Examples:
141
+
142
+ ```bash
143
+ # List all past sessions
144
+ vamp --list
145
+
146
+ # Resume a specific session
147
+ vamp --resume 01a145b4-5103-7014-97da-d5ca9c871d68
148
+ ```
149
+
150
+ ### In-Session Commands
151
+
152
+ | Command | Action |
153
+ | --- | --- |
154
+ | `/mode` | Select `plan` or `normal` mode |
155
+ | `/exit` | Stop the session and remove the active sandbox container |
156
+ | `/quit` | Same as `/exit` |
157
+ | `/fork` | Rewind to a previous user message and create a new branch |
158
+ | `/fork <N>` | Fork directly to before message N (non-interactive) |
159
+ | `/branches` | View all branches in the current session and switch between them |
160
+ | `/compact` | Summarize early conversation turns to reduce context usage |
161
+ | `/compact <N>` | Compact keeping the last N turns intact (default: 4) |
162
+ | `/config` | Change configurations of models, coder or planner profiles, and tool access. |
163
+
164
+ When the agent requests approval, answer `yes` to continue or `no` and provide a reason to deny the action. Approvals are used for plan implementation and security-sensitive tool calls such as destructive commands, package installation, or network access.
165
+
166
+ Example requests:
167
+
168
+ ```text
169
+ Inspect this repository and explain how the authentication flow works.
170
+ ```
171
+
172
+ ```text
173
+ /mode
174
+ Select Mode [plan/normal]: plan
175
+ Add tests for the configuration loader, then implement the changes after I approve the plan.
176
+ ```
177
+
178
+ ## Session Persistence & Resumption
179
+
180
+ VAMP-CLI automatically saves every interaction so you can pick up where you left off.
181
+
182
+ ### How Sessions Are Stored
183
+
184
+ Sessions are persisted in `~/.vamp/` using two complementary mechanisms:
185
+
186
+ | Storage | Location | Contents |
187
+ | --- | --- | --- |
188
+ | **JSONL Event Log** | `~/.vamp/sessions/<id>.jsonl` | Append-only, human-readable record of every event (messages, tool calls, mode switches, interrupts, forks, compactions). Each event has a UUID7, parent UUID, and timestamp. |
189
+ | **Head Sidecar** | `~/.vamp/sessions/<id>.head` | Contains the UUID of the current leaf (tip) of the active branch. |
190
+ | **SQLite Checkpoint** | `~/.vamp/checkpoints/<id>.sqlite` | LangGraph's internal graph state — full message objects, plan, todo list, iteration count, and pipeline flags. |
191
+
192
+ ### Resuming a Session
193
+
194
+ When you resume a session with `vamp --resume <id>`, VAMP-CLI:
195
+
196
+ 1. **Loads the event chain** — walks the `parentUuid` linked list from the current leaf back to `session_start`, reconstructing the full conversation history.
197
+ 2. **Recovers CLI state** — replays the events to determine the current mode, whether the session had started, and whether a human-in-the-loop interrupt is still pending.
198
+ 3. **Restores graph state** — reads the authoritative LangGraph state from the SQLite checkpointer. If the checkpointer is missing or corrupted, it falls back to reconstructing state from the JSONL event log (lossy but functional — preserves messages, reasoning content, plan, and todo list).
199
+ 4. **Handles parked interrupts** — if the previous session was interrupted mid-approval (plan approval or dangerous tool verification), the user is immediately prompted to approve or deny before continuing.
200
+
201
+ ### Platform-Independent
202
+
203
+ The `~/.vamp` directory is relative to the user's home directory, so sessions work across different projects and can be listed from anywhere — not just the original workspace directory.
204
+
205
+ ## Forking & Branching
206
+
207
+ The JSONL event log uses a `parentUuid` chain instead of a linear sequence, which means conversations can branch.
208
+
209
+ ### Forking (`/fork`)
210
+
211
+ Forking lets you rewind to any past user message and start a new branch from that point:
212
+
213
+ 1. Type `/fork` to see a numbered list of user messages on the current branch.
214
+ 2. Choose a message number to rewind to *before* that message.
215
+ 3. VAMP-CLI reconstructs the agent state at that point, creates a new LangGraph checkpointer thread, and appends a `fork` event to the JSONL (pointing its `parentUuid` at the fork point).
216
+ 4. The old branch is **never deleted** — it remains intact and can be switched back to at any time.
217
+
218
+ Compact (summarized) messages are also forkable. Forking to a compacted message creates a new branch where the original (unsummarized) messages are restored.
219
+
220
+ ### Branch Switching (`/branches`)
221
+
222
+ Each fork creates a new branch tip (leaf). Type `/branches` to:
223
+
224
+ - See all branch tips with a short preview of the last user message on each.
225
+ - Identify the current branch (marked with `<- current`).
226
+ - Switch to any branch by number — this repoints the `.head` sidecar, reloads state from the JSONL, and switches the checkpointer thread.
227
+
228
+ ## Conversation Compaction
229
+
230
+ Long conversations can exceed the model's context window. Compaction solves this by summarizing early turns.
231
+
232
+ ### Manual Compaction (`/compact`)
233
+
234
+ Type `/compact` to summarize all but the last 4 user turns. Use `/compact <N>` to keep a different number of recent turns. The process:
235
+
236
+ 1. Identifies the range of events to compact (earliest user messages up to, but not including, the keep boundary).
237
+ 2. Builds a transcript from those events.
238
+ 3. Calls the current model to produce a dense, information-rich summary.
239
+ 4. Appends a `compaction` event to the JSONL (original events are kept — they are "shadowed", not deleted).
240
+ 5. Replaces the checkpointer's message channels with the compacted view (summary marker + recent messages only).
241
+
242
+ ### Auto-Compaction
243
+
244
+ When the last prompt's input tokens exceed **90%** of the model's context window (configurable via `DEFAULT_COMPACT_THRESHOLD`), VAMP-CLI automatically runs compaction before the next turn. This keeps sessions healthy without manual intervention.
245
+
246
+ A progress line is printed:
247
+ ```
248
+ [auto-compact] context at 118,000/128,000 tokens (92.2%) — summarizing…
249
+ [auto-compact] done: 24 events, ~9,500 → ~600 tokens
250
+ ```
251
+
252
+ ## How it works
253
+
254
+ 1. `vamp_cli.main` creates a workspace, ignore matcher, tool registry, model router, EventLog, and Docker sandbox.
255
+ 2. The selected planner or coder profile supplies a system prompt and permitted tools.
256
+ 3. LangGraph routes model output through tool classification, approval, and execution nodes.
257
+ 4. File tools operate within the current workspace; terminal commands execute in the mounted Docker container.
258
+ 5. An `EventEmitter` translates LangChain `astream_events` v2 frames into durable JSONL events in real time — `on_chat_model_start/stream/end` → `assistant_message`, `on_tool_start/end/error` → `tool_result`.
259
+ 6. The session retains graph state via LangGraph's SQLite checkpointer so follow-up prompts can continue the current task.
260
+ 7. On resume, the event log and checkpointer are rehydrated together — the event log provides the human-readable chain and fallback state, while the checkpointer is the authoritative source for the LangGraph agent state.
261
+
262
+ The main package areas are:
263
+
264
+ ```text
265
+ src/vamp_cli/
266
+ ├── agent/ LangGraph state, nodes, routing, and runtime profiles
267
+ ├── config/ YAML loading, validation, model/profile configuration
268
+ ├── llm/ LiteLLM-backed model routing, adapters, fallbacks, usage
269
+ ├── prompts/ Planner and coder system prompts
270
+ ├── sandbox/ Docker lifecycle and command execution
271
+ ├── tools/ File, search, diagnostic, todo, and command tools
272
+ ├── workspace/ Workspace path-safety enforcement
273
+ ├── persistence/ Session event log, emitter, loader, fork, compaction, transcript
274
+ └── main.py Interactive CLI entry point
275
+ ```
276
+
277
+ ### Persistence Module Details
278
+
279
+ ```text
280
+ src/vamp_cli/persistence/
281
+ ├── event_log.py Append-only JSONL writer with async queue, UUID7, parent-chain, and .head sidecar
282
+ ├── emitter.py Translates LangChain astream_events v2 → event log entries
283
+ ├── loader.py Session rehydration: load_chain, derive_display_state,
284
+ │ detect_pending_interrupt, reconstruct_agent_state, list_sessions
285
+ ├── fork.py Rewind to a past event and seed a new checkpointer thread
286
+ ├── compaction.py Summarize early turns, plan ranges, auto-compact on threshold
287
+ └── transcript.py Render and print human-readable session transcripts
288
+ ```
289
+
290
+ ## Development and tests
291
+
292
+ Run the automated test suite from the repository root:
293
+
294
+ ```bash
295
+ python -m pytest
296
+ ```
297
+
298
+ Some sandbox and system-verification tests require Docker. The manual security and tool-operation scenarios are documented in [`tests/TEST_VERIFICATION.md`](tests/TEST_VERIFICATION.md).
299
+
300
+ For a quick syntax check:
301
+
302
+ ```bash
303
+ python -m compileall src
304
+ ```
305
+
306
+ ## Security and operational notes
307
+
308
+ - The host project directory is mounted into the sandbox at `/workspace`.
309
+ - The default sandbox limits are 2 CPUs, 2 GB of memory, 256 processes, and 30 seconds per command.
310
+ - Commands are executed with `/bin/bash -lc` inside the container.
311
+ - The default sandbox has network access; set `network_enabled: false` in the sandbox configuration if an offline container is required.
312
+ - Treat model output as untrusted. Review approval prompts carefully, especially for deletion, package installation, credential access, and network operations.
313
+ - The current graph limits an agent run to 15 iterations to prevent unbounded tool loops.
314
+
315
+ ## License
316
+
317
+ VAMP-CLI is released under the [MIT License](LICENSE).
@@ -0,0 +1,263 @@
1
+ # VAMP-CLI
2
+
3
+ VAMP-CLI is an interactive coding agent for working in a local repository. It combines a planner, a coder, model fallbacks, workspace-aware file tools, and a Docker-backed command sandbox in one terminal application.
4
+
5
+ The agent can inspect and edit files, search a codebase, run commands, maintain a task list, and ask for confirmation before executing potentially dangerous operations.
6
+
7
+ > **Status:** VAMP-CLI is an early-stage project. The interfaces and default model configuration may change.
8
+
9
+ ## Highlights
10
+
11
+ - Interactive terminal UI launched with the `vamp` command.
12
+ - Two operating modes:
13
+ - **Normal mode**: work directly with the coding agent.
14
+ - **Plan mode**: have the planner produce a plan and approve it before implementation.
15
+ - Workspace-scoped file operations and searches.
16
+ - Docker sandbox for command execution, with CPU, memory, process, timeout, and workspace-boundary limits.
17
+ - Human-in-the-loop approval for plan execution and commands classified as dangerous.
18
+ - Configurable models, profiles, prompts, streaming, reasoning, and model fallbacks.
19
+ - Token usage tracking and LangGraph-based agent orchestration.
20
+ - **Session persistence**: all conversations are durably logged as append-only JSONL with per-session SQLite checkpoints.
21
+ - **Session resumption**: resume any past session exactly where it left off, including parked interrupts.
22
+ - **Session listing**: list all past sessions with timestamps and first-message previews.
23
+ - **Forking**: rewind to any past user message and branch off a new conversation path without deleting the original.
24
+ - **Branch switching**: view and switch between conversation branches within a session.
25
+ - **Conversation compaction**: automatically or manually summarize early turns to stay within model context limits.
26
+
27
+ ## Requirements
28
+
29
+ - Python 3.11 or newer
30
+ - Docker Engine or Docker Desktop, running and accessible to the current user
31
+ - An API key for each model configured in `src/vamp_cli/config/config.yaml`
32
+
33
+ The first run automatically builds the `vamp-sandbox:latest` image from [`src/vamp_cli/sandbox/Dockerfile`](src/vamp_cli/sandbox/Dockerfile) when it is not already available locally. The image includes Python, Node.js, Git, `ripgrep`, `fd`, and common build tools.
34
+
35
+ ## Installation
36
+
37
+ Create and activate a virtual environment, then install the project (all dependencies will be installed itself):
38
+
39
+ ```bash
40
+ python3 -m venv .venv
41
+ source .venv/bin/activate
42
+ python -m pip install --upgrade pip
43
+ python -m pip install -e .
44
+ ```
45
+
46
+ Confirm that Docker is available before starting the agent:
47
+
48
+ ```bash
49
+ docker info
50
+ ```
51
+
52
+ ## Configuration
53
+
54
+ Model and profile configuration lives in [`src/vamp_cli/config/config.yaml`](src/vamp_cli/config/config.yaml). API keys are read from environment variables named by each model's `api_key_env` field; keys are not read from YAML values directly.
55
+
56
+ The checked-in default configuration defines `qwen` and `openai`, so both variables must be present unless you edit the configuration to remove or replace one of those models:
57
+
58
+ ```bash
59
+ export DASHSCOPE_API_KEY="your-dashscope-key"
60
+ export OPENAI_API_KEY="your-openai-key"
61
+ ```
62
+
63
+ For a different provider, update the model's `model`, optional `api_base`, `api_key_env`, parameters, capabilities, and fallback list in the YAML file. Profiles select the model and the tools available to the planner or coder.
64
+
65
+ ## Running VAMP-CLI
66
+
67
+ Run it from the repository you want the agent to work on:
68
+
69
+ ```bash
70
+ vamp
71
+ ```
72
+
73
+ The current directory becomes the agent workspace and is mounted at `/workspace` inside the sandbox. On startup, VAMP-CLI prints an interactive prompt:
74
+
75
+ ```text
76
+ You:
77
+ ```
78
+
79
+ ### CLI Arguments
80
+
81
+ | Argument | Action |
82
+ | --- | --- |
83
+ | `--resume <id>` or `-r <id>` | Resume a previous session by its ID |
84
+ | `--list` or `-l` | List all past sessions |
85
+
86
+ Examples:
87
+
88
+ ```bash
89
+ # List all past sessions
90
+ vamp --list
91
+
92
+ # Resume a specific session
93
+ vamp --resume 01a145b4-5103-7014-97da-d5ca9c871d68
94
+ ```
95
+
96
+ ### In-Session Commands
97
+
98
+ | Command | Action |
99
+ | --- | --- |
100
+ | `/mode` | Select `plan` or `normal` mode |
101
+ | `/exit` | Stop the session and remove the active sandbox container |
102
+ | `/quit` | Same as `/exit` |
103
+ | `/fork` | Rewind to a previous user message and create a new branch |
104
+ | `/fork <N>` | Fork directly to before message N (non-interactive) |
105
+ | `/branches` | View all branches in the current session and switch between them |
106
+ | `/compact` | Summarize early conversation turns to reduce context usage |
107
+ | `/compact <N>` | Compact keeping the last N turns intact (default: 4) |
108
+ | `/config` | Change configurations of models, coder or planner profiles, and tool access. |
109
+
110
+ When the agent requests approval, answer `yes` to continue or `no` and provide a reason to deny the action. Approvals are used for plan implementation and security-sensitive tool calls such as destructive commands, package installation, or network access.
111
+
112
+ Example requests:
113
+
114
+ ```text
115
+ Inspect this repository and explain how the authentication flow works.
116
+ ```
117
+
118
+ ```text
119
+ /mode
120
+ Select Mode [plan/normal]: plan
121
+ Add tests for the configuration loader, then implement the changes after I approve the plan.
122
+ ```
123
+
124
+ ## Session Persistence & Resumption
125
+
126
+ VAMP-CLI automatically saves every interaction so you can pick up where you left off.
127
+
128
+ ### How Sessions Are Stored
129
+
130
+ Sessions are persisted in `~/.vamp/` using two complementary mechanisms:
131
+
132
+ | Storage | Location | Contents |
133
+ | --- | --- | --- |
134
+ | **JSONL Event Log** | `~/.vamp/sessions/<id>.jsonl` | Append-only, human-readable record of every event (messages, tool calls, mode switches, interrupts, forks, compactions). Each event has a UUID7, parent UUID, and timestamp. |
135
+ | **Head Sidecar** | `~/.vamp/sessions/<id>.head` | Contains the UUID of the current leaf (tip) of the active branch. |
136
+ | **SQLite Checkpoint** | `~/.vamp/checkpoints/<id>.sqlite` | LangGraph's internal graph state — full message objects, plan, todo list, iteration count, and pipeline flags. |
137
+
138
+ ### Resuming a Session
139
+
140
+ When you resume a session with `vamp --resume <id>`, VAMP-CLI:
141
+
142
+ 1. **Loads the event chain** — walks the `parentUuid` linked list from the current leaf back to `session_start`, reconstructing the full conversation history.
143
+ 2. **Recovers CLI state** — replays the events to determine the current mode, whether the session had started, and whether a human-in-the-loop interrupt is still pending.
144
+ 3. **Restores graph state** — reads the authoritative LangGraph state from the SQLite checkpointer. If the checkpointer is missing or corrupted, it falls back to reconstructing state from the JSONL event log (lossy but functional — preserves messages, reasoning content, plan, and todo list).
145
+ 4. **Handles parked interrupts** — if the previous session was interrupted mid-approval (plan approval or dangerous tool verification), the user is immediately prompted to approve or deny before continuing.
146
+
147
+ ### Platform-Independent
148
+
149
+ The `~/.vamp` directory is relative to the user's home directory, so sessions work across different projects and can be listed from anywhere — not just the original workspace directory.
150
+
151
+ ## Forking & Branching
152
+
153
+ The JSONL event log uses a `parentUuid` chain instead of a linear sequence, which means conversations can branch.
154
+
155
+ ### Forking (`/fork`)
156
+
157
+ Forking lets you rewind to any past user message and start a new branch from that point:
158
+
159
+ 1. Type `/fork` to see a numbered list of user messages on the current branch.
160
+ 2. Choose a message number to rewind to *before* that message.
161
+ 3. VAMP-CLI reconstructs the agent state at that point, creates a new LangGraph checkpointer thread, and appends a `fork` event to the JSONL (pointing its `parentUuid` at the fork point).
162
+ 4. The old branch is **never deleted** — it remains intact and can be switched back to at any time.
163
+
164
+ Compact (summarized) messages are also forkable. Forking to a compacted message creates a new branch where the original (unsummarized) messages are restored.
165
+
166
+ ### Branch Switching (`/branches`)
167
+
168
+ Each fork creates a new branch tip (leaf). Type `/branches` to:
169
+
170
+ - See all branch tips with a short preview of the last user message on each.
171
+ - Identify the current branch (marked with `<- current`).
172
+ - Switch to any branch by number — this repoints the `.head` sidecar, reloads state from the JSONL, and switches the checkpointer thread.
173
+
174
+ ## Conversation Compaction
175
+
176
+ Long conversations can exceed the model's context window. Compaction solves this by summarizing early turns.
177
+
178
+ ### Manual Compaction (`/compact`)
179
+
180
+ Type `/compact` to summarize all but the last 4 user turns. Use `/compact <N>` to keep a different number of recent turns. The process:
181
+
182
+ 1. Identifies the range of events to compact (earliest user messages up to, but not including, the keep boundary).
183
+ 2. Builds a transcript from those events.
184
+ 3. Calls the current model to produce a dense, information-rich summary.
185
+ 4. Appends a `compaction` event to the JSONL (original events are kept — they are "shadowed", not deleted).
186
+ 5. Replaces the checkpointer's message channels with the compacted view (summary marker + recent messages only).
187
+
188
+ ### Auto-Compaction
189
+
190
+ When the last prompt's input tokens exceed **90%** of the model's context window (configurable via `DEFAULT_COMPACT_THRESHOLD`), VAMP-CLI automatically runs compaction before the next turn. This keeps sessions healthy without manual intervention.
191
+
192
+ A progress line is printed:
193
+ ```
194
+ [auto-compact] context at 118,000/128,000 tokens (92.2%) — summarizing…
195
+ [auto-compact] done: 24 events, ~9,500 → ~600 tokens
196
+ ```
197
+
198
+ ## How it works
199
+
200
+ 1. `vamp_cli.main` creates a workspace, ignore matcher, tool registry, model router, EventLog, and Docker sandbox.
201
+ 2. The selected planner or coder profile supplies a system prompt and permitted tools.
202
+ 3. LangGraph routes model output through tool classification, approval, and execution nodes.
203
+ 4. File tools operate within the current workspace; terminal commands execute in the mounted Docker container.
204
+ 5. An `EventEmitter` translates LangChain `astream_events` v2 frames into durable JSONL events in real time — `on_chat_model_start/stream/end` → `assistant_message`, `on_tool_start/end/error` → `tool_result`.
205
+ 6. The session retains graph state via LangGraph's SQLite checkpointer so follow-up prompts can continue the current task.
206
+ 7. On resume, the event log and checkpointer are rehydrated together — the event log provides the human-readable chain and fallback state, while the checkpointer is the authoritative source for the LangGraph agent state.
207
+
208
+ The main package areas are:
209
+
210
+ ```text
211
+ src/vamp_cli/
212
+ ├── agent/ LangGraph state, nodes, routing, and runtime profiles
213
+ ├── config/ YAML loading, validation, model/profile configuration
214
+ ├── llm/ LiteLLM-backed model routing, adapters, fallbacks, usage
215
+ ├── prompts/ Planner and coder system prompts
216
+ ├── sandbox/ Docker lifecycle and command execution
217
+ ├── tools/ File, search, diagnostic, todo, and command tools
218
+ ├── workspace/ Workspace path-safety enforcement
219
+ ├── persistence/ Session event log, emitter, loader, fork, compaction, transcript
220
+ └── main.py Interactive CLI entry point
221
+ ```
222
+
223
+ ### Persistence Module Details
224
+
225
+ ```text
226
+ src/vamp_cli/persistence/
227
+ ├── event_log.py Append-only JSONL writer with async queue, UUID7, parent-chain, and .head sidecar
228
+ ├── emitter.py Translates LangChain astream_events v2 → event log entries
229
+ ├── loader.py Session rehydration: load_chain, derive_display_state,
230
+ │ detect_pending_interrupt, reconstruct_agent_state, list_sessions
231
+ ├── fork.py Rewind to a past event and seed a new checkpointer thread
232
+ ├── compaction.py Summarize early turns, plan ranges, auto-compact on threshold
233
+ └── transcript.py Render and print human-readable session transcripts
234
+ ```
235
+
236
+ ## Development and tests
237
+
238
+ Run the automated test suite from the repository root:
239
+
240
+ ```bash
241
+ python -m pytest
242
+ ```
243
+
244
+ Some sandbox and system-verification tests require Docker. The manual security and tool-operation scenarios are documented in [`tests/TEST_VERIFICATION.md`](tests/TEST_VERIFICATION.md).
245
+
246
+ For a quick syntax check:
247
+
248
+ ```bash
249
+ python -m compileall src
250
+ ```
251
+
252
+ ## Security and operational notes
253
+
254
+ - The host project directory is mounted into the sandbox at `/workspace`.
255
+ - The default sandbox limits are 2 CPUs, 2 GB of memory, 256 processes, and 30 seconds per command.
256
+ - Commands are executed with `/bin/bash -lc` inside the container.
257
+ - The default sandbox has network access; set `network_enabled: false` in the sandbox configuration if an offline container is required.
258
+ - Treat model output as untrusted. Review approval prompts carefully, especially for deletion, package installation, credential access, and network operations.
259
+ - The current graph limits an agent run to 15 iterations to prevent unbounded tool loops.
260
+
261
+ ## License
262
+
263
+ VAMP-CLI is released under the [MIT License](LICENSE).
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "vamp-cli"
7
+ version = "0.1.0"
8
+ authors = [
9
+ { name = "Satyam Kumar", email = "satkr2208@gmail.com" }
10
+ ]
11
+ description = "CLI coding agent."
12
+ readme = "README.md"
13
+ requires-python = ">=3.11"
14
+ license = { file = "LICENSE" }
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ ]
23
+ dependencies = [
24
+ "pydantic",
25
+ "rich",
26
+ "typer",
27
+ "click",
28
+ "orjson",
29
+ "pytest",
30
+ "pyyaml",
31
+ "pathspec",
32
+ "prompt-toolkit",
33
+ "langchain-core",
34
+ "langgraph",
35
+ "langchain-litellm",
36
+ "langgraph-checkpoint-sqlite",
37
+ "aiosqlite",
38
+ ]
39
+
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
43
+
44
+ [project.scripts]
45
+ vamp = "vamp_cli.main:start"
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+ addopts = "-ra"
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/satkr22/vamp-cli"
53
+ Repository = "https://github.com/satkr22/vamp-cli"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
File without changes