regcode 0.3.0__tar.gz → 0.4.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 (42) hide show
  1. {regcode-0.3.0 → regcode-0.4.0}/GOALS.md +9 -6
  2. regcode-0.4.0/PKG-INFO +237 -0
  3. regcode-0.4.0/README.md +219 -0
  4. {regcode-0.3.0 → regcode-0.4.0}/pyproject.toml +7 -5
  5. {regcode-0.3.0 → regcode-0.4.0}/regcode/__init__.py +1 -1
  6. {regcode-0.3.0 → regcode-0.4.0}/regcode/cli.py +1 -0
  7. {regcode-0.3.0 → regcode-0.4.0}/regcode/config.py +47 -21
  8. {regcode-0.3.0 → regcode-0.4.0}/regcode/main.py +45 -0
  9. {regcode-0.3.0 → regcode-0.4.0}/regcode/tools/builtins.py +460 -38
  10. regcode-0.4.0/regcode/tools/web_crawl.py +177 -0
  11. regcode-0.4.0/regcode/tracing.py +107 -0
  12. regcode-0.4.0/regcode/tui.py +965 -0
  13. regcode-0.4.0/repair_tui.md +115 -0
  14. {regcode-0.3.0 → regcode-0.4.0}/tests/test_api.py +1 -1
  15. {regcode-0.3.0 → regcode-0.4.0}/tests/test_cli.py +1 -1
  16. {regcode-0.3.0 → regcode-0.4.0}/tests/test_config.py +3 -3
  17. {regcode-0.3.0 → regcode-0.4.0}/tests/test_main.py +2 -1
  18. regcode-0.4.0/tests/test_osv_cve.py +280 -0
  19. {regcode-0.3.0 → regcode-0.4.0}/tests/test_provider_extra.py +10 -15
  20. {regcode-0.3.0 → regcode-0.4.0}/uv.lock +2044 -1
  21. regcode-0.3.0/PKG-INFO +0 -164
  22. regcode-0.3.0/README.md +0 -148
  23. regcode-0.3.0/regcode/tui.py +0 -663
  24. {regcode-0.3.0 → regcode-0.4.0}/.gitignore +0 -0
  25. {regcode-0.3.0 → regcode-0.4.0}/.python-version +0 -0
  26. {regcode-0.3.0 → regcode-0.4.0}/.qwen/settings.json +0 -0
  27. {regcode-0.3.0 → regcode-0.4.0}/AGENTS.md +0 -0
  28. {regcode-0.3.0 → regcode-0.4.0}/config.yaml.template +0 -0
  29. {regcode-0.3.0 → regcode-0.4.0}/main.py +0 -0
  30. {regcode-0.3.0 → regcode-0.4.0}/regcode/conversation_manager.py +0 -0
  31. {regcode-0.3.0 → regcode-0.4.0}/regcode/monty_sandbox.py +0 -0
  32. {regcode-0.3.0 → regcode-0.4.0}/regcode/permissions.py +0 -0
  33. {regcode-0.3.0 → regcode-0.4.0}/regcode/sandbox.py +0 -0
  34. {regcode-0.3.0 → regcode-0.4.0}/regcode/tools/__init__.py +0 -0
  35. {regcode-0.3.0 → regcode-0.4.0}/regcode/tools/base.py +0 -0
  36. {regcode-0.3.0 → regcode-0.4.0}/regcode/tools/registry.py +0 -0
  37. {regcode-0.3.0 → regcode-0.4.0}/regcode/tools/review_notes.py +0 -0
  38. {regcode-0.3.0 → regcode-0.4.0}/tests/__init__.py +0 -0
  39. {regcode-0.3.0 → regcode-0.4.0}/tests/conftest.py +0 -0
  40. {regcode-0.3.0 → regcode-0.4.0}/tests/test_context_manager.py +0 -0
  41. {regcode-0.3.0 → regcode-0.4.0}/tests/test_monty_sandbox.py +0 -0
  42. {regcode-0.3.0 → regcode-0.4.0}/tests/test_review_notes.py +0 -0
@@ -492,11 +492,14 @@ All phases complete. 50/50 tests passing. Lint clean.
492
492
  ### LLM Hallucinated Tool Calls Fix
493
493
  - DONE: Model was hallucinating tool calls (e.g. `<tool_call>`) when budget was exhausted and `tools=None`. Root cause: tool definitions were baked into the system prompt string, so even with `tools=None` the model still saw tool names and hallucinated calling them. Fix: when budget is exhausted, replace the system prompt with a version stripped of tool definitions (`_build_system_prompt_no_tools()`). Additionally set `tool_choice="none"` and stop sequences `["<tool_call>", "</tool_use>"]`. Message history (including tool_call_ids) is preserved intact to maintain proper conversation continuity.
494
494
 
495
- ## Top Priority To-Dos:
496
495
 
497
- - Currently agent could keep on loading files running into context window limitations. We need to add content compaction threshold and add automatic compaction support.
498
- - I think for this agent to be able to work on big repos, we need to add `add_review_note` tool which basically can write review notes into file which can survive compaction. Review notes are supposed to be preleminary findings. Add `read_review_notes` as well. This must work intune with compaction feature
499
- - Save tokens reported by litellm and use following logic `context_window=max_tokens + message_chain_token_size` and compact based on compaction threshold.
500
- - _build_system_prompt in regcode/main.py and _build_code_review_system_prompt in the same file share an identical loop that constructs a "tool descriptions" string from registered tools. The same logic appears twice. This should be extracted into a single helper method, e.g. _format_tool_descriptions(self) -> str, called by both.
496
+ ### COMPLETED (2026-06-29)
501
497
 
