{
  "generated_at": "2026-08-11T11:39:45.838956+00:00",
  "service": "JARVIS Voice-Diagnosebericht",
  "overview": {
    "status": "planned",
    "message": "Voice ist vorbereitet; STT/TTS sind noch nicht aktiv.",
    "compact_status": {
      "status": "blocked",
      "label": "STT und TTS pruefen",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
      "focus": "voice"
    },
    "daily_test_status": "open",
    "daily_test_message": "Alltagstest ist der Hauptnachweis fuer Hoeren, Antworten und Sprechen und ist noch offen.",
    "next_action": {
      "id": "stt_then_tts",
      "label": "STT-Diagnose starten",
      "target": "run-voice-stt-diagnostics",
      "endpoint": "/voice/stt/diagnostics",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit."
    },
    "runtime_commit": "25b26ef5d824f394460cda67c71cd279b0384f06",
    "runtime_branch": "main",
    "main_test": "POST /voice/daily-test",
    "main_test_flow": "Audio rein -> Transkript -> JARVIS-Antwort -> TTS-Audio raus",
    "safe_mode": "Voice-Bericht startet keine automatischen STT-, TTS- oder Ollama-Livechecks.",
    "last_livechecks": {
      "stt": null,
      "tts": {
        "type": "openai.audio.speech",
        "timestamp": "2026-08-11T11:27:17.639671+00:00",
        "status": "ready",
        "source": "open-webui"
      },
      "open_webui": {
        "type": "openai.audio.speech",
        "timestamp": "2026-08-11T11:27:17.639671+00:00",
        "status": "ready",
        "source": "open-webui"
      },
      "daily": null
    },
    "voice_readiness": {
      "status": "partial",
      "primary_stage": "stt",
      "diagnostic_code": "stt_not_ready",
      "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren.",
      "plain_summary": "3 von 4 Voice-Bereichen sind bereit.",
      "usable_now": [
        {
          "key": "chat",
          "label": "Antworten",
          "message": "Chatten funktioniert ueber Open WebUI/JARVIS."
        },
        {
          "key": "tts",
          "label": "Sprechen",
          "message": "Sprechen funktioniert ueber Open WebUI oder TTS-Audit."
        },
        {
          "key": "audio",
          "label": "Audioausgabe",
          "message": "Open WebUI hat Antwortaudio bestaetigt."
        }
      ],
      "missing_now": [
        {
          "key": "stt",
          "label": "Hoeren",
          "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren."
        }
      ]
    }
  },
  "test_matrix": [
    {
      "name": "Hoeren / STT",
      "status": "blocked",
      "message": "http://host.docker.internal:9000",
      "ok": false
    },
    {
      "name": "Chat / Open WebUI",
      "status": "ready",
      "message": "Chatten funktioniert ueber Open WebUI/JARVIS.",
      "ok": true
    },
    {
      "name": "Sprechen / TTS",
      "status": "ready",
      "message": "Sprechen funktioniert ueber Open WebUI oder TTS-Audit.",
      "ok": true
    }
  ],
  "runtime": {
    "status": "ready",
    "message": "Betriebsstand geladen.",
    "source_dir": "/app/source",
    "branch": "main",
    "current_commit": "25b26ef5d824f394460cda67c71cd279b0384f06",
    "update_status": "running",
    "update_message": "Update laeuft im Hintergrund.",
    "last_update_result": "laeuft",
    "last_update_result_message": "Update laeuft im Hintergrund.",
    "update_started_at": null,
    "update_updated_at": "2026-08-11T11:38:36.292371+00:00",
    "last_completed_at": null,
    "cleanup_status": "unknown",
    "update": {
      "state_found": true,
      "cleanup_status": "unknown",
      "status": "running",
      "started": true,
      "message": "Update laeuft im Hintergrund.",
      "error": null,
      "updater_container": "jarvis-updater",
      "updater_container_id": "c3e303816a02ab9f3fa0d7b3eb532e0a6c940ab2bb93b285aeadd6d9a014c5ea",
      "updated_at": "2026-08-11T11:38:36.292371+00:00",
      "completed_at": null,
      "healthcheck": null,
      "current_commit": "1ef9b2e75abcf7a1983a645267fc5cfc019f5d42",
      "remote_commit": "25b26ef5d824f394460cda67c71cd279b0384f06"
    },
    "voice_success_since_update": {
      "type": "voice.next_action",
      "timestamp": "2026-08-11T11:39:44.027991+00:00",
      "status": "ready"
    },
    "voice_successes_since_update": {
      "stt": null,
      "tts": null,
      "open_webui": null
    }
  },
  "next_action": {
    "status": "ready",
    "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
    "action": {
      "id": "stt_then_tts",
      "label": "STT-Diagnose starten",
      "target": "run-voice-stt-diagnostics",
      "endpoint": "/voice/stt/diagnostics",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit."
    },
    "summary_status": "planned",
    "open_webui_status": "ready",
    "compact_status": {
      "status": "blocked",
      "label": "STT und TTS pruefen",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
      "focus": "voice"
    },
    "priority": "stt_then_tts",
    "checks": [
      {
        "name": "Naechste Voice-Aktion",
        "status": "ok",
        "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
        "recommendation": "STT-Diagnose starten"
      }
    ]
  },
  "audit_status": {
    "status": "ready",
    "ready_count": 4,
    "persistent": true,
    "audit_path": "/app/data/audit.jsonl",
    "successes": {
      "chat": {
        "type": "openai.chat",
        "timestamp": "2026-08-11T11:27:11.108774+00:00",
        "status": "ready",
        "source": "dashboard"
      },
      "stt": null,
      "tts": {
        "type": "openai.audio.speech",
        "timestamp": "2026-08-11T11:27:17.639671+00:00",
        "status": "ready",
        "source": "open-webui"
      },
      "open_webui": {
        "type": "openai.audio.speech",
        "timestamp": "2026-08-11T11:27:17.639671+00:00",
        "status": "ready",
        "source": "open-webui"
      },
      "open_webui_stt": null,
      "open_webui_tts": {
        "type": "openai.audio.speech",
        "timestamp": "2026-08-11T11:27:17.639671+00:00",
        "status": "ready",
        "source": "open-webui"
      },
      "conversation": null,
      "daily": null
    },
    "message": "4 Voice-Erfolgsnachweise gefunden."
  },
  "voice_readiness": {
    "status": "partial",
    "message": "http://host.docker.internal:9000",
    "primary_stage": "stt",
    "ready_count": 3,
    "stage_count": 4,
    "progress_percent": 75,
    "usable_now": [
      {
        "key": "chat",
        "label": "Antworten",
        "message": "Chatten funktioniert ueber Open WebUI/JARVIS."
      },
      {
        "key": "tts",
        "label": "Sprechen",
        "message": "Sprechen funktioniert ueber Open WebUI oder TTS-Audit."
      },
      {
        "key": "audio",
        "label": "Audioausgabe",
        "message": "Open WebUI hat Antwortaudio bestaetigt."
      }
    ],
    "missing_now": [
      {
        "key": "stt",
        "label": "Hoeren",
        "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren."
      }
    ],
    "plain_summary": "3 von 4 Voice-Bereichen sind bereit.",
    "diagnostic_code": "stt_not_ready",
    "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren.",
    "stages": {
      "stt": {
        "name": "STT",
        "status": "blocked",
        "message": "http://host.docker.internal:9000",
        "diagnostic_code": "stt_not_ready",
        "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren.",
        "quality": {
          "status": "planned",
          "message": "Noch kein erfolgreicher STT-Test im Audit.",
          "source": null
        },
        "base_url": "http://host.docker.internal:9000"
      },
      "chat": {
        "name": "Chat",
        "status": "ready",
        "message": "Chatten funktioniert ueber Open WebUI/JARVIS.",
        "diagnostic_code": "open_webui_ready",
        "next_step": "Open WebUI live testen und Modell jarvis pruefen.",
        "openai_base_url": "http://jarvis:8080/v1",
        "model": "qwen3:14b"
      },
      "tts": {
        "name": "TTS",
        "status": "ready",
        "message": "Sprechen funktioniert ueber Open WebUI oder TTS-Audit.",
        "diagnostic_code": "tts_ready",
        "next_step": "TTS-Diagnose starten und Audioausgabe pruefen.",
        "quality": {
          "status": "ready",
          "message": "Letzter TTS-Erfolg ist im Audit vorhanden.",
          "source": {
            "type": "openai.audio.speech",
            "timestamp": "2026-08-11T11:27:17.639671+00:00",
            "status": "ready",
            "source": "open-webui"
          }
        },
        "base_url": "http://192.168.178.113:8085"
      },
      "audio": {
        "name": "Audio",
        "status": "ready",
        "message": "Open WebUI hat Antwortaudio bestaetigt.",
        "diagnostic_code": "voice_audio_not_confirmed",
        "next_step": "Alltagstest mit Audiodatei oder Browseraufnahme ausfuehren.",
        "last_daily_test": null
      }
    },
    "main_test": {
      "label": "Alltagstest",
      "endpoint": "POST /voice/daily-test",
      "requires_audio": true,
      "without_audio_hint": "Audiodatei waehlen oder Browseraufnahme starten."
    },
    "profile_hint": "STT/TTS sind aktiviert; jetzt Erreichbarkeit und Alltagstest pruefen.",
    "open_webui": {
      "base_url": "http://jarvis:8080/v1",
      "api_key_hint": "Lokalen JARVIS-Key verwenden, falls Open WebUI einen API-Key verlangt.",
      "model": "jarvis",
      "models": {
        "visible": [
          "jarvis",
          "qwen3:14b"
        ],
        "expected": [
          "jarvis",
          "qwen3:14b"
        ],
        "visible_expected_count": 2,
        "expected_count": 2,
        "jarvis_ok": true,
        "configured_ok": true
      },
      "connection": {
        "status": "warnings",
        "ok": false,
        "lightweight": true,
        "livecheck_required": true,
        "can_chat_with_jarvis": false,
        "usage_status": "Status leicht geprueft. Echter Chat-Test startet nur per Button.",
        "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt.",
        "openai_base_url": "http://jarvis:8080/v1",
        "local_base_url": "http://localhost:8080/v1",
        "model": "qwen3:14b",
        "provider": null,
        "duration_ms": null,
        "models": {
          "visible": [
            "jarvis",
            "qwen3:14b"
          ],
          "expected": [
            "jarvis",
            "qwen3:14b"
          ],
          "visible_expected_count": 2,
          "expected_count": 2,
          "jarvis_ok": true,
          "configured_ok": true
        },
        "diagnostic_code": "livecheck_not_run",
        "checks": [
          {
            "name": "Bereitschaft",
            "status": "ok",
            "message": "Open WebUI ist fuer JARVIS vorbereitet."
          },
          {
            "name": "Antwortformat",
            "status": "ok",
            "message": "OpenAI-kompatibles Antwortformat ist gueltig."
          },
          {
            "name": "Echter Chatpfad",
            "status": "planned",
            "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt."
          },
          {
            "name": "Modell jarvis",
            "status": "ok",
            "message": "Modell jarvis ist sichtbar."
          },
          {
            "name": "Modell qwen3:14b",
            "status": "ok",
            "message": "Modell qwen3:14b ist sichtbar."
          }
        ],
        "chat_flow": {
          "status": "ready",
          "safe_check": "GET /open-webui/connection-test",
          "live_check": "POST /open-webui/connection-test",
          "base_url": "http://jarvis:8080/v1",
          "model": "jarvis",
          "loads_ollama": false,
          "message": "Open WebUI nutzt JARVIS als OpenAI-kompatible Verbindung."
        },
        "readiness": {
          "status": "ready",
          "ready_for_open_webui": true,
          "local_webui_url": "http://localhost:3000",
          "docker_api_base_url": "http://jarvis:8080/v1",
          "local_api_base_url": "http://localhost:8080/v1",
          "model": "qwen3:14b",
          "compose_file": "/app/docker-compose.yml",
          "unraid_override_file": "/app/docker-compose.unraid.yml",
          "errors": [],
          "warnings": [],
          "checks": [
            {
              "name": "config.open_webui.enabled",
              "status": "ok",
              "message": "Open WebUI ist in der JARVIS-Konfiguration aktiviert"
            },
            {
              "name": "config.openai_api",
              "status": "ok",
              "message": "OpenAI-kompatible API ist fuer Open WebUI freigegeben"
            },
            {
              "name": "compose.open_webui",
              "status": "ok",
              "message": "Open-WebUI-Service ist in Docker Compose vorhanden"
            },
            {
              "name": "compose.openai_base_url",
              "status": "ok",
              "message": "Interne Docker-Adresse stimmt: Open WebUI spricht JARVIS ueber http://jarvis:8080/v1 an"
            },
            {
              "name": "compose.openai_enabled",
              "status": "ok",
              "message": "OpenAI-API ist in Open WebUI aktiviert"
            },
            {
              "name": "compose.api_key",
              "status": "ok",
              "message": "Lokaler API-Key fuer Open WebUI ist gesetzt"
            },
            {
              "name": "compose.webui_name",
              "status": "ok",
              "message": "Open WebUI wird als JARVIS angezeigt"
            },
            {
              "name": "compose.webui_port",
              "status": "ok",
              "message": "Externer Browser-Port stimmt: Open WebUI ist ueber http://SERVER-IP:3000 erreichbar"
            },
            {
              "name": "unraid.override",
              "status": "ok",
              "message": "Unraid-Override nutzt config.unraid.yaml"
            },
            {
              "name": "endpoint.models",
              "status": "ok",
              "message": "GET /v1/models ist fuer Open WebUI vorgesehen"
            },
            {
              "name": "endpoint.chat",
              "status": "ok",
              "message": "POST /v1/chat/completions ist fuer Open WebUI vorgesehen"
            }
          ]
        },
        "selftest": {
          "status": "ok",
          "compatible": true,
          "model": "qwen3:14b",
          "models": {
            "object": "list",
            "data": [
              {
                "id": "jarvis",
                "object": "model",
                "created": 1,
                "owned_by": "jarvis"
              },
              {
                "id": "qwen3:14b",
                "object": "model",
                "created": 1,
                "owned_by": "ollama"
              }
            ]
          },
          "model_ids": [
            "jarvis",
            "qwen3:14b"
          ],
          "checked_endpoints": [
            "/v1/models",
            "/v1/chat/completions"
          ],
          "errors": [],
          "checks": [
            {
              "name": "models.object",
              "status": "ok",
              "message": "Modellantwort nutzt OpenAI-kompatibles Listenformat"
            },
            {
              "name": "models.items",
              "status": "ok",
              "message": "Alle Modell-Eintraege haben id und object=model"
            },
            {
              "name": "models.jarvis",
              "status": "ok",
              "message": "Modell jarvis ist sichtbar und kann in Open WebUI ausgewaehlt werden"
            },
            {
              "name": "models.configured",
              "status": "ok",
              "message": "Aktives Ollama-Modell qwen3:14b ist sichtbar"
            },
            {
              "name": "chat.model_mapping",
              "status": "ok",
              "message": "Open-WebUI-Modell jarvis wird auf das aktive Ollama-Modell geroutet"
            },
            {
              "name": "chat.id",
              "status": "ok",
              "message": "Chatantwort enthaelt eine OpenAI-typische Completion-ID"
            },
            {
              "name": "chat.object",
              "status": "ok",
              "message": "Chatantwort nutzt OpenAI-kompatibles Completion-Format"
            },
            {
              "name": "chat.choice",
              "status": "ok",
              "message": "Chatantwort enthaelt eine Assistant-Nachricht"
            },
            {
              "name": "chat.usage",
              "status": "ok",
              "message": "Chatantwort enthaelt plausible Token-Nutzungsdaten"
            },
            {
              "name": "chat.finish_reason",
              "status": "ok",
              "message": "Chatantwort beendet sauber mit finish_reason=stop"
            },
            {
              "name": "chat.provider",
              "status": "ok",
              "message": "Chatantwort nennt JARVIS als Provider"
            },
            {
              "name": "chat.fingerprint",
              "status": "ok",
              "message": "Chatantwort enthaelt einen stabilen JARVIS-Fingerprint"
            },
            {
              "name": "streaming.error",
              "status": "ok",
              "message": "Streaming-Ablehnung nutzt ein OpenAI-kompatibles Fehlerformat"
            }
          ],
          "model_guidance": {
            "selected_model": "jarvis",
            "active_ollama_model": "qwen3:14b",
            "message": "In Open WebUI Modell jarvis auswaehlen. JARVIS routet jarvis auf das aktuell gespeicherte Ollama-Modell."
          }
        },
        "livecheck": {
          "status": "planned",
          "ok": false,
          "provider": null,
          "model": "qwen3:14b",
          "duration_ms": null,
          "diagnostic_code": "livecheck_not_run",
          "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt."
        },
        "next_steps": [
          "In Open WebUI bei OpenAI-kompatibler Verbindung exakt die Base-URL http://jarvis:8080/v1 eintragen.",
          "Als Modell exakt jarvis auswaehlen.",
          "Eine kurze Chatnachricht in Open WebUI senden."
        ],
        "setup": {
          "base_url": "http://jarvis:8080/v1",
          "local_test_url": "http://localhost:8080/v1",
          "api_key_hint": "jarvis-local-dev-key oder den in Open WebUI erwarteten lokalen Key verwenden.",
          "model": "jarvis",
          "exact_values": {
            "base_url": "http://jarvis:8080/v1",
            "model": "jarvis",
            "api_key": "jarvis-local-dev-key oder lokaler JARVIS-Key"
          },
          "voice_hint": "Mikrofon im Browser ueber Open WebUI verwenden; JARVIS liefert Chat, Diagnose und TTS/STT-Anbindung."
        }
      }
    },
    "next_action": {
      "status": "ready",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
      "action": {
        "id": "stt_then_tts",
        "label": "STT-Diagnose starten",
        "target": "run-voice-stt-diagnostics",
        "endpoint": "/voice/stt/diagnostics",
        "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit."
      },
      "summary_status": "planned",
      "open_webui_status": "ready",
      "compact_status": {
        "status": "blocked",
        "label": "STT und TTS pruefen",
        "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
        "focus": "voice"
      },
      "priority": "stt_then_tts",
      "checks": [
        {
          "name": "Naechste Voice-Aktion",
          "status": "ok",
          "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
          "recommendation": "STT-Diagnose starten"
        }
      ]
    },
    "audit": {
      "status": "ready",
      "ready_count": 4,
      "persistent": true,
      "audit_path": "/app/data/audit.jsonl",
      "successes": {
        "chat": {
          "type": "openai.chat",
          "timestamp": "2026-08-11T11:27:11.108774+00:00",
          "status": "ready",
          "source": "dashboard"
        },
        "stt": null,
        "tts": {
          "type": "openai.audio.speech",
          "timestamp": "2026-08-11T11:27:17.639671+00:00",
          "status": "ready",
          "source": "open-webui"
        },
        "open_webui": {
          "type": "openai.audio.speech",
          "timestamp": "2026-08-11T11:27:17.639671+00:00",
          "status": "ready",
          "source": "open-webui"
        },
        "open_webui_stt": null,
        "open_webui_tts": {
          "type": "openai.audio.speech",
          "timestamp": "2026-08-11T11:27:17.639671+00:00",
          "status": "ready",
          "source": "open-webui"
        },
        "conversation": null,
        "daily": null
      },
      "message": "4 Voice-Erfolgsnachweise gefunden."
    },
    "summary": {
      "status": "planned",
      "message": "Voice ist vorbereitet; STT/TTS sind noch nicht aktiv.",
      "compact_status": {
        "status": "blocked",
        "label": "STT und TTS pruefen",
        "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
        "focus": "voice"
      },
      "safe": true,
      "audio_recorded": false,
      "audio_generated": false,
      "current_state": "idle",
      "stt": {
        "enabled": true,
        "provider": "whisper",
        "base_url": "http://host.docker.internal:9000",
        "timeout_seconds": 45,
        "status": "planned"
      },
      "tts": {
        "enabled": true,
        "provider": "omnivoice-triton",
        "base_url": "http://192.168.178.113:8085",
        "default_voice": "male_en",
        "status": "blocked"
      },
      "checks": [
        {
          "name": "Sprachpipeline",
          "status": "blocked",
          "message": "Die Sprachpipeline braucht zuerst eine Korrektur in der Konfiguration."
        },
        {
          "name": "STT-Livecheck",
          "status": "planned",
          "message": "STT ist aktiviert und wird geprueft. Die echte Audioannahme ist vorbereitet."
        },
        {
          "name": "TTS-Livecheck",
          "status": "blocked",
          "message": "TTS-Livecheck ist blockiert. Adresse oder Dienst muss geprueft werden."
        },
        {
          "name": "Voice-Status",
          "status": "planned",
          "message": "Voice-Ereignisse sind vorbereitet; echte Audioereignisse folgen mit STT/TTS-Anbindung."
        }
      ],
      "endpoints": {
        "readiness": "/voice/readiness",
        "events": "/voice/events",
        "history": "/voice/history",
        "stt_contract": "/voice/stt",
        "stt_livecheck": "/voice/stt/livecheck",
        "stt_upload_plan": "/voice/stt/upload-plan",
        "stt_upload": "/voice/stt/upload",
        "chain_check": "/voice/chain-check",
        "conversation": "/voice/conversation",
        "tts_contract": "/voice/tts/contract",
        "tts_request_plan": "/voice/tts/request-plan",
        "tts_audio": "/voice/tts",
        "tts_livecheck": "/voice/tts/livecheck"
      },
      "next_steps": [
        "Open WebUI als Mikrofon- und Chatoberflaeche verwenden.",
        "Sprachdialog ueber /voice/conversation als STT-Chat-TTS-Kette testen.",
        "Dashboard fuer Status, Diagnose und technische Tests behalten."
      ]
    }
  },
  "summary": {
    "status": "planned",
    "message": "Voice ist vorbereitet; STT/TTS sind noch nicht aktiv.",
    "compact_status": {
      "status": "blocked",
      "label": "STT und TTS pruefen",
      "message": "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
      "focus": "voice"
    },
    "safe": true,
    "audio_recorded": false,
    "audio_generated": false,
    "current_state": "idle",
    "stt": {
      "enabled": true,
      "provider": "whisper",
      "base_url": "http://host.docker.internal:9000",
      "timeout_seconds": 45,
      "status": "planned"
    },
    "tts": {
      "enabled": true,
      "provider": "omnivoice-triton",
      "base_url": "http://192.168.178.113:8085",
      "default_voice": "male_en",
      "status": "blocked"
    },
    "checks": [
      {
        "name": "Sprachpipeline",
        "status": "blocked",
        "message": "Die Sprachpipeline braucht zuerst eine Korrektur in der Konfiguration."
      },
      {
        "name": "STT-Livecheck",
        "status": "planned",
        "message": "STT ist aktiviert und wird geprueft. Die echte Audioannahme ist vorbereitet."
      },
      {
        "name": "TTS-Livecheck",
        "status": "blocked",
        "message": "TTS-Livecheck ist blockiert. Adresse oder Dienst muss geprueft werden."
      },
      {
        "name": "Voice-Status",
        "status": "planned",
        "message": "Voice-Ereignisse sind vorbereitet; echte Audioereignisse folgen mit STT/TTS-Anbindung."
      }
    ],
    "endpoints": {
      "readiness": "/voice/readiness",
      "events": "/voice/events",
      "history": "/voice/history",
      "stt_contract": "/voice/stt",
      "stt_livecheck": "/voice/stt/livecheck",
      "stt_upload_plan": "/voice/stt/upload-plan",
      "stt_upload": "/voice/stt/upload",
      "chain_check": "/voice/chain-check",
      "conversation": "/voice/conversation",
      "tts_contract": "/voice/tts/contract",
      "tts_request_plan": "/voice/tts/request-plan",
      "tts_audio": "/voice/tts",
      "tts_livecheck": "/voice/tts/livecheck"
    },
    "next_steps": [
      "Open WebUI als Mikrofon- und Chatoberflaeche verwenden.",
      "Sprachdialog ueber /voice/conversation als STT-Chat-TTS-Kette testen.",
      "Dashboard fuer Status, Diagnose und technische Tests behalten."
    ]
  },
  "diagnostics": {
    "stt": {
      "name": "STT",
      "status": "blocked",
      "message": "http://host.docker.internal:9000",
      "diagnostic_code": "stt_not_ready",
      "next_step": "Audiodatei waehlen oder Aufnahme starten und STT-Diagnose ausfuehren.",
      "quality": {
        "status": "planned",
        "message": "Noch kein erfolgreicher STT-Test im Audit.",
        "source": null
      },
      "base_url": "http://host.docker.internal:9000"
    },
    "tts": {
      "name": "TTS",
      "status": "ready",
      "message": "Sprechen funktioniert ueber Open WebUI oder TTS-Audit.",
      "diagnostic_code": "tts_ready",
      "next_step": "TTS-Diagnose starten und Audioausgabe pruefen.",
      "quality": {
        "status": "ready",
        "message": "Letzter TTS-Erfolg ist im Audit vorhanden.",
        "source": {
          "type": "openai.audio.speech",
          "timestamp": "2026-08-11T11:27:17.639671+00:00",
          "status": "ready",
          "source": "open-webui"
        }
      },
      "base_url": "http://192.168.178.113:8085"
    },
    "open_webui": {
      "name": "Chat",
      "status": "ready",
      "message": "Chatten funktioniert ueber Open WebUI/JARVIS.",
      "diagnostic_code": "open_webui_ready",
      "next_step": "Open WebUI live testen und Modell jarvis pruefen.",
      "openai_base_url": "http://jarvis:8080/v1",
      "model": "qwen3:14b"
    },
    "open_webui_connection": {
      "status": "warnings",
      "ok": false,
      "lightweight": true,
      "livecheck_required": true,
      "can_chat_with_jarvis": false,
      "usage_status": "Status leicht geprueft. Echter Chat-Test startet nur per Button.",
      "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt.",
      "openai_base_url": "http://jarvis:8080/v1",
      "local_base_url": "http://localhost:8080/v1",
      "model": "qwen3:14b",
      "provider": null,
      "duration_ms": null,
      "models": {
        "visible": [
          "jarvis",
          "qwen3:14b"
        ],
        "expected": [
          "jarvis",
          "qwen3:14b"
        ],
        "visible_expected_count": 2,
        "expected_count": 2,
        "jarvis_ok": true,
        "configured_ok": true
      },
      "diagnostic_code": "livecheck_not_run",
      "checks": [
        {
          "name": "Bereitschaft",
          "status": "ok",
          "message": "Open WebUI ist fuer JARVIS vorbereitet."
        },
        {
          "name": "Antwortformat",
          "status": "ok",
          "message": "OpenAI-kompatibles Antwortformat ist gueltig."
        },
        {
          "name": "Echter Chatpfad",
          "status": "planned",
          "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt."
        },
        {
          "name": "Modell jarvis",
          "status": "ok",
          "message": "Modell jarvis ist sichtbar."
        },
        {
          "name": "Modell qwen3:14b",
          "status": "ok",
          "message": "Modell qwen3:14b ist sichtbar."
        }
      ],
      "chat_flow": {
        "status": "ready",
        "safe_check": "GET /open-webui/connection-test",
        "live_check": "POST /open-webui/connection-test",
        "base_url": "http://jarvis:8080/v1",
        "model": "jarvis",
        "loads_ollama": false,
        "message": "Open WebUI nutzt JARVIS als OpenAI-kompatible Verbindung."
      },
      "readiness": {
        "status": "ready",
        "ready_for_open_webui": true,
        "local_webui_url": "http://localhost:3000",
        "docker_api_base_url": "http://jarvis:8080/v1",
        "local_api_base_url": "http://localhost:8080/v1",
        "model": "qwen3:14b",
        "compose_file": "/app/docker-compose.yml",
        "unraid_override_file": "/app/docker-compose.unraid.yml",
        "errors": [],
        "warnings": [],
        "checks": [
          {
            "name": "config.open_webui.enabled",
            "status": "ok",
            "message": "Open WebUI ist in der JARVIS-Konfiguration aktiviert"
          },
          {
            "name": "config.openai_api",
            "status": "ok",
            "message": "OpenAI-kompatible API ist fuer Open WebUI freigegeben"
          },
          {
            "name": "compose.open_webui",
            "status": "ok",
            "message": "Open-WebUI-Service ist in Docker Compose vorhanden"
          },
          {
            "name": "compose.openai_base_url",
            "status": "ok",
            "message": "Interne Docker-Adresse stimmt: Open WebUI spricht JARVIS ueber http://jarvis:8080/v1 an"
          },
          {
            "name": "compose.openai_enabled",
            "status": "ok",
            "message": "OpenAI-API ist in Open WebUI aktiviert"
          },
          {
            "name": "compose.api_key",
            "status": "ok",
            "message": "Lokaler API-Key fuer Open WebUI ist gesetzt"
          },
          {
            "name": "compose.webui_name",
            "status": "ok",
            "message": "Open WebUI wird als JARVIS angezeigt"
          },
          {
            "name": "compose.webui_port",
            "status": "ok",
            "message": "Externer Browser-Port stimmt: Open WebUI ist ueber http://SERVER-IP:3000 erreichbar"
          },
          {
            "name": "unraid.override",
            "status": "ok",
            "message": "Unraid-Override nutzt config.unraid.yaml"
          },
          {
            "name": "endpoint.models",
            "status": "ok",
            "message": "GET /v1/models ist fuer Open WebUI vorgesehen"
          },
          {
            "name": "endpoint.chat",
            "status": "ok",
            "message": "POST /v1/chat/completions ist fuer Open WebUI vorgesehen"
          }
        ]
      },
      "selftest": {
        "status": "ok",
        "compatible": true,
        "model": "qwen3:14b",
        "models": {
          "object": "list",
          "data": [
            {
              "id": "jarvis",
              "object": "model",
              "created": 1,
              "owned_by": "jarvis"
            },
            {
              "id": "qwen3:14b",
              "object": "model",
              "created": 1,
              "owned_by": "ollama"
            }
          ]
        },
        "model_ids": [
          "jarvis",
          "qwen3:14b"
        ],
        "checked_endpoints": [
          "/v1/models",
          "/v1/chat/completions"
        ],
        "errors": [],
        "checks": [
          {
            "name": "models.object",
            "status": "ok",
            "message": "Modellantwort nutzt OpenAI-kompatibles Listenformat"
          },
          {
            "name": "models.items",
            "status": "ok",
            "message": "Alle Modell-Eintraege haben id und object=model"
          },
          {
            "name": "models.jarvis",
            "status": "ok",
            "message": "Modell jarvis ist sichtbar und kann in Open WebUI ausgewaehlt werden"
          },
          {
            "name": "models.configured",
            "status": "ok",
            "message": "Aktives Ollama-Modell qwen3:14b ist sichtbar"
          },
          {
            "name": "chat.model_mapping",
            "status": "ok",
            "message": "Open-WebUI-Modell jarvis wird auf das aktive Ollama-Modell geroutet"
          },
          {
            "name": "chat.id",
            "status": "ok",
            "message": "Chatantwort enthaelt eine OpenAI-typische Completion-ID"
          },
          {
            "name": "chat.object",
            "status": "ok",
            "message": "Chatantwort nutzt OpenAI-kompatibles Completion-Format"
          },
          {
            "name": "chat.choice",
            "status": "ok",
            "message": "Chatantwort enthaelt eine Assistant-Nachricht"
          },
          {
            "name": "chat.usage",
            "status": "ok",
            "message": "Chatantwort enthaelt plausible Token-Nutzungsdaten"
          },
          {
            "name": "chat.finish_reason",
            "status": "ok",
            "message": "Chatantwort beendet sauber mit finish_reason=stop"
          },
          {
            "name": "chat.provider",
            "status": "ok",
            "message": "Chatantwort nennt JARVIS als Provider"
          },
          {
            "name": "chat.fingerprint",
            "status": "ok",
            "message": "Chatantwort enthaelt einen stabilen JARVIS-Fingerprint"
          },
          {
            "name": "streaming.error",
            "status": "ok",
            "message": "Streaming-Ablehnung nutzt ein OpenAI-kompatibles Fehlerformat"
          }
        ],
        "model_guidance": {
          "selected_model": "jarvis",
          "active_ollama_model": "qwen3:14b",
          "message": "In Open WebUI Modell jarvis auswaehlen. JARVIS routet jarvis auf das aktuell gespeicherte Ollama-Modell."
        }
      },
      "livecheck": {
        "status": "planned",
        "ok": false,
        "provider": null,
        "model": "qwen3:14b",
        "duration_ms": null,
        "diagnostic_code": "livecheck_not_run",
        "message": "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt."
      },
      "next_steps": [
        "In Open WebUI bei OpenAI-kompatibler Verbindung exakt die Base-URL http://jarvis:8080/v1 eintragen.",
        "Als Modell exakt jarvis auswaehlen.",
        "Eine kurze Chatnachricht in Open WebUI senden."
      ],
      "setup": {
        "base_url": "http://jarvis:8080/v1",
        "local_test_url": "http://localhost:8080/v1",
        "api_key_hint": "jarvis-local-dev-key oder den in Open WebUI erwarteten lokalen Key verwenden.",
        "model": "jarvis",
        "exact_values": {
          "base_url": "http://jarvis:8080/v1",
          "model": "jarvis",
          "api_key": "jarvis-local-dev-key oder lokaler JARVIS-Key"
        },
        "voice_hint": "Mikrofon im Browser ueber Open WebUI verwenden; JARVIS liefert Chat, Diagnose und TTS/STT-Anbindung."
      }
    }
  },
  "history": {
    "count": 0,
    "events": [],
    "message": "Noch kein Voice-Testverlauf vorhanden."
  },
  "recommendations": [
    "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
    "Spracheingabe und Sprachausgabe sind noch nicht vollstaendig bereit.",
    "http://host.docker.internal:9000",
    "Sprechen funktioniert ueber Open WebUI oder TTS-Audit.",
    "Echter Chat-Livecheck wurde nicht automatisch ausgefuehrt."
  ]
}