Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions agent/auxiliary_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,10 @@ def _try_openrouter(explicit_api_key: str = None) -> Tuple[Optional[OpenAI], Opt
if pool_present:
or_key = explicit_api_key or _pool_runtime_api_key(entry)
if not or_key:
_mark_provider_unhealthy("openrouter", ttl=60)
# Missing credentials are a static availability/config condition, not
# a transient provider-health issue. Do NOT poison the unhealthy
# cache here — doing so makes later calls skip OpenRouter even after
# a key appears in env/pool during the same process.
return None, None
base_url = _pool_runtime_base_url(entry, OPENROUTER_BASE_URL) or OPENROUTER_BASE_URL
logger.debug("Auxiliary client: OpenRouter via pool")
Expand All @@ -1487,7 +1490,7 @@ def _try_openrouter(explicit_api_key: str = None) -> Tuple[Optional[OpenAI], Opt

or_key = explicit_api_key or os.getenv("OPENROUTER_API_KEY")
if not or_key:
_mark_provider_unhealthy("openrouter", ttl=60)
# No key configured yet: fall through quietly so other providers may win.
return None, None
logger.debug("Auxiliary client: OpenRouter")
return OpenAI(api_key=or_key, base_url=OPENROUTER_BASE_URL,
Expand Down Expand Up @@ -1527,11 +1530,8 @@ def _try_nous(vision: bool = False) -> Tuple[Optional[OpenAI], Optional[str]]:
nous = _read_nous_auth()
runtime = _resolve_nous_runtime_api(force_refresh=False)
if runtime is None and not nous:
logger.warning(
"Auxiliary Nous client unavailable: no Nous authentication found "
"(run: hermes auth)."
)
_mark_provider_unhealthy("nous", ttl=60)
# No Nous auth/runtime configured: this is simple unavailability, not a
# health failure. Let the chain fall through without poisoning cache.
return None, None
if runtime is None and nous:
# Runtime credential mint failed but stored Nous auth is still present.
Expand Down Expand Up @@ -4123,6 +4123,7 @@ def _build_call_kwargs(
"model": model,
"messages": messages,
"timeout": timeout,
"stream": False,
}

fixed_temperature = _fixed_temperature_for_model(model, base_url)
Expand Down
41 changes: 41 additions & 0 deletions gateway/platforms/api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3115,6 +3115,47 @@ def _run_sync():
response_headers = (
{"X-Hermes-Session-Key": gateway_session_key} if gateway_session_key else {}
)
accept_header = request.headers.get("Accept", "").lower()
if body.get("stream") is True and "text/event-stream" in accept_header:
response = web.StreamResponse(
status=200,
headers={
**response_headers,
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"X-Accel-Buffering": "no",
},
)
await response.prepare(request)
try:
await response.write((
"data: "
+ json.dumps({
"event": "response.created",
"run_id": run_id,
"session_id": session_id,
"timestamp": created_at,
})
+ "\n\n"
).encode())
while True:
try:
event = await asyncio.wait_for(q.get(), timeout=30.0)
except asyncio.TimeoutError:
await response.write(b": keepalive\n\n")
continue
if event is None:
await response.write(b": stream closed\n\n")
break
payload = f"data: {json.dumps(event)}\n\n"
await response.write(payload.encode())
except Exception as exc:
logger.debug("[api_server] inline SSE stream error for run %s: %s", run_id, exc)
finally:
self._run_streams.pop(run_id, None)
self._run_streams_created.pop(run_id, None)
return response

return web.json_response(
{"run_id": run_id, "status": "started"},
status=202,
Expand Down
Loading