regcode 0.10.0__tar.gz → 0.12.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.
- {regcode-0.10.0 → regcode-0.12.0}/GOALS.md +64 -0
- regcode-0.10.0/README.md → regcode-0.12.0/PKG-INFO +41 -0
- regcode-0.10.0/PKG-INFO → regcode-0.12.0/README.md +18 -22
- {regcode-0.10.0 → regcode-0.12.0}/pyproject.toml +2 -1
- {regcode-0.10.0 → regcode-0.12.0}/regcode/__init__.py +1 -1
- regcode-0.12.0/regcode/agents_backend.py +739 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/cli.py +12 -1
- {regcode-0.10.0 → regcode-0.12.0}/regcode/main.py +390 -634
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/builtins.py +150 -44
- regcode-0.12.0/tasks.md +632 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/conftest.py +2 -1
- regcode-0.12.0/tests/llm_fakes.py +187 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_clipboard.py +9 -12
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_dependencies.py +27 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_main.py +339 -383
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_provider_extra.py +21 -29
- regcode-0.12.0/tests/test_task_regression.py +463 -0
- {regcode-0.10.0 → regcode-0.12.0}/uv.lock +149 -4
- {regcode-0.10.0 → regcode-0.12.0}/.gitignore +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/.gitlab-ci.yml +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/.python-version +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/.qwen/settings.json +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/AGENTS.md +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/config.yaml.template +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/main.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/clipboard.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/config.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/conversation_manager.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/dependencies.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/mcp_client.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/monty_sandbox.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/paste.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/permissions.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/sandbox.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/__init__.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/base.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/registry.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/review_notes.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/web_crawl.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tools/web_search.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tracing.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/regcode/tui.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/__init__.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_api.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_cli.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_config.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_context_manager.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_mcp.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_mcp_status.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_monty_sandbox.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_osv_cve.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_review_notes.py +0 -0
- {regcode-0.10.0 → regcode-0.12.0}/tests/test_web_search.py +0 -0
|
@@ -581,3 +581,67 @@ mcp_servers:
|
|
|
581
581
|
2. ✅ **TUI integration** — `_run_agent_sync()` and `_run_agent_multimodal()` now pass `on_message` callback to `agent.chat()`. The callback inserts each assistant text response directly into the chat area via `call_from_thread(self._insert_rich, text)`, so the user sees intermediate thinking ("Let me search the internet...") BEFORE tool execution markers appear. This makes the agent feel alive and responsive instead of silent during multi-tool chains.
|
|
582
582
|
|
|
583
583
|
3. ✅ **All 193 tests pass, lint clean.**
|
|
584
|
+
|
|
585
|
+
## Completed (tasks.md — upstream fixes for GitKnecht)
|
|
586
|
+
|
|
587
|
+
All twelve defects in `tasks.md` are fixed. See the ticked **Task Status** section there
|
|
588
|
+
for the per-task mapping to tests.
|
|
589
|
+
|
|
590
|
+
1. ✅ **Deleted the two dead tool loops** — the real cause of most of the list was that
|
|
591
|
+
`Agent` carried three tool loops (`_stream`, `_chat_loop`, and the SDK path) and only
|
|
592
|
+
the SDK one was reachable from `chat()`. Tasks 1/2/8/9/12 were all symptoms of the same
|
|
593
|
+
unreachable, never-executed `_stream`. `_stream`, `_chat_loop`,
|
|
594
|
+
`Agent._execute_tool_calls` and `_convert_registry_tools_to_sdk_tools` are deleted;
|
|
595
|
+
`test_module_level_helpers_exist` pins their absence.
|
|
596
|
+
|
|
597
|
+
2. ✅ **One implementation for both modes** — `Agent.chat()` delegates to `_run_sdk()`,
|
|
598
|
+
which drives the OpenAI Agents SDK `Runner` in either `run()` or `run_streamed()` form.
|
|
599
|
+
`RegCodeModel` (`regcode/agents_backend.py`) is now a **pure model**: one completion in,
|
|
600
|
+
output items out, exactly like the SDK's own `LitellmModel`. The Runner owns the tool
|
|
601
|
+
loop, so `max_tool_calls` (as `max_turns`), `response_format`, the budget and the
|
|
602
|
+
callbacks behave identically streaming or not.
|
|
603
|
+
|
|
604
|
+
3. ✅ **Streaming actually works** — `stream_response` uses `await litellm.acompletion(
|
|
605
|
+
stream=True)` and hands the async iterator to `ChatCmplStreamHandler` with an empty
|
|
606
|
+
`Response` shell. It previously called the *sync* `completion(stream=True)` and passed
|
|
607
|
+
the result in twice, so `chat(stream=True)` raised
|
|
608
|
+
`TypeError: 'async for' requires an object with __aiter__ method, got ModelResponse`.
|
|
609
|
+
|
|
610
|
+
4. ✅ `status_callback`/`result_callback` **never fired** — the model loop ignored them
|
|
611
|
+
entirely. They now fire from `_run_tool`, the single place tools execute, with
|
|
612
|
+
`is_error` read from `ToolResult.error`.
|
|
613
|
+
|
|
614
|
+
5. ✅ **`FunctionTool` wrapper fixed** — it read `ctx.tool_registry` (a
|
|
615
|
+
`RunContextWrapper` has no such attribute) and closed over the loop variable, so every
|
|
616
|
+
tool would have invoked the *last* registered one. The name is now bound via a default
|
|
617
|
+
argument.
|
|
618
|
+
|
|
619
|
+
6. ✅ **`directory` is now enforced** — `validate_tool_args` rejects any
|
|
620
|
+
`path`/`file_path`/`script_path`/`directory` argument resolving outside the root;
|
|
621
|
+
`shell_command` runs with `cwd=directory` and rejects absolute arguments outside it;
|
|
622
|
+
the CLI gained `--directory` (previously the agent was constructed with no directory at
|
|
623
|
+
all, so the default toolset was unconfined). README documents that `directory` is
|
|
624
|
+
confinement, not a sandbox.
|
|
625
|
+
|
|
626
|
+
7. ✅ **`AGENTS.md` no longer leaks from the process cwd** — `include_cwd` defaults to
|
|
627
|
+
`False`, closing a prompt-injection surface where the host project's instructions were
|
|
628
|
+
injected into answers about an unrelated repository.
|
|
629
|
+
|
|
630
|
+
8. ✅ **Per-iteration compaction restored** — `call_model_input_filter` on `RunConfig`
|
|
631
|
+
re-checks the token budget on every Runner iteration, which the SDK had silently
|
|
632
|
+
dropped along with the old loops.
|
|
633
|
+
|
|
634
|
+
9. ✅ **`MaxTurnsExceeded` is handled, not fatal** — hitting the turn limit is an
|
|
635
|
+
expected outcome for long reviews, so the best text produced so far is recovered from
|
|
636
|
+
`exc.run_data` instead of crashing the caller.
|
|
637
|
+
|
|
638
|
+
10. ✅ **Test fidelity** — `tests/llm_fakes.py` builds **real** `litellm.types.utils`
|
|
639
|
+
objects instead of `MagicMock`. The streaming bug survived for releases because a
|
|
640
|
+
`MagicMock` answered whatever the test asked it to; a response shape the SDK cannot
|
|
641
|
+
parse now fails the test the way it fails in production. Also fixed
|
|
642
|
+
`tests/test_dependencies.py`, which deleted `regcode.*` from `sys.modules` without
|
|
643
|
+
restoring it, so later tests received a second `AgentStatus` class and enum identity
|
|
644
|
+
comparisons failed purely on execution order.
|
|
645
|
+
|
|
646
|
+
11. ✅ **270 tests pass** (up from 231), `uv run ruff check` clean.
|
|
647
|
+
|
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: regcode
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: Minimalistic coding agent with Python API and CLI
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: boto3>=1.43.40
|
|
7
|
+
Requires-Dist: click>=8.0
|
|
8
|
+
Requires-Dist: crawl4ai>=0.4.0
|
|
9
|
+
Requires-Dist: litellm>=1.83.17
|
|
10
|
+
Requires-Dist: mcp>=1.0.0
|
|
11
|
+
Requires-Dist: mlflow>=3.14.0
|
|
12
|
+
Requires-Dist: openai-agents>=0.18.0
|
|
13
|
+
Requires-Dist: pathspec>=1.1.1
|
|
14
|
+
Requires-Dist: pydantic-monty>=0.0.18
|
|
15
|
+
Requires-Dist: pydantic-settings>=2.14.2
|
|
16
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
17
|
+
Requires-Dist: pytest>=8.0
|
|
18
|
+
Requires-Dist: pyyaml>=6.0
|
|
19
|
+
Requires-Dist: ruff>=0.8
|
|
20
|
+
Requires-Dist: textual>=2.0.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
1
24
|
# RegCode
|
|
2
25
|
|
|
3
26
|
A minimalistic coding agent with Python API bindings and CLI interface.
|
|
@@ -101,6 +124,24 @@ RegCode includes several built-in tools the agent can use:
|
|
|
101
124
|
|
|
102
125
|
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
126
|
|
|
127
|
+
### Working directory and confinement
|
|
128
|
+
|
|
129
|
+
`Agent(directory=...)` (and the CLI's `--directory`, which defaults to the current
|
|
130
|
+
directory) is the root every tool is confined to:
|
|
131
|
+
|
|
132
|
+
- Every path-like tool argument (`path`, `file_path`, `script_path`, `directory`) is
|
|
133
|
+
resolved against it and **rejected** when it resolves outside — absolute paths and
|
|
134
|
+
`..` escapes alike.
|
|
135
|
+
- `shell_command` runs with `cwd` set to it, and its arguments are checked the same way,
|
|
136
|
+
so `cat /etc/passwd` is rejected even though `cat` is allowlisted.
|
|
137
|
+
- `python_code` and `run_script` execute inside the Monty sandbox, which has no host
|
|
138
|
+
filesystem access at all.
|
|
139
|
+
|
|
140
|
+
> **`directory` is a confinement boundary, not a security sandbox.** `shell_command`
|
|
141
|
+
> still runs a real subprocess as the current user, and the toolset is only as safe as
|
|
142
|
+
> its permission list. Services embedding RegCode behind an authenticated endpoint should
|
|
143
|
+
> restrict `permissions` (or unregister tools) rather than relying on `directory` alone.
|
|
144
|
+
|
|
104
145
|
## Project Structure
|
|
105
146
|
|
|
106
147
|
```
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: regcode
|
|
3
|
-
Version: 0.10.0
|
|
4
|
-
Summary: Minimalistic coding agent with Python API and CLI
|
|
5
|
-
Requires-Python: >=3.10
|
|
6
|
-
Requires-Dist: boto3>=1.43.40
|
|
7
|
-
Requires-Dist: click>=8.0
|
|
8
|
-
Requires-Dist: crawl4ai>=0.4.0
|
|
9
|
-
Requires-Dist: litellm>=1.83.17
|
|
10
|
-
Requires-Dist: mcp>=1.0.0
|
|
11
|
-
Requires-Dist: mlflow>=3.14.0
|
|
12
|
-
Requires-Dist: pathspec>=1.1.1
|
|
13
|
-
Requires-Dist: pydantic-monty>=0.0.18
|
|
14
|
-
Requires-Dist: pydantic-settings>=2.14.2
|
|
15
|
-
Requires-Dist: pyperclip>=1.9.0
|
|
16
|
-
Requires-Dist: pytest>=8.0
|
|
17
|
-
Requires-Dist: pyyaml>=6.0
|
|
18
|
-
Requires-Dist: ruff>=0.8
|
|
19
|
-
Requires-Dist: textual>=2.0.0
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
|
|
23
1
|
# RegCode
|
|
24
2
|
|
|
25
3
|
A minimalistic coding agent with Python API bindings and CLI interface.
|
|
@@ -123,6 +101,24 @@ RegCode includes several built-in tools the agent can use:
|
|
|
123
101
|
|
|
124
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.
|
|
125
103
|
|
|
104
|
+
### Working directory and confinement
|
|
105
|
+
|
|
106
|
+
`Agent(directory=...)` (and the CLI's `--directory`, which defaults to the current
|
|
107
|
+
directory) is the root every tool is confined to:
|
|
108
|
+
|
|
109
|
+
- Every path-like tool argument (`path`, `file_path`, `script_path`, `directory`) is
|
|
110
|
+
resolved against it and **rejected** when it resolves outside — absolute paths and
|
|
111
|
+
`..` escapes alike.
|
|
112
|
+
- `shell_command` runs with `cwd` set to it, and its arguments are checked the same way,
|
|
113
|
+
so `cat /etc/passwd` is rejected even though `cat` is allowlisted.
|
|
114
|
+
- `python_code` and `run_script` execute inside the Monty sandbox, which has no host
|
|
115
|
+
filesystem access at all.
|
|
116
|
+
|
|
117
|
+
> **`directory` is a confinement boundary, not a security sandbox.** `shell_command`
|
|
118
|
+
> still runs a real subprocess as the current user, and the toolset is only as safe as
|
|
119
|
+
> its permission list. Services embedding RegCode behind an authenticated endpoint should
|
|
120
|
+
> restrict `permissions` (or unregister tools) rather than relying on `directory` alone.
|
|
121
|
+
|
|
126
122
|
## Project Structure
|
|
127
123
|
|
|
128
124
|
```
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "regcode"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.12.0"
|
|
4
4
|
description = "Minimalistic coding agent with Python API and CLI"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
dependencies = [
|
|
8
8
|
"crawl4ai>=0.4.0",
|
|
9
9
|
"litellm>=1.83.17",
|
|
10
|
+
"openai-agents>=0.18.0",
|
|
10
11
|
"pydantic-settings>=2.14.2",
|
|
11
12
|
"pyyaml>=6.0",
|
|
12
13
|
"click>=8.0",
|