502
- Additionally, _build_code_review_system_prompt in regcode/main.py calls self.registry.list_tools() and builds tool descriptions, but it could simply accept a system prompt string and tool descriptions as parameters, instead of duplicating the logic again.
498
+ 1. ✅ **Remove model config params from AgentConfig** — `model`, `max_tokens`, `temperature` moved from `Config.agent` to `Config.provider`. `AgentConfig` now only holds `context_window`, `compaction_threshold`, and `enable_compaction`. All tests updated to use new format.
499
+
500
+ 2. ✅ **TUI complete overhaul** — `tui.py` rewritten from scratch. New layout: (1) top status bar showing `[RegCode <version>] [model] [$cost] [tokens]`, (2) large chat history area with clearly separated user/agent/tool/system message blocks, (3) bottom bar with progress indicator and input field. Streaming works correctly: text chunks stream live, then on completion full Markdown is rendered. Tool calls are interleaved after streaming text (stream buffer flushed before status rendering). Context compaction shows status indicators. All 137 tests pass, lint clean.
501
+
502
+
503
+ ## To Dos:
504
+ - implement web crawl tool with https://github.com/unclecode/crawl4AI, the api should be straight forward. Use its inbuilt markdown generation and markdown integration.
505
+ - If current Dir has `Agents.MD`, or `AGENTS.md` or `agents.md`, read it and provide it clearly marked as content of Agents.md to the model as extra context about the project.
regcode-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: regcode
3
+ Version: 0.4.0
4
+ Summary: Minimalistic coding agent with Python API and CLI
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: click>=8.0
7
+ Requires-Dist: crawl4ai>=0.4.0
8
+ Requires-Dist: litellm>=1.83.17
9
+ Requires-Dist: mlflow>=3.14.0
10
+ Requires-Dist: pydantic-monty>=0.0.18
11
+ Requires-Dist: pydantic-settings>=2.14.2
12
+ Requires-Dist: pytest>=8.0
13
+ Requires-Dist: pyyaml>=6.0
14
+ Requires-Dist: ruff>=0.8
15
+ Requires-Dist: textual>=8.2.7
16
+ Provides-Extra: dev
17
+ Description-Content-Type: text/markdown
18
+
19
+ # RegCode
20
+
21
+ A minimalistic coding agent with Python API bindings and CLI interface.
22
+
23
+ ## Features
24
+
25
+ - **litellm** as the LLM backbone (supports OpenAI, Anthropic, and 100+ providers)
26
+ - **YAML configuration** for model, tokens, temperature, and provider settings via Pydantic models
27
+ - **Environment variable expansion** in config values (e.g., `${OPENAI_API_KEY}`)
28
+ - **CLI** via click: `chat`, `configure`, `version`
29
+ - **Python API**: `import regcode; agent = regcode.Agent()`
30
+ - **Host filesystem I/O**: `write_file` and `patch_file` operate directly on the host filesystem with path traversal protection
31
+ - **Robust tool call handling**: malformed tool calls and JSON parse errors are gracefully handled
32
+ - **Progressive streaming**: TUI always streams assistant responses progressively rather than all at once
33
+ - **Context window compaction**: Automatically compacts conversation history when approaching token limits, preserving system instructions and review notes
34
+ - **Review notes**: Persistent findings stored across context compaction sessions
35
+ - **Tool budget limits**: Configurable maximum number of tool calls per conversation turn
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # Install dependencies
41
+ uv sync
42
+
43
+ # Configure your API key (or set OPENAI_API_KEY in your environment)
44
+ # Edit config.yaml or use environment variables
45
+
46
+ # Chat with the agent (uses Textual TUI)
47
+ uv run regcode chat
48
+
49
+ # Interactive config generator
50
+ uv run regcode configure
51
+
52
+ # View version
53
+ uv run regcode version
54
+ ```
55
+
56
+ ## CLI Chat Options
57
+
58
+ ```bash
59
+ # Full agent mode (enables write permissions)
60
+ uv run regcode chat --full
61
+
62
+ # Use a specific model
63
+ uv run regcode chat --model "openai/gpt-4o"
64
+
65
+ # Disable colored output
66
+ uv run regcode chat --no-color
67
+
68
+ # Use a custom config file
69
+ uv run regcode chat --config /path/to/config.yaml
70
+ ```
71
+
72
+ ## TUI Slash Commands
73
+
74
+ While chatting, you can use these slash commands in the input bar:
75
+
76
+ - `/exit` or `/quit` — Quit the application
77
+ - `/clear` — Clear the chat history
78
+ - `/reset` — Reset the session (clear history and tools)
79
+
80
+ ## Usage as a Library
81
+
82
+ ```python
83
+ import regcode
84
+
85
+ # Load config (reads config.yaml, falls back to ~/.regcode/config.yaml, then defaults)
86
+ config = regcode.Config.load("config.yaml")
87
+
88
+ # Create agent
89
+ agent = regcode.Agent(config=config)
90
+
91
+ # Chat (TUI always streams responses progressively)
92
+ reply = agent.chat("Refactor this function to use async/await.")
93
+ print(reply)
94
+
95
+ # Reset conversation
96
+ agent.reset()
97
+ ```
98
+
99
+ ## Tools
100
+
101
+ RegCode includes several built-in tools the agent can use:
102
+
103
+ | Tool | Permission | Description |
104
+ |------|-----------|-------------|
105
+ | `python_code` | `EXECUTE` | Execute Python code in an isolated Monty sandbox with Rust-based security and resource limits |
106
+ | `shell_command` | `EXECUTE` | Execute shell commands (subprocess, not sandbox). Only safe, read-only commands are allowed (ls, cat, echo, head, tail, wc, grep, sort, uniq, date, pwd, whoami, id, uname, df, free, which, type, stat, file, sha256sum, md5sum, base64, xxd, od, hexdump, find) |
107
+ | `run_script` | `EXECUTE` | Execute a Python script file in the Monty sandbox |
108
+ | `read_file` | `READ` | Read the contents of a file from the filesystem |
109
+ | `write_file` | `WRITE` | Write content to a file on the host filesystem |
110
+ | `patch_file` | `WRITE` | Replace a range of lines in an existing file |
111
+ | `list_dir` | `READ` | List contents of a directory |
112
+ | `search_files` | `READ` | Search for files matching a pattern |
113
+ | `search_dir` | `READ` | Search for a pattern inside all files within a directory |
114
+ | `fetch_git_diff` | `READ` | Fetch the git diff of the current repository |
115
+ | `osv_cve_scan` | `READ` | Scan project dependencies for known CVEs via OSV.dev API. Optionally scans the codebase for vulnerable usage patterns |
116
+ | `system_info` | `READ` | Get system information (OS, Python version, etc.) |
117
+
118
+ > **Note**: `browse_dir` is defined in the codebase but **not included in the default tools**. It can be explicitly registered if needed, but is excluded by default because it recursively lists all files in a directory, which can fill the context window in large projects (e.g., `.venv`, `node_modules`).
119
+
120
+ All file-writing tools (`write_file`, `patch_file`) include path traversal protection (`..` is blocked). The `patch_file` tool validates line number bounds and type correctness before performing the replacement.
121
+
122
+ ## Project Structure
123
+
124
+ ```
125
+ project-root/
126
+ ├── main.py # Unused stub (hello world only)
127
+ ├── config.yaml # Runtime configuration
128
+ ├── config.yaml.template # Template for new configs
129
+ ├── pyproject.toml # Project metadata and dependencies
130
+ ├── uv.lock # Locked dependencies
131
+ └── regcode/ # Python package
132
+ ├── __init__.py # Python API entry point
133
+ ├── main.py # Agent core (chat, review, etc.)
134
+ ├── cli.py # CLI entry point (click)
135
+ ├── config.py # Config loader (yaml + pydantic)
136
+ ├── permissions.py # Tool permission definitions
137
+ ├── tui.py # Textual-based terminal UI
138
+ ├── conversation_manager.py # Context compaction & review notes
139
+ ├── sandbox.py # Legacy sandbox support
140
+ ├── monty_sandbox.py # Monty sandbox integration
141
+ └── tools/
142
+ ├── __init__.py
143
+ ├── base.py # Base tool classes
144
+ ├── builtins.py # Built-in tool implementations
145
+ ├── registry.py # Tool registry management
146
+ └── review_notes.py # Review notes persistence
147
+ ├── tests/
148
+ │ ├── conftest.py
149
+ │ ├── test_main.py
150
+ │ ├── test_config.py
151
+ │ ├── test_api.py
152
+ │ ├── test_cli.py
153
+ │ ├── test_context_manager.py
154
+ │ ├── test_monty_sandbox.py
155
+ │ ├── test_provider_extra.py
156
+ │ └── test_review_notes.py
157
+ └── README.md
158
+ ```
159
+
160
+ ## Testing & Linting
161
+
162
+ ```bash
163
+ uv run pytest tests/ -v
164
+ uv run ruff check --fix regcode/ tests/
165
+ ```
166
+
167
+ ## Configuration
168
+
169
+ Edit `config.yaml` to customize the agent's behavior. The config is loaded from the specified path, `~/.regcode/config.yaml`, or falls back to defaults.
170
+
171
+ ```yaml
172
+ agent:
173
+ context_window: 128000 # Maximum context window size
174
+ compaction_threshold: 0.8 # Compact when context > 80% of window
175
+ enable_compaction: true # Enable automatic context compaction
176
+
177
+ provider:
178
+ model: "openai/gpt-4o" # Model identifier (litellm format)
179
+ base_url: "https://api.openai.com/v1"
180
+ api_key: "${OPENAI_API_KEY}" # Environment variable expansion supported
181
+ temperature: 1.0
182
+ max_tokens: 4096
183
+
184
+ system_prompt: | # Custom system prompt (default is provided)
185
+ You are a coding agent.
186
+
187
+ tools: {} # Reserved for future tool configuration
188
+
189
+ sandbox:
190
+ use_monty: true # Enable Monty sandbox for Python execution
191
+ max_duration_secs: 10.0
192
+ max_memory_mb: 64
193
+ max_recursion_depth: 100
194
+ type_check: true
195
+ allowed_imports: []
196
+
197
+ tool_budget: 20 # Max tool calls per agent turn
198
+
199
+ permissions:
200
+ - read # READ: read_file, list_dir, search_files, search_dir, browse_dir, fetch_git_diff, read_review_notes, system_info
201
+ - execute # EXECUTE: python_code, shell_command, run_script
202
+ - write # WRITE: write_file, patch_file, add_review_note
203
+ # - delete # DELETE: no tools currently mapped
204
+ # - all # ALL: grants all permissions
205
+ ```
206
+
207
+ ### Permission Levels
208
+
209
+ | Permission | Tools Granted |
210
+ |-----------|---------------|
211
+ | `read` | `read_file`, `list_dir`, `search_files`, `search_dir`, `fetch_git_diff`, `system_info`, `osv_cve_scan` |
212
+ | `write` | `write_file`, `patch_file` |
213
+ | `execute` | `python_code`, `shell_command`, `run_script` |
214
+ | `delete` | *(no tools currently)* |
215
+ | `all` | All permissions |
216
+
217
+ ### Key Settings
218
+
219
+ - **`context_window`**: Maximum token budget for the conversation context.
220
+ - **`compaction_threshold`**: Ratio of context window at which compaction triggers (e.g., `0.8` = compact at 80%).
221
+ - **`tool_budget`**: Maximum number of tool calls the agent can make in a single turn before responding.
222
+ - **`permissions`**: List of permission levels granted to the agent. The `chat --full` CLI flag automatically adds `WRITE` permission.
223
+
224
+ ### Environment Variables
225
+
226
+ Values in `config.yaml` can reference environment variables using `${VAR_NAME}` syntax. For example:
227
+
228
+ ```yaml
229
+ provider:
230
+ api_key: "${OPENAI_API_KEY}"
231
+ ```
232
+
233
+ Supported formats: `${VAR}`, `${VAR:-default}`, and standard shell variable expansion.
234
+
235
+ ## License
236
+
237
+ MIT
@@ -0,0 +1,219 @@
1
+ # RegCode
2
+
3
+ A minimalistic coding agent with Python API bindings and CLI interface.
4
+
5
+ ## Features
6
+
7
+ - **litellm** as the LLM backbone (supports OpenAI, Anthropic, and 100+ providers)
8
+ - **YAML configuration** for model, tokens, temperature, and provider settings via Pydantic models
9
+ - **Environment variable expansion** in config values (e.g., `${OPENAI_API_KEY}`)
10
+ - **CLI** via click: `chat`, `configure`, `version`
11
+ - **Python API**: `import regcode; agent = regcode.Agent()`
12
+ - **Host filesystem I/O**: `write_file` and `patch_file` operate directly on the host filesystem with path traversal protection
13
+ - **Robust tool call handling**: malformed tool calls and JSON parse errors are gracefully handled
14
+ - **Progressive streaming**: TUI always streams assistant responses progressively rather than all at once
15
+ - **Context window compaction**: Automatically compacts conversation history when approaching token limits, preserving system instructions and review notes
16
+ - **Review notes**: Persistent findings stored across context compaction sessions
17
+ - **Tool budget limits**: Configurable maximum number of tool calls per conversation turn
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # Install dependencies
23
+ uv sync
24
+
25
+ # Configure your API key (or set OPENAI_API_KEY in your environment)
26
+ # Edit config.yaml or use environment variables
27
+
28
+ # Chat with the agent (uses Textual TUI)
29
+ uv run regcode chat
30
+
31
+ # Interactive config generator
32
+ uv run regcode configure
33
+
34
+ # View version
35
+ uv run regcode version
36
+ ```
37
+
38
+ ## CLI Chat Options
39
+
40
+ ```bash
41
+ # Full agent mode (enables write permissions)
42
+ uv run regcode chat --full
43
+
44
+ # Use a specific model
45
+ uv run regcode chat --model "openai/gpt-4o"
46
+
47
+ # Disable colored output
48
+ uv run regcode chat --no-color
49
+
50
+ # Use a custom config file
51
+ uv run regcode chat --config /path/to/config.yaml
52
+ ```
53
+
54
+ ## TUI Slash Commands
55
+
56
+ While chatting, you can use these slash commands in the input bar:
57
+
58
+ - `/exit` or `/quit` — Quit the application
59
+ - `/clear` — Clear the chat history
60
+ - `/reset` — Reset the session (clear history and tools)
61
+
62
+ ## Usage as a Library
63
+
64
+ ```python
65
+ import regcode
66
+
67
+ # Load config (reads config.yaml, falls back to ~/.regcode/config.yaml, then defaults)
68
+ config = regcode.Config.load("config.yaml")
69
+
70
+ # Create agent
71
+ agent = regcode.Agent(config=config)
72
+
73
+ # Chat (TUI always streams responses progressively)
74
+ reply = agent.chat("Refactor this function to use async/await.")
75
+ print(reply)
76
+
77
+ # Reset conversation
78
+ agent.reset()
79
+ ```
80
+
81
+ ## Tools
82
+
83
+ RegCode includes several built-in tools the agent can use:
84
+
85
+ | Tool | Permission | Description |
86
+ |------|-----------|-------------|
87
+ | `python_code` | `EXECUTE` | Execute Python code in an isolated Monty sandbox with Rust-based security and resource limits |
88
+ | `shell_command` | `EXECUTE` | Execute shell commands (subprocess, not sandbox). Only safe, read-only commands are allowed (ls, cat, echo, head, tail, wc, grep, sort, uniq, date, pwd, whoami, id, uname, df, free, which, type, stat, file, sha256sum, md5sum, base64, xxd, od, hexdump, find) |
89
+ | `run_script` | `EXECUTE` | Execute a Python script file in the Monty sandbox |
90
+ | `read_file` | `READ` | Read the contents of a file from the filesystem |
91
+ | `write_file` | `WRITE` | Write content to a file on the host filesystem |
92
+ | `patch_file` | `WRITE` | Replace a range of lines in an existing file |
93
+ | `list_dir` | `READ` | List contents of a directory |
94
+ | `search_files` | `READ` | Search for files matching a pattern |
95
+ | `search_dir` | `READ` | Search for a pattern inside all files within a directory |
96
+ | `fetch_git_diff` | `READ` | Fetch the git diff of the current repository |
97
+ | `osv_cve_scan` | `READ` | Scan project dependencies for known CVEs via OSV.dev API. Optionally scans the codebase for vulnerable usage patterns |
98
+ | `system_info` | `READ` | Get system information (OS, Python version, etc.) |
99
+
100
+ > **Note**: `browse_dir` is defined in the codebase but **not included in the default tools**. It can be explicitly registered if needed, but is excluded by default because it recursively lists all files in a directory, which can fill the context window in large projects (e.g., `.venv`, `node_modules`).
101
+
102
+ All file-writing tools (`write_file`, `patch_file`) include path traversal protection (`..` is blocked). The `patch_file` tool validates line number bounds and type correctness before performing the replacement.
103
+
104
+ ## Project Structure
105
+
106
+ ```
107
+ project-root/
108
+ ├── main.py # Unused stub (hello world only)
109
+ ├── config.yaml # Runtime configuration
110
+ ├── config.yaml.template # Template for new configs
111
+ ├── pyproject.toml # Project metadata and dependencies
112
+ ├── uv.lock # Locked dependencies
113
+ └── regcode/ # Python package
114
+ ├── __init__.py # Python API entry point
115
+ ├── main.py # Agent core (chat, review, etc.)
116
+ ├── cli.py # CLI entry point (click)
117
+ ├── config.py # Config loader (yaml + pydantic)
118
+ ├── permissions.py # Tool permission definitions
119
+ ├── tui.py # Textual-based terminal UI
120
+ ├── conversation_manager.py # Context compaction & review notes
121
+ ├── sandbox.py # Legacy sandbox support
122
+ ├── monty_sandbox.py # Monty sandbox integration
123
+ └── tools/
124
+ ├── __init__.py
125
+ ├── base.py # Base tool classes
126
+ ├── builtins.py # Built-in tool implementations
127
+ ├── registry.py # Tool registry management
128
+ └── review_notes.py # Review notes persistence
129
+ ├── tests/
130
+ │ ├── conftest.py
131
+ │ ├── test_main.py
132
+ │ ├── test_config.py
133
+ │ ├── test_api.py
134
+ │ ├── test_cli.py
135
+ │ ├── test_context_manager.py
136
+ │ ├── test_monty_sandbox.py
137
+ │ ├── test_provider_extra.py
138
+ │ └── test_review_notes.py
139
+ └── README.md
140
+ ```
141
+
142
+ ## Testing & Linting
143
+
144
+ ```bash
145
+ uv run pytest tests/ -v
146
+ uv run ruff check --fix regcode/ tests/
147
+ ```
148
+
149
+ ## Configuration
150
+
151
+ Edit `config.yaml` to customize the agent's behavior. The config is loaded from the specified path, `~/.regcode/config.yaml`, or falls back to defaults.
152
+
153
+ ```yaml
154
+ agent:
155
+ context_window: 128000 # Maximum context window size
156
+ compaction_threshold: 0.8 # Compact when context > 80% of window
157
+ enable_compaction: true # Enable automatic context compaction
158
+
159
+ provider:
160
+ model: "openai/gpt-4o" # Model identifier (litellm format)
161
+ base_url: "https://api.openai.com/v1"
162
+ api_key: "${OPENAI_API_KEY}" # Environment variable expansion supported
163
+ temperature: 1.0
164
+ max_tokens: 4096
165
+
166
+ system_prompt: | # Custom system prompt (default is provided)
167
+ You are a coding agent.
168
+
169
+ tools: {} # Reserved for future tool configuration
170
+
171
+ sandbox:
172
+ use_monty: true # Enable Monty sandbox for Python execution
173
+ max_duration_secs: 10.0
174
+ max_memory_mb: 64
175
+ max_recursion_depth: 100
176
+ type_check: true
177
+ allowed_imports: []
178
+
179
+ tool_budget: 20 # Max tool calls per agent turn
180
+
181
+ permissions:
182
+ - read # READ: read_file, list_dir, search_files, search_dir, browse_dir, fetch_git_diff, read_review_notes, system_info
183
+ - execute # EXECUTE: python_code, shell_command, run_script
184
+ - write # WRITE: write_file, patch_file, add_review_note
185
+ # - delete # DELETE: no tools currently mapped
186
+ # - all # ALL: grants all permissions
187
+ ```
188
+
189
+ ### Permission Levels
190
+
191
+ | Permission | Tools Granted |
192
+ |-----------|---------------|
193
+ | `read` | `read_file`, `list_dir`, `search_files`, `search_dir`, `fetch_git_diff`, `system_info`, `osv_cve_scan` |
194
+ | `write` | `write_file`, `patch_file` |
195
+ | `execute` | `python_code`, `shell_command`, `run_script` |
196
+ | `delete` | *(no tools currently)* |
197
+ | `all` | All permissions |
198
+
199
+ ### Key Settings
200
+
201
+ - **`context_window`**: Maximum token budget for the conversation context.
202
+ - **`compaction_threshold`**: Ratio of context window at which compaction triggers (e.g., `0.8` = compact at 80%).
203
+ - **`tool_budget`**: Maximum number of tool calls the agent can make in a single turn before responding.
204
+ - **`permissions`**: List of permission levels granted to the agent. The `chat --full` CLI flag automatically adds `WRITE` permission.
205
+
206
+ ### Environment Variables
207
+
208
+ Values in `config.yaml` can reference environment variables using `${VAR_NAME}` syntax. For example:
209
+
210
+ ```yaml
211
+ provider:
212
+ api_key: "${OPENAI_API_KEY}"
213
+ ```
214
+
215
+ Supported formats: `${VAR}`, `${VAR:-default}`, and standard shell variable expansion.
216
+
217
+ ## License
218
+
219
+ MIT
@@ -1,10 +1,11 @@
1
1
  [project]
