codegpt-ai 1.19.0 → 1.21.0
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.
- package/chat.py +87 -27
- package/package.json +1 -1
package/chat.py
CHANGED
|
@@ -28,6 +28,21 @@ from prompt_toolkit.styles import Style as PtStyle
|
|
|
28
28
|
|
|
29
29
|
# --- Config ---
|
|
30
30
|
|
|
31
|
+
# Fix PATH for Termux and pip --user installs
|
|
32
|
+
_extra_paths = [
|
|
33
|
+
os.path.expanduser("~/.local/bin"),
|
|
34
|
+
os.path.expanduser("~/bin"),
|
|
35
|
+
]
|
|
36
|
+
if os.path.exists("/data/data/com.termux"):
|
|
37
|
+
_extra_paths.extend([
|
|
38
|
+
"/data/data/com.termux/files/usr/bin",
|
|
39
|
+
"/data/data/com.termux/files/home/.local/bin",
|
|
40
|
+
os.path.expanduser("~/.npm-global/bin"),
|
|
41
|
+
])
|
|
42
|
+
for _p in _extra_paths:
|
|
43
|
+
if _p not in os.environ.get("PATH", "") and os.path.isdir(_p):
|
|
44
|
+
os.environ["PATH"] = _p + os.pathsep + os.environ.get("PATH", "")
|
|
45
|
+
|
|
31
46
|
OLLAMA_URL = os.environ.get("OLLAMA_URL", "http://localhost:11434/api/chat")
|
|
32
47
|
MODEL = "llama3.2"
|
|
33
48
|
CHATS_DIR = Path.home() / ".codegpt" / "conversations"
|
|
@@ -223,7 +238,7 @@ AI_TOOLS = {
|
|
|
223
238
|
"install": ["npm", "i", "-g", "@openai/codex"],
|
|
224
239
|
"default_args": [],
|
|
225
240
|
"needs_key": "OPENAI_API_KEY",
|
|
226
|
-
"termux": False,
|
|
241
|
+
"termux": False, # ARM64 build fails on Termux
|
|
227
242
|
},
|
|
228
243
|
"gemini": {
|
|
229
244
|
"name": "Gemini CLI",
|
|
@@ -232,16 +247,17 @@ AI_TOOLS = {
|
|
|
232
247
|
"install": ["npm", "i", "-g", "@google/gemini-cli"],
|
|
233
248
|
"default_args": [],
|
|
234
249
|
"needs_key": "Google login",
|
|
235
|
-
"termux":
|
|
250
|
+
"termux": True, # Pure JS, no native deps
|
|
236
251
|
},
|
|
237
252
|
"copilot": {
|
|
238
253
|
"name": "GitHub Copilot",
|
|
239
254
|
"desc": "AI pair programmer in terminal",
|
|
240
255
|
"bin": "gh",
|
|
241
256
|
"install": ["gh", "extension", "install", "github/gh-copilot"],
|
|
257
|
+
"install_termux": ["pkg", "install", "-y", "gh"],
|
|
242
258
|
"default_args": ["copilot"],
|
|
243
259
|
"needs_key": "GitHub login",
|
|
244
|
-
"termux":
|
|
260
|
+
"termux": True, # gh available via pkg
|
|
245
261
|
},
|
|
246
262
|
"gpt4all": {
|
|
247
263
|
"name": "GPT4All",
|
|
@@ -259,7 +275,7 @@ AI_TOOLS = {
|
|
|
259
275
|
"install": ["npm", "i", "-g", "cursor-cli"],
|
|
260
276
|
"default_args": [],
|
|
261
277
|
"needs_key": "Cursor account",
|
|
262
|
-
"termux":
|
|
278
|
+
"termux": True, # Pure JS
|
|
263
279
|
},
|
|
264
280
|
# --- Deploy CLIs (work everywhere) ---
|
|
265
281
|
"vercel": {
|
|
@@ -5803,10 +5819,6 @@ def main():
|
|
|
5803
5819
|
print_sys("Use a desktop/PC for this tool.")
|
|
5804
5820
|
continue
|
|
5805
5821
|
|
|
5806
|
-
if not ask_permission("tool_install", f"Install {tool['name']} via {' '.join(install_cmd[:3])}"):
|
|
5807
|
-
continue
|
|
5808
|
-
print_sys(f"Installing {tool['name']}...")
|
|
5809
|
-
|
|
5810
5822
|
# Pick platform-specific install command
|
|
5811
5823
|
if is_termux and "install_termux" in tool:
|
|
5812
5824
|
install_cmd = list(tool["install_termux"])
|
|
@@ -5815,6 +5827,10 @@ def main():
|
|
|
5815
5827
|
else:
|
|
5816
5828
|
install_cmd = list(tool["install"])
|
|
5817
5829
|
|
|
5830
|
+
if not ask_permission("tool_install", f"Install {tool['name']} via {' '.join(install_cmd[:3])}"):
|
|
5831
|
+
continue
|
|
5832
|
+
print_sys(f"Installing {tool['name']}...")
|
|
5833
|
+
|
|
5818
5834
|
is_npm = install_cmd[0] in ("npm", "npm.cmd")
|
|
5819
5835
|
|
|
5820
5836
|
if is_npm and os.name == "nt":
|
|
@@ -5832,11 +5848,14 @@ def main():
|
|
|
5832
5848
|
)
|
|
5833
5849
|
install_ok[0] = r.returncode == 0
|
|
5834
5850
|
if not install_ok[0]:
|
|
5835
|
-
|
|
5851
|
+
# Show both stderr and stdout for better debugging
|
|
5852
|
+
err = r.stderr.strip() if r.stderr else ""
|
|
5853
|
+
out = r.stdout.strip() if r.stdout else ""
|
|
5854
|
+
install_err[0] = err[:300] or out[:300] or f"Exit code {r.returncode}"
|
|
5836
5855
|
except subprocess.TimeoutExpired:
|
|
5837
5856
|
install_err[0] = "Timed out (5min)"
|
|
5838
5857
|
except Exception as e:
|
|
5839
|
-
install_err[0] = str(e)
|
|
5858
|
+
install_err[0] = str(e)[:300]
|
|
5840
5859
|
install_done[0] = True
|
|
5841
5860
|
|
|
5842
5861
|
thr = threading.Thread(target=do_tool_install, daemon=True)
|
|
@@ -5866,25 +5885,66 @@ def main():
|
|
|
5866
5885
|
))
|
|
5867
5886
|
time.sleep(0.1)
|
|
5868
5887
|
|
|
5869
|
-
if install_ok[0]
|
|
5888
|
+
if install_ok[0]:
|
|
5870
5889
|
elapsed = time.time() - start_t
|
|
5871
|
-
print_sys(f"Installed in {elapsed:.1f}s. Launching...")
|
|
5872
|
-
audit_log(f"TOOL_INSTALL", tool_key)
|
|
5873
5890
|
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5891
|
+
# Rehash PATH — find newly installed binaries
|
|
5892
|
+
for _p in [
|
|
5893
|
+
os.path.expanduser("~/.local/bin"),
|
|
5894
|
+
os.path.expanduser("~/.npm-global/bin"),
|
|
5895
|
+
"/data/data/com.termux/files/usr/bin",
|
|
5896
|
+
os.path.expanduser("~/bin"),
|
|
5897
|
+
]:
|
|
5898
|
+
if os.path.isdir(_p) and _p not in os.environ.get("PATH", ""):
|
|
5899
|
+
os.environ["PATH"] = _p + os.pathsep + os.environ["PATH"]
|
|
5900
|
+
|
|
5901
|
+
# Try to find the binary
|
|
5902
|
+
found_bin = shutil.which(tool_bin)
|
|
5903
|
+
|
|
5904
|
+
# Fallback: search common install locations
|
|
5905
|
+
if not found_bin:
|
|
5906
|
+
search_dirs = [
|
|
5907
|
+
os.path.expanduser("~/.local/bin"),
|
|
5908
|
+
os.path.expanduser("~/.npm-global/bin"),
|
|
5909
|
+
"/data/data/com.termux/files/usr/bin",
|
|
5910
|
+
]
|
|
5911
|
+
for sd in search_dirs:
|
|
5912
|
+
candidate = os.path.join(sd, tool_bin)
|
|
5913
|
+
if os.path.isfile(candidate):
|
|
5914
|
+
found_bin = candidate
|
|
5915
|
+
break
|
|
5916
|
+
|
|
5917
|
+
# Fallback: try python -m for pip packages
|
|
5918
|
+
pip_module_map = {
|
|
5919
|
+
"sgpt": "sgpt",
|
|
5920
|
+
"llm": "llm",
|
|
5921
|
+
"litellm": "litellm",
|
|
5922
|
+
"gorilla": "gorilla_cli",
|
|
5923
|
+
"chatgpt": "chatgpt",
|
|
5924
|
+
"aider": "aider",
|
|
5925
|
+
"interpreter": "interpreter",
|
|
5926
|
+
"gpte": "gpt_engineer",
|
|
5927
|
+
"mentat": "mentat",
|
|
5928
|
+
}
|
|
5929
|
+
|
|
5930
|
+
if found_bin:
|
|
5931
|
+
print_sys(f"Installed in {elapsed:.1f}s. Launching...")
|
|
5932
|
+
audit_log(f"TOOL_INSTALL", tool_key)
|
|
5933
|
+
launch_cmd = [found_bin] + tool.get("default_args", [])
|
|
5934
|
+
subprocess.run(launch_cmd, shell=True)
|
|
5935
|
+
print_sys("Back to CodeGPT.")
|
|
5936
|
+
elif tool_bin in pip_module_map:
|
|
5937
|
+
# Try python -m fallback
|
|
5938
|
+
mod = pip_module_map[tool_bin]
|
|
5939
|
+
print_sys(f"Installed in {elapsed:.1f}s. Launching via python -m {mod}...")
|
|
5940
|
+
audit_log(f"TOOL_INSTALL", tool_key)
|
|
5941
|
+
launch_cmd = [sys.executable, "-m", mod] + tool.get("default_args", [])
|
|
5942
|
+
subprocess.run(launch_cmd)
|
|
5943
|
+
print_sys("Back to CodeGPT.")
|
|
5944
|
+
else:
|
|
5945
|
+
print_err(f"Installed but '{tool_bin}' not found in PATH.")
|
|
5946
|
+
print_sys(f"Try: which {tool_bin}")
|
|
5947
|
+
print_sys("Or restart your terminal and try again.")
|
|
5888
5948
|
else:
|
|
5889
5949
|
print_err(f"Install failed: {install_err[0]}")
|
|
5890
5950
|
manual = " ".join(tool["install"])
|