alpiecode 10.7.0__tar.gz → 10.7.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.
- {alpiecode-10.7.0 → alpiecode-10.7.1}/PKG-INFO +1 -1
- {alpiecode-10.7.0 → alpiecode-10.7.1}/pyproject.toml +1 -1
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/PKG-INFO +1 -1
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/__init__.py +1 -1
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/backends/local_backend.py +23 -9
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/backends/openai_backend.py +1 -1
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/config.py +7 -3
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_non_thinking_and_local_stream.py +25 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/README.md +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/setup.cfg +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode/__init__.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/SOURCES.txt +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/dependency_links.txt +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/entry_points.txt +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/requires.txt +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/alpiecode.egg-info/top_level.txt +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/agent.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/assessment.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/backends/__init__.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/backends/base.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/cache.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/cli.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/client.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/compaction.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/context.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/discovery.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/doctor.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/dream_rsi.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/executor.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/extension/alpiecode.vsix +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/git_ops.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/github.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/guardian.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/guardrails.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/ipython_ext.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/local_model.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/media.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/memory.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/metrics.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/orchestrator.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/paths.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/progress.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/prompt.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/rephraser.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/server.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/session.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/system1.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/tools.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/updater.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/verifier.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/src/codeagent/vscode_installer.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_adaptive_resilience.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_cli_ui.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_context_and_trajectory.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_dream_rsi.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_local_model_download.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_task_assessment.py +0 -0
- {alpiecode-10.7.0 → alpiecode-10.7.1}/test/test_verifier.py +0 -0
|
@@ -17,7 +17,7 @@ Supports:
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import Optional, Any, Dict
|
|
19
19
|
|
|
20
|
-
__version__ = "10.
|
|
20
|
+
__version__ = "10.7.1"
|
|
21
21
|
|
|
22
22
|
def run(task: str, workdir: str = ".", reasoning_level: str = "thinking", **kwargs):
|
|
23
23
|
"""Run an autonomous coding task programmatically."""
|
|
@@ -877,7 +877,7 @@ class iOSBackend(BasePlatformBackend):
|
|
|
877
877
|
if tools:
|
|
878
878
|
payload["tools"] = tools
|
|
879
879
|
payload["tool_choice"] = "auto"
|
|
880
|
-
resp = httpx.post(f"{bridge_url}/v1/chat/completions", json=payload, timeout=
|
|
880
|
+
resp = httpx.post(f"{bridge_url}/v1/chat/completions", json=payload, timeout=300.0)
|
|
881
881
|
if resp.status_code != 200:
|
|
882
882
|
raise RuntimeError(f"iOS bridge HTTP {resp.status_code}: {resp.text}")
|
|
883
883
|
data = json.loads(resp.text)
|
|
@@ -956,7 +956,7 @@ class iOSBackend(BasePlatformBackend):
|
|
|
956
956
|
if tools:
|
|
957
957
|
payload["tools"] = tools
|
|
958
958
|
payload["tool_choice"] = "auto"
|
|
959
|
-
client = httpx.Client(timeout=
|
|
959
|
+
client = httpx.Client(timeout=httpx.Timeout(300.0, connect=10.0, read=300.0, write=30.0))
|
|
960
960
|
req = client.build_request("POST", f"{bridge_url}/v1/chat/completions", json=payload)
|
|
961
961
|
resp = client.send(req, stream=True)
|
|
962
962
|
if resp.status_code != 200:
|
|
@@ -1056,11 +1056,14 @@ class AndroidBackend(BasePlatformBackend):
|
|
|
1056
1056
|
if not model_path:
|
|
1057
1057
|
self._last_server_error = "No GGUF model found in ~/.alpiecode/models or ~/models."
|
|
1058
1058
|
return False
|
|
1059
|
-
|
|
1060
|
-
|
|
1059
|
+
n_ctx = getattr(self._cfg, "n_ctx", 2048)
|
|
1060
|
+
if n_ctx > 2048:
|
|
1061
|
+
n_ctx = 2048
|
|
1062
|
+
n_ctx_val = str(n_ctx)
|
|
1063
|
+
base_cmd = [
|
|
1061
1064
|
str(server_bin),
|
|
1062
1065
|
"-m", str(model_path),
|
|
1063
|
-
"-c",
|
|
1066
|
+
"-c", n_ctx_val,
|
|
1064
1067
|
"-t", "4",
|
|
1065
1068
|
"-np", "1",
|
|
1066
1069
|
"-b", "512",
|
|
@@ -1069,10 +1072,21 @@ class AndroidBackend(BasePlatformBackend):
|
|
|
1069
1072
|
"--cache-type-v", "q8_0",
|
|
1070
1073
|
"--port", "8080",
|
|
1071
1074
|
]
|
|
1072
|
-
if
|
|
1073
|
-
|
|
1075
|
+
# Only load vision projector if specifically needed to keep RAM footprint under 5GB
|
|
1076
|
+
if getattr(self._cfg, "enable_vision", False):
|
|
1077
|
+
mmprojs = list(model_path.parent.glob("*mmproj*.gguf"))
|
|
1078
|
+
if mmprojs:
|
|
1079
|
+
base_cmd += ["--mmproj", str(mmprojs[0])]
|
|
1080
|
+
|
|
1081
|
+
taskset_bin = shutil.which("taskset")
|
|
1082
|
+
if taskset_bin and os.cpu_count() == 8:
|
|
1083
|
+
cmd = [taskset_bin, "-c", "4-7"] + base_cmd
|
|
1084
|
+
else:
|
|
1085
|
+
cmd = base_cmd
|
|
1086
|
+
|
|
1074
1087
|
try:
|
|
1075
|
-
print(f"⏳ Starting
|
|
1088
|
+
print(f"⏳ Starting Alpie ({model_path.name}) in background...")
|
|
1089
|
+
print(f" Context window: {n_ctx_val} tokens | Performance cores: 4 | Lean KV cache active")
|
|
1076
1090
|
subprocess.Popen(
|
|
1077
1091
|
cmd,
|
|
1078
1092
|
stdout=subprocess.DEVNULL,
|
|
@@ -1080,7 +1094,7 @@ class AndroidBackend(BasePlatformBackend):
|
|
|
1080
1094
|
start_new_session=True,
|
|
1081
1095
|
)
|
|
1082
1096
|
import time
|
|
1083
|
-
for _ in range(
|
|
1097
|
+
for _ in range(40):
|
|
1084
1098
|
if self._is_bridge_online():
|
|
1085
1099
|
return True
|
|
1086
1100
|
time.sleep(0.5)
|
|
@@ -180,7 +180,7 @@ class _HTTPXClient:
|
|
|
180
180
|
elif "127.0.0.1" in base_url or "localhost" in base_url:
|
|
181
181
|
self.http_client = httpx.Client(
|
|
182
182
|
http2=False,
|
|
183
|
-
timeout=httpx.Timeout(
|
|
183
|
+
timeout=httpx.Timeout(300.0, connect=10.0, read=300.0, write=30.0),
|
|
184
184
|
limits=httpx.Limits(max_keepalive_connections=5, max_connections=10),
|
|
185
185
|
)
|
|
186
186
|
else:
|
|
@@ -233,9 +233,13 @@ def load_config() -> Config:
|
|
|
233
233
|
except ValueError:
|
|
234
234
|
pass
|
|
235
235
|
|
|
236
|
-
#
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
# On mobile (Android / Termux), keep context at 2048 to prevent ZRAM thrashing with 9B models
|
|
237
|
+
if is_android() and not any(os.environ.get(v) for v in ("ALPIECODE_N_CTX", "ALPIECODE_CTX_SIZE")):
|
|
238
|
+
if data.get("n_ctx", 32768) > 2048:
|
|
239
|
+
data["n_ctx"] = 2048
|
|
240
|
+
if data.get("max_tokens", 8192) > 1024:
|
|
241
|
+
data["max_tokens"] = 1024
|
|
242
|
+
elif data.get("base_url") == "offline" and not any(os.environ.get(v) for v in ("ALPIECODE_N_CTX", "ALPIECODE_CTX_SIZE")):
|
|
239
243
|
if data.get("n_ctx") in (32768, 4096, 16384):
|
|
240
244
|
data["n_ctx"] = 8192
|
|
241
245
|
if data.get("max_tokens", 8192) > 4096:
|
|
@@ -134,3 +134,28 @@ def test_prompt_builder_lean_offline_prompt():
|
|
|
134
134
|
assert "You are running in OFFLINE mode" in prompt
|
|
135
135
|
assert "Execution & Goal Convergence Rules" not in prompt
|
|
136
136
|
assert len(prompt) < 3500 # Lean offline prompt under 3500 chars (~600 tokens vs 4500 cloud tokens)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_android_backend_skips_mmproj_for_code_tasks(tmp_path):
|
|
140
|
+
from pathlib import Path
|
|
141
|
+
from codeagent.backends.local_backend import AndroidBackend
|
|
142
|
+
cfg = Config(base_url="offline")
|
|
143
|
+
backend = AndroidBackend(cfg)
|
|
144
|
+
|
|
145
|
+
fake_model = tmp_path / "alpie-vl-text-q3_k_m.gguf"
|
|
146
|
+
fake_model.touch()
|
|
147
|
+
fake_mmproj = tmp_path / "alpie-vl-mmproj-f16.gguf"
|
|
148
|
+
fake_mmproj.touch()
|
|
149
|
+
|
|
150
|
+
with patch.object(backend, "_find_llama_server_bin", return_value=Path("/bin/llama-server")):
|
|
151
|
+
with patch.object(backend, "_find_gguf_model", return_value=fake_model):
|
|
152
|
+
with patch("subprocess.Popen") as mock_popen:
|
|
153
|
+
with patch.object(backend, "_is_bridge_online", side_effect=[False, True]):
|
|
154
|
+
backend._ensure_local_server()
|
|
155
|
+
assert mock_popen.called
|
|
156
|
+
args = mock_popen.call_args[0][0]
|
|
157
|
+
# By default (for code tasks), --mmproj must NOT be loaded
|
|
158
|
+
assert "--mmproj" not in args
|
|
159
|
+
assert "-c" in args
|
|
160
|
+
assert "2048" in args
|
|
161
|
+
|
|
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
|
|
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
|