alpiecode 0.9.0__tar.gz → 0.9.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-0.9.0 → alpiecode-0.9.2}/PKG-INFO +4 -5
- {alpiecode-0.9.0 → alpiecode-0.9.2}/pyproject.toml +5 -5
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/PKG-INFO +4 -5
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/SOURCES.txt +3 -1
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/requires.txt +0 -2
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/cli.py +5 -0
- alpiecode-0.9.2/src/codeagent/extension/alpiecode.vsix +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/orchestrator.py +14 -3
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/server.py +10 -0
- alpiecode-0.9.2/src/codeagent/vscode_installer.py +122 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/README.md +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/setup.cfg +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/dependency_links.txt +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/entry_points.txt +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/top_level.txt +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/__init__.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/agent.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/__init__.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/base.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/local_backend.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/openai_backend.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/client.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/compaction.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/config.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/context.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/executor.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/github.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/guardian.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/local_model.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/media.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/memory.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/prompt.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/session.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/tools.py +0 -0
- {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/updater.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpiecode
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.2
|
|
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
|
|
@@ -12,7 +12,6 @@ Requires-Dist: duckduckgo-search>=7.0.0
|
|
|
12
12
|
Requires-Dist: beautifulsoup4>=4.12.0
|
|
13
13
|
Requires-Dist: yt-dlp>=2024.0.0
|
|
14
14
|
Requires-Dist: imageio-ffmpeg>=0.4.0
|
|
15
|
-
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist: sse-starlette>=2.0.0; extra == "server"
|
|
15
|
+
Requires-Dist: fastapi>=0.100.0
|
|
16
|
+
Requires-Dist: uvicorn>=0.20.0
|
|
17
|
+
Requires-Dist: sse-starlette>=2.0.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "alpiecode"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.2"
|
|
8
8
|
description = "AlpieCode — Autonomous AI Coding Agent CLI powered by local 169Pi GGUF VLM"
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
dependencies = [
|
|
@@ -17,10 +17,6 @@ dependencies = [
|
|
|
17
17
|
"beautifulsoup4>=4.12.0",
|
|
18
18
|
"yt-dlp>=2024.0.0",
|
|
19
19
|
"imageio-ffmpeg>=0.4.0",
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
[project.optional-dependencies]
|
|
23
|
-
server = [
|
|
24
20
|
"fastapi>=0.100.0",
|
|
25
21
|
"uvicorn>=0.20.0",
|
|
26
22
|
"sse-starlette>=2.0.0",
|
|
@@ -32,3 +28,7 @@ codeagent = "codeagent.cli:main"
|
|
|
32
28
|
|
|
33
29
|
[tool.setuptools.packages.find]
|
|
34
30
|
where = ["src"]
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.package-data]
|
|
33
|
+
codeagent = ["extension/*.vsix"]
|
|
34
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alpiecode
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.2
|
|
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
|
|
@@ -12,7 +12,6 @@ Requires-Dist: duckduckgo-search>=7.0.0
|
|
|
12
12
|
Requires-Dist: beautifulsoup4>=4.12.0
|
|
13
13
|
Requires-Dist: yt-dlp>=2024.0.0
|
|
14
14
|
Requires-Dist: imageio-ffmpeg>=0.4.0
|
|
15
|
-
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist: sse-starlette>=2.0.0; extra == "server"
|
|
15
|
+
Requires-Dist: fastapi>=0.100.0
|
|
16
|
+
Requires-Dist: uvicorn>=0.20.0
|
|
17
|
+
Requires-Dist: sse-starlette>=2.0.0
|
|
@@ -25,7 +25,9 @@ src/codeagent/server.py
|
|
|
25
25
|
src/codeagent/session.py
|
|
26
26
|
src/codeagent/tools.py
|
|
27
27
|
src/codeagent/updater.py
|
|
28
|
+
src/codeagent/vscode_installer.py
|
|
28
29
|
src/codeagent/backends/__init__.py
|
|
29
30
|
src/codeagent/backends/base.py
|
|
30
31
|
src/codeagent/backends/local_backend.py
|
|
31
|
-
src/codeagent/backends/openai_backend.py
|
|
32
|
+
src/codeagent/backends/openai_backend.py
|
|
33
|
+
src/codeagent/extension/alpiecode.vsix
|
|
@@ -119,6 +119,11 @@ def main():
|
|
|
119
119
|
|
|
120
120
|
if args.command == "serve":
|
|
121
121
|
_show_banner()
|
|
122
|
+
try:
|
|
123
|
+
from .vscode_installer import ensure_vscode_extension
|
|
124
|
+
ensure_vscode_extension()
|
|
125
|
+
except Exception as e:
|
|
126
|
+
pass
|
|
122
127
|
from .server import run_server
|
|
123
128
|
run_server(host=args.host, port=args.port)
|
|
124
129
|
return
|
|
Binary file
|
|
@@ -28,9 +28,13 @@ class AgentEvent:
|
|
|
28
28
|
data: Dict[str, Any]
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def resolve_backend(cfg: Config) -> InferenceBackend:
|
|
32
|
-
"""Resolve online vs offline backend based on server reachability.
|
|
33
|
-
|
|
31
|
+
def resolve_backend(cfg: Config, timeout: float = 2.0) -> InferenceBackend:
|
|
32
|
+
"""Resolve online vs offline backend based on server reachability.
|
|
33
|
+
|
|
34
|
+
Uses a generous timeout at startup (2s default) to avoid false negatives
|
|
35
|
+
when the remote API is slow to respond (e.g. Azure VM cold start).
|
|
36
|
+
"""
|
|
37
|
+
if is_server_reachable(cfg.base_url, timeout=timeout):
|
|
34
38
|
return OpenAIBackend(cfg)
|
|
35
39
|
return LocalBackend(cfg)
|
|
36
40
|
|
|
@@ -59,6 +63,13 @@ class AgentOrchestrator:
|
|
|
59
63
|
"""
|
|
60
64
|
Run full agent task loop for a session. Yields AgentEvents.
|
|
61
65
|
"""
|
|
66
|
+
# Dynamic backend re-check: if currently on LocalBackend but remote
|
|
67
|
+
# API is now reachable, switch to OnlineBackend automatically.
|
|
68
|
+
# This handles the case where the server started offline but the
|
|
69
|
+
# remote API came online later (e.g. VM cold start, network hiccup).
|
|
70
|
+
if isinstance(self.backend, LocalBackend) and is_server_reachable(cfg.base_url, timeout=1.5):
|
|
71
|
+
self.backend = OpenAIBackend(cfg)
|
|
72
|
+
|
|
62
73
|
is_offline = not self.backend.is_available or isinstance(self.backend, LocalBackend)
|
|
63
74
|
session.is_offline = is_offline
|
|
64
75
|
|
|
@@ -13,6 +13,7 @@ from typing import Any, Dict, Optional
|
|
|
13
13
|
|
|
14
14
|
try:
|
|
15
15
|
from fastapi import FastAPI, HTTPException, Request, Response
|
|
16
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
16
17
|
from fastapi.responses import JSONResponse, StreamingResponse
|
|
17
18
|
HAS_FASTAPI = True
|
|
18
19
|
except ImportError:
|
|
@@ -53,6 +54,15 @@ if HAS_FASTAPI:
|
|
|
53
54
|
lifespan=lifespan,
|
|
54
55
|
)
|
|
55
56
|
|
|
57
|
+
# CORS — allow VS Code extensions, web UIs, and external clients
|
|
58
|
+
app.add_middleware(
|
|
59
|
+
CORSMiddleware,
|
|
60
|
+
allow_origins=["*"],
|
|
61
|
+
allow_credentials=True,
|
|
62
|
+
allow_methods=["*"],
|
|
63
|
+
allow_headers=["*"],
|
|
64
|
+
)
|
|
65
|
+
|
|
56
66
|
@app.get("/health")
|
|
57
67
|
async def health_check():
|
|
58
68
|
"""Health check and engine status."""
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
VS Code Extension Auto-Installer for AlpieCode.
|
|
3
|
+
|
|
4
|
+
Detects if VS Code is available, checks if the AlpieCode extension is installed,
|
|
5
|
+
and prompts/auto-installs the bundled .vsix if missing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import shutil
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_bundled_vsix_path() -> Path:
|
|
17
|
+
"""Return path to bundled .vsix inside the codeagent package."""
|
|
18
|
+
pkg_dir = Path(__file__).parent
|
|
19
|
+
return pkg_dir / "extension" / "alpiecode.vsix"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def find_code_cli() -> Optional[str]:
|
|
23
|
+
"""Find the VS Code CLI executable across Windows, WSL, Linux, and macOS."""
|
|
24
|
+
for cmd in ("code", "code.cmd", "code.exe"):
|
|
25
|
+
found = shutil.which(cmd)
|
|
26
|
+
if found:
|
|
27
|
+
return found
|
|
28
|
+
|
|
29
|
+
# Check common WSL / Windows paths if not found directly in PATH
|
|
30
|
+
wsl_code_paths = [
|
|
31
|
+
"/mnt/c/Users/*/AppData/Local/Programs/Microsoft VS Code/bin/code",
|
|
32
|
+
"/usr/local/bin/code",
|
|
33
|
+
"/usr/bin/code",
|
|
34
|
+
]
|
|
35
|
+
import glob
|
|
36
|
+
for pattern in wsl_code_paths:
|
|
37
|
+
matches = glob.glob(pattern)
|
|
38
|
+
if matches:
|
|
39
|
+
return matches[0]
|
|
40
|
+
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def is_extension_installed() -> bool:
|
|
45
|
+
"""Check if 'alpiecode' extension is already installed in VS Code."""
|
|
46
|
+
code_bin = find_code_cli()
|
|
47
|
+
if not code_bin:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
res = subprocess.run(
|
|
52
|
+
[code_bin, "--list-extensions"],
|
|
53
|
+
capture_output=True,
|
|
54
|
+
text=True,
|
|
55
|
+
timeout=8,
|
|
56
|
+
)
|
|
57
|
+
if res.returncode == 0:
|
|
58
|
+
installed = res.stdout.lower()
|
|
59
|
+
return "alpiecode" in installed
|
|
60
|
+
except Exception:
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def ensure_vscode_extension(auto_confirm: bool = False, quiet: bool = False) -> bool:
|
|
67
|
+
"""
|
|
68
|
+
Check if VS Code extension is installed. If missing:
|
|
69
|
+
- Asks user: 'Would you like to install the AlpieCode VS Code extension? [Y/n]'
|
|
70
|
+
- If Yes (or auto_confirm=True): installs bundled .vsix via `code --install-extension`
|
|
71
|
+
- Returns True if installed or successfully installed, False otherwise.
|
|
72
|
+
"""
|
|
73
|
+
if is_extension_installed():
|
|
74
|
+
if not quiet:
|
|
75
|
+
print("✅ AlpieCode VS Code extension is installed.")
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
code_bin = find_code_cli()
|
|
79
|
+
if not code_bin:
|
|
80
|
+
if not quiet:
|
|
81
|
+
print("ℹ️ VS Code CLI ('code') not detected on PATH. Skipping extension check.")
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
vsix_path = get_bundled_vsix_path()
|
|
85
|
+
if not vsix_path.exists():
|
|
86
|
+
if not quiet:
|
|
87
|
+
print(f"ℹ️ Bundled extension VSIX not found at {vsix_path}")
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
if not quiet:
|
|
91
|
+
print("\n💡 VS Code detected, but the AlpieCode extension is not installed.")
|
|
92
|
+
|
|
93
|
+
if not auto_confirm:
|
|
94
|
+
try:
|
|
95
|
+
prompt_text = " Would you like to install the AlpieCode VS Code extension now? [Y/n]: "
|
|
96
|
+
choice = input(prompt_text).strip().lower()
|
|
97
|
+
if choice and choice not in ("y", "yes"):
|
|
98
|
+
if not quiet:
|
|
99
|
+
print(" Skipped VS Code extension installation.\n")
|
|
100
|
+
return False
|
|
101
|
+
except (KeyboardInterrupt, EOFError):
|
|
102
|
+
print()
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
print(f"📦 Installing AlpieCode VS Code extension ({vsix_path.name})...")
|
|
106
|
+
try:
|
|
107
|
+
res = subprocess.run(
|
|
108
|
+
[code_bin, "--install-extension", str(vsix_path), "--force"],
|
|
109
|
+
capture_output=True,
|
|
110
|
+
text=True,
|
|
111
|
+
timeout=30,
|
|
112
|
+
)
|
|
113
|
+
if res.returncode == 0:
|
|
114
|
+
print("✅ AlpieCode VS Code extension installed successfully!")
|
|
115
|
+
print(" 👉 Reload VS Code (`Ctrl+Shift+P` → `Developer: Reload Window`) to start chatting!\n")
|
|
116
|
+
return True
|
|
117
|
+
else:
|
|
118
|
+
print(f"⚠️ Could not install VS Code extension: {res.stderr.strip()}\n")
|
|
119
|
+
except Exception as e:
|
|
120
|
+
print(f"⚠️ Extension installation error: {e}\n")
|
|
121
|
+
|
|
122
|
+
return False
|
|
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
|