devagent-cli 3.2.1__tar.gz → 3.2.2__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.
- {devagent_cli-3.2.1/devagent_cli.egg-info → devagent_cli-3.2.2}/PKG-INFO +11 -9
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/README.md +10 -8
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/agent.py +3 -1
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/cli.py +36 -4
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/utils/config.py +2 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/utils/metrics.py +2 -0
- devagent_cli-3.2.2/devagent/utils/safety.py +73 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2/devagent_cli.egg-info}/PKG-INFO +11 -9
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent_cli.egg-info/SOURCES.txt +1 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/pyproject.toml +1 -1
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/LICENSE +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/__init__.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/__init__.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/llm.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/memory.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/patcher.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/planner.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/reviewer.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/sandbox.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/app/state.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/__init__.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/benchmark_runner.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/file_ops.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/git_tools.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/linter.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/search.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/semantic_search.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/surgical_patcher.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/tools/test_runner.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/utils/__init__.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent/utils/logger.py +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent_cli.egg-info/dependency_links.txt +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent_cli.egg-info/entry_points.txt +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent_cli.egg-info/requires.txt +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/devagent_cli.egg-info/top_level.txt +0 -0
- {devagent_cli-3.2.1 → devagent_cli-3.2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devagent-cli
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Professional Local autonomous coding agent powered by Ollama
|
|
5
5
|
Author: Vedant Jadhav
|
|
6
6
|
License: MIT
|
|
@@ -31,6 +31,7 @@ Dynamic: license-file
|
|
|
31
31
|
### A Lightweight Local Open-Source Miniature of Claude Code CLI
|
|
32
32
|
|
|
33
33
|
[](https://opensource.org/licenses/MIT)
|
|
34
|
+
[](https://badge.fury.io/py/devagent-cli)
|
|
34
35
|
[](https://www.python.org/)
|
|
35
36
|
[](https://ollama.ai)
|
|
36
37
|
[](CONTRIBUTING.md)
|
|
@@ -140,16 +141,16 @@ devagent run --task "Fix the divide-by-zero bug" --root ./demo_project
|
|
|
140
141
|
| `devagent models` | List available Ollama models |
|
|
141
142
|
| `devagent version` | Show current version |
|
|
142
143
|
|
|
143
|
-
###
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
- **
|
|
148
|
-
- **Forensic Test Detection**:
|
|
149
|
-
- **
|
|
144
|
+
### 🛡️ Reliability & Safety (v3.2.1+)
|
|
145
|
+
DevAgent is built for **Enterprise-grade safety**:
|
|
146
|
+
- **Dry Run Mode**: Use `--dry-run` to see what the agent *would* do without touching your files.
|
|
147
|
+
- **Auto-Snapshot**: Creates a safety restore point before every run.
|
|
148
|
+
- **Rollback**: Revert the last agent changes instantly with `devagent rollback`.
|
|
149
|
+
- **Forensic Test Detection**: Detects successful test runs even in noisy environments.
|
|
150
|
+
- **Path Anchoring**: Automatically corrects "root hallucinations" for subdirectories.
|
|
150
151
|
|
|
151
152
|
#### 🕹️ Interactive Mode
|
|
152
|
-
Run with `--interactive` (or `-i`) to review diffs before they are applied to your project.
|
|
153
|
+
Run with `--interactive` (or `-i`) to review colorized diffs before they are applied to your project.
|
|
153
154
|
```bash
|
|
154
155
|
devagent run --task "Fix bug" --interactive
|
|
155
156
|
```
|
|
@@ -161,6 +162,7 @@ devagent run --task "Fix bug" --interactive
|
|
|
161
162
|
```mermaid
|
|
162
163
|
graph TD
|
|
163
164
|
CLI[DevAgent CLI] --> Orchestrator[ReAct Orchestrator]
|
|
165
|
+
Orchestrator --> Safety[Safety Manager: Snapshots]
|
|
164
166
|
Orchestrator --> Memory[Working Memory]
|
|
165
167
|
Orchestrator --> Retrieval[Semantic Retrieval FAISS]
|
|
166
168
|
Orchestrator --> Tools[Tool Suite: pytest, ripgrep, git]
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
### A Lightweight Local Open-Source Miniature of Claude Code CLI
|
|
6
6
|
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://badge.fury.io/py/devagent-cli)
|
|
8
9
|
[](https://www.python.org/)
|
|
9
10
|
[](https://ollama.ai)
|
|
10
11
|
[](CONTRIBUTING.md)
|
|
@@ -114,16 +115,16 @@ devagent run --task "Fix the divide-by-zero bug" --root ./demo_project
|
|
|
114
115
|
| `devagent models` | List available Ollama models |
|
|
115
116
|
| `devagent version` | Show current version |
|
|
116
117
|
|
|
117
|
-
###
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- **
|
|
122
|
-
- **Forensic Test Detection**:
|
|
123
|
-
- **
|
|
118
|
+
### 🛡️ Reliability & Safety (v3.2.1+)
|
|
119
|
+
DevAgent is built for **Enterprise-grade safety**:
|
|
120
|
+
- **Dry Run Mode**: Use `--dry-run` to see what the agent *would* do without touching your files.
|
|
121
|
+
- **Auto-Snapshot**: Creates a safety restore point before every run.
|
|
122
|
+
- **Rollback**: Revert the last agent changes instantly with `devagent rollback`.
|
|
123
|
+
- **Forensic Test Detection**: Detects successful test runs even in noisy environments.
|
|
124
|
+
- **Path Anchoring**: Automatically corrects "root hallucinations" for subdirectories.
|
|
124
125
|
|
|
125
126
|
#### 🕹️ Interactive Mode
|
|
126
|
-
Run with `--interactive` (or `-i`) to review diffs before they are applied to your project.
|
|
127
|
+
Run with `--interactive` (or `-i`) to review colorized diffs before they are applied to your project.
|
|
127
128
|
```bash
|
|
128
129
|
devagent run --task "Fix bug" --interactive
|
|
129
130
|
```
|
|
@@ -135,6 +136,7 @@ devagent run --task "Fix bug" --interactive
|
|
|
135
136
|
```mermaid
|
|
136
137
|
graph TD
|
|
137
138
|
CLI[DevAgent CLI] --> Orchestrator[ReAct Orchestrator]
|
|
139
|
+
Orchestrator --> Safety[Safety Manager: Snapshots]
|
|
138
140
|
Orchestrator --> Memory[Working Memory]
|
|
139
141
|
Orchestrator --> Retrieval[Semantic Retrieval FAISS]
|
|
140
142
|
Orchestrator --> Tools[Tool Suite: pytest, ripgrep, git]
|
|
@@ -114,13 +114,14 @@ EXTRACT_ACTION_PATTERN = re.compile(
|
|
|
114
114
|
class Agent:
|
|
115
115
|
"""ReAct agent with planner, retrieval, self-review, and sandbox support."""
|
|
116
116
|
|
|
117
|
-
def __init__(self, task: str, project_root: str = ".", max_steps: int = 5):
|
|
117
|
+
def __init__(self, task: str, project_root: str = ".", max_steps: int = 5, dry_run: bool = False):
|
|
118
118
|
self.state = AgentState(
|
|
119
119
|
task=task,
|
|
120
120
|
project_root=os.path.abspath(project_root),
|
|
121
121
|
max_steps=max_steps,
|
|
122
122
|
working_root=os.path.abspath(project_root),
|
|
123
123
|
)
|
|
124
|
+
self.dry_run = dry_run
|
|
124
125
|
self.logger = AgentLogger(log_dir=os.path.join(project_root, "logs"))
|
|
125
126
|
self.metrics = RunMetrics(task=task)
|
|
126
127
|
self.memory = WorkingMemory()
|
|
@@ -556,6 +557,7 @@ class Agent:
|
|
|
556
557
|
if approved:
|
|
557
558
|
return code_fix, review_text
|
|
558
559
|
|
|
560
|
+
self.metrics.patch_rejections += 1
|
|
559
561
|
print(f" [REVISE] Revising code (attempt {revision + 1})...")
|
|
560
562
|
code_fix = revise_code(code_fix, review_text, self.state.task)
|
|
561
563
|
code_fix = self._strip_code_fences(code_fix)
|
|
@@ -92,15 +92,24 @@ def cmd_run(args):
|
|
|
92
92
|
# Sandbox setup
|
|
93
93
|
sandbox = None
|
|
94
94
|
working_root = root
|
|
95
|
-
if config.sandbox:
|
|
95
|
+
if config.sandbox or config.dry_run:
|
|
96
|
+
if config.dry_run:
|
|
97
|
+
console.print("[bold yellow][DRY RUN][/bold yellow] Agent will work in an isolated sandbox. No changes will be applied.")
|
|
96
98
|
sandbox = SandboxManager(root)
|
|
97
99
|
working_root = sandbox.create()
|
|
98
100
|
|
|
101
|
+
# Safety Snapshot
|
|
102
|
+
if not config.dry_run:
|
|
103
|
+
from devagent.utils.safety import SafetyManager
|
|
104
|
+
safety = SafetyManager(root)
|
|
105
|
+
safety.create_snapshot(task_id=config.task[:10].replace(" ", "_"))
|
|
106
|
+
|
|
99
107
|
# Run agent
|
|
100
108
|
agent = Agent(
|
|
101
109
|
task=config.task,
|
|
102
110
|
project_root=working_root,
|
|
103
111
|
max_steps=config.max_steps,
|
|
112
|
+
dry_run=config.dry_run
|
|
104
113
|
)
|
|
105
114
|
|
|
106
115
|
start_time = time.time()
|
|
@@ -135,10 +144,19 @@ def cmd_run(args):
|
|
|
135
144
|
for reason in final_state.confidence_reasons:
|
|
136
145
|
console.print(f" [dim]• {reason}[/dim]")
|
|
137
146
|
|
|
138
|
-
# Sandbox apply
|
|
147
|
+
# Sandbox apply / Dry Run
|
|
139
148
|
if sandbox and sandbox.is_active:
|
|
149
|
+
if config.dry_run:
|
|
150
|
+
console.print("\n[bold yellow][DRY RUN][/bold yellow] Completed. No changes applied.")
|
|
151
|
+
# Show diffs anyway to show what would have happened
|
|
152
|
+
for i, patch in enumerate(final_state.patches_applied):
|
|
153
|
+
console.print(f"\n[bold]Proposed Patch #{i+1}[/bold] for [cyan]{patch.get('file', 'unknown')}[/cyan]:")
|
|
154
|
+
console.print(f"[dim]{patch.get('diff', 'No diff available')}[/dim]")
|
|
155
|
+
sandbox.destroy()
|
|
156
|
+
return 0
|
|
157
|
+
|
|
140
158
|
if final_state.status == "success":
|
|
141
|
-
if
|
|
159
|
+
if config.interactive:
|
|
142
160
|
console.print("\n[bold yellow][INTERACTIVE][/bold yellow] Reviewing changes...")
|
|
143
161
|
# Show diff for each applied patch
|
|
144
162
|
for i, patch in enumerate(final_state.patches_applied):
|
|
@@ -159,7 +177,7 @@ def cmd_run(args):
|
|
|
159
177
|
sandbox.destroy()
|
|
160
178
|
|
|
161
179
|
# Git operations
|
|
162
|
-
if final_state.status == "success" and config.auto_commit:
|
|
180
|
+
if final_state.status == "success" and config.auto_commit and not config.dry_run:
|
|
163
181
|
_handle_git(root, config)
|
|
164
182
|
|
|
165
183
|
return 0 if final_state.status == "success" else 1
|
|
@@ -231,6 +249,13 @@ def cmd_models(args):
|
|
|
231
249
|
console.print("[red][ERROR][/red] Could not list Ollama models.")
|
|
232
250
|
return 0
|
|
233
251
|
|
|
252
|
+
def cmd_rollback(args):
|
|
253
|
+
"""Implementation of 'devagent rollback' command."""
|
|
254
|
+
from devagent.utils.safety import SafetyManager
|
|
255
|
+
root = os.path.abspath(getattr(args, "root", "."))
|
|
256
|
+
safety = SafetyManager(root)
|
|
257
|
+
return 0 if safety.rollback() else 1
|
|
258
|
+
|
|
234
259
|
def main():
|
|
235
260
|
parser = argparse.ArgumentParser(description="DevAgent CLI — Professional local coding agent.")
|
|
236
261
|
parser.add_argument("--version", action="version", version=f"DevAgent v{__version__}")
|
|
@@ -247,6 +272,7 @@ def main():
|
|
|
247
272
|
run_parser.add_argument("--auto-commit", action="store_true", help="Auto-commit on success")
|
|
248
273
|
run_parser.add_argument("--auto-push", action="store_true", help="Auto-push after commit")
|
|
249
274
|
run_parser.add_argument("--interactive", "-i", action="store_true", help="Review changes before applying")
|
|
275
|
+
run_parser.add_argument("--dry-run", action="store_true", help="Run without applying any changes")
|
|
250
276
|
run_parser.add_argument("--verbose", action="store_true", help="Verbose output")
|
|
251
277
|
|
|
252
278
|
# Command: benchmark
|
|
@@ -260,6 +286,10 @@ def main():
|
|
|
260
286
|
# Command: models
|
|
261
287
|
subparsers.add_parser("models", help="List installed Ollama models")
|
|
262
288
|
|
|
289
|
+
# Command: rollback
|
|
290
|
+
roll_parser = subparsers.add_parser("rollback", help="Revert the last agent changes")
|
|
291
|
+
roll_parser.add_argument("--root", "-r", default=".", help="Project root")
|
|
292
|
+
|
|
263
293
|
# Command: version
|
|
264
294
|
subparsers.add_parser("version", help="Show version")
|
|
265
295
|
|
|
@@ -273,6 +303,8 @@ def main():
|
|
|
273
303
|
sys.exit(cmd_doctor(args))
|
|
274
304
|
elif args.command == "models":
|
|
275
305
|
sys.exit(cmd_models(args))
|
|
306
|
+
elif args.command == "rollback":
|
|
307
|
+
sys.exit(cmd_rollback(args))
|
|
276
308
|
elif args.command == "version":
|
|
277
309
|
console.print(f"DevAgent CLI v{__version__}")
|
|
278
310
|
else:
|
|
@@ -53,6 +53,7 @@ class AgentConfig:
|
|
|
53
53
|
|
|
54
54
|
# ── Feature flags ──
|
|
55
55
|
sandbox: bool = True
|
|
56
|
+
dry_run: bool = False
|
|
56
57
|
auto_commit: bool = False
|
|
57
58
|
auto_push: bool = False # DISABLED by default — safety first
|
|
58
59
|
benchmark: bool = False
|
|
@@ -98,6 +99,7 @@ class AgentConfig:
|
|
|
98
99
|
max_steps=getattr(args, "max_steps", 5),
|
|
99
100
|
verbose=getattr(args, "verbose", False),
|
|
100
101
|
sandbox=getattr(args, "sandbox", True),
|
|
102
|
+
dry_run=getattr(args, "dry_run", False),
|
|
101
103
|
auto_commit=getattr(args, "auto_commit", False),
|
|
102
104
|
auto_push=getattr(args, "auto_push", False),
|
|
103
105
|
benchmark=getattr(args, "benchmark", False),
|
|
@@ -36,6 +36,7 @@ class RunMetrics:
|
|
|
36
36
|
end_time: float = 0.0
|
|
37
37
|
total_steps: int = 0
|
|
38
38
|
retries: int = 0
|
|
39
|
+
patch_rejections: int = 0
|
|
39
40
|
successes: int = 0
|
|
40
41
|
failures: int = 0
|
|
41
42
|
total_latency_s: float = 0.0
|
|
@@ -88,6 +89,7 @@ class RunMetrics:
|
|
|
88
89
|
"task": self.task[:100],
|
|
89
90
|
"total_steps": self.total_steps,
|
|
90
91
|
"retries": self.retries,
|
|
92
|
+
"patch_rejections": self.patch_rejections,
|
|
91
93
|
"successes": self.successes,
|
|
92
94
|
"failures": self.failures,
|
|
93
95
|
"total_latency_s": round(self.total_latency_s, 2),
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Safety Manager — handles snapshots and rollbacks.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import time
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from devagent.tools.git_tools import is_git_repo
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
class SafetyManager:
|
|
14
|
+
def __init__(self, project_root: str):
|
|
15
|
+
self.root = os.path.abspath(project_root)
|
|
16
|
+
self.snapshot_dir = os.path.join(self.root, ".devagent", "snapshots")
|
|
17
|
+
|
|
18
|
+
def create_snapshot(self, task_id: str = "latest") -> str:
|
|
19
|
+
"""Create a safety snapshot of the current project state."""
|
|
20
|
+
if is_git_repo(self.root):
|
|
21
|
+
# For git repos, we rely on the user's ability to git checkout
|
|
22
|
+
# but we could also do a 'git stash' here for safety.
|
|
23
|
+
return "git"
|
|
24
|
+
|
|
25
|
+
# For non-git repos, we do a physical backup of .py files
|
|
26
|
+
os.makedirs(self.snapshot_dir, exist_ok=True)
|
|
27
|
+
timestamp = int(time.time())
|
|
28
|
+
dest = os.path.join(self.snapshot_dir, f"{task_id}_{timestamp}")
|
|
29
|
+
|
|
30
|
+
# Simple copy of python files
|
|
31
|
+
os.makedirs(dest, exist_ok=True)
|
|
32
|
+
for root, _, files in os.walk(self.root):
|
|
33
|
+
if ".devagent" in root or "venv" in root:
|
|
34
|
+
continue
|
|
35
|
+
for f in files:
|
|
36
|
+
if f.endswith(".py"):
|
|
37
|
+
src_file = os.path.join(root, f)
|
|
38
|
+
rel_path = os.path.relpath(src_file, self.root)
|
|
39
|
+
target_file = os.path.join(dest, rel_path)
|
|
40
|
+
os.makedirs(os.path.dirname(target_file), exist_ok=True)
|
|
41
|
+
shutil.copy2(src_file, target_file)
|
|
42
|
+
|
|
43
|
+
return dest
|
|
44
|
+
|
|
45
|
+
def rollback(self, snapshot_id: str = "latest") -> bool:
|
|
46
|
+
"""Rollback the project to a previous snapshot."""
|
|
47
|
+
if is_git_repo(self.root):
|
|
48
|
+
console.print("[bold yellow][SAFETY][/bold yellow] This is a Git repository. Use [bold cyan]git checkout .[/bold cyan] to rollback.")
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
# Find latest snapshot if not specified
|
|
52
|
+
if not os.path.exists(self.snapshot_dir):
|
|
53
|
+
console.print("[bold red][ERROR][/bold red] No snapshots found.")
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
snapshots = sorted(os.listdir(self.snapshot_dir))
|
|
57
|
+
if not snapshots:
|
|
58
|
+
console.print("[bold red][ERROR][/bold red] No snapshots found.")
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
target = os.path.join(self.snapshot_dir, snapshots[-1])
|
|
62
|
+
console.print(f"[bold yellow][SAFETY][/bold yellow] Rolling back from {target}...")
|
|
63
|
+
|
|
64
|
+
# Restore files
|
|
65
|
+
for root, _, files in os.walk(target):
|
|
66
|
+
for f in files:
|
|
67
|
+
src_file = os.path.join(root, f)
|
|
68
|
+
rel_path = os.path.relpath(src_file, target)
|
|
69
|
+
dest_file = os.path.join(self.root, rel_path)
|
|
70
|
+
shutil.copy2(src_file, dest_file)
|
|
71
|
+
|
|
72
|
+
console.print("[bold green]Rollback complete.[/bold green]")
|
|
73
|
+
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devagent-cli
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.2
|
|
4
4
|
Summary: Professional Local autonomous coding agent powered by Ollama
|
|
5
5
|
Author: Vedant Jadhav
|
|
6
6
|
License: MIT
|
|
@@ -31,6 +31,7 @@ Dynamic: license-file
|
|
|
31
31
|
### A Lightweight Local Open-Source Miniature of Claude Code CLI
|
|
32
32
|
|
|
33
33
|
[](https://opensource.org/licenses/MIT)
|
|
34
|
+
[](https://badge.fury.io/py/devagent-cli)
|
|
34
35
|
[](https://www.python.org/)
|
|
35
36
|
[](https://ollama.ai)
|
|
36
37
|
[](CONTRIBUTING.md)
|
|
@@ -140,16 +141,16 @@ devagent run --task "Fix the divide-by-zero bug" --root ./demo_project
|
|
|
140
141
|
| `devagent models` | List available Ollama models |
|
|
141
142
|
| `devagent version` | Show current version |
|
|
142
143
|
|
|
143
|
-
###
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
- **
|
|
148
|
-
- **Forensic Test Detection**:
|
|
149
|
-
- **
|
|
144
|
+
### 🛡️ Reliability & Safety (v3.2.1+)
|
|
145
|
+
DevAgent is built for **Enterprise-grade safety**:
|
|
146
|
+
- **Dry Run Mode**: Use `--dry-run` to see what the agent *would* do without touching your files.
|
|
147
|
+
- **Auto-Snapshot**: Creates a safety restore point before every run.
|
|
148
|
+
- **Rollback**: Revert the last agent changes instantly with `devagent rollback`.
|
|
149
|
+
- **Forensic Test Detection**: Detects successful test runs even in noisy environments.
|
|
150
|
+
- **Path Anchoring**: Automatically corrects "root hallucinations" for subdirectories.
|
|
150
151
|
|
|
151
152
|
#### 🕹️ Interactive Mode
|
|
152
|
-
Run with `--interactive` (or `-i`) to review diffs before they are applied to your project.
|
|
153
|
+
Run with `--interactive` (or `-i`) to review colorized diffs before they are applied to your project.
|
|
153
154
|
```bash
|
|
154
155
|
devagent run --task "Fix bug" --interactive
|
|
155
156
|
```
|
|
@@ -161,6 +162,7 @@ devagent run --task "Fix bug" --interactive
|
|
|
161
162
|
```mermaid
|
|
162
163
|
graph TD
|
|
163
164
|
CLI[DevAgent CLI] --> Orchestrator[ReAct Orchestrator]
|
|
165
|
+
Orchestrator --> Safety[Safety Manager: Snapshots]
|
|
164
166
|
Orchestrator --> Memory[Working Memory]
|
|
165
167
|
Orchestrator --> Retrieval[Semantic Retrieval FAISS]
|
|
166
168
|
Orchestrator --> Tools[Tool Suite: pytest, ripgrep, git]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|