Compare commits

...

1 Commits

Author SHA1 Message Date
vh e4317f6a73 fix: pin the eager-503 default error_code to not_ready (Worldtree b2)
worldtree-dev finalized the #331 503 turn-launch error_code as `not_ready`
(re-pinned from internal_error; retryable, matching the /readyz 503 sense)
and re-froze the OpenAPI at 2.2.0 documenting the 409/503 statuses our
v0.18.3 mapping already handles. Tighten our fallback default from the
placeholder `turn_launch_unavailable` to the canonical `not_ready` (the
default only fires when the body omits error_code — the real code is
surfaced verbatim regardless). +1 test, suite 510 green.

NOTE: a full conversation-api-spec.md re-vendor to the b2 era is a separate,
larger pin-refresh (ratatoskr vendors the markdown spec, not the OpenAPI
JSON) — deferred, to bundle with the v1 coverage-audit / when personal is on b2.
2026-06-30 13:26:14 -07:00
4 changed files with 20 additions and 3 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "ratatoskr"
version = "0.18.3"
version = "0.18.4"
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
readme = "README.md"
requires-python = ">=3.12"
+5 -1
View File
@@ -241,7 +241,11 @@ class TurnLaunchUnavailable(SseConnectFailed):
self.message = message
_EAGER_TURN_FAILURE_CODE = {409: "agent_not_available", 503: "turn_launch_unavailable"}
# Canonical error_codes (Worldtree #331 / v1.0.0b2): 409 -> agent_not_available,
# 503 -> not_ready (retryable; re-pinned from internal_error). Used only as a
# fallback default when the body omits error_code — the real code is surfaced
# verbatim from the {detail:{error_code,message}} envelope.
_EAGER_TURN_FAILURE_CODE = {409: "agent_not_available", 503: "not_ready"}
def _eager_failure_fields(body: bytes, status: int) -> tuple[str, str]:
+13
View File
@@ -479,6 +479,19 @@ class TestStreamTurn:
_ = [e async for e in stream_turn(client, "s1", "hi")]
assert exc.value.error_code == "agent_not_available"
@respx.mock
async def test_eager_503_non_json_body_defaults_not_ready(self) -> None:
"""b2: eager 503 with a non-JSON body -> TurnLaunchUnavailable with the
canonical default error_code `not_ready`."""
respx.post("https://w.example/sessions/s1/messages").mock(
return_value=httpx.Response(503, content=b"<html>nope</html>")
)
async with httpx.AsyncClient(base_url="https://w.example") as client:
with pytest.raises(TurnLaunchUnavailable) as exc:
_ = [e async for e in stream_turn(client, "s1", "hi")]
assert exc.value.error_code == "not_ready"
assert exc.value.retryable is True
@respx.mock
async def test_no_text_aggregation(self) -> None:
"""no_text_aggregation: consumer yields each text event separately; no concat."""
Generated
+1 -1
View File
@@ -1052,7 +1052,7 @@ wheels = [
[[package]]
name = "ratatoskr"
version = "0.18.3"
version = "0.18.4"
source = { editable = "." }
dependencies = [
{ name = "httpx" },