Lokaler LM-Studio-Adapter fuer Gemma und Qwen (Skill 10.1.0)

Der TensorX-Wrapper wird providerneutral: opencode-tensorx-adapter.py heisst
jetzt opencode-adapter.py und waehlt ueber --provider {tensorx,lmstudio}
Gateway und Modellvorlage. Der TensorX-Pfad bleibt unveraendert; die vier
bestehenden Regressionstests laufen durch.

Neu fuer den lokalen Betrieb:
- opencode-lmstudio.json fuer google/gemma-4-e4b und qwen/qwen3.8-27b
- Preflight ueber /api/v0/models: Servererreichbarkeit, Modellverfuegbarkeit,
  tool_use-Faehigkeit, geladenes Kontextfenster (--min-context, Standard 32768)
  und genau eine geladene Instanz; --lmstudio-autoload stellt das selbst her
- local_runtime in RawResult.json (Quantisierung, Architektur, Runtime,
  lms-Version, Instanzbezeichner, Kontextfenster) fuer Kap. 4.3
- effort_applied, da der lokale Endpunkt keinen Thinking-Level annimmt

Drei Befunde aus der Inbetriebnahme, alle im Adapter abgefangen: LM Studio
laedt standardmaessig nur 8192 Kontexttokens; ein erneutes lms load erzeugt
eine zweite Instanz und macht das Routing mehrdeutig; Effort ist lokal
wirkungslos. Dazu zwei Korrekturen am gemeinsamen Pfad (Abbruchgrund nur
einmal in errors, saubere lms-Versionskennung).

