Compare commits

..
Author SHA1 Message Date
abiba-bot 4320369bb9 Merge pull request 'fix(alignment): resolve /root/ hardcoding and stale tanko-DSH references' (#147) from fix/agent-health-root-hardcoding-20260928 into master
PR Pipeline — Authorize → Validate → Review → Merge / auth (push) Successful in 6s
PR Pipeline — Authorize → Validate → Review → Merge / validate (push) Successful in 5s
PR Pipeline — Authorize → Validate → Review → Merge / lint (push) Successful in 18s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (push) Successful in 11s
PR Pipeline — Authorize → Validate → Review → Merge / gate (push) Successful in 0s
2026-09-28 23:05:30 +00:00
abiba-bot 3b74ca28d1 Merge branch 'master' into fix/agent-health-root-hardcoding-20260928
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 6s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 5s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 17s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 11s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 2s
2026-09-28 23:03:53 +00:00
root af9397d672 fix(alignment): accept multiple wrapper shapes in hermes-real check
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 8s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 6s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 19s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 6s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 0s
The fleet's wrappers do not all use a hermes-real indirection. Some (tanko,
mumuni) exec the venv module directly. This check now:
  1. Tries hermes-real at {home}/.local/bin (koonimo's shape)
  2. Tries the venv under {home}/.hermes/hermes-agent/venv (tanko/mumuni shape)
  3. Tries /usr/local/lib/hermes-agent/venv (legacy system-wide shape)

Each match is reported with which shape it matched, so a genuinely broken
wrapper is still a failure while a different-but-valid shape is not.
2026-09-28 22:23:08 +00:00
root 97dc2d772f fix(alignment): repair f-string quoting in config check, add home to scope
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 6s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 8s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 18s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 9s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 3s
- Fixed line 537: f-string now uses single quotes inside double-quoted shell
  command to avoid nested quote collision
- Added home = get_user_home(user) to check_config_integrity loop scope so
  the config check can resolve the correct home directory
2026-09-28 21:20:42 +00:00
root 2238777a2f fix(alignment): resolve /root/ hardcoding and stale tanko-DSH references
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Failing after 13m19s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Skipped
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Skipped
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Skipped
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Skipped
F1: agent-health-check.py now resolves the home directory from the agent's
user field via a shared helper (get_user_home) instead of hardcoding /root/.
This fixes the false-positive wrapper-missing:tanko report — tanko has a
working wrapper at /home/jerome/.local/bin/hermes, but the check was looking
in /root/.local/bin/.

F2: Updated stale references that described tanko as DSH-only:
- hermes-zulip-restore.prose.md: tanko excluded — hybrid (DSH + Hermes)
- hermes-zulip-plugin.prose.md: tanko excluded — hybrid (DSH + Hermes)
- infrastructure-control.prose.md: tanko is hybrid (DSH + Hermes) agent
- docs/probe-drift-round2-evidence.md: marked as historical record with
  dated note explaining that the DSH-only observations reflected the
  /root/ hardcoding bug, not the underlying truth

Refs: fix/agent-health-root-hardcoding-20260928
2026-09-28 20:48:49 +00:00
abiba-bot 6b2ba1bba5 Merge pull request 'fix(alignment): clarify tanko live LiteLLM proxy status in health-check description' (#145) from fix/contract-alignment-f2-hermes-baseline-20260928 into master
PR Pipeline — Authorize → Validate → Review → Merge / auth (push) Successful in 27s
PR Pipeline — Authorize → Validate → Review → Merge / validate (push) Successful in 33s
PR Pipeline — Authorize → Validate → Review → Merge / lint (push) Successful in 14s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (push) Successful in 8s
PR Pipeline — Authorize → Validate → Review → Merge / gate (push) Successful in 4s
2026-09-28 12:59:50 +00:00
abiba-bot ba9d29b4b9 Merge pull request 'fix(alignment): recognize tanko as hybrid (DSH + Hermes) in agent-health-check' (#146) from fix/contract-alignment-f3-tanko-hybrid-20260928 into master 2026-09-28 12:54:42 +00:00
abiba-bot d6376e5142 Merge pull request 'fix(alignment): use llmuser with sudo for swap-gpu-dense-model.sh' (#144) from fix/contract-alignment-f1-swap-gpu-user-20260928 into master
PR Pipeline — Authorize → Validate → Review → Merge / auth (push) Successful in 18s
PR Pipeline — Authorize → Validate → Review → Merge / validate (push) Successful in 24s
PR Pipeline — Authorize → Validate → Review → Merge / lint (push) Successful in 15s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (push) Successful in 11s
PR Pipeline — Authorize → Validate → Review → Merge / gate (push) Successful in 2s
2026-09-28 12:53:53 +00:00
root 2ea6b4fc17 Merge PR #146: fix(alignment): recognize tanko as hybrid (DSH + Hermes) in agent-health-check 2026-09-28 12:50:23 +00:00
root c6fd8eece3 Merge PR #145: fix(alignment): clarify tanko live LiteLLM proxy status in health-check description 2026-09-28 12:50:23 +00:00
root 4c715526ef Merge PR #144: fix(alignment): use llmuser with sudo for swap-gpu-dense-model.sh 2026-09-28 12:50:23 +00:00
root 308265e7ce fix(alignment): recognize tanko as hybrid (DSH + Hermes) in agent-health-check
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 17s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 32s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 11s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 17s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 3s
Tanko runs both DSH (pnpm dsh web) and Hermes (hermes gateway) concurrently.
The false premise was that tanko is DSH-only with no Hermes gateway, which
caused the gateway liveness, config.yaml, and wrapper integrity checks to be
skipped entirely. Now tanko gets the full Hermes-era checks like koonimo and
koby, while dsh/pi-only agents still skip those legs correctly.
2026-09-28 12:44:25 +00:00
root 13ac189365 fix(alignment): use llmuser with sudo for swap-gpu-dense-model.sh (root SSH to .8 denied)
PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 25s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 16s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 42s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 23s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 1s
2026-09-28 12:34:32 +00:00
6 changed files with 62 additions and 29 deletions
+9
View File
@@ -1,5 +1,14 @@
# Probe-drift round 2 — per-leg before/after evidence # Probe-drift round 2 — per-leg before/after evidence
> **Historical record** — 2026-09-28: The lines below that describe tanko as
> "DSH (DeepSeek Harness)" only reflect what the check reported when it was
> running. Tanko's runtime was later found to be **hybrid (DSH + Hermes)** —
> the check had a `/root/` hardcoding bug that made it probe the wrong home
> directory and report `wrapper-missing:tanko` for an agent with a working
> wrapper. This document records the observed output, not the underlying
> truth; see `fix/agent-health-root-hardcoding-20260928` for the correction.
**Date:** 2026-09-10 **Date:** 2026-09-10
**Worktree (absolute execution path):** `/root/.treehouse/prose-contracts-9ce5f3/3/prose-contracts` **Worktree (absolute execution path):** `/root/.treehouse/prose-contracts-9ce5f3/3/prose-contracts`
**Branch:** `fm/probe-drift-round2-20260909` **Branch:** `fm/probe-drift-round2-20260909`
+3 -3
View File
@@ -28,7 +28,7 @@ connectivity recovery including end-to-end DM validation.
| Param | Type | Required | Default | Description | | Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------| |-------|------|----------|---------|-------------|
| `target` | string | yes | — | Agent name: `mumuni`, `koby`, or `shumba` (Tanko excluded — on DSH since 2026-08-27, no Hermes plugin) | | `target` | string | yes | — | Agent name: `mumuni`, `koby`, or `shumba` (Tanko excluded — hybrid (DSH + Hermes) since 2026-08-27, no Hermes plugin) |
| `branch` | string | no | `master` | Git branch to pull (overridable for pinning) | | `branch` | string | no | `master` | Git branch to pull (overridable for pinning) |
## Maintains ## Maintains
@@ -55,7 +55,7 @@ connectivity recovery including end-to-end DM validation.
| Host | CT | Proxmox | IP (direct) | Hermes Home | User | | Host | CT | Proxmox | IP (direct) | Hermes Home | User |
|------|-----|---------|-------------|-------------|------| |------|-----|---------|-------------|-------------|------|
| Tanko | CT112 | minipve | 192.168.68.122 | /home/jerome/.hermes | jerome | *(DSH since 2026-08-27 — historical, plugin retired on this host)* | | Tanko | CT112 | minipve | 192.168.68.122 | /home/jerome/.hermes | jerome | *(hybrid (DSH + Hermes) since 2026-08-27 — historical, plugin retired on this host)* |
| Koby | CT111 | storepve | 192.168.68.129 | /root/.hermes | root | | Koby | CT111 | storepve | 192.168.68.129 | /root/.hermes | root |
| Shumba | — | — | 192.168.68.119 | /home/lucky/.hermes | lucky | | Shumba | — | — | 192.168.68.119 | /home/lucky/.hermes | lucky |
@@ -121,7 +121,7 @@ cp plugins/platforms/zulip/adapter.py \
{{hermes_home}}/hermes-agent/plugins/platforms/zulip/ {{hermes_home}}/hermes-agent/plugins/platforms/zulip/
# Fix ownership (was Tanko-only, runs as jerome user) # Fix ownership (was Tanko-only, runs as jerome user)
# RETIRED 2026-08-27: tanko no longer uses the Hermes Zulip plugin (DSH). # RETIRED 2026-08-27: tanko no longer uses the Hermes Zulip plugin (hybrid: DSH + Hermes).
[ "{{target}}" = "tanko" ] && chown -R jerome:jerome \ [ "{{target}}" = "tanko" ] && chown -R jerome:jerome \
{{hermes_home}}/hermes-agent/plugins/platforms/zulip/ {{hermes_home}}/hermes-agent/plugins/platforms/zulip/
+2 -2
View File
@@ -24,7 +24,7 @@ gateway restart, and connection validation.
| Param | Type | Required | Default | Description | | Param | Type | Required | Default | Description |
|-------|------|----------|---------|-------------| |-------|------|----------|---------|-------------|
| `target` | string | yes | — | Agent name: `mumuni`, `koby`, or `shumba` (Tanko excluded — DSH since 2026-08-27) | | `target` | string | yes | — | Agent name: `mumuni`, `koby`, or `shumba` (Tanko excluded — hybrid (DSH + Hermes) since 2026-08-27) |
## Maintains ## Maintains
@@ -93,7 +93,7 @@ cp zulip-platform-plugins/plugins/platforms/zulip/adapter.py \
zulip-platform-plugins/plugins/platforms/zulip/plugin.yaml \ zulip-platform-plugins/plugins/platforms/zulip/plugin.yaml \
<HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/
# Fix ownership (was Tanko-only; RETIRED 2026-08-27 — tanko on DSH, no Hermes plugin) # Fix ownership (was Tanko-only; RETIRED 2026-08-27 — tanko on hybrid (DSH + Hermes), no Hermes plugin)
chown -R jerome:jerome <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ # Tanko only (historical) chown -R jerome:jerome <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ # Tanko only (historical)
# Clean up # Clean up
+1 -1
View File
@@ -682,7 +682,7 @@ ssh root@192.168.68.110 "systemctl restart llama-server"
| 109 | docker-vm | storepve | .7 | Docker host | ❌ | | 109 | docker-vm | storepve | .7 | Docker host | ❌ |
| 110 | gitea | minipve | **.17** | Git | ❌ | | 110 | gitea | minipve | **.17** | Git | ❌ |
| 111 | tdunna | storepve | .129 | Hermes agent — ⛔ REPORT-ONLY (Theo's box, no GC) | ✅ | | 111 | tdunna | storepve | .129 | Hermes agent — ⛔ REPORT-ONLY (Theo's box, no GC) | ✅ |
| 112 | tanko | minipve | .122 | DSH (DeepSeek Harness) agent | ✅ | | 112 | tanko | minipve | .122 | hybrid (DSH + Hermes) agent | ✅ |
| 113 | baggy | amdpve | .114 | Hermes agent | ✅ | | 113 | baggy | amdpve | .114 | Hermes agent | ✅ |
| 115 | scottdenya | amdpve | .75 | Denya OneCare | ❌ | | 115 | scottdenya | amdpve | .75 | Denya OneCare | ❌ |
| 116 | syslog-api | minipve | .116 | LiteLLM + Grafana | ❌ | | 116 | syslog-api | minipve | .116 | LiteLLM + Grafana | ❌ |
+46 -22
View File
@@ -75,7 +75,7 @@ PVE_NODES = {
# Agent definitions: ct, host, user, pve_node, vault_key_name # Agent definitions: ct, host, user, pve_node, vault_key_name
AGENTS = { AGENTS = {
"tanko": {"ct": 112, "host": "192.168.68.122", "user": "jerome", "pve": "minipve", "vault_key": "TANKO_LITELLM_API_KEY", "runtime": "dsh"}, "tanko": {"ct": 112, "host": "192.168.68.122", "user": "jerome", "pve": "minipve", "vault_key": "TANKO_LITELLM_API_KEY", "runtime": "hybrid"},
# abiba = pi agent (.24) — no vault key; its LiteLLM key is read from its # abiba = pi agent (.24) — no vault key; its LiteLLM key is read from its
# local env file (key_env below), not from the shared vault or .bashrc. # local env file (key_env below), not from the shared vault or .bashrc.
# runtime=pi: abiba has run pi-only since the harness purge. There is no # runtime=pi: abiba has run pi-only since the harness purge. There is no
@@ -152,6 +152,18 @@ def ssh(host, cmd, user="root"):
except: except:
return None return None
def get_user_home(user):
"""Resolve the home directory for a user.
For 'root', returns '/root'. For any other user, returns '/home/<user>'.
This is used to construct paths that reference a user's home directory
(e.g., ~/.local/bin/hermes, ~/.hermes/config.yaml) instead of hardcoding /root/.
"""
if user == "root":
return "/root"
else:
return f"/home/{user}"
def http_get(url, headers=None, timeout=5): def http_get(url, headers=None, timeout=5):
"""Return HTTP status code as string.""" """Return HTTP status code as string."""
try: try:
@@ -382,10 +394,10 @@ def check_agents():
ct = agent["ct"] ct = agent["ct"]
report_only = agent.get("report_only", False) report_only = agent.get("report_only", False)
# Tanko runs on DSH (DeepSeek Harness) since 2026-08-27 — it no longer runs a # Tanko runs hybrid (DSH + Hermes) since 2026-08-27 — it runs both DSH and Hermes gateway.
# Hermes gateway, so skip the Hermes gateway/state/streaming/journal checks. # Hermes gateway, so skip the Hermes gateway/state/streaming/journal checks.
# Non-Hermes runtimes have no gateway to probe. dsh = Tanko since # Non-Hermes runtimes have no gateway to probe. dsh/pi-only skip the check;
# 2026-08-27; pi = abiba since the harness purge (.24 is pi-only). # hybrid runs both DSH and Hermes and is checked normally.
if agent.get("runtime") in ("dsh", "pi"): if agent.get("runtime") in ("dsh", "pi"):
is_dsh = agent.get("runtime") == "dsh" is_dsh = agent.get("runtime") == "dsh"
label = "DSH (DeepSeek Harness)" if is_dsh else "pi-only runtime" label = "DSH (DeepSeek Harness)" if is_dsh else "pi-only runtime"
@@ -506,7 +518,7 @@ def check_ct_liveness():
def check_config_integrity(): def check_config_integrity():
"""Verify agent config.yaml parses as valid YAML.""" """Verify agent config.yaml parses as valid YAML."""
for name, agent in AGENTS.items(): for name, agent in AGENTS.items():
# Tanko runs on DSH (DeepSeek Harness) since 2026-08-27 — no Hermes config.yaml. # DSH/pi-only runtimes have no Hermes config.yaml; hybrid has both.
if agent.get("runtime") == "dsh": if agent.get("runtime") == "dsh":
print(f" ⏭️ {name}: DSH — no Hermes config.yaml since 2026-08-27") print(f" ⏭️ {name}: DSH — no Hermes config.yaml since 2026-08-27")
continue continue
@@ -519,11 +531,11 @@ def check_config_integrity():
print(f" ⬜ {name}: cannot SSH — skip config check") print(f" ⬜ {name}: cannot SSH — skip config check")
continue continue
home = get_user_home(user)
# Check YAML parses # Check YAML parses
yaml_ok = ssh(host, yaml_ok = ssh(host,
"python3 -c " f"python3 -c \"import yaml; yaml.safe_load(open('{home}/.hermes/config.yaml')); print('OK')\" 2>&1 || echo 'FAIL'",
'"import yaml; yaml.safe_load(open(\'/root/.hermes/config.yaml\')); print(\'OK\')" '
"2>&1 || echo 'FAIL'",
user=user) user=user)
if not yaml_ok: if not yaml_ok:
print(f" ❌ {name}: SSH UNREACHABLE (config check skipped)") print(f" ❌ {name}: SSH UNREACHABLE (config check skipped)")
@@ -562,7 +574,7 @@ def _infisical_invocation_paths(wrapper_body):
def check_wrapper_integrity(): def check_wrapper_integrity():
"""Verify the hermes CLI wrapper exists and can reach hermes-real.""" """Verify the hermes CLI wrapper exists and can reach hermes-real."""
for name, agent in AGENTS.items(): for name, agent in AGENTS.items():
# Tanko runs on DSH (DeepSeek Harness) since 2026-08-27 — no hermes CLI wrapper. # DSH/pi-only runtimes have no hermes CLI wrapper; hybrid has both.
if agent.get("runtime") == "dsh": if agent.get("runtime") == "dsh":
print(f" ⏭️ {name}: DSH — no hermes CLI wrapper since 2026-08-27") print(f" ⏭️ {name}: DSH — no hermes CLI wrapper since 2026-08-27")
continue continue
@@ -576,7 +588,8 @@ def check_wrapper_integrity():
continue continue
# Check wrapper exists # Check wrapper exists
wrapper = ssh(host, "ls -la /root/.local/bin/hermes 2>/dev/null", user=user) home = get_user_home(user)
wrapper = ssh(host, f"ls -la {home}/.local/bin/hermes 2>/dev/null", user=user)
if not wrapper: if not wrapper:
# Check alternate wrapper locations # Check alternate wrapper locations
wrapper = ssh(host, "which hermes 2>/dev/null; command -v hermes 2>/dev/null", user=user) wrapper = ssh(host, "which hermes 2>/dev/null; command -v hermes 2>/dev/null", user=user)
@@ -599,7 +612,7 @@ def check_wrapper_integrity():
# a removed path (litellm-api-keys.prose.md documents # a removed path (litellm-api-keys.prose.md documents
# `rm -f /usr/local/bin/infisical`) must neither produce a dangling path # `rm -f /usr/local/bin/infisical`) must neither produce a dangling path
# nor trigger the PATH check — it is not an invocation. # nor trigger the PATH check — it is not an invocation.
wrapper_body = ssh(host, "cat /root/.local/bin/hermes 2>/dev/null", user=user) or "" wrapper_body = ssh(host, f"cat {home}/.local/bin/hermes 2>/dev/null", user=user) or ""
wrapper_code = "\n".join(line.split("#", 1)[0] for line in wrapper_body.splitlines()) wrapper_code = "\n".join(line.split("#", 1)[0] for line in wrapper_body.splitlines())
invoked_paths = _infisical_invocation_paths(wrapper_body) invoked_paths = _infisical_invocation_paths(wrapper_body)
if "infisical" in wrapper_code: if "infisical" in wrapper_code:
@@ -633,24 +646,35 @@ def check_wrapper_integrity():
else: else:
print(f" ℹ️ {name}: wrapper resolves creds without infisical (e.g. ~/.hermes/.env) — OK") print(f" ℹ️ {name}: wrapper resolves creds without infisical (e.g. ~/.hermes/.env) — OK")
# Check hermes-real exists # Check that the wrapper's target resolves. The fleet's wrappers do NOT
# all use a hermes-real indirection — some exec the venv module directly.
# Verify the wrapper actually points to something runnable.
hermes_real = ssh(host, hermes_real = ssh(host,
"ls -la /root/.local/bin/hermes-real 2>/dev/null || echo MISS", f"ls -la {home}/.local/bin/hermes-real 2>/dev/null || echo MISS",
user=user) user=user)
if not hermes_real or hermes_real.strip() == "MISS": if hermes_real and hermes_real.strip() != "MISS":
# Check venv path print(f" ✅ {name}: wrapper shape: hermes-real at {home}/.local/bin/hermes-real")
hermes_real = ssh(host, else:
"ls -la /usr/local/lib/hermes-agent/venv/bin/hermes 2>/dev/null || echo MISS", # Try the venv under home
venv_home = ssh(host,
f"test -x {home}/.hermes/hermes-agent/venv/bin/python && echo OK || echo MISS",
user=user) user=user)
if not hermes_real or hermes_real.strip() == "MISS": if venv_home and venv_home.strip().splitlines()[-1] == "OK":
print(f" ❌ {name}: hermes-real NOT FOUND (wrapper broken)") print(f" ✅ {name}: wrapper shape: direct venv exec ({home}/.hermes/hermes-agent/venv/bin/python)")
_fail(f"wrapper-no-hermes-real:{name}", name)
else: else:
print(f" ✅ {name}: hermes-real at alt path") # Try the system-wide venv
venv_sys = ssh(host,
"test -x /usr/local/lib/hermes-agent/venv/bin/python && echo OK || echo MISS",
user=user)
if venv_sys and venv_sys.strip().splitlines()[-1] == "OK":
print(f" ✅ {name}: wrapper shape: system venv (/usr/local/lib/hermes-agent/venv/bin/python)")
else:
print(f" ❌ {name}: wrapper target NOT RESOLVABLE (no hermes-real, no venv)")
_fail(f"wrapper-no-hermes-real:{name}", name)
# Check the .env file has the key # Check the .env file has the key
env_has_key = ssh(host, env_has_key = ssh(host,
"grep -c 'LITELLM_API_KEY' /root/.hermes/.env 2>/dev/null || echo 0", f"grep -c 'LITELLM_API_KEY' {home}/.hermes/.env 2>/dev/null || echo 0",
user=user) user=user)
if env_has_key and env_has_key.strip() not in ("", "0"): if env_has_key and env_has_key.strip() not in ("", "0"):
print(f" ✅ {name}: wrapper + .env key present") print(f" ✅ {name}: wrapper + .env key present")
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# swap-gpu-dense-model.sh — Swap RTX 3090 from qwen3.6-27B-code to SmartCode-Fable-5 # swap-gpu-dense-model.sh — Swap RTX 3090 from qwen3.6-27B-code to SmartCode-Fable-5
# Run when download completes: ssh root@192.168.68.8 'bash -s' < this script # Run when download completes: ssh llmuser@192.168.68.8 'sudo bash -s' < this script
# #
# Usage: bash swap-gpu-dense-model.sh # Usage: bash swap-gpu-dense-model.sh
# Requires: new model at /home/llmuser/models/SmartCode-Fable-5-27B-UD-Q4_K_XL.gguf # Requires: new model at /home/llmuser/models/SmartCode-Fable-5-27B-UD-Q4_K_XL.gguf