[Sync] LLM clients → Qwen3.6-35B-A3B-Thinking default, Ornith preset, fl GPU monitor abbrs

Re-export of private HEAD 73b4a65: default-model flip + 8k thinking budget
in the aichat/opencode/pi client configs, the Ornith-1.5-35B-A3B preset and
its gate bench in fl/.config/llamacpp, and the fl fish abbrs `vram` /
`vramx` with the new gpumon.sh (sysfs VRAM/GTT monitor).
This commit is contained in:
Coja committed 2026-10-16 14:11:09 +02:00
1 parent 2fa113cd15
commit 93b4f695ce
15 files changed
+340 -18

No files matched your search

+2 -1
View File
@@ -8,7 +8,7 @@ resize), trailing (lowest-priority) segments are dropped from the right until it
Wide — everything:
```
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Fable 5 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h │ ♻️ 91% 1h │ 💾 81%
📁 ~/.dots │ 🌿 .dots main* │ 🤖 Fable 5 (1M) · xhigh │ 📝 84% (843k) │ 📊 34% 2h54m │ 💰 $0.40 $12.00/h │ 🔢 ↑63M ↓595k │ ♻️ 91% 1h │ 💾 81%
```
Narrow — trailing segments trimmed:
@@ -32,6 +32,7 @@ is supplementary to the main colored value.
| 📝 | **Context** | `% of context window used` + `(Nk)` tokens | usage comes from the payload's `context_window` (`used_percentage` + `current_usage`, Claude Code 2.1.x); the transcript's last `message.usage` is only a fallback. Window from `context_window.context_window_size`, then `(1M …)` in the display name, else 200k — **not** from `model.id`, which arrives with any `[1m]` suffix already stripped. Adds a red **⚠compact** at ≥80% |
| 📊 | **5h usage** | `% of the 5-hour rolling limit used` + time until it resets | from `rate_limits.five_hour`; Pro/Max only, and absent until the first API response of a session |
| 💰 | **Cost** | `$` session cost so far + `$/h` burn rate | burn rate shown once the session exceeds ~30s |
| 🔢 | **Session tokens** | `↑` input + `↓` output tokens used so far this session (cumulative, `k`/`M`) | summed over the transcript's assistant `message.usage` blocks, de-duplicated by message id (one line per content block shares the same usage). Input = `input + cache_creation + cache_read` — everything billed as input, so on a 1M session it dwarfs output (every call re-reads the cached prefix). Main transcript only: subagent usage lives in separate sidechain files. Incremental: a per-session state file `~/.claude/cache/statusline.tokens.<session>.json` remembers the byte offset already summed, so each refresh parses only the new tail (cold scan of a 6.5 MB transcript ≈ 70 ms, warm ≈ 0.1 ms); stale state files are pruned after 7 days once 50+ pile up. Omitted when there is no transcript; `↑` cyan, `↓` green, no thresholds |
| ♻️ | **Prompt cache** | hit `%` (higher is better) + cache TTL (`5m` / `1h`), yellow `·cold` once it has expired | from the payload's `prompt_cache` (2.1.260+: `hit_ratio` 0–1, `ttl`, `warm`); computed from usage on older payloads. A `1h` TTL is what keeps a 10-min `/pr-loop` cadence warm |
| 💾 | **Disk** | `% used` of the filesystem at the cwd | from `statvfs` |
+9 -3
View File
@@ -5,15 +5,21 @@
{
"context": "Chat",
"bindings": {
"shift+enter": "chat:newline"
"shift+enter": "chat:newline",
"ctrl+x v": "app:toggleTranscript"
}
},
{
"context": "Transcript",
"bindings": {
"ctrl+x v": "app:toggleTranscript"
}
},
{
"context": "Global",
"bindings": {
"alt+j": "scroll:lineDown",
"alt+k": "scroll:lineUp",
"ctrl+x v": "app:toggleTranscript"
"alt+k": "scroll:lineUp"
}
},
{
+143 -1
View File
@@ -4,7 +4,7 @@
One line: vim mode | dir (repo-relative, hidden at the root) |
git(repo/branch +dirty +ahead/behind) | model (+effort) |
context% (+compact warn) | 5h usage (+reset eta) | cost (+burn rate) |
prompt-cache hit% (+ttl, cold marker) | disk. If the
session tokens (cumulative in/out) | prompt-cache hit% (+ttl, cold marker) | disk. If the
rendered line would overflow the terminal, trailing (lowest-priority) segments are
dropped until it fits.
(Dormant, re-addable in main(): ram, cpu%, temp -- retired 2026-07-26 because the
@@ -156,6 +156,133 @@ def last_usage(data):
return {}
# --- session token totals (transcript, incremental) ---------------------------
TOKENS_STATE_DIR = os.path.expanduser("~/.claude/cache")
TOKENS_RECENT_IDS = 20 # message ids remembered across runs for de-duplication
TOKENS_STATE_MAX_AGE = 7 * 86400 # prune per-session state files older than this
def fmt_tokens(n):
"""1234 -> 1.2k, 843000 -> 843k, 1_234_567 -> 1.2M, 12_345_678 -> 12M.
Thresholds sit at the rounding boundaries (0.9995, 9.95) so a value never prints as
"10.0k" or "1000k" -- it rolls into the shorter form / the next unit instead."""
n = float(n)
for unit, div in (("M", 1e6), ("k", 1e3)):
v = n / div
if v < 0.9995:
continue
return f"{v:.0f}{unit}" if v >= 9.95 else f"{v:.1f}{unit}"
return f"{n:.0f}"
def _tokens_state_path(data, path):
sid = data.get("session_id") or os.path.splitext(os.path.basename(path))[0]
sid = re.sub(r"[^A-Za-z0-9_-]", "_", str(sid))[:80]
return os.path.join(TOKENS_STATE_DIR, f"statusline.tokens.{sid}.json")
def _prune_tokens_state(keep):
"""Drop stale per-session state files (one scandir, only when the dir has piled up)."""
try:
entries = [e for e in os.scandir(TOKENS_STATE_DIR) if e.name.startswith("statusline.tokens.")]
if len(entries) < 50:
return
cutoff = time.time() - TOKENS_STATE_MAX_AGE
for e in entries:
if e.path != keep and e.stat().st_mtime < cutoff:
os.unlink(e.path)
except Exception:
pass
def session_tokens(data):
"""Cumulative (input, output) tokens this session, summed over the transcript's
assistant `message.usage` blocks -- or None when there is no transcript.
Input = input + cache_creation + cache_read (everything the API billed as input), so
on a 1M session it dwarfs output: every call re-reads the whole cached prefix.
Only the main transcript is counted; subagent usage lives in separate sidechain files.
Incremental: the status line runs on every refresh and transcripts grow to tens of
MB, so a per-session state file (~/.claude/cache/statusline.tokens.<session>.json)
remembers the byte offset already summed and only the new tail is parsed. Lines are
de-duplicated by message id: the transcript writes one line per content block of a
turn, all carrying the same id and the same usage block. Only complete lines are
consumed (the writer may be mid-line); a shrunken file (truncate/rotate) resets.
"""
path = data.get("transcript_path")
if not path or not os.path.exists(path):
return None
state_path = _tokens_state_path(data, path)
state = {"path": path, "offset": 0, "in": 0, "out": 0, "ids": []}
try:
with open(state_path) as fh:
s = json.load(fh)
if (
isinstance(s, dict)
and s.get("path") == path
and all(isinstance(s.get(k), int) and s[k] >= 0 for k in ("offset", "in", "out"))
and isinstance(s.get("ids"), list)
):
state = s
except Exception:
pass
size = os.path.getsize(path)
if size < state["offset"]: # truncated or rotated under us: start over
state = {"path": path, "offset": 0, "in": 0, "out": 0, "ids": []}
if size == state["offset"]:
return state["in"], state["out"]
with open(path, "rb") as fh:
fh.seek(state["offset"])
chunk = fh.read()
end = chunk.rfind(b"\n")
if end < 0: # no complete new line yet
return state["in"], state["out"]
text = chunk[: end + 1].decode("utf-8", "ignore")
tin, tout = state["in"], state["out"]
ids = [i for i in state["ids"] if isinstance(i, str)]
seen = set(ids)
for line in text.splitlines():
if '"usage"' not in line:
continue
try:
obj = json.loads(line)
except Exception:
continue
msg = obj.get("message") if isinstance(obj, dict) else None
usage = msg.get("usage") if isinstance(msg, dict) else None
if not isinstance(usage, dict):
continue
mid = msg.get("id") or obj.get("requestId") or obj.get("uuid")
if not isinstance(mid, str) or mid in seen:
continue
seen.add(mid)
ids.append(mid)
def num(k):
v = usage.get(k, 0)
return int(v) if isinstance(v, (int, float)) else 0
tin += num("input_tokens") + num("cache_creation_input_tokens") + num("cache_read_input_tokens")
tout += num("output_tokens")
state = {"path": path, "offset": state["offset"] + end + 1, "in": tin, "out": tout, "ids": ids[-TOKENS_RECENT_IDS:]}
try:
os.makedirs(TOKENS_STATE_DIR, exist_ok=True)
tmp = f"{state_path}.{os.getpid()}.tmp"
with open(tmp, "w") as fh:
json.dump(state, fh)
os.replace(tmp, state_path) # atomic: a concurrent refresh never reads a half-written file
_prune_tokens_state(state_path)
except Exception:
pass
return tin, tout
# --- row 1: work ------------------------------------------------------------
def vim_segment(data):
"""Vim editor mode as a compact [I]/[N]/[V] (only present with editorMode: vim).
@@ -376,6 +503,20 @@ def velocity_segment(data):
return ""
def tokens_segment(data):
"""Cumulative session tokens: ↑ input (incl. cache reads/writes) and ↓ output."""
try:
totals = session_tokens(data)
if not totals:
return ""
tin, tout = totals
if not (tin or tout):
return ""
return "🔢 " + color(f"↑{fmt_tokens(tin)}", "cyan") + " " + color(f"↓{fmt_tokens(tout)}", "green")
except Exception:
return ""
def cache_segment(usage, data=None):
"""Prompt-cache hit % (higher is better) + the cache TTL, `·cold` when the cache has
expired. Hit % from the 2.1.260+ payload `prompt_cache.hit_ratio` (a 0..1 fraction, null
@@ -583,6 +724,7 @@ def main():
context_segment(data, usage),
usage_segment(data),
cost_segment(data),
tokens_segment(data),
cache_segment(usage, data),
) if s]
system = [s for s in (
+1 -1
View File
@@ -41,7 +41,7 @@ gui:
# If true, wrap lines in the staging view to the width of the view. This
# makes it much easier to work with diffs that have long lines, e.g.
# paragraphs of markdown text.
wrapLinesInStagingView: true
wrapLinesInDiffView: true
# One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
language: auto
# Format used when displaying time e.g. commit time.
+2
View File
@@ -30,7 +30,9 @@ pake
bwrap
dog
nmap
rustscan
traceroute
fuck
atool
aria2c
+3 -1
View File
@@ -25,6 +25,7 @@ gittype
toofan
pastel
hexyl
binsider
tmux
zellij
nvim
@@ -61,7 +62,7 @@ bookokrat
tennis
llmfit
termdraw
torlink
torlnk
riptide
quien
eilmeldung
@@ -73,3 +74,4 @@ netwatch
gpk
circumflex
darya
usbtree