Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Versions follow semver beta: `1.0.0-beta.N`, bumped on each dev->master promotio

## [Unreleased]

## [1.0.0-beta.8] - 2026-06-21

### Fixed
- Install: the controller venv now uses a litellm-compatible Python (3.11 to 3.13). A fresh distro that defaults python3 to 3.14 (e.g. WSL on Ubuntu 26.04) previously aborted with "No matching distribution found for litellm>=1.89.3", because litellm supports only >=3.10,<3.14. The installer now picks a supported interpreter, installs python3.13 if none is present, and fails with a clear message otherwise; requires-python is capped at <3.14 to match.

## [1.0.0-beta.7] - 2026-06-21

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions desktop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "tinyagentos-desktop",
"private": true,
"version": "1.0.0-beta.7",
"version": "1.0.0-beta.8",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ build-backend = "setuptools.build_meta"

[project]
name = "tinyagentos"
version = "1.0.0-beta.7"
version = "1.0.0-beta.8"
description = "Self-hosted AI agent memory system for low-power hardware"
license = { file = "LICENSE" }
requires-python = ">=3.11"
# Upper-capped at <3.14 because litellm (the proxy extra, the agent/model proxy
# runtime) supports only >=3.10,<3.14. A fresh distro that defaults python3 to
# 3.14 would otherwise build the venv on 3.14 and abort with "No matching
# distribution found for litellm". The installer also steers the venv to a
# supported interpreter; this cap makes the constraint explicit to pip and uv.
requires-python = ">=3.11,<3.14"
dependencies = [
# Cap below 0.137: fastapi 0.137.0 regressed include_router so that a
# mounted APIRouter contributes none of its routes to the app, leaving
Expand Down
44 changes: 35 additions & 9 deletions scripts/install-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1024,17 +1024,43 @@ install_rk3588_perf_if_needed

# --- python venv + controller deps ---------------------------------------

# Resolve a Python the controller deps support: litellm (the proxy extra) needs
# >=3.10,<3.14. Prefer a system interpreter in range; otherwise provision a
# standalone 3.13 with uv. The reported failure was a fresh WSL/Ubuntu 26.04 that
# ships only Python 3.14 and does not package python3.13, so apt cannot help and
# uv (which downloads a standalone CPython on any distro) is the reliable path.
# libtorrent is optional, so the venv is clean -- no system-site-packages binding
# juggling (a 3.13 venv could not import a 3.14-built system binding anyway).
pick_system_python() {
local c v
for c in python3.13 python3.12 python3.11 python3; do
command -v "$c" >/dev/null 2>&1 || continue
v=$("$c" -c 'import sys;print(sys.version_info[0]*100+sys.version_info[1])' 2>/dev/null) || continue
if [ "$v" -ge 311 ] && [ "$v" -lt 314 ]; then echo "$c"; return 0; fi
done
return 1
}

ensure_uv() {
command -v uv >/dev/null 2>&1 && return 0
if [[ -x "$HOME/.local/bin/uv" ]]; then export PATH="$HOME/.local/bin:$PATH"; return 0; fi
log "installing uv to provision a supported Python"
curl -LsSf https://astral.sh/uv/install.sh | sh >/dev/null 2>&1 || return 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and examine the surrounding context
file="scripts/install-server.sh"
if [ -f "$file" ]; then
  echo "=== File exists ==="
  wc -l "$file"
  echo "=== Lines 1040-1060 ==="
  sed -n '1040,1060p' "$file"
else
  echo "File not found at $file"
  # Try to find it
  find . -name "install-server.sh" 2>/dev/null
fi

Repository: jaylfc/taOS

Length of output: 871


🌐 Web query:

curl pipe sh security risks arbitrary code execution

💡 Result:

The practice of piping the output of a remote command like curl or wget directly into a shell interpreter (e.g., | sh or | bash) is widely considered a significant security risk and a poor technical practice [1][2][3][4]. The primary dangers include arbitrary code execution and the bypass of critical security and integrity checks [2][4]. The core risks include: Arbitrary Code Execution: The command immediately executes code from a remote source with the privileges of the user running the shell [2][4]. If the command is run with sudo, it grants root-level access to the remote script, which can result in full system compromise [1][5]. Lack of Integrity Verification: This method bypasses the ability to inspect the script, verify a cryptographic signature (such as GPG), or check a checksum (like SHA-256) before execution [1][2]. You have no assurance that the content received matches what the publisher intended [1]. Transport and Supply Chain Attacks: Relying solely on HTTPS is insufficient [2]. Any compromise of the server, CDN, DNS, or network path (man-in-the-middle attack) can lead to the silent delivery of malicious payloads [6][2]. Failure Modes and Partial Execution: Bash does not necessarily wait for the entire script to download before beginning execution [4]. If the connection is severed mid-stream, the shell may execute a partial, truncated, or malformed script, which can lead to unpredictable behavior, such as unintended file deletions [3][7][4]. Detection of Transport Method: A malicious server can detect that a script is being piped into a shell (versus being saved to a file) by observing timing and TCP behavior, allowing it to serve a clean script to users who save the file but a malicious one to those who pipe it [1][8]. Best Practices: The recommended alternative is to separate the download, verification, and execution steps [2][7][5]: 1. Download: Fetch the script to a local file (e.g., curl -sSL https://example.com/install.sh -o install.sh) [2][4][8]. 2. Verify: Inspect the script content manually or use verification tools to check the file against a known-good checksum or GPG signature provided through a separate, trusted channel [2][4][5]. 3. Execute: Only after verifying the integrity of the downloaded file should you run it (e.g., bash./install.sh) [2][5][8]. If you must use automation, consider caching the script, pinning it to a specific versioned URL, or using a proper package manager that natively handles signatures and integrity validation [4][9].

Citations:


Avoid piping a remote script directly to sh.

Line 1048 executes network-fetched content immediately, which is an arbitrary-code-execution risk if that payload is tampered with. This pattern bypasses integrity verification, exposes the installation to supply-chain and man-in-the-middle attacks, and may execute partial content if the connection is interrupted mid-stream.

Separate the download, verification, and execution steps:

Recommended fix
-    curl -LsSf https://astral.sh/uv/install.sh | sh >/dev/null 2>&1 || return 1
+    local uv_installer
+    uv_installer="$(mktemp)" || return 1
+    curl --proto '=https' --tlsv1.2 -LsSf --connect-timeout 15 --max-time 120 \
+        -o "$uv_installer" https://astral.sh/uv/install.sh || { rm -f "$uv_installer"; return 1; }
+    # Verify checksum/signature against a pinned trusted value before execution.
+    sh "$uv_installer" >/dev/null 2>&1 || { rm -f "$uv_installer"; return 1; }
+    rm -f "$uv_installer"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -LsSf https://astral.sh/uv/install.sh | sh >/dev/null 2>&1 || return 1
local uv_installer
uv_installer="$(mktemp)" || return 1
curl --proto '=https' --tlsv1.2 -LsSf --connect-timeout 15 --max-time 120 \
-o "$uv_installer" https://astral.sh/uv/install.sh || { rm -f "$uv_installer"; return 1; }
# Verify checksum/signature against a pinned trusted value before execution.
sh "$uv_installer" >/dev/null 2>&1 || { rm -f "$uv_installer"; return 1; }
rm -f "$uv_installer"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install-server.sh` at line 1048, The curl command on line 1048 pipes
the remote installation script directly to sh, creating a security
vulnerability. Refactor this to separate the download, verification, and
execution steps: first download the install script to a temporary file using
curl, then verify the integrity of the downloaded file using checksums or
signatures provided by the astral project, and finally execute the verified
script. This prevents arbitrary code execution from tampering or
man-in-the-middle attacks.

export PATH="$HOME/.local/bin:$PATH"
command -v uv >/dev/null 2>&1
}

if [[ ! -d .venv ]]; then
log "creating venv"
# On distros that ship Python 3.14+ (Arch) or where libtorrent's Python
# binding is only available as a system package (Fedora — see dnf branch
# above), we need the venv to inherit system site-packages so `import
# libtorrent` resolves against the OS-installed binding. PyPI does not
# publish libtorrent wheels for 3.14 yet.
if command -v pacman >/dev/null 2>&1 || [[ -f /etc/fedora-release ]]; then
python3 -m venv --system-site-packages .venv
PYBIN="$(pick_system_python || true)"
if [[ -n "$PYBIN" ]]; then
log "creating venv with $PYBIN ($("$PYBIN" --version 2>&1))"
"$PYBIN" -m venv .venv
elif ensure_uv; then
log "no system Python 3.11-3.13; provisioning 3.13 with uv"
uv python install 3.13 >/dev/null 2>&1 || true
uv venv --seed --python 3.13 .venv || die "uv could not create a Python 3.13 venv"
else
python3 -m venv .venv
die "taOS needs Python 3.11-3.13 (litellm has no 3.14 build yet) and uv could not be installed to provision one. Install python3.13 (e.g. 'sudo apt install python3.13 python3.13-venv') and re-run."
Comment on lines 1053 to +1063

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Revalidate existing .venv interpreter before reusing it.

Line 1053 only bootstraps when .venv is missing. If a prior run left a 3.14 .venv, this hotfix is bypassed and litellm install can keep failing on reruns.

Suggested fix
+if [[ -d .venv ]]; then
+    VENV_PY=".venv/bin/python"
+    vv=0
+    if [[ -x "$VENV_PY" ]]; then
+        vv=$("$VENV_PY" -c 'import sys;print(sys.version_info[0]*100+sys.version_info[1])' 2>/dev/null || echo 0)
+    fi
+    if [[ "$vv" -lt 311 || "$vv" -ge 314 ]]; then
+        log "existing .venv uses unsupported Python; recreating"
+        rm -rf .venv
+    fi
+fi
 if [[ ! -d .venv ]]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ ! -d .venv ]]; then
log "creating venv"
# On distros that ship Python 3.14+ (Arch) or where libtorrent's Python
# binding is only available as a system package (Fedora — see dnf branch
# above), we need the venv to inherit system site-packages so `import
# libtorrent` resolves against the OS-installed binding. PyPI does not
# publish libtorrent wheels for 3.14 yet.
if command -v pacman >/dev/null 2>&1 || [[ -f /etc/fedora-release ]]; then
python3 -m venv --system-site-packages .venv
PYBIN="$(pick_system_python || true)"
if [[ -n "$PYBIN" ]]; then
log "creating venv with $PYBIN ($("$PYBIN" --version 2>&1))"
"$PYBIN" -m venv .venv
elif ensure_uv; then
log "no system Python 3.11-3.13; provisioning 3.13 with uv"
uv python install 3.13 >/dev/null 2>&1 || true
uv venv --seed --python 3.13 .venv || die "uv could not create a Python 3.13 venv"
else
python3 -m venv .venv
die "taOS needs Python 3.11-3.13 (litellm has no 3.14 build yet) and uv could not be installed to provision one. Install python3.13 (e.g. 'sudo apt install python3.13 python3.13-venv') and re-run."
if [[ -d .venv ]]; then
VENV_PY=".venv/bin/python"
vv=0
if [[ -x "$VENV_PY" ]]; then
vv=$("$VENV_PY" -c 'import sys;print(sys.version_info[0]*100+sys.version_info[1])' 2>/dev/null || echo 0)
fi
if [[ "$vv" -lt 311 || "$vv" -ge 314 ]]; then
log "existing .venv uses unsupported Python; recreating"
rm -rf .venv
fi
fi
if [[ ! -d .venv ]]; then
PYBIN="$(pick_system_python || true)"
if [[ -n "$PYBIN" ]]; then
log "creating venv with $PYBIN ($("$PYBIN" --version 2>&1))"
"$PYBIN" -m venv .venv
elif ensure_uv; then
log "no system Python 3.11-3.13; provisioning 3.13 with uv"
uv python install 3.13 >/dev/null 2>&1 || true
uv venv --seed --python 3.13 .venv || die "uv could not create a Python 3.13 venv"
else
die "taOS needs Python 3.11-3.13 (litellm has no 3.14 build yet) and uv could not be installed to provision one. Install python3.13 (e.g. 'sudo apt install python3.13 python3.13-venv') and re-run."
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/install-server.sh` around lines 1053 - 1063, The current code at line
1053 only checks if the `.venv` directory exists but does not validate whether
the Python interpreter inside it is compatible (3.11-3.13). If a prior run left
an incompatible `.venv` with Python 3.14, the condition will skip the entire
bootstrap block and subsequent litellm installations will fail. Add validation
logic to check if an existing `.venv` contains a compatible Python version by
extracting and testing the version of the Python interpreter in the existing
`.venv`. If the existing `.venv` has an incompatible version, remove it before
proceeding with the bootstrap logic that calls pick_system_python or ensure_uv.
This ensures that incompatible virtual environments are replaced with compatible
ones on reruns.

fi
fi

Expand Down
2 changes: 1 addition & 1 deletion tinyagentos/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.0-beta.7"
__version__ = "1.0.0-beta.8"
Loading
Loading