alpiecode 2.0.0__tar.gz → 2.0.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.
- {alpiecode-2.0.0 → alpiecode-2.0.2}/PKG-INFO +1 -1
- {alpiecode-2.0.0 → alpiecode-2.0.2}/pyproject.toml +1 -1
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/PKG-INFO +1 -1
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/SOURCES.txt +1 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/cli.py +48 -2
- alpiecode-2.0.2/src/codeagent/doctor.py +208 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/extension/alpiecode.vsix +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/README.md +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/setup.cfg +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/dependency_links.txt +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/entry_points.txt +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/requires.txt +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/alpiecode.egg-info/top_level.txt +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/__init__.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/agent.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/backends/__init__.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/backends/base.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/backends/local_backend.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/backends/openai_backend.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/cache.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/client.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/compaction.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/config.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/context.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/executor.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/github.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/guardian.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/local_model.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/media.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/memory.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/orchestrator.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/prompt.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/server.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/session.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/tools.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/updater.py +0 -0
- {alpiecode-2.0.0 → alpiecode-2.0.2}/src/codeagent/vscode_installer.py +0 -0
|
@@ -29,7 +29,7 @@ def _show_banner():
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def _normalize_args():
|
|
32
|
-
known_commands = {"init", "serve", "run", "chat", "plan", "diff", "-h", "--help", "--version"}
|
|
32
|
+
known_commands = {"init", "serve", "run", "chat", "plan", "diff", "doctor", "explain", "-h", "--help", "--version"}
|
|
33
33
|
subcommand = None
|
|
34
34
|
|
|
35
35
|
# Check if a subcommand is present
|
|
@@ -42,7 +42,7 @@ def _normalize_args():
|
|
|
42
42
|
subcommand = "run"
|
|
43
43
|
sys.argv.insert(1, "run")
|
|
44
44
|
|
|
45
|
-
if subcommand in ("run", "plan") and len(sys.argv) > 2:
|
|
45
|
+
if subcommand in ("run", "plan", "explain") and len(sys.argv) > 2:
|
|
46
46
|
cmd_idx = sys.argv.index(subcommand)
|
|
47
47
|
sub_args = sys.argv[cmd_idx + 1:]
|
|
48
48
|
|
|
@@ -107,6 +107,13 @@ def main():
|
|
|
107
107
|
# ── diff ──
|
|
108
108
|
diff_p = sub.add_parser("diff", help="Show changes AlpieCode has made since last checkpoint", parents=[common])
|
|
109
109
|
|
|
110
|
+
# ── doctor ──
|
|
111
|
+
sub.add_parser("doctor", help="Run system health checks (CUDA, Python, network, dev tools)")
|
|
112
|
+
|
|
113
|
+
# ── explain ──
|
|
114
|
+
explain_p = sub.add_parser("explain", help="Explain a file, function, or codebase concept", parents=[common])
|
|
115
|
+
explain_p.add_argument("target", help="File path or concept to explain")
|
|
116
|
+
|
|
110
117
|
args = parser.parse_args()
|
|
111
118
|
|
|
112
119
|
if not args.command:
|
|
@@ -117,6 +124,10 @@ def main():
|
|
|
117
124
|
interactive_init()
|
|
118
125
|
return
|
|
119
126
|
|
|
127
|
+
if args.command == "doctor":
|
|
128
|
+
from .doctor import run_doctor
|
|
129
|
+
sys.exit(run_doctor())
|
|
130
|
+
|
|
120
131
|
if args.command == "serve":
|
|
121
132
|
_show_banner()
|
|
122
133
|
try:
|
|
@@ -181,6 +192,41 @@ def main():
|
|
|
181
192
|
github_repo=getattr(args, "github", None),
|
|
182
193
|
)
|
|
183
194
|
|
|
195
|
+
elif args.command == "doctor":
|
|
196
|
+
from .doctor import run_doctor
|
|
197
|
+
sys.exit(run_doctor())
|
|
198
|
+
|
|
199
|
+
elif args.command == "explain":
|
|
200
|
+
_show_banner()
|
|
201
|
+
target = args.target
|
|
202
|
+
target_path = Path(args.workdir) / target if not Path(target).is_absolute() else Path(target)
|
|
203
|
+
if target_path.exists() and target_path.is_file():
|
|
204
|
+
content = target_path.read_text(encoding="utf-8", errors="replace")
|
|
205
|
+
explain_task = (
|
|
206
|
+
f"EXPLANATION ONLY — Do NOT make any file edits or run modifying commands.\n\n"
|
|
207
|
+
f"Please explain the file `{target}` in detail:\n"
|
|
208
|
+
f"1. Overview of its purpose and architecture role\n"
|
|
209
|
+
f"2. Key functions, classes, and internal logic\n"
|
|
210
|
+
f"3. Dependencies and connections to the rest of the project\n"
|
|
211
|
+
f"4. Step-by-step walkthrough of how it operates\n\n"
|
|
212
|
+
f"File content ({target}):\n```\n{content[:16000]}\n```"
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
explain_task = (
|
|
216
|
+
f"EXPLANATION ONLY — Do NOT make any file edits.\n\n"
|
|
217
|
+
f"Explain the following codebase concept, architecture, or question in detail:\n"
|
|
218
|
+
f"Topic: {target}\n\n"
|
|
219
|
+
f"Use read_file, file_search, or list_files if needed to understand the codebase context."
|
|
220
|
+
)
|
|
221
|
+
from .agent import run_agent
|
|
222
|
+
run_agent(
|
|
223
|
+
explain_task, Path(args.workdir), cfg, verbose=True,
|
|
224
|
+
image_path=args.image,
|
|
225
|
+
video_path=getattr(args, "video", None),
|
|
226
|
+
url=getattr(args, "url", None),
|
|
227
|
+
github_repo=getattr(args, "github", None),
|
|
228
|
+
)
|
|
229
|
+
|
|
184
230
|
elif args.command == "diff":
|
|
185
231
|
workdir = Path(args.workdir).resolve()
|
|
186
232
|
# Show git diff since the first checkpoint
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AlpieCode Doctor — Comprehensive System Diagnostic Tool.
|
|
3
|
+
|
|
4
|
+
Checks Python, CUDA/GPU, compilers, runtime tools, network connectivity,
|
|
5
|
+
local/remote VLM status, and VS Code extension health.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
import shutil
|
|
12
|
+
import socket
|
|
13
|
+
import subprocess
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Dict, List, Tuple
|
|
16
|
+
from urllib.parse import urlparse
|
|
17
|
+
|
|
18
|
+
from .config import load_config, is_server_reachable, is_internet_available
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _colorize(text: str, color: str) -> str:
|
|
22
|
+
colors = {
|
|
23
|
+
"green": "\033[92m",
|
|
24
|
+
"red": "\033[91m",
|
|
25
|
+
"yellow": "\033[93m",
|
|
26
|
+
"blue": "\033[94m",
|
|
27
|
+
"cyan": "\033[96m",
|
|
28
|
+
"bold": "\033[1m",
|
|
29
|
+
"dim": "\033[2m",
|
|
30
|
+
"reset": "\033[0m",
|
|
31
|
+
}
|
|
32
|
+
return f"{colors.get(color, '')}{text}{colors['reset']}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _check_command(cmd: str) -> Tuple[bool, str]:
|
|
36
|
+
"""Check if a CLI binary is available and return version if possible."""
|
|
37
|
+
path = shutil.which(cmd)
|
|
38
|
+
if not path:
|
|
39
|
+
return False, "not installed"
|
|
40
|
+
try:
|
|
41
|
+
res = subprocess.run([cmd, "--version"], capture_output=True, text=True, timeout=3)
|
|
42
|
+
out = (res.stdout or res.stderr or "").strip().split("\n")[0]
|
|
43
|
+
return True, out[:60] if out else "installed"
|
|
44
|
+
except Exception:
|
|
45
|
+
return True, "installed"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _check_gpu() -> Tuple[bool, str]:
|
|
49
|
+
"""Check NVIDIA GPU and CUDA support."""
|
|
50
|
+
nvidia_smi = shutil.which("nvidia-smi")
|
|
51
|
+
if not nvidia_smi:
|
|
52
|
+
return False, "No NVIDIA GPU detected (CPU mode)"
|
|
53
|
+
try:
|
|
54
|
+
res = subprocess.run(
|
|
55
|
+
[nvidia_smi, "--query-gpu=name,memory.total", "--format=csv,noheader"],
|
|
56
|
+
capture_output=True,
|
|
57
|
+
text=True,
|
|
58
|
+
timeout=3,
|
|
59
|
+
)
|
|
60
|
+
if res.returncode == 0 and res.stdout.strip():
|
|
61
|
+
gpu_info = res.stdout.strip().split("\n")[0]
|
|
62
|
+
return True, f"NVIDIA GPU: {gpu_info}"
|
|
63
|
+
except Exception:
|
|
64
|
+
pass
|
|
65
|
+
return True, "NVIDIA GPU driver present"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _check_remote_latency(base_url: str) -> Tuple[bool, str]:
|
|
69
|
+
"""Measure roundtrip latency to the remote VLM server."""
|
|
70
|
+
if not base_url:
|
|
71
|
+
return False, "No base_url configured"
|
|
72
|
+
try:
|
|
73
|
+
parsed = urlparse(base_url)
|
|
74
|
+
host = parsed.hostname
|
|
75
|
+
port = parsed.port or (443 if parsed.scheme == "https" else 80)
|
|
76
|
+
if not host:
|
|
77
|
+
return False, "Invalid base_url format"
|
|
78
|
+
|
|
79
|
+
t0 = time.perf_counter()
|
|
80
|
+
with socket.create_connection((host, port), timeout=3.0):
|
|
81
|
+
elapsed_ms = (time.perf_counter() - t0) * 1000.0
|
|
82
|
+
return True, f"Online ({elapsed_ms:.1f}ms latency)"
|
|
83
|
+
except Exception as e:
|
|
84
|
+
return False, f"Unreachable ({e})"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _check_vscode_extension() -> Tuple[bool, str]:
|
|
88
|
+
"""Check if the AlpieCode VS Code extension is installed."""
|
|
89
|
+
code_bin = shutil.which("code") or shutil.which("code.cmd") or shutil.which("code.exe")
|
|
90
|
+
if not code_bin:
|
|
91
|
+
return True, "VS Code CLI not in PATH (extension status unknown)"
|
|
92
|
+
try:
|
|
93
|
+
res = subprocess.run([code_bin, "--list-extensions"], capture_output=True, text=True, timeout=5)
|
|
94
|
+
if "alpiecode" in res.stdout.lower() or "169pi.alpiecode" in res.stdout.lower():
|
|
95
|
+
return True, "AlpieCode extension installed in VS Code"
|
|
96
|
+
return False, "AlpieCode extension not detected in VS Code"
|
|
97
|
+
except Exception:
|
|
98
|
+
return True, "VS Code detected"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def run_doctor() -> int:
|
|
102
|
+
"""Run all system diagnostic checks and print a structured report."""
|
|
103
|
+
print()
|
|
104
|
+
print(_colorize(" 🩺 AlpieCode System Health Diagnostic", "bold"))
|
|
105
|
+
print(_colorize(" " + "═" * 50, "dim"))
|
|
106
|
+
print()
|
|
107
|
+
|
|
108
|
+
total_checks = 0
|
|
109
|
+
passed_checks = 0
|
|
110
|
+
|
|
111
|
+
cfg = load_config()
|
|
112
|
+
|
|
113
|
+
# 1. Python Environment
|
|
114
|
+
print(_colorize(" 🐍 Python Environment", "cyan"))
|
|
115
|
+
py_ver = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
116
|
+
if sys.version_info >= (3, 9):
|
|
117
|
+
print(f" {_colorize('✅', 'green')} Python {py_ver} ({sys.executable})")
|
|
118
|
+
passed_checks += 1
|
|
119
|
+
else:
|
|
120
|
+
print(f" {_colorize('❌', 'red')} Python {py_ver} (Requires Python >= 3.9)")
|
|
121
|
+
total_checks += 1
|
|
122
|
+
|
|
123
|
+
venv_active = "VIRTUAL_ENV" in os.environ or hasattr(sys, "real_prefix") or (hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)
|
|
124
|
+
if venv_active:
|
|
125
|
+
print(f" {_colorize('✅', 'green')} Virtual Environment active ({os.environ.get('VIRTUAL_ENV', sys.prefix)})")
|
|
126
|
+
passed_checks += 1
|
|
127
|
+
else:
|
|
128
|
+
print(f" {_colorize('⚠️ ', 'yellow')} No virtual environment active (using system Python)")
|
|
129
|
+
total_checks += 1
|
|
130
|
+
|
|
131
|
+
# 2. CUDA / Hardware Acceleration
|
|
132
|
+
print()
|
|
133
|
+
print(_colorize(" 🖥️ Hardware & GPU Acceleration", "cyan"))
|
|
134
|
+
has_gpu, gpu_msg = _check_gpu()
|
|
135
|
+
if has_gpu:
|
|
136
|
+
print(f" {_colorize('✅', 'green')} {gpu_msg}")
|
|
137
|
+
passed_checks += 1
|
|
138
|
+
else:
|
|
139
|
+
print(f" {_colorize('ℹ️ ', 'blue')} {gpu_msg}")
|
|
140
|
+
total_checks += 1
|
|
141
|
+
|
|
142
|
+
# 3. Network & Connectivity
|
|
143
|
+
print()
|
|
144
|
+
print(_colorize(" 🌐 Network & Remote Model API", "cyan"))
|
|
145
|
+
inet_ok = is_internet_available(timeout=2.0)
|
|
146
|
+
if inet_ok:
|
|
147
|
+
print(f" {_colorize('✅', 'green')} General Internet: Connected (DNS 8.8.8.8)")
|
|
148
|
+
passed_checks += 1
|
|
149
|
+
else:
|
|
150
|
+
print(f" {_colorize('❌', 'red')} General Internet: Offline")
|
|
151
|
+
total_checks += 1
|
|
152
|
+
|
|
153
|
+
remote_ok, remote_msg = _check_remote_latency(cfg.base_url)
|
|
154
|
+
if remote_ok:
|
|
155
|
+
print(f" {_colorize('✅', 'green')} Remote VLM Endpoint: {cfg.base_url} — {remote_msg}")
|
|
156
|
+
print(f" {_colorize('✅', 'green')} Model Target: {cfg.model}")
|
|
157
|
+
passed_checks += 2
|
|
158
|
+
else:
|
|
159
|
+
print(f" {_colorize('⚠️ ', 'yellow')} Remote VLM Endpoint: {cfg.base_url} — {remote_msg}")
|
|
160
|
+
print(f" {_colorize('ℹ️ ', 'blue')} Offline fallback ready with: {cfg.model_repo}")
|
|
161
|
+
passed_checks += 1
|
|
162
|
+
total_checks += 2
|
|
163
|
+
|
|
164
|
+
# 4. Development Compilers & Runtimes
|
|
165
|
+
print()
|
|
166
|
+
print(_colorize(" 🧰 Development Tools & Compilers", "cyan"))
|
|
167
|
+
tools_to_check = [
|
|
168
|
+
("node", "Node.js (JavaScript/TypeScript runtime)"),
|
|
169
|
+
("npm", "Node Package Manager"),
|
|
170
|
+
("gcc", "GNU C Compiler"),
|
|
171
|
+
("g++", "GNU C++ Compiler"),
|
|
172
|
+
("git", "Git Version Control"),
|
|
173
|
+
("go", "Go Programming Language (optional)"),
|
|
174
|
+
("rustc", "Rust Compiler (optional)"),
|
|
175
|
+
("java", "Java JDK (optional)"),
|
|
176
|
+
]
|
|
177
|
+
for tool_name, desc in tools_to_check:
|
|
178
|
+
ok, msg = _check_command(tool_name)
|
|
179
|
+
is_optional = "optional" in desc
|
|
180
|
+
if ok:
|
|
181
|
+
print(f" {_colorize('✅', 'green')} {tool_name:8s} : {msg}")
|
|
182
|
+
passed_checks += 1
|
|
183
|
+
elif is_optional:
|
|
184
|
+
print(f" {_colorize('ℹ️ ', 'dim')} {tool_name:8s} : not installed (optional)")
|
|
185
|
+
else:
|
|
186
|
+
print(f" {_colorize('⚠️ ', 'yellow')} {tool_name:8s} : not installed")
|
|
187
|
+
total_checks += 1
|
|
188
|
+
|
|
189
|
+
# 5. VS Code Integration
|
|
190
|
+
print()
|
|
191
|
+
print(_colorize(" 📦 VS Code Extension", "cyan"))
|
|
192
|
+
ext_ok, ext_msg = _check_vscode_extension()
|
|
193
|
+
if ext_ok:
|
|
194
|
+
print(f" {_colorize('✅', 'green')} {ext_msg}")
|
|
195
|
+
passed_checks += 1
|
|
196
|
+
else:
|
|
197
|
+
print(f" {_colorize('⚠️ ', 'yellow')} {ext_msg} (run: alpiecode serve)")
|
|
198
|
+
total_checks += 1
|
|
199
|
+
|
|
200
|
+
# Summary
|
|
201
|
+
print()
|
|
202
|
+
print(_colorize(" " + "═" * 50, "dim"))
|
|
203
|
+
if passed_checks >= total_checks - 3:
|
|
204
|
+
print(f" {_colorize('🎉 System Health Status: EXCELLENT', 'green')} ({passed_checks}/{total_checks} checks passed)\n")
|
|
205
|
+
return 0
|
|
206
|
+
else:
|
|
207
|
+
print(f" {_colorize('⚠️ System Health Status: ATTENTION NEEDED', 'yellow')} ({passed_checks}/{total_checks} checks passed)\n")
|
|
208
|
+
return 1
|
|
index 13b805a..c508484 100644
|
|
|
Binary file
|
|
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
|