style: apply ruff's automatic fixes and formatter

Mechanical only, and separated from the judgment calls that follow so the
reviewable changes are not buried in a 98-file whitespace diff.

227 automatic fixes: 60 blank lines carrying whitespace, 60 unsorted import
blocks, 34 Optional[X] to X | None, 28 unused imports, 16 deprecated typing
imports, 12 datetime.timezone.utc to datetime.UTC, and assorted smaller
modernisations. Then `ruff format` over src and tests: 98 files reformatted,
35 already conforming.

No file among the unused-import findings defines __all__ or is an __init__.py,
so nothing here removes a re-export.

`make test`: 658 passed, unchanged from HEAD.

Two things observed while verifying, neither addressed here:

`pytest tests/` cannot collect — tests/e2e/test_orchestration_e2e.py uses an
`e2e` marker that is not registered, and the config is strict about markers.
This fails identically at HEAD, so it predates this change; `make test` passes
because it ignores tests/e2e, tests/integration and tests/contracts.

test_tatlock_tool_call_logging_calculator is flaky. It failed once in a full run
with these changes and passed on the next, passes in isolation with them, and
fails in isolation at HEAD. It is order- or timing-dependent, not a regression
from this commit — established by running the full suite both ways rather than
by reasoning about which change could have caused it.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-11 17:25:18 +02:00
co-authored by Claude
parent 57fa6c13fc
commit 78066fab1b
103 changed files with 1601 additions and 1749 deletions
+83 -83
View File
@@ -30,8 +30,10 @@ logger = get_logger(__name__)
# Stream Event Types
# ============================================================================
class StreamEventType(str, Enum):
"""Streaming event types for Responses API."""
REASONING_SUMMARY_DELTA = "response.reasoning_summary_text.delta"
REASONING_SUMMARY_DONE = "response.reasoning_summary_text.done"
OUTPUT_TEXT_DELTA = "response.output_text.delta"
@@ -46,30 +48,38 @@ class StreamEventType(str, Enum):
# Stream Event Schemas
# ============================================================================
class ReasoningSummaryDelta(CustomBaseModel):
"""Reasoning summary text delta event."""
event: Literal[StreamEventType.REASONING_SUMMARY_DELTA] = StreamEventType.REASONING_SUMMARY_DELTA
event: Literal[StreamEventType.REASONING_SUMMARY_DELTA] = (
StreamEventType.REASONING_SUMMARY_DELTA
)
delta: str
class ReasoningSummaryDone(CustomBaseModel):
"""Reasoning summary completion event."""
event: Literal[StreamEventType.REASONING_SUMMARY_DONE] = StreamEventType.REASONING_SUMMARY_DONE
class OutputTextDelta(CustomBaseModel):
"""Output text delta event."""
event: Literal[StreamEventType.OUTPUT_TEXT_DELTA] = StreamEventType.OUTPUT_TEXT_DELTA
delta: str
class OutputTextDone(CustomBaseModel):
"""Output text completion event."""
event: Literal[StreamEventType.OUTPUT_TEXT_DONE] = StreamEventType.OUTPUT_TEXT_DONE
class FunctionCallDelta(CustomBaseModel):
"""Function call arguments delta event."""
event: Literal[StreamEventType.FUNCTION_CALL_DELTA] = StreamEventType.FUNCTION_CALL_DELTA
delta: str
name: str | None = None # Only in first chunk
@@ -77,31 +87,34 @@ class FunctionCallDelta(CustomBaseModel):
class FunctionCallDone(CustomBaseModel):
"""Function call completion event."""
event: Literal[StreamEventType.FUNCTION_CALL_DONE] = StreamEventType.FUNCTION_CALL_DONE
class ResponseDone(CustomBaseModel):
"""Response completion event with full response."""
event: Literal[StreamEventType.RESPONSE_DONE] = StreamEventType.RESPONSE_DONE
response: Response
class ErrorEvent(CustomBaseModel):
"""Error event."""
event: Literal[StreamEventType.ERROR] = StreamEventType.ERROR
error: dict
# Union type for all stream events
StreamEvent = (
ReasoningSummaryDelta |
ReasoningSummaryDone |
OutputTextDelta |
OutputTextDone |
FunctionCallDelta |
FunctionCallDone |
ResponseDone |
ErrorEvent
ReasoningSummaryDelta
| ReasoningSummaryDone
| OutputTextDelta
| OutputTextDone
| FunctionCallDelta
| FunctionCallDone
| ResponseDone
| ErrorEvent
)
@@ -109,6 +122,7 @@ StreamEvent = (
# Streaming Coordinator
# ============================================================================
class StreamingCoordinator:
"""
Coordinates streaming from agents to SSE format.
@@ -123,7 +137,7 @@ class StreamingCoordinator:
async def stream_response_with_steward(
self,
request: "ResponseRequest" # type: ignore # Forward reference
request: "ResponseRequest", # type: ignore # Forward reference
) -> AsyncGenerator[StreamEvent, None]:
"""
Stream response with Steward preprocessing and two-phase Tatlock execution.
@@ -181,10 +195,13 @@ class StreamingCoordinator:
# Check if direct delegation is recommended
delegation_agents = {"biographer", "librarian", "housekeeper"}
delegation_only = all(
cap in delegation_agents
for cap in enriched.recommendation.recommended_capabilities
) and enriched.recommendation.recommended_capabilities
delegation_only = (
all(
cap in delegation_agents
for cap in enriched.recommendation.recommended_capabilities
)
and enriched.recommendation.recommended_capabilities
)
tatlock = TatlockAgent()
@@ -222,7 +239,7 @@ class StreamingCoordinator:
# Stream the synthesized response
chunk_size = 50
for i in range(0, len(tatlock_response), chunk_size):
yield OutputTextDelta(delta=tatlock_response[i:i + chunk_size])
yield OutputTextDelta(delta=tatlock_response[i : i + chunk_size])
await asyncio.sleep(0.02)
yield OutputTextDone()
@@ -231,12 +248,10 @@ class StreamingCoordinator:
message_item = MessageOutputItem(
id=f"msg_{generate_id()}",
role="assistant",
content=[OutputTextContent(
type="output_text",
text=tatlock_response,
annotations=[]
)],
status="completed"
content=[
OutputTextContent(type="output_text", text=tatlock_response, annotations=[])
],
status="completed",
)
output_items.append(message_item)
@@ -252,7 +267,7 @@ class StreamingCoordinator:
model=request.model,
status="completed",
output=output_items,
usage=usage
usage=usage,
)
# Track conversation history
@@ -319,17 +334,11 @@ class StreamingCoordinator:
try:
# Execute delegation
if agent == "librarian":
result = await delegate_to_librarian(
task=user_message, context=context
)
result = await delegate_to_librarian(task=user_message, context=context)
elif agent == "biographer":
result = await delegate_to_biographer(
task=user_message, context=context
)
result = await delegate_to_biographer(task=user_message, context=context)
elif agent == "housekeeper":
result = await delegate_to_housekeeper(
task=user_message, context=context
)
result = await delegate_to_housekeeper(task=user_message, context=context)
else:
result = None
@@ -366,17 +375,19 @@ class StreamingCoordinator:
yield ReasoningSummaryDone()
if results is not None:
results.update({
"tools_called": tools_called,
"expert_results": expert_results,
"tool_outputs": {},
"raw_output": "",
"think_messages": think_messages,
})
results.update(
{
"tools_called": tools_called,
"expert_results": expert_results,
"tool_outputs": {},
"raw_output": "",
"think_messages": think_messages,
}
)
async def stream_response(
self,
request: "ResponseRequest" # type: ignore # Forward reference
request: "ResponseRequest", # type: ignore # Forward reference
) -> AsyncGenerator[StreamEvent, None]:
"""
Coordinate streaming from agent to SSE events.
@@ -435,18 +446,13 @@ class StreamingCoordinator:
elif item.type == "function_call":
# Stream function call arguments
# First chunk includes name
yield FunctionCallDelta(
name=item.data["name"],
delta=""
)
yield FunctionCallDelta(name=item.data["name"], delta="")
# Stream arguments in chunks
args = item.data["arguments"]
chunk_size = 20
for i in range(0, len(args), chunk_size):
yield FunctionCallDelta(
delta=args[i:i+chunk_size]
)
yield FunctionCallDelta(delta=args[i : i + chunk_size])
await asyncio.sleep(0.03)
yield FunctionCallDone()
@@ -458,7 +464,7 @@ class StreamingCoordinator:
# Only stream the NEW text (delta) since last update
if current_text.startswith(last_message_text):
# Extract only the new portion
delta_text = current_text[len(last_message_text):]
delta_text = current_text[len(last_message_text) :]
if delta_text:
# Stream the delta text in chunks while preserving formatting
@@ -466,17 +472,16 @@ class StreamingCoordinator:
chunk_size = 50 # characters per chunk
for i in range(0, len(delta_text), chunk_size):
chunk = delta_text[i:i+chunk_size]
chunk = delta_text[i : i + chunk_size]
# Check stop sequences on full accumulated text
stop_found, text_before_stop = self._check_stop_sequence(
current_text,
request.stop
current_text, request.stop
)
if stop_found:
# Only emit remaining delta before stop
remaining = text_before_stop[len(last_message_text):]
remaining = text_before_stop[len(last_message_text) :]
if remaining:
yield OutputTextDelta(delta=remaining)
yield OutputTextDone()
@@ -508,11 +513,12 @@ class StreamingCoordinator:
model=request.model,
status="completed",
output=self._convert_output_items(output_items),
usage=usage
usage=usage,
)
# Track conversation history (import here to avoid circular dependency)
from src.responses.service import _conversation_history
conversation_id = await _conversation_history.get_conversation_id(request)
await _conversation_history.add_response(conversation_id, final_response)
@@ -534,24 +540,30 @@ class StreamingCoordinator:
converted = []
for item in items:
if item.type == "message":
converted.append(MessageOutputItem(
id=item.id,
content=[OutputTextContent(**c) for c in item.data["content"]],
status=item.data.get("status", "completed")
))
converted.append(
MessageOutputItem(
id=item.id,
content=[OutputTextContent(**c) for c in item.data["content"]],
status=item.data.get("status", "completed"),
)
)
elif item.type == "reasoning":
converted.append(ReasoningOutputItem(
id=item.id,
summary=item.data["summary"],
status=item.data.get("status", "completed")
))
converted.append(
ReasoningOutputItem(
id=item.id,
summary=item.data["summary"],
status=item.data.get("status", "completed"),
)
)
elif item.type == "function_call":
converted.append(FunctionCallOutputItem(
id=item.id,
name=item.data["name"],
arguments=item.data["arguments"],
status=item.data.get("status", "completed")
))
converted.append(
FunctionCallOutputItem(
id=item.id,
name=item.data["name"],
arguments=item.data["arguments"],
status=item.data.get("status", "completed"),
)
)
return converted
@@ -576,18 +588,10 @@ class StreamingCoordinator:
error_type = "internal_error"
code = 500
return ErrorEvent(
error={
"type": error_type,
"message": str(error),
"code": code
}
)
return ErrorEvent(error={"type": error_type, "message": str(error), "code": code})
def _check_stop_sequence(
self,
accumulated_text: str,
stop_sequences: list[str] | None
self, accumulated_text: str, stop_sequences: list[str] | None
) -> tuple[bool, str]:
"""
Check if any stop sequence is encountered.
@@ -624,11 +628,7 @@ class StreamingCoordinator:
"""
return len(text) // 4
def _check_max_tokens(
self,
current_tokens: int,
max_tokens: int | None
) -> bool:
def _check_max_tokens(self, current_tokens: int, max_tokens: int | None) -> bool:
"""
Check if max tokens limit reached.