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.
Files changed (35) hide show
  1. {alpiecode-0.9.0 → alpiecode-0.9.2}/PKG-INFO +4 -5
  2. {alpiecode-0.9.0 → alpiecode-0.9.2}/pyproject.toml +5 -5
  3. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/PKG-INFO +4 -5
  4. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/SOURCES.txt +3 -1
  5. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/requires.txt +0 -2
  6. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/cli.py +5 -0
  7. alpiecode-0.9.2/src/codeagent/extension/alpiecode.vsix +0 -0
  8. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/orchestrator.py +14 -3
  9. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/server.py +10 -0
  10. alpiecode-0.9.2/src/codeagent/vscode_installer.py +122 -0
  11. {alpiecode-0.9.0 → alpiecode-0.9.2}/README.md +0 -0
  12. {alpiecode-0.9.0 → alpiecode-0.9.2}/setup.cfg +0 -0
  13. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/dependency_links.txt +0 -0
  14. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/entry_points.txt +0 -0
  15. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/alpiecode.egg-info/top_level.txt +0 -0
  16. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/__init__.py +0 -0
  17. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/agent.py +0 -0
  18. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/__init__.py +0 -0
  19. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/base.py +0 -0
  20. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/local_backend.py +0 -0
  21. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/backends/openai_backend.py +0 -0
  22. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/client.py +0 -0
  23. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/compaction.py +0 -0
  24. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/config.py +0 -0
  25. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/context.py +0 -0
  26. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/executor.py +0 -0
  27. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/github.py +0 -0
  28. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/guardian.py +0 -0
  29. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/local_model.py +0 -0
  30. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/media.py +0 -0
  31. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/memory.py +0 -0
  32. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/prompt.py +0 -0
  33. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/session.py +0 -0
  34. {alpiecode-0.9.0 → alpiecode-0.9.2}/src/codeagent/tools.py +0 -0
  35. {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.0
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
- Provides-Extra: server
16
- Requires-Dist: fastapi>=0.100.0; extra == "server"
17
- Requires-Dist: uvicorn>=0.20.0; extra == "server"
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.0"
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.0
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
- Provides-Extra: server
16
- Requires-Dist: fastapi>=0.100.0; extra == "server"
17
- Requires-Dist: uvicorn>=0.20.0; extra == "server"
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
@@ -7,8 +7,6 @@ duckduckgo-search>=7.0.0
7
7
  beautifulsoup4>=4.12.0
8
8
  yt-dlp>=2024.0.0
9
9
  imageio-ffmpeg>=0.4.0
10
-
11
- [server]
12
10
  fastapi>=0.100.0
13
11
  uvicorn>=0.20.0
14
12
  sse-starlette>=2.0.0
@@ -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
@@ -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
- if is_server_reachable(cfg.base_url):
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