From 599822036f5536bbc903f91a5aac00385e0530f7 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 16 Jun 2026 14:12:56 +0200 Subject: [PATCH] Add: Cline integration --- .clinerules | 16 +++ .env.example | 5 +- README.md | 61 ++++++++ compose.amd.yaml | 2 + docs/clinememory/activeContext.md | 28 ++++ docs/clinememory/productContext.md | 16 +++ docs/clinememory/progress.md | 18 +++ docs/clinememory/projectbrief.md | 16 +++ docs/clinememory/systemPatterns.md | 31 ++++ docs/clinememory/techContext.md | 35 +++++ ollama/modelfiles/deepseek-coding.modelfile | 22 +++ ...long.modelfile => qwen25-coding.modelfile} | 20 +-- ...oding.modelfile => qwen3-coding.modelfile} | 8 +- openclaw/config/openclaw.json | 2 +- scripts/benchmark-model-suite.sh | 132 ++++++++++++++++++ scripts/benchmark-stack.sh | 6 +- tools/router/Containerfile | 15 +- tools/router/app/main.py | 4 +- .../app/{mcp => mcp_client}/__init__.py | 0 .../app/{mcp => mcp_client}/handlers.py | 0 .../server.py => mcp_client/mcp_server.py} | 0 21 files changed, 409 insertions(+), 28 deletions(-) create mode 100644 .clinerules create mode 100644 docs/clinememory/activeContext.md create mode 100644 docs/clinememory/productContext.md create mode 100644 docs/clinememory/progress.md create mode 100644 docs/clinememory/projectbrief.md create mode 100644 docs/clinememory/systemPatterns.md create mode 100644 docs/clinememory/techContext.md create mode 100644 ollama/modelfiles/deepseek-coding.modelfile rename ollama/modelfiles/{qwen-coding-long.modelfile => qwen25-coding.modelfile} (55%) rename ollama/modelfiles/{qwen-coding.modelfile => qwen3-coding.modelfile} (84%) create mode 100755 scripts/benchmark-model-suite.sh rename tools/router/app/{mcp => mcp_client}/__init__.py (100%) rename tools/router/app/{mcp => mcp_client}/handlers.py (100%) rename tools/router/app/{mcp/server.py => mcp_client/mcp_server.py} (100%) diff --git a/.clinerules b/.clinerules new file mode 100644 index 0000000..42c5764 --- /dev/null +++ b/.clinerules @@ -0,0 +1,16 @@ +# Cline's Memory Bank + +Du bist Cline, ein erfahrener Softwareentwickler. Du hast eine Besonderheit: Dein Gedächtnis wird periodisch komplett zurückgesetzt. Das ist kein Bug, sondern sorgt dafür, dass du eine perfekte Dokumentation führst. Nach jedem Reset verlässt du dich VOLLSTÄNDIG auf deine "Memory Bank", um das Projekt zu verstehen und die Arbeit fortzusetzen. + +## Struktur der Memory Bank +Die Memory Bank besteht aus Markdown-Dateien im Ordner `docs/clinememory/` im Projekt-Root: +- `projectbrief.md`: Das übergeordnete Ziel des Projekts (Was ist das, für wen ist es?). +- `productContext.md`: Warum existiert dieses Projekt, welche Probleme löst es, wie soll es sich verhalten? +- `systemPatterns.md`: Systemarchitektur, technische Muster, wichtige Design-Entscheidungen. +- `techContext.md`: Verwendete Technologien, Laufzeiten, Tools, Build-Befehle, Abhängigkeiten. +- `activeContext.md`: Woran wird *aktuell* gearbeitet, was sind die nächsten Schritte? +- `progress.md`: Was wurde bereits erreicht, was fehlt noch (Roadmap)? + +## Deine Pflichten +1. **Prüfung beim Start:** Lies bei JEDER neuen Aufgabe als Erstes die Dateien in `docs/clinememory/`, um den Kontext zu laden. Sollte der Ordner oder die Dateien fehlen, lege sie sofort selbstständig an, indem du das Projekt analysierst! +2. **Aktualisierung:** Wenn du Änderungen am Projekt vornimmst oder wichtige Erkenntnisse gewinnst, aktualisiere die entsprechenden Dateien in der Memory Bank (besonders `activeContext.md` und `progress.md`), bevor du die Aufgabe als beendet erklärst. diff --git a/.env.example b/.env.example index 4444c90..fdd85a8 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,7 @@ # ========================================== # --- LLM ENGINE & MODEL SELECTION --- -MODEL_LIST=gemma4:e4b,qwen3.6:35b-a3b-q4_K_M +MODEL_LIST=qwen2.5-coder:14b,qwen3:14b,deepseek-coder-v2:16b OLLAMA_KEEP_ALIVE=-1 # KV cache quantization for large contexts (recommended on desktop GPUs): q8_0 or q4_0 # OLLAMA_KV_CACHE_TYPE=q8_0 @@ -41,6 +41,9 @@ CONTAINER_ENGINE=podman # HOST_OPENCLAW_CONFIG_MOUNT_OPTS=:ro,Z # Optional explicit host workspace path seen by sandbox runtime # OPENCLAW_SANDBOX_HOST_WORKSPACE=/absolute/path/to/storage/workspace +# Optional localhost publish settings for the MCP router (used by host clients like Cline) +# TOOL_ROUTER_BIND=127.0.0.1 +# TOOL_ROUTER_HOST_PORT=3000 # Sandbox base image is auto-built by ghostnet.sh as # localhost/ghostnet-openclaw_sandbox:latest to include rootless apt defaults. diff --git a/README.md b/README.md index fefe1d1..d007e31 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,67 @@ Use the integrated management script, which automatically selects the correct ve ### 3. Open the Interactive Chat `podman exec -it openclaw-agent openclaw chat` +## Using the Stack with Cline in VS Code + +You do not need a second local model runtime for Cline. The existing Ollama container is already published on the host at `http://127.0.0.1:11434`. + +### 1. Configure Cline to use Ollama + +In Cline, select the Ollama provider and use: + +```text +Base URL: http://127.0.0.1:11434 +Model: qwen3-coding +``` + +Use `ollama list` inside the container or on the host to see the exact model names currently available. + +Recommended custom profiles for this stack: + +```text +qwen3-coding -> Qwen3 14B, balanced default for agentic coding +qwen25-coding -> Qwen2.5-Coder 14B, code-first edit and repair profile +deepseek-coding -> DeepSeek-Coder-V2 16B, long-context repo analysis profile +``` + +### 2. Reuse the existing MCP router for tools + +The GhostNet router exposes an MCP SSE endpoint at `http://127.0.0.1:3000/sse`. Add it to your Cline MCP configuration: + +```json +{ + "mcpServers": { + "ghostnet-router": { + "transport": "sse", + "url": "http://127.0.0.1:3000/sse" + } + } +} +``` + +This lets Cline reuse the same routed tool surface that OpenClaw uses internally. + +### 3. What Cline does not need + +Cline does not need to connect to the OpenClaw gateway on port 8080 for normal local usage. The direct path is: + +* Cline -> Ollama for model inference +* Cline -> GhostNet router for MCP tools + +If you change the host binding, use `TOOL_ROUTER_BIND` and `TOOL_ROUTER_HOST_PORT` in `.env`. + +## Benchmarking Custom Models + +The repository includes a reproducible benchmark script for comparing local models through the OpenClaw agent path. + +```bash +./scripts/benchmark-stack.sh --model ollama/qwen3-coding:latest --lines 140 --timeout-sec 300 --no-start +./scripts/benchmark-stack.sh --model ollama/qwen25-coding:latest --lines 140 --timeout-sec 300 --no-start +./scripts/benchmark-stack.sh --model ollama/deepseek-coding:latest --lines 140 --timeout-sec 300 --no-start +``` + +This benchmark is useful for latency, stability, and tool-path comparison under identical conditions. + ## Technical Architecture & Key Highlights This setup relies on unique architectural design patterns engineered to overcome container engines boundaries and system strictness: diff --git a/compose.amd.yaml b/compose.amd.yaml index c14cd8f..3432b71 100644 --- a/compose.amd.yaml +++ b/compose.amd.yaml @@ -109,6 +109,8 @@ services: environment: - PORT=3000 - LOG_LEVEL=debug + ports: + - "${TOOL_ROUTER_BIND:-127.0.0.1}:${TOOL_ROUTER_HOST_PORT:-3000}:3000" expose: - "3000" dns: diff --git a/docs/clinememory/activeContext.md b/docs/clinememory/activeContext.md new file mode 100644 index 0000000..c0e2ad5 --- /dev/null +++ b/docs/clinememory/activeContext.md @@ -0,0 +1,28 @@ +# Active Context + +## Aktuelles Epic: Tool-Router online bringen +**Status**: Code-Basis repariert, bereit für Build +**Datum**: 15.06.2026 + +### Ziel +Den Tool-Router Container erfolgreich starten und mit OpenClaw verbinden, sodass MCP-basierte Skill-Orchestrierung funktioniert. + +### Erledigt +- Containerfile korrigiert (Python 3.11, Poetry, Healthcheck) +- main.py Import-Pfade repariert (app.* prefixed) +- MCP-Client-Integration vollständig validiert +- Memory Bank vollständig erstellt + +### Nächste Schritte +1. Container-Image bauen (`podman build -t ghostnet-router .`) +2. In compose.amd.yaml integrieren +3. Gateway-Konfiguration validieren +4. Health-Endpunkt testen (`/health` auf Port 8090) +5. MCP-Verbindung zu OpenClaw testen + +### Wichtige Erkenntnisse +- Tool-Router läuft auf Port 8090 +- Nutzt FastAPI mit SSE-Support für MCP +- Skill-Registry in `app/registry/skill_registry.py` +- Gateway-Konfiguration in `config/gateway.json` +- Import-Pfade müssen mit `app.` Prefix geschrieben werden (da Python von innerhalb des `app/` Verzeichens startet) \ No newline at end of file diff --git a/docs/clinememory/productContext.md b/docs/clinememory/productContext.md new file mode 100644 index 0000000..27dd611 --- /dev/null +++ b/docs/clinememory/productContext.md @@ -0,0 +1,16 @@ +# Product Context + +**Warum existiert dieses Projekt?** +Um ein vollständig lokales, souveränes KI-Agenten-System zu betreiben, das ohne externe Cloud-APIs auskommt. Der Nutzer soll komplexe Aufgaben automatisieren können (Forschung, Code-Generierung, Datenverarbeitung) durch Kombination von LLM-Fähigkeiten mit konkreten Tools. + +**Welche Probleme löst es?** +- Cloud-Abhängigkeit bei LLM-APIs (Kosten, Datenschutz, Verfügbarkeit) +- Manuelle Tool-Orchestrierung zwischen verschiedenen Diensten +- Fehlende zentrale Koordination für MCP-basierte Skills + +**Wie soll es sich verhalten?** +- Der Tool-Router dient als zentrales Gateway, das Skill-Anfragen empfängt, validiert und an die richtigen MCP-Tools weiterleitet +- Skills sind modular erweiterbar (z.B. Searchfetch für Web-Suche) +- Der Openclaw-Agent kommuniziert mit dem Router über MCP-Protokoll +- Alle Komponenten laufen isoliert in Podman-Containern +- Konfiguration über JSON-Dateien, Logging über structured logging \ No newline at end of file diff --git a/docs/clinememory/progress.md b/docs/clinememory/progress.md new file mode 100644 index 0000000..50d1631 --- /dev/null +++ b/docs/clinememory/progress.md @@ -0,0 +1,18 @@ +# Progress + +## Abgeschlossene Meilensteine +- [x] Projektstruktur analysiert +- [x] Memory Bank angelegt +- [x] Systemarchitektur dokumentiert +- [x] Technology-Stack katalogisiert + +## Roadmap: Tool-Router Epic +- [ ] Container-Image bauen +- [ ] Compose-Integration prüfen +- [ ] Konfiguration validieren +- [ ] Health-Check testen +- [ ] MCP-Verbindung etablieren +- [ ] End-zu-End-Test + +## Blocker +- Keine bekannt \ No newline at end of file diff --git a/docs/clinememory/projectbrief.md b/docs/clinememory/projectbrief.md new file mode 100644 index 0000000..0b67853 --- /dev/null +++ b/docs/clinememory/projectbrief.md @@ -0,0 +1,16 @@ +# Projekt-Brief: Ghostnet-Openclaw + +**Was ist das?** +Ein Container-basiertes LLM-Agent-System, das Openclaw (Agent-Framework) mit Ollama (lokaler LLM-Server) und einem MCP-Tool-Router verbindet. + +**Für wen?** +Für den Betreiber selbst – ein lokal laufendes, souveränes KI-Agenten-System ohne Cloud-Abhängigkeiten. + +**Kernkomponenten:** +- **Ollama**: Lokaler LLM-Server (Qwen-Modelle) mit SSE-Proxy (Squid) +- **Openclaw**: Haupt-Agent mit Sandbox-Container +- **Tool-Router**: MCP-Gateway zur Orchestrierung externer Skills (z.B. Searchfetch) +- **Searchfetch**: SearXNG-basierter Suchdienst als MCP-Skill + +**Laufzeit-Umgebung:** +Podman-Container-Stack auf Linux mit AMD/Intel/NVIDIA Hardware-Support. \ No newline at end of file diff --git a/docs/clinememory/systemPatterns.md b/docs/clinememory/systemPatterns.md new file mode 100644 index 0000000..f365411 --- /dev/null +++ b/docs/clinememory/systemPatterns.md @@ -0,0 +1,31 @@ +# System Patterns + +## Architektur +``` +┌─────────────────────────────────────────────────────────┐ +│ Host (Podman) │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │ +│ │ Ollama │ │ OpenClaw │ │ Tool Router│ │ +│ │ (LLM Backend)│◄──►│ (Agent) │◄──►│ (FastAPI) │ │ +│ │ Port 11434 │ │ Port 18789 │ │ Port 8090 │ │ +│ └──────────────┘ └──────────────┘ └────────────┘ │ +│ │ +│ ┌──────────────┐ │ +│ │ SearchFetch │ (SearXNG Search Tool) │ +│ │ (SearXNG) │ Port 8888 │ +│ └──────────────┘ │ +└─────────────────────────────────────────────────────────┘ +``` + +## Design-Entscheidungen +1. **Podman statt Docker**: Rootless Container, keine Daemon-Abhängigkeit +2. **GPU-Unterstützung**: 3 compose-Dateien (AMD/Nvidia/Intel) für verschiedene Hardware +3. **MCP-Protokoll**: Tool-Router nutzt Model Context Protocol für Skill-Orchestrierung +4. **Sandbox**: OpenClaw hat separaten Sandbox-Container für sichere Code-Ausführung +5. **Gateway-Proxy**: Squid-Proxy vor Ollama für Request-Logging und Caching + +## Kommunikationsmuster +- Ollama ↔ OpenClaw: HTTP REST (Port 11434) +- OpenClaw ↔ Tool-Router: MCP over HTTP/SSE (Port 8090) +- Tool-Router ↔ externe APIs: HTTP (httpx Client) \ No newline at end of file diff --git a/docs/clinememory/techContext.md b/docs/clinememory/techContext.md new file mode 100644 index 0000000..1f7ced3 --- /dev/null +++ b/docs/clinememory/techContext.md @@ -0,0 +1,35 @@ +# Tech Context + +## Technologien +- **Container Runtime**: Podman (rootless) +- **Orchestrierung**: Podman Compose +- **LLM Backend**: Ollama (Qwen2.5-Coder:7b, bge-large:1.5) +- **Agent**: OpenClaw (Python/FastAPI) +- **Tool-Router**: Python 3.11 + FastAPI + httpx + pydantic +- **Search**: SearXNG +- **Proxy**: Squid + +## Build-Befehle +```bash +# Stack starten (AMD-GPU) +podman compose -f compose.amd.yaml up -d + +# Images bauen +./ghostnet.sh build + +# Tool-Router separat bauen +podman build -t tool-router tools/router/ + +# Logs +podman compose -f compose.amd.yaml logs -f tool-router +``` + +## Ports +- Ollama: 11434 +- OpenClaw: 18789 +- Tool-Router: 8090 +- SearXNG: 8888 + +## Abhängigkeiten +- Python: fastapi, uvicorn, httpx, pydantic, mcp, pydantic-settings +- Host: podman, podman-compose \ No newline at end of file diff --git a/ollama/modelfiles/deepseek-coding.modelfile b/ollama/modelfiles/deepseek-coding.modelfile new file mode 100644 index 0000000..772ff3f --- /dev/null +++ b/ollama/modelfiles/deepseek-coding.modelfile @@ -0,0 +1,22 @@ +# Basis-Modell aus der Registry laden +FROM deepseek-coder-v2:16b + +# Long-context-faehiges Profil fuer Repo-Analysen und groessere Patches +PARAMETER num_ctx 12288 +PARAMETER num_predict 4096 +PARAMETER temperature 0.15 + +# Dem Modell seine primaere Identitaet verpassen +SYSTEM """ +Du bist ein hochentwickelter, autonomer KI-Coding-Agent innerhalb des OpenClaw-Frameworks. +Deine Aufgaben: +- Schreibe sauberen, performanten und fehlerfreien Python- und C#-Code. +- Analysiere Code-Strukturen tiefgehend und halte dich strikt an Best Practices. +- Gib praezise Antworten und vermeide unnoetiges Blabla. + +Arbeitsregeln: +- Simuliere keine Terminal-Ausgaben, keine "Let me check..."-Monologe und keine erfundenen Befehlslogs. +- Nutze verfuegbare Tools/Befehle tatsaechlich und berichte nur echte Ergebnisse. +- Wenn etwas nicht fertig ist, nenne den konkreten naechsten Schritt statt langer Zwischenkommentare. +- Antworte standardmaessig auf Deutsch, ausser der Nutzer fordert explizit etwas anderes. +""" \ No newline at end of file diff --git a/ollama/modelfiles/qwen-coding-long.modelfile b/ollama/modelfiles/qwen25-coding.modelfile similarity index 55% rename from ollama/modelfiles/qwen-coding-long.modelfile rename to ollama/modelfiles/qwen25-coding.modelfile index 45d0467..0fce868 100644 --- a/ollama/modelfiles/qwen-coding-long.modelfile +++ b/ollama/modelfiles/qwen25-coding.modelfile @@ -1,22 +1,22 @@ # Basis-Modell aus der Registry laden -FROM qwen3.6:27b +FROM qwen2.5-coder:14b -# Long-Context-Profil fuer umfangreiche Edits -PARAMETER num_ctx 16384 +# Code-spezifisches Profil fuer stabile Edits und Repairs +PARAMETER num_ctx 12288 PARAMETER num_predict 4096 -PARAMETER temperature 0.2 +PARAMETER temperature 0.15 -# Dem Modell seine primäre Identität verpassen +# Dem Modell seine primaere Identitaet verpassen SYSTEM """ Du bist ein hochentwickelter, autonomer KI-Coding-Agent innerhalb des OpenClaw-Frameworks. Deine Aufgaben: - Schreibe sauberen, performanten und fehlerfreien Python- und C#-Code. - Analysiere Code-Strukturen tiefgehend und halte dich strikt an Best Practices. -- Gib präzise Antworten und vermeide unnoetiges Blabla. +- Gib praezise Antworten und vermeide unnoetiges Blabla. Arbeitsregeln: - Simuliere keine Terminal-Ausgaben, keine "Let me check..."-Monologe und keine erfundenen Befehlslogs. -- Nutze verfügbare Tools/Befehle tatsächlich und berichte nur echte Ergebnisse. -- Wenn etwas nicht fertig ist, nenne den konkreten nächsten Schritt statt langer Zwischenkommentare. -- Antworte standardmäßig auf Deutsch, außer der Nutzer fordert explizit etwas anderes. -""" +- Nutze verfuegbare Tools/Befehle tatsaechlich und berichte nur echte Ergebnisse. +- Wenn etwas nicht fertig ist, nenne den konkreten naechsten Schritt statt langer Zwischenkommentare. +- Antworte standardmaessig auf Deutsch, ausser der Nutzer fordert explizit etwas anderes. +""" \ No newline at end of file diff --git a/ollama/modelfiles/qwen-coding.modelfile b/ollama/modelfiles/qwen3-coding.modelfile similarity index 84% rename from ollama/modelfiles/qwen-coding.modelfile rename to ollama/modelfiles/qwen3-coding.modelfile index 9db0243..7288747 100644 --- a/ollama/modelfiles/qwen-coding.modelfile +++ b/ollama/modelfiles/qwen3-coding.modelfile @@ -1,12 +1,12 @@ # Basis-Modell aus der Registry laden -FROM qwen3.6:27b +FROM qwen3:14b -# VRAM- und Kontext-Parameter direkt einbacken -PARAMETER num_ctx 8192 +# Ausgewogenes Profil fuer reaktives Agentic Coding auf 24-GB-GPUs +PARAMETER num_ctx 12288 PARAMETER num_predict 4096 PARAMETER temperature 0.2 -# Dem Modell seine primäre Identität verpassen +# Dem Modell seine primaere Identitaet verpassen SYSTEM """ Du bist ein hochentwickelter, autonomer KI-Coding-Agent innerhalb des OpenClaw-Frameworks. Deine Aufgaben: diff --git a/openclaw/config/openclaw.json b/openclaw/config/openclaw.json index d7b4d41..4f9bf2c 100644 --- a/openclaw/config/openclaw.json +++ b/openclaw/config/openclaw.json @@ -9,7 +9,7 @@ }, "agents": { "defaults": { - "model": "ollama/qwen-coding", + "model": "ollama/qwen3-coding", "workspace": "/home/node/.openclaw/workspace", "sandbox": { "mode": "all", diff --git a/scripts/benchmark-model-suite.sh b/scripts/benchmark-model-suite.sh new file mode 100755 index 0000000..ac415ce --- /dev/null +++ b/scripts/benchmark-model-suite.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash + +set -euo pipefail + +PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$PROJECT_DIR" + +usage() { + cat <<'EOF' +Usage: ./scripts/benchmark-model-suite.sh [options] + +Fuehrt den bestehenden Stack-Benchmark fuer die drei lokalen Coding-Profile aus +und schreibt Artefakte plus eine Vergleichszusammenfassung. + +Optionen: + --lines Erwartete Zeilenanzahl LINE_1..LINE_n (default: 140) + --timeout-sec Timeout je Lauf in Sekunden (default: 300) + --artifact-root

