This commit is contained in:
Etienne Chabert 2026-08-26 17:06:08 -07:00 committed by GitHub
commit 6c10572cf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 0 deletions

View file

@ -621,6 +621,23 @@ def _extract_codex_session_id_from_headers(
)
def _extract_bare_session_id_from_headers(
normalized: Mapping[str, str],
) -> str | None:
"""
Return a vendor-less ``x-session-id`` header value (e.g. opencode) when it
is a plausible session/trace identifier (same value rules as the
vendor-scoped scan).
Checked after the ``x-<vendor>-session-id`` headers so a more specific
header (e.g. opencode's ``x-parent-session-id`` on subagent calls) wins.
"""
value: Final = normalized.get("x-session-id")
if isinstance(value, str) and _SESSION_ID_VALUE_RE.match(value):
return value
return None
def get_chain_id_from_headers(headers: dict[str, str] | None) -> str | None:
"""
Extract chain id for call chaining from request headers.
@ -631,6 +648,9 @@ def get_chain_id_from_headers(headers: dict[str, str] | None) -> str | None:
3. Any ``x-<vendor>-session-id`` header whose value looks like a session id
(alphanumeric / UUID, at least 8 chars). E.g. ``x-claude-code-session-id``.
4. Codex's unprefixed ``session-id`` / ``thread-id``, for Codex callers only.
5. A vendor-less ``x-session-id`` header (e.g. opencode), with the same
value rules. Checked last so a more specific vendor-scoped header
(e.g. opencode's ``x-parent-session-id`` on subagent calls) still wins.
Header keys are matched case-insensitively so this works with raw header
dicts from any transport.
@ -646,6 +666,7 @@ def get_chain_id_from_headers(headers: dict[str, str] | None) -> str | None:
or normalized.get("x-litellm-session-id")
or _extract_generic_session_id_from_headers(normalized)
or _extract_codex_session_id_from_headers(normalized)
or _extract_bare_session_id_from_headers(normalized)
)

View file

@ -3263,6 +3263,20 @@ def test_add_litellm_metadata_from_request_headers_explicit_header_beats_generic
assert data["litellm_trace_id"] == "explicit-trace-id-value"
def test_add_litellm_metadata_from_request_headers_bare_session_id():
"""A vendor-less x-session-id header (e.g. opencode) lands on litellm_session_id."""
data = {"metadata": {}}
LiteLLMProxyRequestSetup.add_litellm_metadata_from_request_headers(
headers={"X-Session-Id": "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"},
data=data,
_metadata_variable_name="metadata",
)
assert data["litellm_session_id"] == "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
assert data["litellm_trace_id"] == "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
assert data["metadata"]["session_id"] == "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
assert data["metadata"]["trace_id"] == "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
def test_get_chain_id_from_headers_generic_vendor_session_id():
"""get_chain_id_from_headers picks up any x-<vendor>-session-id with a valid value."""
from litellm.proxy.litellm_pre_call_utils import get_chain_id_from_headers
@ -3411,6 +3425,40 @@ def test_add_litellm_metadata_groups_codex_turns_into_one_session():
assert turn["litellm_metadata"]["session_id"] == CODEX_SESSION_UUID
def test_get_chain_id_from_headers_bare_session_id():
"""get_chain_id_from_headers picks up a vendor-less x-session-id (e.g. opencode)."""
from litellm.proxy.litellm_pre_call_utils import get_chain_id_from_headers
assert (
get_chain_id_from_headers({"x-session-id": "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"})
== "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
)
assert (
get_chain_id_from_headers({"X-Session-Id": "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"})
== "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J"
)
assert get_chain_id_from_headers({"x-session-id": "short"}) is None
assert get_chain_id_from_headers({"x-session-id": "has spaces!!"}) is None
assert (
get_chain_id_from_headers(
{
"x-litellm-session-id": "explicit-id-value",
"x-session-id": "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J",
}
)
== "explicit-id-value"
)
assert (
get_chain_id_from_headers(
{
"x-session-id": "ses_01J5Z8K2M4NQRA6BCD8E9FGH0J",
"x-parent-session-id": "e96634a3-fa28-4083-b354-55542e2dca01",
}
)
== "e96634a3-fa28-4083-b354-55542e2dca01"
)
def test_trace_id_from_traceparent_valid():
from litellm.proxy.litellm_pre_call_utils import _trace_id_from_traceparent