fix: recover character sheet requests from gateway 405
Some checks are pending
Test and SonarQube / quality (push) Waiting to run
Some checks are pending
Test and SonarQube / quality (push) Waiting to run
This commit is contained in:
parent
b7aade39db
commit
ff827a74bd
10
CHANGELOG.md
10
CHANGELOG.md
@ -9,6 +9,16 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
|
||||
|
||||
---
|
||||
|
||||
## [1.26.2] — 2026-09-09
|
||||
|
||||
### Fixed
|
||||
- **Character-Sheet Generation Could Stop on HTTP 405.** If an OpenAI-compatible LLM gateway rejects the configured
|
||||
version-prefixed chat route (`/v1/chat/completions`) with 405, character-sheet extraction now retries the gateway's
|
||||
root chat route (`/chat/completions`). This applies to both the live stream and its non-streaming fallback, so an
|
||||
otherwise healthy gateway no longer drops the current passage.
|
||||
|
||||
---
|
||||
|
||||
## [1.26.1] — 2026-09-08
|
||||
|
||||
### Added
|
||||
|
||||
@ -395,11 +395,23 @@ def _response_error_text(resp) -> str:
|
||||
|
||||
|
||||
def _llm_chat_completion_urls(llm_url: str) -> list[str]:
|
||||
"""Return compatible chat-completions routes for an LLM base URL.
|
||||
|
||||
Most OpenAI-compatible servers use a ``/v1`` prefix, but a few routing
|
||||
gateways expose the same API at their root. In particular, gateways can
|
||||
reply 405 (rather than 404) when the version-prefixed route is disabled.
|
||||
Trying the root route after a versioned route prevents a single passage
|
||||
from being lost just because the configured gateway uses that variant.
|
||||
"""
|
||||
base = (llm_url or "http://localhost:11434/v1").rstrip("/")
|
||||
versioned = bool(re.search(r"/v\d+(?:\.\d+)?$", base))
|
||||
root = re.sub(r"/v\d+(?:\.\d+)?$", "", base) if versioned else base
|
||||
urls: list[str] = []
|
||||
if not re.search(r"/v\d+(?:\.\d+)?$", base):
|
||||
if not versioned:
|
||||
urls.append(f"{base}/v1/chat/completions")
|
||||
urls.append(f"{base}/chat/completions")
|
||||
if versioned:
|
||||
urls.append(f"{root}/chat/completions")
|
||||
return list(dict.fromkeys(urls))
|
||||
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ from routes.conversation import (
|
||||
match_characters_voices,
|
||||
_request_timeout_seconds,
|
||||
_response_error_text,
|
||||
_llm_chat_completion_urls,
|
||||
_persist_consistent_image_artifacts,
|
||||
_data_image_digest,
|
||||
)
|
||||
@ -112,6 +113,25 @@ class AttributionParserTests(unittest.TestCase):
|
||||
reason = "Bad Gateway"
|
||||
self.assertEqual(len(_response_error_text(ResponseStub())), 2000)
|
||||
|
||||
def test_chat_completion_urls_fall_back_from_versioned_gateway_route(self):
|
||||
# Some OpenAI-compatible routing gateways return 405 for /v1 but
|
||||
# accept their chat endpoint at the root. Keep the configured route
|
||||
# first, then try that compatible alternative.
|
||||
self.assertEqual(
|
||||
_llm_chat_completion_urls("http://gateway:28080/v1"),
|
||||
[
|
||||
"http://gateway:28080/v1/chat/completions",
|
||||
"http://gateway:28080/chat/completions",
|
||||
],
|
||||
)
|
||||
self.assertEqual(
|
||||
_llm_chat_completion_urls("http://gateway:28080"),
|
||||
[
|
||||
"http://gateway:28080/v1/chat/completions",
|
||||
"http://gateway:28080/chat/completions",
|
||||
],
|
||||
)
|
||||
|
||||
def test_repairs_epigraph_split_before_mixed_guillemet_close(self):
|
||||
raw = '{"segments":[' \
|
||||
'{"speaker":"Schwester Larissa","type":"dialogue","text":"»Von dem Windhager Felsgesteyn bis zur Kueste von Mendena ziehet es sich hin, von Ifirns Eisgebirg bis zu dem dampfenden Waldt der Mohas, und"},' \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user