2
2
  name = "regcode"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  description = "Minimalistic coding agent with Python API and CLI"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
7
  dependencies = [
8
+ "crawl4ai>=0.4.0",
8
9
  "litellm>=1.83.17",
9
10
  "pydantic-settings>=2.14.2",
10
11
  "pyyaml>=6.0",
@@ -13,15 +14,16 @@ dependencies = [
13
14
  "ruff>=0.8",
14
15
  "pydantic-monty>=0.0.18",
15
16
  "textual>=8.2.7",
17
+ "mlflow>=3.14.0",
16
18
  ]
17
19
 
18
- [build-system]
19
- requires = ["hatchling"]
20
- build-backend = "hatchling.build"
21
-
22
20
  [project.scripts]
23
21
  regcode = "regcode.cli:cli"
24
22
 
23
+ [build-system]
24
+ requires = ["hatchling", "setuptools"]
25
+ build-backend = "hatchling.build"
26
+
25
27
  [project.optional-dependencies]
26
28
  dev = []
27
29
 
@@ -2,4 +2,4 @@ from regcode.config import Config
2
2
  from regcode.main import Agent, AgentStatus, ToolCall
3
3
 
4
4
  __all__ = ["Agent", "Config", "AgentStatus", "ToolCall"]
5
- __version__ = "0.1.0"
5
+ __version__ = "0.4.0"
@@ -61,6 +61,7 @@ def chat(model, config_path, stream, full, no_color):
61
61
  status_callback=ui.handle_status,
62
62
  result_callback=ui.handle_result,
63
63
  context_callback=ui.set_context_progress,
64
+ cost_callback=ui.handle_cost,
64
65
  )
