devagent-cli 3.2.2__tar.gz → 3.2.3__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 (37) hide show
  1. {devagent_cli-3.2.2/devagent_cli.egg-info → devagent_cli-3.2.3}/PKG-INFO +1 -1
  2. devagent_cli-3.2.3/devagent/__init__.py +1 -0
  3. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/agent.py +18 -0
  4. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/state.py +1 -0
  5. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/cli.py +16 -1
  6. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/utils/config.py +2 -0
  7. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/utils/safety.py +20 -3
  8. {devagent_cli-3.2.2 → devagent_cli-3.2.3/devagent_cli.egg-info}/PKG-INFO +1 -1
  9. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/pyproject.toml +1 -1
  10. devagent_cli-3.2.2/devagent/__init__.py +0 -1
  11. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/LICENSE +0 -0
  12. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/README.md +0 -0
  13. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/__init__.py +0 -0
  14. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/llm.py +0 -0
  15. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/memory.py +0 -0
  16. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/patcher.py +0 -0
  17. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/planner.py +0 -0
  18. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/reviewer.py +0 -0
  19. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/app/sandbox.py +0 -0
  20. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/__init__.py +0 -0
  21. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/benchmark_runner.py +0 -0
  22. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/file_ops.py +0 -0
  23. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/git_tools.py +0 -0
  24. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/linter.py +0 -0
  25. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/search.py +0 -0
  26. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/semantic_search.py +0 -0
  27. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/surgical_patcher.py +0 -0
  28. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/tools/test_runner.py +0 -0
  29. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/utils/__init__.py +0 -0
  30. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/utils/logger.py +0 -0
  31. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent/utils/metrics.py +0 -0
  32. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent_cli.egg-info/SOURCES.txt +0 -0
  33. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent_cli.egg-info/dependency_links.txt +0 -0
  34. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent_cli.egg-info/entry_points.txt +0 -0
  35. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent_cli.egg-info/requires.txt +0 -0
  36. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/devagent_cli.egg-info/top_level.txt +0 -0
  37. {devagent_cli-3.2.2 → devagent_cli-3.2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-cli
3
- Version: 3.2.2
3
+ Version: 3.2.3
4
4
  Summary: Professional Local autonomous coding agent powered by Ollama
5
5
  Author: Vedant Jadhav
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ __version__ = "3.2.3"
@@ -280,6 +280,12 @@ class Agent:
280
280
  observation = self._execute_action(action_name, action_arg)
281
281
  self.state.last_observation = observation
282
282
  self.state.observations.append(observation[:2000])
283
+
284
+ self.state.explanations.append({
285
+ "type": "action",
286
+ "action": f"{action_name}: {action_arg}",
287
+ "reason": thought
288
+ })
283
289
 
284
290
  # STEP 3 — GENERATE FIX (if we have a file in context)
285
291
  code_fix = ""
@@ -555,9 +561,21 @@ class Agent:
555
561
  print(f" [REVIEW] #{revision + 1}: {review_text[:100]}")
556
562
 
557
563
  if approved:
564
+ self.state.explanations.append({
565
+ "type": "review",
566
+ "file": self.state.current_file,
567
+ "reason": review_text,
568
+ "status": "APPROVED"
569
+ })
558
570
  return code_fix, review_text
559
571
 
560
572
  self.metrics.patch_rejections += 1
573
+ self.state.explanations.append({
574
+ "type": "review",
575
+ "file": self.state.current_file,
576
+ "reason": review_text,
577
+ "status": "REJECTED"
578
+ })
561
579
  print(f" [REVISE] Revising code (attempt {revision + 1})...")
562
580
  code_fix = revise_code(code_fix, review_text, self.state.task)
563
581
  code_fix = self._strip_code_fences(code_fix)
@@ -73,6 +73,7 @@ class AgentState:
73
73
  # -- Trust & Confidence --
74
74
  confidence_score: float = 0.0
75
75
  confidence_reasons: list[str] = field(default_factory=list)
76
+ explanations: list[dict[str, str]] = field(default_factory=list)
76
77
 
77
78
  def to_dict(self) -> dict[str, Any]:
78
79
  """Return a JSON-serialisable snapshot of the current state."""
@@ -142,7 +142,21 @@ def cmd_run(args):
142
142
  if final_state.confidence_reasons:
143
143
  console.print("\n[bold]Confidence Breakdown:[/bold]")
144
144
  for reason in final_state.confidence_reasons:
145
- console.print(f" [dim] {reason}[/dim]")
145
+ console.print(f" [green]✓[/green] {reason}")
146
+
147
+ # Explain Mode
148
+ if config.explain and final_state.explanations:
149
+ console.print("\n" + "=" * 60)
150
+ console.print(" [bold cyan]TRACEABILITY REPORT (EXPLAIN MODE)[/bold cyan]")
151
+ console.print("=" * 60)
152
+ for exp in final_state.explanations:
153
+ if exp["type"] == "action":
154
+ console.print(f"\n[bold yellow]Selection:[/bold yellow] {exp['action']}")
155
+ console.print(f" [dim]Why:[/dim] {exp['reason']}")
156
+ elif exp["type"] == "review":
157
+ status_color = "green" if exp["status"] == "APPROVED" else "red"
158
+ console.print(f"\n[bold {status_color}]Review:[/bold {status_color}] {exp['file']} ({exp['status']})")
159
+ console.print(f" [dim]Logic:[/dim] {exp['reason']}")
146
160
 
147
161
  # Sandbox apply / Dry Run
148
162
  if sandbox and sandbox.is_active:
@@ -273,6 +287,7 @@ def main():
273
287
  run_parser.add_argument("--auto-push", action="store_true", help="Auto-push after commit")
274
288
  run_parser.add_argument("--interactive", "-i", action="store_true", help="Review changes before applying")
275
289
  run_parser.add_argument("--dry-run", action="store_true", help="Run without applying any changes")
290
+ run_parser.add_argument("--explain", action="store_true", help="Explain why files were chosen and patches applied")
276
291
  run_parser.add_argument("--verbose", action="store_true", help="Verbose output")
277
292
 
278
293
  # Command: benchmark
@@ -54,6 +54,7 @@ class AgentConfig:
54
54
  # ── Feature flags ──
55
55
  sandbox: bool = True
56
56
  dry_run: bool = False
57
+ explain: bool = False
57
58
  auto_commit: bool = False
58
59
  auto_push: bool = False # DISABLED by default — safety first
59
60
  benchmark: bool = False
@@ -100,6 +101,7 @@ class AgentConfig:
100
101
  verbose=getattr(args, "verbose", False),
101
102
  sandbox=getattr(args, "sandbox", True),
102
103
  dry_run=getattr(args, "dry_run", False),
104
+ explain=getattr(args, "explain", False),
103
105
  auto_commit=getattr(args, "auto_commit", False),
104
106
  auto_push=getattr(args, "auto_push", False),
105
107
  benchmark=getattr(args, "benchmark", False),
@@ -5,6 +5,7 @@ Safety Manager — handles snapshots and rollbacks.
5
5
  import os
6
6
  import shutil
7
7
  import time
8
+ import subprocess
8
9
  from rich.console import Console
9
10
  from devagent.tools.git_tools import is_git_repo
10
11
 
@@ -13,7 +14,7 @@ console = Console()
13
14
  class SafetyManager:
14
15
  def __init__(self, project_root: str):
15
16
  self.root = os.path.abspath(project_root)
16
- self.snapshot_dir = os.path.join(self.root, ".devagent", "snapshots")
17
+ self.snapshot_dir = os.path.join(self.root, ".devagent_backups")
17
18
 
18
19
  def create_snapshot(self, task_id: str = "latest") -> str:
19
20
  """Create a safety snapshot of the current project state."""
@@ -40,13 +41,29 @@ class SafetyManager:
40
41
  os.makedirs(os.path.dirname(target_file), exist_ok=True)
41
42
  shutil.copy2(src_file, target_file)
42
43
 
44
+ # Save metadata
45
+ metadata = {
46
+ "task_id": task_id,
47
+ "timestamp": timestamp,
48
+ "root": self.root
49
+ }
50
+ with open(os.path.join(dest, "metadata.json"), "w") as f:
51
+ import json
52
+ json.dump(metadata, f, indent=2)
53
+
43
54
  return dest
44
55
 
45
56
  def rollback(self, snapshot_id: str = "latest") -> bool:
46
57
  """Rollback the project to a previous snapshot."""
47
58
  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
59
+ console.print("[bold yellow][SAFETY][/bold yellow] This is a Git repository. Reverting all local changes...")
60
+ try:
61
+ subprocess.run(["git", "checkout", "."], cwd=self.root, check=True, capture_output=True)
62
+ console.print("[bold green]Git rollback complete.[/bold green]")
63
+ return True
64
+ except Exception as e:
65
+ console.print(f"[bold red][ERROR][/bold red] Git rollback failed: {e}")
66
+ return False
50
67
 
51
68
  # Find latest snapshot if not specified
52
69
  if not os.path.exists(self.snapshot_dir):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-cli
3
- Version: 3.2.2
3
+ Version: 3.2.3
4
4
  Summary: Professional Local autonomous coding agent powered by Ollama
5
5
  Author: Vedant Jadhav
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-cli"
7
- version = "3.2.2"
7
+ version = "3.2.3"
8
8
  description = "Professional Local autonomous coding agent powered by Ollama"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1 +0,0 @@
1
- __version__ = "3.2.1"
File without changes
File without changes
File without changes