Zielordner fuer alle Benchmark-Artefakte (default: auto) + --session-prefix Prefix fuer Session-Keys (default: suite:) + -h, --help Hilfe anzeigen +EOF +} + +slugify_model() { + local model="$1" + local slug="${model#ollama/}" + slug="${slug//:/-}" + slug="${slug//./-}" + printf '%s' "$slug" +} + +extract_value() { + local label="$1" + local file="$2" + local value + value="$(sed -n "s/^${label}: //p" "$file" | head -n 1)" + printf '%s' "${value:-n/a}" +} + +extract_metric() { + local label="$1" + local file="$2" + local value + value="$(sed -n "s/^- ${label}: //p" "$file" | head -n 1)" + printf '%s' "${value:-n/a}" +} + +EXPECTED_LINES=140 +TIMEOUT_SEC=300 +ARTIFACT_ROOT="" +SESSION_PREFIX="suite:$(date +%Y%m%d-%H%M%S)" + +while [ "$#" -gt 0 ]; do + case "$1" in + --lines) + EXPECTED_LINES="$2" + shift 2 + ;; + --timeout-sec) + TIMEOUT_SEC="$2" + shift 2 + ;; + --artifact-root) + ARTIFACT_ROOT="$2" + shift 2 + ;; + --session-prefix) + SESSION_PREFIX="$2" + shift 2 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unbekannte Option: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +if [ -z "$ARTIFACT_ROOT" ]; then + ARTIFACT_ROOT="$PROJECT_DIR/storage/workspace/benchmarks/model-suite-$(date +%Y%m%d-%H%M%S)" +fi + +mkdir -p "$ARTIFACT_ROOT" + +MODELS=( + "ollama/qwen3-coding:latest" + "ollama/qwen25-coding:latest" + "ollama/deepseek-coding:latest" +) + +SUMMARY_TABLE="$ARTIFACT_ROOT/summary.tsv" +printf 'model\tbenchmark_rc\tvalidation\trequest_exit\twall_ms\tprovider_tps\tend_to_end_tps\tload_sec\tkv_tokens\n' > "$SUMMARY_TABLE" + +for model in "${MODELS[@]}"; do + slug="$(slugify_model "$model")" + run_dir="$ARTIFACT_ROOT/$slug" + session_key="$SESSION_PREFIX:$slug" + + echo "=== Benchmark fuer $model ===" + benchmark_rc=0 + if ! ./scripts/benchmark-stack.sh \ + --model "$model" \ + --lines "$EXPECTED_LINES" \ + --timeout-sec "$TIMEOUT_SEC" \ + --session-key "$session_key" \ + --artifact-dir "$run_dir" \ + --no-start; then + benchmark_rc=$? + fi + + summary_file="$run_dir/summary.txt" + + validation="$(extract_value 'Validation' "$summary_file")" + request_exit="$(extract_value 'Request exit code' "$summary_file")" + wall_ms="$(extract_metric 'end_to_end_wall_ms' "$summary_file")" + provider_tps="$(extract_metric 'output_tokens_per_sec_provider' "$summary_file")" + end_to_end_tps="$(extract_metric 'output_tokens_per_sec_end_to_end' "$summary_file")" + load_sec="$(extract_metric 'model_load_time_sec' "$summary_file")" + kv_tokens="$(extract_metric 'kv_size_tokens' "$summary_file")" + + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "$model" "$benchmark_rc" "$validation" "$request_exit" "$wall_ms" "$provider_tps" "$end_to_end_tps" "$load_sec" "$kv_tokens" \ + >> "$SUMMARY_TABLE" +done + +echo +echo "Vergleich gespeichert unter: $ARTIFACT_ROOT" +column -ts $'\t' "$SUMMARY_TABLE" \ No newline at end of file diff --git a/scripts/benchmark-stack.sh b/scripts/benchmark-stack.sh index 4f2d403..a0494db 100755 --- a/scripts/benchmark-stack.sh +++ b/scripts/benchmark-stack.sh @@ -35,7 +35,7 @@ Startet den Stack (optional), fuehrt eine reproduzierbare OpenClaw-Anfrage aus, validiert den Output und zeigt Metriken (Laufzeit, Token, KV-/VRAM-Metriken). Optionen: - --model OpenClaw-Modell (default: ollama/qwen-coding-long:latest) + --model OpenClaw-Modell (default: ollama/qwen3-coding:latest) --lines Erwartete Zeilenanzahl LINE_1..LINE_n (default: 120) --timeout-sec Timeout fuer den Agent-Call in Sekunden (default: 480) --session-key Session-Key fuer den Lauf (default: auto) @@ -45,7 +45,7 @@ Optionen: -h, --help Hilfe anzeigen Beispiel: - ./scripts/benchmark-stack.sh --model ollama/qwen-coding-long:latest --lines 140 + ./scripts/benchmark-stack.sh --model ollama/qwen3-coding:latest --lines 140 EOF } @@ -132,7 +132,7 @@ extract_unquoted_metric() { fi } -MODEL="ollama/qwen-coding-long:latest" +MODEL="ollama/qwen3-coding:latest" EXPECTED_LINES=120 TIMEOUT_SEC=480 SESSION_KEY="" diff --git a/tools/router/Containerfile b/tools/router/Containerfile index 3b2d17f..f182de7 100644 --- a/tools/router/Containerfile +++ b/tools/router/Containerfile @@ -4,14 +4,15 @@ FROM docker.io/library/python:3.12-slim RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* # Application dependencies -WORKDIR /app -COPY app/requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +WORKDIR /opt/router +COPY app/requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt -COPY app/ . -COPY config/ /app/config/ +# Copy application maintaining package structure +COPY app/ /opt/router/app/ +COPY config/ /opt/router/config/ # Default environment variables -ENV CONFIG_PATH=/app/config/gateway.json +ENV CONFIG_PATH=/opt/router/config/gateway.json -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000", "--log-level", "info", "--timeout-keep-alive", "120", "--limit-concurrency", "10"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "3000", "--log-level", "info", "--timeout-keep-alive", "120", "--limit-concurrency", "10"] \ No newline at end of file diff --git a/tools/router/app/main.py b/tools/router/app/main.py index 97b5a77..e5f8cd1 100644 --- a/tools/router/app/main.py +++ b/tools/router/app/main.py @@ -12,8 +12,8 @@ from app.registry.skill_registry import SkillRegistry from app.services.skill_manager import SkillManager -from app.mcp.server import master_server -from app.mcp.handlers import register_handlers +from app.mcp_client.mcp_server import master_server +from app.mcp_client.handlers import register_handlers from app.api.routes import register_routes diff --git a/tools/router/app/mcp/__init__.py b/tools/router/app/mcp_client/__init__.py similarity index 100% rename from tools/router/app/mcp/__init__.py rename to tools/router/app/mcp_client/__init__.py diff --git a/tools/router/app/mcp/handlers.py b/tools/router/app/mcp_client/handlers.py similarity index 100% rename from tools/router/app/mcp/handlers.py rename to tools/router/app/mcp_client/handlers.py diff --git a/tools/router/app/mcp/server.py b/tools/router/app/mcp_client/mcp_server.py similarity index 100% rename from tools/router/app/mcp/server.py rename to tools/router/app/mcp_client/mcp_server.py