65
66
 
66
67
  # Attach agent to the Textual app
@@ -44,7 +44,15 @@ default_system_prompt = dedent(
44
44
  logger = logging.getLogger(__name__)
45
45
 
46
46
  class AgentConfig(BaseModel):
47
- model_config = ConfigDict(extra="allow")
47
+ """Configuration specific to the agent's behavior (not provider params).
48
+
49
+ Model, temperature, max_tokens belong in ProviderConfig where
50
+ litellm.completion expects them. AgentConfig only holds compaction
51
+ and context-window tuning — passing model params through this object
52
+ caused conflicts with different providers.
53
+ """
54
+
55
+ model_config = ConfigDict(extra="forbid")
48
56
  context_window: int = 128000
49
57
  compaction_threshold: float = 0.8 # Compact when context > 80% of window
50
58
  enable_compaction: bool = True
@@ -81,11 +89,30 @@ class SandboxConfig(BaseModel):
81
89
  type_check: bool = True
82
90
  allowed_imports: list[str] = []
83
91
 
92
+ class TracingConfig(BaseModel):
93
+ """Configuration for tracing and logging."""
94
+
95
+ model_config = ConfigDict(extra="allow")
96
+ enable_tracing: bool = False
97
+ mlflow_url: str | None = None
98
+ mlflow_experiment_name: str | None = None
99
+ mlflow_async: bool = True
100
+ mlflow_requires_auth: bool = True
101
+ mlflow_username: str | None = None
102
+ mlflow_password: str | None = None
103
+
104
+ def tracing_enabled(self) -> bool:
105
+ """Check if tracing is fully configured and enabled."""
106
+ return (
107
+ self.enable_tracing
108
+ and self.mlflow_url is not None
109
+ )
84
110
 
85
111
  class Config(BaseModel):
86
112
  model_config = ConfigDict(extra="allow")
87
113
 
88
114
  agent: AgentConfig = AgentConfig()
115
+ tracing: TracingConfig = TracingConfig()
89
116
  provider: ProviderConfig = ProviderConfig()
90
117
  system_prompt: str = default_system_prompt
91
118
  tools: dict = {}
@@ -96,19 +123,29 @@ class Config(BaseModel):
96
123
  @classmethod
97
124
  def load(cls, path: str | None = None) -> "Config":
98
125
  # get default home dir for user first
126
+ _path = None
99
127
  if path is None:
100
- logger.warning(
101
- "No config path provided, looking for ~/.regcode/config.yaml"
102
- )
103
- alt_config_path = Path.home() / ".regcode" / "config.yaml"
104
- if alt_config_path.exists():
105
- logger.warning(f"Loading from config at {alt_config_path}")
106
- _path = alt_config_path
107
- else:
108
- _path = Path("config.yaml")
128
+ possible_paths = [
129
+ Path("./config.yaml"), Path.home() / ".regcode" / "config.yaml"
130
+ ]
131
+ for p in possible_paths:
132
+ if p.exists():
133
+ logger.info(f"Loading from config at {p}")
134
+ _path = p
135
+ break
136
+ if _path is None:
137
+ logger.warning(
138
+ "No config file found, using default config, "
139
+ "Use `regcode configure` to configure."
140
+ )
141
+ return cls()
109
142
  else:
110
143
  _path = Path(path)
111
144
  if not _path.exists():
145
+ logger.warning(
146
+ f"Config file {path} not found, using default config, "
147
+ "Use `regcode configure` to configure."
148
+ )
112
149
  return cls()
113
150
  with open(_path) as f:
114
151
  data = yaml.safe_load(f)
@@ -135,17 +172,6 @@ class Config(BaseModel):
135
172
  result = self.provider.model_dump()
136
173
  if extra_kwargs:
137
174
  result.update(extra_kwargs)
138
- # Agent-level config overrides provider defaults for known keys
139
- if self.agent.context_window is not None:
140
- result["context_window"] = self.agent.context_window
141
- if hasattr(self.agent, "compaction_threshold"):
142
- result["compaction_threshold"] = self.agent.compaction_threshold
143
- if hasattr(self.agent, "enable_compaction"):
144
- result["enable_compaction"] = self.agent.enable_compaction
145
- # Apply agent-level extra fields (e.g. model, max_tokens, temperature
146
- # from YAML agent section) as overrides over provider defaults
147
- if hasattr(self.agent, "model_extra") and self.agent.model_extra:
148
- result.update(self.agent.model_extra)
149
175
  return result
150
176
 
151
177