refactor(gateway/platforms): api_server — shared _session_headers builder, tuple unpacks in session chat handlers

This commit is contained in:
Teknium
2026-09-02 23:02:05 -07:00
parent 7035c2c82c
commit 46bd3e9031
+26 -25
View File
@@ -367,9 +367,7 @@ def _project_client_message(message: Dict[str, Any]) -> Dict[str, Any]:
_COMPACTION_INTERNAL_FIELDS, project_compaction_message_for_display)
projected = project_compaction_message_for_display(message)
if projected is None:
projected = message.copy()
for internal_key in _COMPACTION_INTERNAL_FIELDS:
projected.pop(internal_key, None)
projected = {k: v for k, v in message.items() if k not in _COMPACTION_INTERNAL_FIELDS}
projected["content"] = ""
projected["display_kind"] = "hidden"
return projected
@@ -1601,8 +1599,9 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
logger.warning(
"X-Hermes-Session-Key rejected: no API key configured. "
"Set API_SERVER_KEY to enable long-term memory scoping.")
return None, _error_response("X-Hermes-Session-Key requires API key authentication. "
"Configure API_SERVER_KEY to enable this feature.", 403)
return None, _error_response(
"X-Hermes-Session-Key requires API key authentication. "
"Configure API_SERVER_KEY to enable this feature.", 403)
# Control characters could enable header injection on the echo path.
if re.search(r'[\r\n\x00]', raw):
return None, _invalid_request("Invalid session key")
@@ -2658,9 +2657,9 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
"actual_cost_usd", "api_call_count", "parent_session_id", "last_active", "preview",
"_lineage_root_id", "pinned", "archived", "hidden")
payload = {key: session.get(key) for key in safe_keys if key in session}
for flag in ("pinned", "archived", "hidden"): # SQLite stores 0/1
if flag in payload:
payload[flag] = bool(payload[flag])
# SQLite stores the flags as 0/1.
payload.update(
{f: bool(payload[f]) for f in ("pinned", "archived", "hidden") if f in payload})
# Full system prompts / model_config never cross the client API; only their presence.
payload["has_system_prompt"] = bool(session.get("system_prompt"))
payload["has_model_config"] = bool(session.get("model_config"))
@@ -2882,8 +2881,7 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
return err
db = await self._ensure_session_db_async()
resolved_id = await asyncio.to_thread(db.resolve_resume_session_id, session_id)
raw_limit = request.query.get("limit")
raw_offset = request.query.get("offset", "0")
raw_limit, raw_offset = request.query.get("limit"), request.query.get("offset", "0")
order = request.query.get("order")
if order not in (None, "oldest", "latest"):
return _error_response("order must be one of: oldest, latest", 400, code="invalid_pagination")
@@ -3008,6 +3006,14 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
"user_message": user_message, "runtime_request": runtime_request,
"lock_active": lock_active, "run_kwargs": run_kwargs}, None
@staticmethod
def _session_headers(session_id: str, gateway_session_key: Optional[str]) -> Dict[str, str]:
"""``X-Hermes-Session-Id`` (+ ``X-Hermes-Session-Key`` when declared) response headers."""
headers = {"X-Hermes-Session-Id": session_id}
if gateway_session_key:
headers["X-Hermes-Session-Key"] = gateway_session_key
return headers
def _effective_turn_runtime(self, runtime_request: Dict[str, Any], result: Any, usage: Any) -> Dict[str, Any]:
"""Sanitized runtime metadata for a finished session-chat turn."""
runtime = self._result_runtime(result, usage)
@@ -3040,11 +3046,11 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
session_id = ctx["session_id"]
history = await self._conversation_history_for_session(session_id)
result, usage = await self._run_agent(conversation_history=history, **ctx["run_kwargs"])
effective_session_id = result.get("session_id") if isinstance(result, dict) else session_id
final_response = _resolve_media_to_data_urls(result.get("final_response", "") if isinstance(result, dict) else "")
headers = {"X-Hermes-Session-Id": effective_session_id or session_id}
if gateway_session_key:
headers["X-Hermes-Session-Key"] = gateway_session_key
is_dict = isinstance(result, dict)
effective_session_id = result.get("session_id") if is_dict else session_id
final_response = _resolve_media_to_data_urls(
result.get("final_response", "") if is_dict else "")
headers = self._session_headers(effective_session_id or session_id, gateway_session_key)
return web.json_response(
{"object": "hermes.session.chat.completion",
"session_id": effective_session_id or session_id,
@@ -3058,10 +3064,8 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
ctx, err = await self._prepare_session_chat(request)
if err is not None:
return err
gateway_session_key = ctx["gateway_session_key"]
session_id = ctx["session_id"]
user_message = ctx["user_message"]
runtime_request = ctx["runtime_request"]
gateway_session_key, session_id = ctx["gateway_session_key"], ctx["session_id"]
user_message, runtime_request = ctx["user_message"], ctx["runtime_request"]
runtime_meta = self._sanitize_runtime_metadata(
requested_runtime=runtime_request.get("requested"),
route_source=runtime_request.get("route_source") or "global",
@@ -3069,8 +3073,7 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
message_id = f"msg_{uuid.uuid4().hex}"
run_id = f"run_{uuid.uuid4().hex}"
events = _SessionEventQueue(session_id, run_id)
queue = events.queue
_event_payload = events.payload
queue, _event_payload = events.queue, events.payload
# Claim ownership inside the request's profile scope before any run-keyed state
# exists, so /v1/runs/{id}* control is confined to the starting profile.
self._run_owners[run_id] = self._run_idempotency_scope(request)
@@ -3139,10 +3142,8 @@ class APIServerAdapter(OpenAICompatRoutesMixin, BasePlatformAdapter):
task = asyncio.create_task(_run_and_signal())
self._track_background_task(task)
headers = {
"Content-Type": "text/event-stream", "Cache-Control": "no-cache",
"X-Accel-Buffering": "no", "X-Hermes-Session-Id": session_id}
if gateway_session_key:
headers["X-Hermes-Session-Key"] = gateway_session_key
"Content-Type": "text/event-stream", "Cache-Control": "no-cache", "X-Accel-Buffering": "no",
**self._session_headers(session_id, gateway_session_key)}
response = web.StreamResponse(status=200, headers=headers)
await response.prepare(request)
try: