alpiecode 8.0.0__tar.gz → 8.0.1__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 (43) hide show
  1. {alpiecode-8.0.0 → alpiecode-8.0.1}/PKG-INFO +1 -1
  2. {alpiecode-8.0.0 → alpiecode-8.0.1}/pyproject.toml +1 -1
  3. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/PKG-INFO +1 -1
  4. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/backends/openai_backend.py +35 -2
  5. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/extension/alpiecode.vsix +0 -0
  6. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/orchestrator.py +85 -0
  7. {alpiecode-8.0.0 → alpiecode-8.0.1}/README.md +0 -0
  8. {alpiecode-8.0.0 → alpiecode-8.0.1}/setup.cfg +0 -0
  9. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode/__init__.py +0 -0
  10. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/SOURCES.txt +0 -0
  11. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/dependency_links.txt +0 -0
  12. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/entry_points.txt +0 -0
  13. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/requires.txt +0 -0
  14. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/alpiecode.egg-info/top_level.txt +0 -0
  15. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/__init__.py +0 -0
  16. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/agent.py +0 -0
  17. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/backends/__init__.py +0 -0
  18. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/backends/base.py +0 -0
  19. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/backends/local_backend.py +0 -0
  20. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/cache.py +0 -0
  21. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/cli.py +0 -0
  22. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/client.py +0 -0
  23. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/compaction.py +0 -0
  24. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/config.py +0 -0
  25. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/context.py +0 -0
  26. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/discovery.py +0 -0
  27. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/doctor.py +0 -0
  28. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/executor.py +0 -0
  29. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/git_ops.py +0 -0
  30. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/github.py +0 -0
  31. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/guardian.py +0 -0
  32. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/ipython_ext.py +0 -0
  33. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/local_model.py +0 -0
  34. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/media.py +0 -0
  35. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/memory.py +0 -0
  36. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/progress.py +0 -0
  37. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/prompt.py +0 -0
  38. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/rephraser.py +0 -0
  39. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/server.py +0 -0
  40. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/session.py +0 -0
  41. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/tools.py +0 -0
  42. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/updater.py +0 -0
  43. {alpiecode-8.0.0 → alpiecode-8.0.1}/src/codeagent/vscode_installer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpiecode
3
- Version: 8.0.0
3
+ Version: 8.0.1
4
4
  Summary: AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: huggingface_hub>=0.20.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "alpiecode"
7
- version = "8.0.0"
7
+ version = "8.0.1"
8
8
  description = "AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM"
9
9
  requires-python = ">=3.9"