Enthaelt ausserdem die bislang nicht committeten Laeufe der Iterationen 8
und 9 sowie Versuch 2 (Iterationen 1 bis 3). Der laufende Lauf unter
Iteration 10 ist bewusst nicht enthalten.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christoph Schwörer
2026-08-31 20:19:33 +02:00
co-authored by Claude Opus 5
parent b369e6115e
commit 611fd0a80c
132 changed files with 83432 additions and 204 deletions
+60 -18
View File
@@ -1,8 +1,8 @@
---
name: run-experiment
description: Führt einen Versuchs-Prompt aus einer Prompt-Datei als messbaren Headless-Lauf mit Claude Code, Codex CLI oder OpenCode über TensorX aus und schreibt ein Messprotokoll mit Start-/Endzeit, Modell, Tokenverbrauch und weiteren Metriken. Verwenden bei "/run-experiment <Pfad-zur-Prompt-Datei>" oder wenn der User einen Versuch/ein Experiment ausführen und tracken will.
description: Führt einen Versuchs-Prompt aus einer Prompt-Datei als messbaren Headless-Lauf mit Claude Code, Codex CLI oder OpenCode (TensorX oder lokales LM Studio) aus und schreibt ein Messprotokoll mit Start-/Endzeit, Modell, Tokenverbrauch und weiteren Metriken. Verwenden bei "/run-experiment <Pfad-zur-Prompt-Datei>" oder wenn der User einen Versuch/ein Experiment ausführen und tracken will.
argument-hint: <Pfad zur Prompt-Datei> <Root-Verzeichnis>
version: 10.0.2
version: 10.1.0
---
# RunExperiment – Versuchslauf mit Messprotokoll
@@ -126,9 +126,15 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
2. Aus dem Metadaten-Block der Prompt-Datei (falls vorhanden) Versuch/Prompt-Version übernehmen.
3. **Werkzeugadapter bestimmen und CLI-Pfad auflösen.** Die Modell-ID entscheidet eindeutig:
`claude-*` verwendet Claude Code, OpenAI-IDs wie `gpt-*` oder `o*` verwenden Codex CLI,
`z-ai/*`, `qwen/*` und `moonshotai/*` verwenden OpenCode über den TensorX-Gateway.
`z-ai/*`, `qwen/qwen3.8-flash-next` und `moonshotai/*` verwenden OpenCode mit
`--provider tensorx`, `google/gemma-4-e4b` und `qwen/qwen3.8-27b` verwenden OpenCode mit
`--provider lmstudio` gegen den lokalen LM-Studio-Server.
Keine Modell-ID an eine CLI übergeben, die sie nicht unterstützt.
**Achtung Präfixkollision:** `qwen/qwen3.8-flash-next` läuft remote über TensorX,
`qwen/qwen3.8-27b` lokal über LM Studio. Das Präfix `qwen/` allein entscheidet **nicht** –
maßgeblich ist die vollständige Modell-ID.
Unter Windows liegt `claude` in der Regel **nicht im PATH**. Erst
`Get-Command claude -ErrorAction SilentlyContinue` versuchen; schlägt das fehl, auf die
VSCode-Extension zurückfallen und die höchste Versionsnummer wählen:
@@ -177,6 +183,16 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
| `qwen/qwen3.8-flash-next` | Qwen 3.8 Flash Next über TensorX-Gateway |
| `moonshotai/kimi-k3` | Moonshot Kimi K3 – 1-Mio.-Kontext, 2,8T Parameter |
| Lokale Modell-ID (LM Studio) | Einordnung |
|---|---|
| `google/gemma-4-e4b` | Gemma 4 E4B, 7,5B Parameter, lokal über LM Studio |
| `qwen/qwen3.8-27b` | Qwen 3.8 27B, lokal über LM Studio |
Lokale IDs nur anbieten, wenn `lms ls` das Modell als heruntergeladen ausweist. Fehlt es,
den User auf `lms get <ID>` hinweisen und den Download **nicht** ungefragt starten – es
sind mehrere Gigabyte. Lokale Läufe sind eine eigene Versuchsbedingung und nicht mit
Cloud-Läufen poolbar: anderes Kontextfenster, quantisierte Gewichte, kein Effort.
In der Frage den letzten verwendeten Stand nennen, damit der User bewusst wechseln oder
bewusst wiederholen kann (z. B. „Lauf 3 lief mit `claude-sonnet-5`, 11.516.200 Tokens, 23:40").
@@ -610,8 +626,8 @@ Regeln:
`RawResult.json` im Laufverzeichnis lesen und defensiv parsen. Beim Claude-Adapter ist dies die
unveränderte CLI-Antwort; beim Codex-Adapter erzeugt `normalise-codex-result.py` diese Datei aus
`RawEvents.jsonl` und `_meta\final_response.json`; beim OpenCode-Adapter erzeugt
`opencode-tensorx-adapter.py` sie aus dem Sessionexport und `OpenCodeEvents.jsonl` gemäß der
TensorX-Referenz. Relevante Claude-Felder:
`opencode-adapter.py` sie aus dem Sessionexport und `OpenCodeEvents.jsonl` gemäß der
OpenCode-Referenz. Relevante Claude-Felder:
| Feld | Bedeutung |
|---|---|
@@ -1091,22 +1107,45 @@ die angeforderte ID; da `codex exec --json` sie im Ereignisstrom nicht wiederhol
Modellkontrolle im Protokoll `nicht prüfbar`. Temperatur und weitere Sampling-Parameter sind in
diesem CLI-Ablauf nicht steuerbar; Effort und Service-Tier werden dagegen explizit festgelegt.
### Adapter: OpenCode / GLM-, Qwen- und Kimi-Modelle über TensorX
### Adapter: OpenCode / TensorX-Modelle und lokale LM-Studio-Modelle
Dies ist der **primäre Adapter für alle TensorX-Modell-IDs**. Er verwendet OpenCodes
OpenAI-kompatiblen Custom Provider und das Skript `opencode-tensorx-adapter.py`. OpenCode
verwaltet Authentifizierung, Agenten-Loop und Session; der Wrapper erzeugt eine isolierte
Konfiguration, streamt die Rohereignisse, erzwingt Berechtigungen und normalisiert das Ergebnis
nach `RawResult.json`. Es besteht keine Abhängigkeit zu Cline.
Dies ist der **primäre Adapter für alle TensorX-Modell-IDs und für den lokalen
LM-Studio-Betrieb**. Beide nutzen OpenCodes OpenAI-kompatiblen Custom Provider und dasselbe
Skript `opencode-adapter.py`; `--provider` wählt Gateway und Modellvorlage. OpenCode verwaltet
Authentifizierung, Agenten-Loop und Session; der Wrapper erzeugt eine isolierte Konfiguration,
streamt die Rohereignisse, erzwingt Berechtigungen und normalisiert das Ergebnis nach
`RawResult.json`. Es besteht keine Abhängigkeit zu Cline.
Vor jedem TensorX-Lauf die vollständige Referenz
[`references/opencode-tensorx.md`](references/opencode-tensorx.md) lesen und deren Aufruf,
Timeouts, Artefakte und Pflichtprüfungen anwenden. Die Provider- und Modellvorlage liegt in
`opencode-tensorx.json`; API-Keys gehören ausschließlich in OpenCodes Credential-Store.
| `--provider` | Modell-IDs | Betrieb | Vorlage |
|---|---|---|---|
| `tensorx` (Standard) | `z-ai/*`, `qwen/qwen3.8-flash-next`, `moonshotai/*` | Remote `https://api.tensorx.ai/v1` | `opencode-tensorx.json` |
| `lmstudio` | `google/gemma-4-e4b`, `qwen/qwen3.8-27b` | lokal `http://localhost:1234/v1` | `opencode-lmstudio.json` |
Vor jedem Lauf die vollständige Referenz
[`references/opencode-adapter.md`](references/opencode-adapter.md) lesen und deren Aufruf,
Timeouts, Artefakte und Pflichtprüfungen anwenden. API-Keys gehören ausschließlich in OpenCodes
Credential-Store; die Vorlagen enthalten keine.
**Lokaler Betrieb ist eine eigene Versuchsbedingung.** Ein Preflight prüft Server,
Modellverfügbarkeit, Tool-Fähigkeit, geladenes Kontextfenster (`--min-context`, Standard 32768)
und dass genau eine Modellinstanz geladen ist; er bricht sonst mit Exitcode `2` und dem exakt
nötigen `lms`-Befehl ab. `RawResult.json` führt zusätzlich `local_runtime` (Quantisierung,
Architektur, Runtime, `lms`-Version, Kontextfenster) und `context_window` – damit sind die von
Kap. 4.3 geforderten Angaben für lokalen Betrieb erfasst. **Effort ist bei `lmstudio` nicht
steuerbar** (`effort_applied: false`) und im Protokoll so auszuweisen; Kosten sind
definitionsgemäß `0`, Cache-Metriken `nicht erfasst`. Lokale Läufe niemals mit Cloud-Läufen
poolen.
Referenzstand bei Einführung: **OpenCode 1.18.25**. Ein Live-Smoke-Test mit
`qwen/qwen3.8-flash-next`, Variante `low`, bestätigte Headless-Ausführung, Sessionexport,
Reasoning-/Cache-Metriken und die erwartete Textantwort.
Reasoning-/Cache-Metriken und die erwartete Textantwort. Für LM Studio bestätigte ein
Smoke-Test mit `google/gemma-4-e4b` (Q4_K_M, gguf, 32768 Kontexttokens) Preflight,
Providerauflösung, Streaming und Tool-Calling.
**Terminierung kleiner lokaler Modelle.** Im Smoke-Test lief `google/gemma-4-e4b` über 50
Schritte weiter, ohne die geforderte Datei zu schreiben. Da laufend Text erzeugt wird, greift
der Stall-Timeout nicht. Lokale Läufe deshalb immer mit absolutem `--max-runtime` starten und
einen Abbruch als Abbruch protokollieren, nicht als Ergebnis.
### Legacy-Adapter: direkte Python API / GLM-, Qwen- und Kimi-Modelle über TensorX
@@ -1255,8 +1294,10 @@ Reasoning-Effort ist steuerbar (`--effort`).
### Weitere Adapter (für Versuch 4 nachzurüsten)
Kapitel 4 der Arbeit sieht zusätzlich Qwen Code CLI über LM Studio und DeepSeek über die
Cloud-API vor. Diese Adapter sind noch nicht ausgearbeitet. Damit ein
Kapitel 4 der Arbeit sieht zusätzlich DeepSeek über die Cloud-API vor; dieser Adapter ist noch
nicht ausgearbeitet. Der lokale LM-Studio-Betrieb ist seit 10.1.0 über
`opencode-adapter.py --provider lmstudio` abgedeckt – allerdings mit OpenCode als Agenten-Loop
statt der in Kap. 4 genannten Qwen Code CLI. Diese Abweichung gehört ins Protokoll. Damit ein
Lauf als Messpunkt taugt, muss ein Adapter mindestens liefern:
| Pflichtangabe | Zweck |
@@ -1313,6 +1354,7 @@ der Historie unten – im selben Arbeitsschritt.
| Version | Änderung | Grund | Verwendet in |
|---|---|---|---|
| **10.1.0** | **Lokaler LM-Studio-Adapter für `google/gemma-4-e4b` und `qwen/qwen3.8-27b`.** `opencode-tensorx-adapter.py` heißt jetzt `opencode-adapter.py` und wählt über `--provider {tensorx,lmstudio}` Gateway und Modellvorlage; die Referenz heißt entsprechend `references/opencode-adapter.md`. Neue keyfreie Vorlage `opencode-lmstudio.json` (`http://localhost:1234/v1`). Ein Preflight über `/api/v0/models` prüft Servererreichbarkeit, Modellverfügbarkeit, `tool_use`-Fähigkeit, geladenes Kontextfenster (`--min-context`, Standard 32768) und dass genau **eine** Modellinstanz geladen ist; `--lmstudio-autoload` stellt den Sollzustand per `lms unload`/`lms load` selbst her. Das geladene Fenster wird als `limit.context` in die Laufkonfiguration gepinnt. `RawResult.json` erhält `local_runtime` (Quantisierung, Architektur, Runtime, `lms`-Version, Instanzbezeichner, Kontextfenster), `context_window`, `cost_source` und providerübergreifend `effort_applied`. Neue Artefaktdatei `_meta/lmstudio-modelle.json`. Adapter-Version 1.1.0, fünf zusätzliche Unit-Tests. Zwei Korrekturen am gemeinsamen Pfad: Der Abbruchgrund wird nur noch einmal in `errors` vermerkt statt je Sekunde bis zum Prozessende, und die `lms`-Version wird aus dem ANSI-Banner der CLI sauber extrahiert. | Kapitel 4 sieht lokalen Betrieb als eigene Bedingung vor und fordert nach Kap. 4.3 Runtime samt Version und Quantisierungsstufe – beides liefert erst der Preflight. Drei Befunde aus der Inbetriebnahme sind direkt in den Adapter eingeflossen: LM Studio lädt Modelle standardmäßig mit nur 8192 Kontexttokens, was eine Codebasisanalyse stillschweigend abschneiden würde; ein erneutes `lms load` erzeugt eine **zweite** Instanz (`modell:2`), womit die `model`-Angabe der OpenAI-API nicht mehr eindeutig routet; und der lokale Endpunkt nimmt keinen Thinking-Level entgegen, weshalb Effort als nicht steuerbar auszuweisen ist statt als gesetzt. MINOR: neuer Provider und neue Messgrößen; für `--provider tensorx` bleiben Aufruf, Berechtigungen und Metriken unverändert – die vier bestehenden TensorX-Regressionstests laufen unverändert durch, sodass laufende V2-Läufe vergleichbar bleiben. Live-Smoke-Test am 31.08.2026 mit `google/gemma-4-e4b` (Q4_K_M, gguf, 32768 Tokens): Preflight bestanden, Providerauflösung, Streaming und Tool-Calling bestätigt. | ab dem ersten LM-Studio-Lauf |
| **10.0.2** | Ergebnis-Allowlist zusätzlich relativ zur per Git ermittelten Worktree-Wurzel; Adapter-Version 1.0.2. | Der erste Fix deckte den aktiven Root und den kanonischen Pfad ab. OpenCode 1.18.25 matcht ein Ziel innerhalb desselben Repositories jedoch gegen den Pfad relativ zur Worktree-Wurzel. PATCH: weitere Normalisierungsform desselben bereits autorisierten Zielverzeichnisses. | ab dem ersten OpenCode-V2-Lauf |
| **10.0.1** | Der OpenCode-Adapter autorisiert Ergebnisziele zusätzlich mit einem zum aktiven Root relativen Pfad, einschließlich notwendiger `..`-Segmente; Adapter-Version 1.0.1. Regressionstest für Root und Laufverzeichnis in verschiedenen Unterordnern desselben Windows-Git-Worktrees. | OpenCode normalisiert solche Ziele intern worktree-relativ. Die alleinige kanonische Allow-Regel griff daher nicht, obwohl der absolute Werkzeugpfad exakt im erlaubten Ergebnisordner lag. Ein Custom/max-Preflight startete den vorgesehenen Subagenten erfolgreich, konnte anschließend aber keine Ergebnisdatei schreiben. PATCH: korrigiert nur die beabsichtigte Schreibfreigabe. | ab dem ersten OpenCode-V2-Lauf |
| **10.0.0** | **OpenCode wird primärer TensorX-Adapter.** Neue keyfreie Provider-/Modellvorlage `opencode-tensorx.json`, Wrapper `opencode-tensorx-adapter.py`, Unit-Tests und Detailreferenz. Der Wrapper startet `opencode run --pure` mit einer isolierten Laufkonfiguration, streamt JSONL und stderr, exportiert die Session, normalisiert Token-, Tool- und Subagentenmetriken und beendet bei Inaktivität oder Benutzerabbruch den Prozessbaum. `solo`, `builtin` und aus `03_Agents.json` übersetztes `custom` werden unterstützt. Der direkte Python-Adapter bleibt als ausdrücklich gewählter Legacy-Fallback erhalten. | Der direkte Adapter hing bei `qwen/qwen3.8-flash-next` in einem nicht gestreamten HTTP-Aufruf ohne lokalisierbaren Fortschritt. OpenCode liefert inkrementelle Ereignisse, eine persistierte Session und einen klaren Prozesslebenszyklus; außerdem entfällt die Kopplung der TensorX-Authentifizierung an Cline. MAJOR, weil Agentenlaufzeit, Werkzeugsemantik und Metrikquelle eine neue Versuchsbedingung bilden. Live-Smoke-Test am 31.08.2026 mit Qwen/low: Exitcode 0, erwartete Antwort, Sessionexport und vollständige Tokenfelder. | ab dem nächsten TensorX-Lauf; vorherige direkte Python-Läufe bleiben Legacy-Bedingung |