alpiecode 6.1.0__tar.gz → 6.2.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.
- {alpiecode-6.1.0 → alpiecode-6.2.0}/PKG-INFO +1 -1
- {alpiecode-6.1.0 → alpiecode-6.2.0}/pyproject.toml +1 -1
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/PKG-INFO +1 -1
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/agent.py +93 -54
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/cli.py +0 -3
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/guardian.py +5 -2
- {alpiecode-6.1.0 → alpiecode-6.2.0}/README.md +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/setup.cfg +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode/__init__.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/SOURCES.txt +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/dependency_links.txt +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/entry_points.txt +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/requires.txt +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/alpiecode.egg-info/top_level.txt +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/__init__.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/backends/__init__.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/backends/base.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/backends/local_backend.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/backends/openai_backend.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/cache.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/client.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/compaction.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/config.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/context.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/discovery.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/doctor.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/executor.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/extension/alpiecode.vsix +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/github.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/ipython_ext.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/local_model.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/media.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/memory.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/orchestrator.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/progress.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/prompt.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/server.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/session.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/tools.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/updater.py +0 -0
- {alpiecode-6.1.0 → alpiecode-6.2.0}/src/codeagent/vscode_installer.py +0 -0
|
@@ -65,45 +65,88 @@ except ImportError:
|
|
|
65
65
|
def _print_reasoning(reasoning: str):
|
|
66
66
|
if not reasoning or not reasoning.strip():
|
|
67
67
|
return
|
|
68
|
+
clean = reasoning.strip()
|
|
68
69
|
if HAS_RICH:
|
|
69
|
-
|
|
70
|
-
console.print(Panel(text, title="💭 Thinking", border_style="dim blue", padding=(0, 1)))
|
|
70
|
+
console.print(Text(f"💭 {clean}", style="dim italic"))
|
|
71
71
|
else:
|
|
72
|
-
console.print(f"
|
|
72
|
+
console.print(f"💭 {clean}")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _format_tool_summary(name: str, args: dict) -> str:
|
|
76
|
+
if not isinstance(args, dict):
|
|
77
|
+
return ""
|
|
78
|
+
if name == "bash":
|
|
79
|
+
cmd = args.get("command", "").strip()
|
|
80
|
+
return f"$ {cmd[:80]}..." if len(cmd) > 80 else f"$ {cmd}"
|
|
81
|
+
elif name in ("write_file", "edit_file", "read_file"):
|
|
82
|
+
path = args.get("path", "")
|
|
83
|
+
extra = ""
|
|
84
|
+
if name == "write_file" and "content" in args:
|
|
85
|
+
lines = len(str(args["content"]).splitlines())
|
|
86
|
+
extra = f" ({lines} lines)"
|
|
87
|
+
return f"{path}{extra}"
|
|
88
|
+
elif name == "list_files":
|
|
89
|
+
return args.get("path", ".")
|
|
90
|
+
elif name in ("search", "web_search"):
|
|
91
|
+
return f"'{args.get('query', '')}'"
|
|
92
|
+
elif name == "fetch_web_page":
|
|
93
|
+
return args.get("url", "")
|
|
94
|
+
else:
|
|
95
|
+
parts = [f"{k}={repr(v)[:30]}" for k, v in args.items() if k != "content"]
|
|
96
|
+
return " ".join(parts)
|
|
73
97
|
|
|
74
98
|
|
|
75
99
|
def _print_tool_call(turn: int, name: str, args: dict):
|
|
76
|
-
|
|
77
|
-
for k, v in args.items():
|
|
78
|
-
if isinstance(v, str) and len(v) > 200:
|
|
79
|
-
display_args[k] = v[:200] + "..."
|
|
80
|
-
else:
|
|
81
|
-
display_args[k] = v
|
|
100
|
+
summary = _format_tool_summary(name, args)
|
|
82
101
|
if HAS_RICH:
|
|
83
|
-
|
|
84
|
-
console.print(f"\n🔧 [bold cyan]Tool:[/bold cyan] [bold]{name}[/bold]", highlight=False)
|
|
85
|
-
console.print(Text(f" {args_str}", style="cyan"))
|
|
102
|
+
console.print(f"\n⏺ [bold cyan]{name}[/bold cyan] [white]{summary}[/white]")
|
|
86
103
|
else:
|
|
87
|
-
console.print(f"\n
|
|
104
|
+
console.print(f"\n⏺ {name} {summary}")
|
|
88
105
|
|
|
89
106
|
|
|
90
107
|
def _print_tool_result(result: str):
|
|
91
|
-
|
|
108
|
+
clean = result.strip()
|
|
109
|
+
if '"exit_code"' in clean:
|
|
110
|
+
try:
|
|
111
|
+
data = json.loads(clean.split("\n", 1)[-1] if clean.startswith("⚠️") else clean)
|
|
112
|
+
out = data.get("stdout", "").strip()
|
|
113
|
+
err = data.get("stderr", "").strip()
|
|
114
|
+
code = data.get("exit_code", 0)
|
|
115
|
+
if code == 0:
|
|
116
|
+
clean = out if out else "success"
|
|
117
|
+
else:
|
|
118
|
+
clean = f"exit {code}: {err}" if err else f"exit {code}"
|
|
119
|
+
except Exception:
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
lines = clean.splitlines()
|
|
123
|
+
if len(lines) > 8:
|
|
124
|
+
display = "\n".join(lines[:6]) + f"\n ... ({len(lines)-6} lines omitted)"
|
|
125
|
+
else:
|
|
126
|
+
display = clean[:500] + ("..." if len(clean) > 500 else "")
|
|
127
|
+
|
|
92
128
|
if HAS_RICH:
|
|
93
|
-
|
|
129
|
+
style = "dim green" if not ("exit 1" in clean or "error:" in clean.lower()[:30]) else "dim red"
|
|
130
|
+
console.print(Text(f" └ {display}", style=style))
|
|
94
131
|
else:
|
|
95
|
-
console.print(f"
|
|
132
|
+
console.print(f" └ {display}")
|
|
96
133
|
|
|
97
134
|
|
|
98
135
|
def _print_assistant_message(content: str):
|
|
136
|
+
if not content or not content.strip():
|
|
137
|
+
return
|
|
138
|
+
text = content.strip()
|
|
139
|
+
if text.upper().startswith("DONE:"):
|
|
140
|
+
text = text[5:].strip()
|
|
99
141
|
if HAS_RICH:
|
|
100
142
|
try:
|
|
101
|
-
|
|
102
|
-
console.print(
|
|
143
|
+
console.print()
|
|
144
|
+
console.print(Markdown(text))
|
|
103
145
|
except Exception:
|
|
104
|
-
console.print(
|
|
146
|
+
console.print()
|
|
147
|
+
console.print(text)
|
|
105
148
|
else:
|
|
106
|
-
|
|
149
|
+
print(f"\n{text}")
|
|
107
150
|
|
|
108
151
|
|
|
109
152
|
# ── Git helpers ───────────────────────────────────────────────────────
|
|
@@ -227,9 +270,27 @@ def run_agent(
|
|
|
227
270
|
|
|
228
271
|
elif event.type == "start" and verbose:
|
|
229
272
|
data = event.data
|
|
230
|
-
if
|
|
231
|
-
|
|
232
|
-
|
|
273
|
+
if debug:
|
|
274
|
+
if HAS_RICH:
|
|
275
|
+
console.rule("[bold blue]Agent Started (Debug)[/bold blue]")
|
|
276
|
+
console.print(Text(f"📋 Task: {task.splitlines()[0]}", style="bold"))
|
|
277
|
+
console.print(f"📂 Workdir: {workdir}", style="dim")
|
|
278
|
+
mode_str = "[bold green]ONLINE[/bold green]" if not data["is_offline"] else "[bold yellow]OFFLINE[/bold yellow]"
|
|
279
|
+
console.print(f"🌐 Mode: {mode_str}", style="dim")
|
|
280
|
+
comp = data.get("complexity", "low")
|
|
281
|
+
comp_label = {"qa": "Q&A (instant)", "low": "Low (fast)", "medium": "Medium (balanced)", "high": "High (thorough)"}.get(comp, comp)
|
|
282
|
+
console.print(f"⚡ Complexity: {comp_label}", style="dim")
|
|
283
|
+
if last_discovery:
|
|
284
|
+
console.print(f"🔍 Discovery: {last_discovery.get('intent', 'create')} on {last_discovery.get('project_type', 'empty')} project", style="dim")
|
|
285
|
+
else:
|
|
286
|
+
print(f"[Start] task={task.splitlines()[0]}, mode={'offline' if data['is_offline'] else 'online'}")
|
|
287
|
+
else:
|
|
288
|
+
# Clean, professional presentation like Claude Code / Codex
|
|
289
|
+
if data.get("is_offline"):
|
|
290
|
+
if HAS_RICH:
|
|
291
|
+
console.print("[dim yellow]⚡ Offline mode[/dim yellow]")
|
|
292
|
+
else:
|
|
293
|
+
print("⚡ Offline mode")
|
|
233
294
|
if github_repo:
|
|
234
295
|
console.print(f"🐙 GitHub Repo: {github_repo}", style="cyan")
|
|
235
296
|
if image_path:
|
|
@@ -238,36 +299,17 @@ def run_agent(
|
|
|
238
299
|
console.print(f"🎬 Video: {video_path}", style="cyan")
|
|
239
300
|
if url:
|
|
240
301
|
console.print(f"📺 URL: {url}", style="cyan")
|
|
241
|
-
console.print(f"📂 Workdir: {workdir}", style="dim")
|
|
242
|
-
if not data["is_offline"]:
|
|
243
|
-
console.print(f"🌐 Mode: [bold green]ONLINE[/bold green]", style="dim")
|
|
244
|
-
else:
|
|
245
|
-
console.print(f"🧠 Mode: [bold yellow]OFFLINE[/bold yellow]", style="dim")
|
|
246
|
-
comp = data.get("complexity", "low")
|
|
247
|
-
comp_label = {"qa": "Q&A (instant)", "low": "Low (fast)", "medium": "Medium (balanced)", "high": "High (thorough)"}.get(comp, comp)
|
|
248
|
-
comp_color = {"qa": "cyan", "low": "green", "medium": "yellow", "high": "red"}.get(comp, "white")
|
|
249
|
-
console.print(f"⚡ Complexity: [bold {comp_color}]{comp_label}[/bold {comp_color}]", style="dim")
|
|
250
|
-
if last_discovery:
|
|
251
|
-
intent_str = last_discovery.get('intent', 'create').title()
|
|
252
|
-
proj_str = last_discovery.get('project_type', 'empty')
|
|
253
|
-
console.print(f"🔍 Discovery: {intent_str} on {proj_str} project ({last_discovery.get('shell', 'bash')})", style="dim")
|
|
254
|
-
if cfg.enable_thinking:
|
|
255
|
-
console.print(f"🧠 Reasoning: [bold green]ON[/bold green]", style="dim")
|
|
256
|
-
else:
|
|
257
|
-
console.rule("Agent Started")
|
|
258
|
-
console.print(f"📋 Task: {task.splitlines()[0]}")
|
|
259
|
-
console.print(f"📂 Workdir: {workdir}")
|
|
260
302
|
|
|
261
303
|
elif event.type == "adaptive_mode" and verbose and HAS_RICH:
|
|
262
304
|
console.print("⚡ [dim]Adaptive mode: simple task detected, skipping deep reasoning for speed[/dim]")
|
|
263
305
|
|
|
264
306
|
elif event.type == "turn_start":
|
|
265
307
|
current_turn = event.data["turn"]
|
|
266
|
-
if
|
|
308
|
+
if debug:
|
|
267
309
|
if HAS_RICH:
|
|
268
|
-
console.
|
|
310
|
+
console.print(f"[dim]── Step {current_turn} ──[/dim]")
|
|
269
311
|
else:
|
|
270
|
-
|
|
312
|
+
print(f"── Step {current_turn} ──")
|
|
271
313
|
|
|
272
314
|
elif event.type == "compaction" and verbose:
|
|
273
315
|
console.print("🗜️ Compacting context (approaching token limit)...", style="yellow")
|
|
@@ -338,13 +380,10 @@ def run_agent(
|
|
|
338
380
|
print(f"\n🛑 Safety ceiling ({event.data['ceiling']}) reached.")
|
|
339
381
|
|
|
340
382
|
elif event.type == "done":
|
|
341
|
-
summary = event.data
|
|
383
|
+
summary = event.data.get("summary", "")
|
|
342
384
|
_checkpoint(workdir, "checkpoint: done")
|
|
343
|
-
if
|
|
344
|
-
|
|
345
|
-
console.rule("[bold green]✅ Task Complete[/bold green]")
|
|
346
|
-
else:
|
|
347
|
-
console.rule("[bold yellow]💬 Agent Replied[/bold yellow]")
|
|
385
|
+
if debug and HAS_RICH:
|
|
386
|
+
console.rule("[bold green]✅ Complete[/bold green]")
|
|
348
387
|
|
|
349
388
|
elif event.type == "max_turns_reached" and verbose:
|
|
350
389
|
progress = event.data.get("progress", {})
|
|
@@ -410,11 +449,11 @@ def run_chat(workdir: Path, cfg: Config, verbose: bool = True) -> None:
|
|
|
410
449
|
break
|
|
411
450
|
|
|
412
451
|
for event in orchestrator.run_task(session, user_input, cfg):
|
|
413
|
-
if event.type == "turn_start" and
|
|
452
|
+
if event.type == "turn_start" and debug:
|
|
414
453
|
if HAS_RICH:
|
|
415
|
-
console.
|
|
454
|
+
console.print(f"[dim]── Step {event.data['turn']} ──[/dim]")
|
|
416
455
|
else:
|
|
417
|
-
|
|
456
|
+
print(f"── Step {event.data['turn']} ──")
|
|
418
457
|
|
|
419
458
|
elif event.type == "thinking" and verbose:
|
|
420
459
|
_print_reasoning(event.data["content"])
|
|
@@ -162,7 +162,6 @@ def main():
|
|
|
162
162
|
if args.command == "run":
|
|
163
163
|
if args.max_turns:
|
|
164
164
|
cfg.max_turns = args.max_turns
|
|
165
|
-
_show_banner()
|
|
166
165
|
from .agent import run_agent
|
|
167
166
|
run_agent(
|
|
168
167
|
args.task, Path(args.workdir), cfg,
|
|
@@ -182,7 +181,6 @@ def main():
|
|
|
182
181
|
run_chat(Path(args.workdir), cfg, verbose=not args.quiet)
|
|
183
182
|
|
|
184
183
|
elif args.command == "plan":
|
|
185
|
-
_show_banner()
|
|
186
184
|
plan_task = (
|
|
187
185
|
f"PLANNING ONLY — Do NOT make any file edits. "
|
|
188
186
|
f"Analyze the codebase and create a detailed implementation plan for the following task. "
|
|
@@ -206,7 +204,6 @@ def main():
|
|
|
206
204
|
sys.exit(run_doctor())
|
|
207
205
|
|
|
208
206
|
elif args.command == "explain":
|
|
209
|
-
_show_banner()
|
|
210
207
|
target = args.target
|
|
211
208
|
target_path = Path(args.workdir) / target if not Path(target).is_absolute() else Path(target)
|
|
212
209
|
if target_path.exists() and target_path.is_file():
|
|
@@ -48,6 +48,8 @@ SAFE_PREFIXES = [
|
|
|
48
48
|
"python -m pytest", "python3 -m pytest", "pytest", "npm test",
|
|
49
49
|
"npm run test", "make test", "cargo test", "go test",
|
|
50
50
|
"python -c", "python3 -c", "node -e",
|
|
51
|
+
"python3 ", "python ", "node ", "bun ", "deno ", "cargo ", "go ",
|
|
52
|
+
"make", "cmake", "gcc", "g++", "clang", "clang++", "./",
|
|
51
53
|
"tree", "sort", "uniq", "cut", "awk", "sed -n", "diff",
|
|
52
54
|
"env", "printenv", "set",
|
|
53
55
|
"type", "command -v",
|
|
@@ -138,8 +140,9 @@ def gate_command(command: str, auto_approve: bool = False) -> bool:
|
|
|
138
140
|
|
|
139
141
|
if risk == RiskLevel.WARNING:
|
|
140
142
|
if auto_approve:
|
|
141
|
-
if
|
|
142
|
-
|
|
143
|
+
if "Unknown command" not in reason:
|
|
144
|
+
if HAS_RICH:
|
|
145
|
+
console.print(Text(f" ⚠️ {reason}", style="yellow"))
|
|
143
146
|
return True
|
|
144
147
|
# In interactive mode, show warning but proceed
|
|
145
148
|
if HAS_RICH:
|
|
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
|
|
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
|