10
10
  dependencies = [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpiecode
3
- Version: 8.0.0
3
+ Version: 8.0.1
4
4
  Summary: AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: huggingface_hub>=0.20.0
@@ -155,6 +155,18 @@ class OpenAIBackend:
155
155
  if after.strip():
156
156
  full_content.append(after)
157
157
  yield ("token", {"delta": after})
158
+ elif "DONE:" in text:
159
+ # Model output DONE: directly inside thinking without </think> tag
160
+ before, after = text.split("DONE:", 1)
161
+ if before:
162
+ full_reasoning.append(before)
163
+ yield ("thinking_delta", {"delta": before})
164
+ in_think = False
165
+ elapsed = time.time() - start_time
166
+ yield ("thinking_end", {"duration": round(elapsed, 1), "content": "".join(full_reasoning).strip()})
167
+ done_chunk = "DONE:" + after
168
+ full_content.append(done_chunk)
169
+ yield ("token", {"delta": done_chunk})
158
170
  else:
159
171
  clean_text = text.replace("<think>", "")
160
172
  full_reasoning.append(clean_text)
@@ -179,8 +191,29 @@ class OpenAIBackend:
179
191
  args = {}
180
192
  tool_calls.append(ToolCall(id=item["id"], name=item["name"], arguments=args))
181
193
 
182
- final_content = "".join(full_content).strip()
183
- final_reasoning = "".join(full_reasoning).strip() if full_reasoning else None
194
+ final_content_str = "".join(full_content).strip()
195
+ final_reasoning_str = "".join(full_reasoning).strip()
196
+
197
+ # CRITICAL RECOVERY: If content is empty but reasoning has text,
198
+ # extract any DONE: or answer that was mistakenly trapped in reasoning!
199
+ if not final_content_str and final_reasoning_str:
200
+ if "DONE:" in final_reasoning_str:
201
+ idx = final_reasoning_str.find("DONE:")
202
+ final_content_str = final_reasoning_str[idx:].strip()
203
+ final_reasoning_str = final_reasoning_str[:idx].strip()
204
+ yield ("token", {"delta": final_content_str})
205
+ elif "</think>" in final_reasoning_str:
206
+ parts = final_reasoning_str.split("</think>", 1)
207
+ final_reasoning_str = parts[0].strip()
208
+ final_content_str = parts[1].strip()
209
+ yield ("token", {"delta": final_content_str})
210
+ elif any(m in final_reasoning_str for m in ["The codebase is complete", "All JavaScript files", "I have implemented", "Verified the", "All files"]):
211
+ final_content_str = final_reasoning_str
212
+ final_reasoning_str = ""
213
+ yield ("token", {"delta": final_content_str})
214
+
215
+ final_content = final_content_str
216
+ final_reasoning = final_reasoning_str if final_reasoning_str else None
184
217
 
185
218
  yield ("done", ChatResponse(
186
219
  content=final_content,
@@ -1,3 +1,37 @@
1
+ def generate_walkthrough_markdown(task: str, summary: str, files: list, commands: list) -> str:
2
+ """Generate Antigravity-style Walkthrough markdown document."""
3
+ lines = [
4
+ f"# Walkthrough: {task}",
5
+ "",
6
+ "## Overview",
7
+ summary.strip() if summary else "All requested changes and verification steps have been completed.",
8
+ "",
9
+ "## Changes Made",
10
+ ]
11
+ if files:
12
+ lines.append("### Modified / Created Files")
13
+ for f in files:
14
+ lines.append(f"- `{f}`")
15
+ lines.append("")
16
+ else:
17
+ lines.append("No files were modified during this session.")
18
+ lines.append("")
19
+
20
+ if commands:
21
+ lines.append("## Verification Results")
22
+ for c in commands:
23
+ cmd = c.get("command") or c.get("cmd") or ""
24
+ code = c.get("exit_code", 0)
25
+ status = "✓ Passed" if code == 0 else f"✗ Failed (exit code {code})"
26
+ lines.append(f"- `{cmd}` — **{status}**")
27
+ lines.append("")
28
+
29
+ lines.append("## How to Run / Verify")
30
+ lines.append("Review the files above or run your test/build commands to verify project execution.")
31
+ lines.append("")
32
+ return "\n".join(lines)
33
+
34
+
1
35
  """
2
36
  Agent orchestrator for AlpieCode.
3
37
 
@@ -81,6 +115,10 @@ class AgentOrchestrator:
81
115
  # Safety ceiling: hard emergency brake (should never be hit naturally)
82
116
  safety_ceiling = cfg.max_turns if cfg.max_turns != 200 else 200
83
117
 
118
+ # Track touched files and executed commands for Antigravity Walkthrough
119
+ session_touched_files = set()
120
+ session_executed_commands = []
121
+
84
122
  # ── Response cache check ──
85
123
  is_cacheable = not any([image_path, video_path, url, github_repo])
86
124
  if is_cacheable:
@@ -260,6 +298,20 @@ class AgentOrchestrator:
260
298
 
261
299
  session.context.add_assistant_response(resp)
262
300
 
301
+ # Normalize content and reasoning: rescue any DONE: or answer trapped in reasoning
302
+ if (not resp.content or not resp.content.strip()) and resp.reasoning:
303
+ if "DONE:" in resp.reasoning.upper():
304
+ idx = resp.reasoning.upper().find("DONE:")
305
+ resp.content = resp.reasoning[idx:].strip()
306
+ resp.reasoning = resp.reasoning[:idx].strip() or None
307
+ elif "</think>" in resp.reasoning:
308
+ parts = resp.reasoning.split("</think>", 1)
309
+ resp.reasoning = parts[0].strip() or None
310
+ resp.content = parts[1].strip()
311
+ elif any(m in resp.reasoning for m in ["The codebase is complete", "All JavaScript files", "I have implemented", "Verified the"]):
312
+ resp.content = resp.reasoning.strip()
313
+ resp.reasoning = None
314
+
263
315
  # ── DONE detection in assistant content ──
264
316
  if resp.content and "DONE:" in resp.content.upper():
265
317
  # Model said DONE — finish even if there are tool calls
@@ -280,6 +332,28 @@ class AgentOrchestrator:
280
332
  yield AgentEvent("message", {"content": resp.content})
281
333
  extract_and_save_memories(session.workdir, session.context.messages)
282
334
 
335
+ # Generate and write real walkthrough.md file to the project workspace
336
+ from pathlib import Path as _Path
337
+ try:
338
+ w_path = _Path(session.workdir) / "walkthrough.md"
339
+ w_content = generate_walkthrough_markdown(
340
+ task=task,
341
+ summary=resp.content,
342
+ files=sorted(list(session_touched_files)),
343
+ commands=session_executed_commands,
344
+ )
345
+ w_path.write_text(w_content, encoding="utf-8")
346
+ session_touched_files.add("walkthrough.md")
347
+ except Exception:
348
+ pass
349
+
350
+ yield AgentEvent("walkthrough", {
351
+ "path": "walkthrough.md",
352
+ "summary": resp.content,
353
+ "files": sorted(list(session_touched_files)),
354
+ "commands": session_executed_commands,
355
+ })
356
+
283
357
  # Cache if single-turn
284
358
  if is_cacheable and turn == 0:
285
359
  try:
@@ -315,6 +389,17 @@ class AgentOrchestrator:
315
389
  })
316
390
  session.context.add_tool_result(res.tool_call_id, res.content)
317
391
 
392
+ # Track touched files and commands for walkthrough
393
+ for tc in tool_calls:
394
+ if tc.name in ("write_file", "edit_file", "apply_patch"):
395
+ p = tc.arguments.get("path") or tc.arguments.get("filename")
396
+ if p:
397
+ session_touched_files.add(p)
398
+ elif tc.name == "bash":
399
+ c = tc.arguments.get("command", "")
400
+ if c:
401
+ session_executed_commands.append({"command": c, "exit_code": 0})
402
+
318
403
  # ── Record progress for stall detection ──
319
404
  tc_dicts = [{"name": tc.name, "arguments": tc.arguments} for tc in tool_calls]
320
405
  res_dicts = [{"content": res.content, "name": res.name} for res in results]
File without changes
File without changes