Skip to content

release: promote dev to master (1.0.0-beta.11)#1303

Merged
jaylfc merged 39 commits into
masterfrom
dev
Jun 21, 2026
Merged

release: promote dev to master (1.0.0-beta.11)#1303
jaylfc merged 39 commits into
masterfrom
dev

Conversation

@jaylfc

@jaylfc jaylfc commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Promotes 1.0.0-beta.11 to master. Includes: agent deploy fix (master-key fallback + restricted-project proxy self-heal), DeepSeek/cloud model picker fix, free-tier manual cluster pairing, Hermes default, dev/master version reconcile. All on dev with green CI.

jaylfc added 30 commits June 21, 2026 14:08
…58)

First-run GPU auto-detect as a fast-follow to the manual Reduce-effects toggle.
usePerfAutoDetect probes the frame rate for ~1s on boot when the user has made
no explicit choice yet, and enables Reduce effects if the device is struggling
(< 40 fps), so low-end hardware is smooth out of the box. An explicit on/off is
always honored and never overridden. A small inline script in index.html applies
the saved choice before first paint so a low-end device never flashes the full
effects on load. Re-created fresh off current dev (the original branch was 182
commits stale).
…tar #1289)

A hidden tab throttles requestAnimationFrame to ~1fps, which the probe would
read as a struggling GPU and wrongly enable Reduce effects on a capable machine.
Bail if the tab starts hidden, drop the result if it goes hidden during the
probe, and clean up the visibilitychange listener. Clarified the misleading
comment (the probe persists effects ON, not OFF). Added a backgrounded-tab test.
… the account proxy

