From 4bef7f27fd25e115b0bd9f5c329ee719c17316e4 Mon Sep 17 00:00:00 2001 From: Lukas Geiger Date: Thu, 15 Oct 2026 15:23:07 +0200 Subject: [PATCH] fix(ai): use documented Claude 4.6 model IDs Remove invalid date suffixes from Sonnet and Opus; verify actual SDK model payloads with local fixtures. Generated-with: gpt-6.1-sol --- CHANGELOG.md | 4 +++ src/modules/ai_assistant/ai_service.py | 4 +-- tests/test_ai_model_ids.py | 45 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/test_ai_model_ids.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 8822ad3..d52f2e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/). ## [Unreleased] +### KI-Modellkennungen / AI model IDs (2026-10-15) +- Die Claude-4.6-Modellkennungen für Sonnet und Opus verwenden das dokumentierte Format ohne Datumsanhang. Die Haiku-4.5-Kennung bleibt unverändert. +- Regressionstests prüfen die an das SDK übergebenen Modellkennungen für Standardauswahl, Opus und Haiku mit einem Testdouble, ohne echte API-Anfragen. + ### High-End-Kontrolle / High-end review (2026-10-13) [P 2026-10-13] - CI-Vertragstests prüfen versionierte Actions ohne Bindung an eine feste Major-Version (PR #7). - Die zwei persönlichen OneDrive-Rechnerpfade in der deutschen und englischen Beitragsrichtlinie durch den hostneutralen Platzhalter `` ersetzt. diff --git a/src/modules/ai_assistant/ai_service.py b/src/modules/ai_assistant/ai_service.py index 4d6d080..8bcf321 100644 --- a/src/modules/ai_assistant/ai_service.py +++ b/src/modules/ai_assistant/ai_service.py @@ -14,8 +14,8 @@ class AIModel(Enum): """Verfügbare AI-Modelle""" - CLAUDE_SONNET = "claude-sonnet-4-6-20250514" - CLAUDE_OPUS = "claude-opus-4-6-20250514" + CLAUDE_SONNET = "claude-sonnet-4-6" + CLAUDE_OPUS = "claude-opus-4-6" CLAUDE_HAIKU = "claude-haiku-4-5-20251001" diff --git a/tests/test_ai_model_ids.py b/tests/test_ai_model_ids.py new file mode 100644 index 0000000..65dd17f --- /dev/null +++ b/tests/test_ai_model_ids.py @@ -0,0 +1,45 @@ +"""Verify the actual SDK payload without importing a real provider client.""" + +import asyncio +import sys +from types import SimpleNamespace +from unittest.mock import Mock + +import pytest + +from modules.ai_assistant.ai_service import AIModel, AIService + + +@pytest.mark.parametrize( + ("selection", "expected"), + [ + (None, "claude-sonnet-4-6"), + (AIModel.CLAUDE_OPUS, "claude-opus-4-6"), + (AIModel.CLAUDE_HAIKU, "claude-haiku-4-5-20251001"), + ], +) +def test_complete_sends_documented_model_id(monkeypatch, selection, expected): + """The default and selectable models must reach the SDK with valid IDs.""" + create = Mock( + return_value=SimpleNamespace( + content=[SimpleNamespace(text="fixture response")], + model=expected, + usage=SimpleNamespace(input_tokens=1, output_tokens=1), + ) + ) + client = SimpleNamespace(messages=SimpleNamespace(create=create)) + monkeypatch.setitem( + sys.modules, "anthropic", SimpleNamespace(Anthropic=Mock(return_value=client)) + ) + service = AIService(api_key="fixture-not-a-real-key") + if selection is not None: + service.set_model(selection) + + result = asyncio.run(service.complete("fixture prompt", use_history=False)) + + assert result.success + create.assert_called_once() + assert create.call_args.kwargs["model"] == expected + assert create.call_args.kwargs["messages"] == [ + {"role": "user", "content": "fixture prompt"} + ]