The taOS client surfaces the join approve/deny UX and the worker app posts its
join request through same-origin /api/account/cluster/join/*, forwarded to the
taos.my /api/cluster/join/* endpoints (taos-website PR #35) with the same
cookie-passthrough as the auth actions. The request_id path param is validated
against an opaque-token regex before it reaches the upstream URL, so it cannot
inject path segments or query (traversal / SSRF guard). Refactored the forward
core into _forward_to(method, path) so the path-param routes reuse it; the
existing auth-action routes are unchanged. 4 new tests; suite 11 green.
feat(perf): first-run GPU auto-detect for Reduce effects (#58)
feat(taosgo): account-proxy the cluster-join consent endpoints
…not abort

libtorrent has no PyPI wheel on most platforms (it is the OS-level
libtorrent-rasterbar / python3-libtorrent package), so listing it as a CORE
dependency made every fresh 'pip install -e .[proxy]' fail with 'No matching
distribution found for libtorrent>=2.0.9' -- a WSL user hit exactly this on a
clean install. The code already treats it as optional: torrent_downloader
guards the import (TORRENT_AVAILABLE) and DownloadManager falls back to a direct
download when it is absent, and the torrent tests skip when it is not installed.
Moved it to a 'torrent' optional extra; the model torrent mesh is enabled only
where the OS package is present (worker install scripts add it via apt/brew).
Regenerated uv.lock (libtorrent now resolves under the torrent extra).
fix(install): make libtorrent optional so fresh installs do not abort
A fresh distro (e.g. WSL on Ubuntu 26.04) defaults python3 to 3.14, but litellm
(the proxy extra) supports only >=3.10,<3.14, so the installer built the venv on
3.14 and aborted with 'No matching distribution found for litellm>=1.89.3'. The
installer now picks the newest interpreter in [3.11,3.14) for the venv, installs
python3.13 via the system package manager if none is present, and fails with a
clear message (pointing to uv) otherwise. Capped requires-python to <3.14 so the
constraint is explicit to pip and uv. Regenerated uv.lock.
… + WSL audit)

Strengthen the venv-Python selection after auditing for further fresh-install
failures and folding gitar review:
- The apt/dnf python3.13 fallback is unreliable on the reported platform (fresh
  WSL/Ubuntu 26.04 ships only 3.14 and may not package python3.13). Provision a
  standalone 3.13 with uv instead, which works on any distro; install uv if absent.
- Drop the bogus 'pacman -S python313' (Arch has no such package; gitar bug).
- Drop --system-site-packages: libtorrent is optional now, and a 3.13 venv could
  not import a 3.14-built system binding anyway (gitar Fedora/Arch edge case).
- Clean venv with the supported interpreter; clear error if uv is also unavailable.
Verified: sqlcipher3 and the other deps ship cp313 wheels; uv venv --seed gives pip.
fix(install): use a litellm-compatible Python (3.11-3.13) for the venv
A re-install over an existing .venv created with Python 3.14 (e.g. from an
attempt before the beta.8 interpreter-selection fix) reused that venv, so
'pip install -e .' failed 'requires a different Python: 3.14.x not in <3.14,>=3.11'.
The venv-selection logic only ran when creating a fresh .venv. Now, before that,
probe an existing .venv's interpreter and rm -rf it if it is outside [3.11,3.14)
so it is recreated with a supported Python. Verified: 3.11/3.13 kept, 3.14 or an
unreadable interpreter trigger recreate.
The Activity NPU card rendered whenever npu.type was set, but a machine with no
NPU reports type 'none' (truthy), so it showed a 'grant debugfs access' message
on hardware that has no NPU at all. Gate the card on a real NPU (type set and
not 'none'), matching the existing hardwareLabel check, so it is hidden entirely
when none is present. A real NPU device still shows it (with the per-core
permission hint when debugfs is unreadable).
showWidgets now defaults to false for fresh/default state, so the widget layer
is off until the widgets are overhauled. A user who already enabled widgets is
unaffected -- their persisted showWidgets choice is restored.
fix(install): recreate a stale venv built with an unsupported Python
fix(desktop): hide NPU card with no NPU + default widgets off until redesign
A newly-added DeepSeek provider's models did not appear in the agent
model picker. The picker lists LiteLLM /v1/models intersected with the
per-provider model lists from GET /api/providers, dropping any model
whose id is not in a provider's list. list_providers built that list
only from the live /models health probe, which 401s for DeepSeek
without a key it can reach, so the entry shipped with models=[] even
though add_provider had seeded PROVIDER_DEFAULT_MODELS into the backend
config. The seeded ids were in LiteLLM but had no provider to map to,
so the picker filtered them out.

Fall back to the models stored on the backend in config when the live
probe and the api-key re-probe both come up empty. Extends the same
#356 fix that added the key re-probe.

Test: list_providers returns the seeded deepseek models when the health
probe yields none and no api key resolves.
…y picker

The taOS agent settings chooser built its model list differently from the
agent deploy wizard, so a cloud provider like DeepSeek that showed in the
deploy picker did not appear for the taOS agent. Add a shared
loadAgentModels() that builds the exact union the deploy wizard uses
(downloaded controller-catalog + cluster-worker + cloud-provider models
from LiteLLM /v1/models keyed back to a provider via /api/providers), and
point both taOS agent surfaces (TaosAgentCard, TaosAssistantSettings) at it.

Per-model hostKind is preserved, so ModelPickerFlow's source-select screen
still separates local / worker / cloud before the user picks a model.

Tests: loadAgentModels unit tests (cloud model surfaces, internal aliases
dropped, controller-catalog filtering) + TaosAssistantSettings updated to
the shared loader.
…-master

# Conflicts:
#	pyproject.toml
#	scripts/install-server.sh
Reconcile dev onto beta.10 across all version files (pyproject,
__init__, desktop package.json + lockfile, uv.lock 1.0.0b10) after the
master sync. No runtime change; the WSL install fixes from beta.7-9 are
carried unchanged.
chore: sync dev with master + bump to 1.0.0-beta.10
fix(models): taOS agent chooser lists same models as deploy picker (DeepSeek)
…+ Hermes default

Restores agent deploys on boxes that can't mint per-agent LiteLLM virtual
keys (ARM/Pi where prisma can't start, or any no-Postgres install). #668
made the per-agent scoped key mandatory and dropped the master-key
fallback, which broke every framework deploy on those hosts (Discord
report + reproduced on the Pi).

deployer.py: when create_agent_key returns None, fall back to the shared
LiteLLM master key by default (taOS is single-user per instance) with a
loud warning and a deploy step noting the loss of per-agent isolation.
A hardened / multi-tenant operator sets
TAOS_DISABLE_AGENT_MASTER_KEY_FALLBACK=1 to keep the hard refusal.

DeployWizard: Hermes is the recommended default -- shown first and
auto-selected; OpenClaw second; the rest preserve order. (Hermes was
already beta/visible in the manifest; only ordering + default-select
changed.)

tests: master-key fallback used by default; refusal preserved when the
env opt-out is set; the two prior 'must refuse' tests updated to the
opt-out path. 50 passed.
…jects

The second blocker behind 'agent deploy fails': multi-user installs put
agent containers in a restricted incus project (e.g. user-999) that
blocks proxy devices by default, so attaching the LiteLLM/controller
proxy devices fails with 'Proxy devices are forbidden' and the deploy
dies at container_created. The restricted project is provisioned outside
taOS (manually / per-user incus default), so there is no install step to
patch.

add_proxy_device now self-heals: on that exact error it reads the project
name from the message, sets restricted.devices.proxy=allow on it, and
retries once. Only the trusted controller adds devices (never the agent
inside the container), so relaxing this one restriction is safe; idmap /
disk-path / network isolation is unchanged. Confirmed on the Pi: with
this + the master-key fallback, the Hermes deploy reaches RUNNING and
installs the framework.

tests: relax+retry on forbidden; no self-heal on unrelated failures.
… faults (gitar)

gitar Security finding on the fallback: it masked two different failures.
Now split:
- db_url is None (routing-only / no virtual-key capability, e.g. ARM):
  fall back to the master key by default (opt-out via env). Expected gap.
- db_url set but mint failed (migration pending, DB unreachable, master
  key drift): a real LiteLLM/DB fault. Always refuse, never mask it with
  the master key, and point the operator at the DB. Independent of the
  env opt-out.

test updated: db-configured-but-broken refuses unconditionally (opt-out
unset).
jaylfc added 9 commits June 21, 2026 21:39
…back

fix(deploy): restore agent deploys (master-key fallback + restricted-project proxy self-heal) + Hermes default
…e}, worker polls

The free LAN tier (no taOSgo) is deliberately manual: the worker shows a code,
the user enters the worker IP + code in the Cluster app, and the worker polls
for its key. No announce, no network discovery -- the convenience is the paid
taOSgo tier. Backend:
- ClusterPairingStore.manual_authorize(url, code): mint a key keyed by code hash
  (the worker is not known by name yet), single-use, 15min TTL.
- ClusterPairingStore.manual_claim(name, code): once authorized, persist the key
  under the worker name (so its HMAC-signed requests authenticate) and return
  (key, url) once; awaiting/None otherwise.
- POST /api/cluster/pairing/manual (admin) + /api/cluster/pairing/manual-claim
  (worker poll). 6 new store tests; full pairing suite 43 green.
Adds a 'Add worker' button (toolbar + empty state) that opens a modal
to enter the worker's LAN IP and pairing PIN, POSTing to
/api/cluster/pairing/manual. This is the free-tier manual flow: no
network discovery, the user types the IP and the PIN the worker shows.
taOSgo remains the one-tap automated path.
run_manual_pairing displays the worker address + PIN and polls
/api/cluster/pairing/manual-claim until the admin enters the IP and PIN
in taOS > Cluster > Add worker. No network announce or discovery, which
is the free-tier model: discovery and one-tap install stay taOSgo-only.

- pairing.py: run_manual_pairing + _print_manual_instructions
- pair.py: --manual flag selects the manual flow
- install-worker.sh: TAOS_PAIR_MANUAL threads --manual into the pair call
- tests: happy path, already-paired short-circuit, timeout (no announce)
…anup)

CodeRabbit/gitar review of #1298:
- BUG: pairing_manual called urlparse without importing it (local imports in
  other functions do not leak) -> every authorize raised NameError/500. Add a
  local import. Now covered by a route-level test.
- SECURITY: manual-claim is unauthenticated and matches purely by sha256(code),
  so a wrong code is indistinguishable from a worker polling pre-authorize
  (both 'awaiting'). A failure cap would throttle legit polling, so add a
  per-IP fixed-window rate limit (20/10s) -> caps brute-force on top of the
  high-entropy PIN; legit workers poll ~0.3 req/s.
- CLEANUP: switch manual single-use from a consumed flag to DELETE-on-claim and
  delete expired rows on access, so no stale signing key lingers at rest.
- auth_middleware: exempt POST /manual-claim (code is the proof); authorize
  stays admin-gated.
- tests: 6 new route tests (admin-gate, authorize+claim happy path incl. the
  urlparse regression, empty/invalid address, awaiting, rate-limit).
Covers TAOS_PAIR_MANUAL + Cluster > Add worker (enter IP + PIN), the
single-use 15-min authorisation, and notes taOSgo automates it over the
relay.
feat(cluster): manual free-tier worker pairing (controller + UI + worker)
Promotes the deploy-fix + manual-pairing + DeepSeek-picker work to a
release. Bumps all version files beta.10 -> beta.11.

Highlights:
- agent deploy restored on ARM/no-Postgres (gated master-key fallback)
  + restricted-incus-project proxy self-heal
- DeepSeek/cloud provider models surface in both agent model pickers
- free-tier manual cluster-worker pairing
- Hermes default framework
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions

Copy link
Copy Markdown

👋 Thanks for the PR! This one targets master, which is our
stable branch (it's what live installs track). Please retarget it to
dev — click Edit next to the PR title and change the base
branch dropdown from master to dev. Your commits and any review
carry over, nothing is lost.

See CONTRIBUTING.md for the branch model.

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jaylfc, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 18 minutes and 46 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f6b55664-c5f6-453f-8b36-5646a209d7d7

📥 Commits

Reviewing files that changed from the base of the PR and between 2def425 and 65d6fa9.

⛔ Files ignored due to path filters (2)
  • desktop/package-lock.json is excluded by !**/package-lock.json
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • CHANGELOG.md
  • README.md
  • desktop/index.html
  • desktop/package.json
  • desktop/src/App.tsx
  • desktop/src/apps/ActivityApp.tsx
  • desktop/src/apps/ClusterApp.tsx
  • desktop/src/apps/agents/DeployWizard.tsx
  • desktop/src/components/TaosAgentCard.tsx
  • desktop/src/components/TaosAssistantSettings.test.tsx
  • desktop/src/components/TaosAssistantSettings.tsx
  • desktop/src/lib/__tests__/use-perf-autodetect.test.ts
  • desktop/src/lib/models.test.ts
  • desktop/src/lib/models.ts
  • desktop/src/lib/use-perf-autodetect.ts
  • desktop/src/stores/widget-store.ts
  • docs/STATUS.md
  • pyproject.toml
  • scripts/install-worker.sh
  • tests/test_containers.py
  • tests/test_deployer.py
  • tests/test_pairing_store.py
  • tests/test_routes_account_proxy.py
  • tests/test_routes_cluster_pairing.py
  • tests/test_routes_providers.py
  • tests/worker/test_pairing.py
  • tinyagentos/__init__.py
  • tinyagentos/auth_middleware.py
  • tinyagentos/cluster/pairing_store.py
  • tinyagentos/containers/__init__.py
  • tinyagentos/deployer.py
  • tinyagentos/routes/account_proxy.py
  • tinyagentos/routes/cluster.py
  • tinyagentos/routes/providers.py
  • tinyagentos/worker/pair.py
  • tinyagentos/worker/pairing.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jaylfc jaylfc merged commit c81ed1a into master Jun 21, 2026
10 of 11 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in TinyAgentOS Roadmap Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant