Skip to content

feat(loop): configurable session-affinity header names - #39

Merged
zhanghanduo merged 3 commits into
mainfrom
feat/session-header-names
Sep 24, 2026
Merged

zhanghanduo merged 3 commits into
mainfrom
feat/session-header-names

Conversation

@zhanghanduo

@zhanghanduo zhanghanduo commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Why

bind_session_id hardcodes x-upstream-session-id, a header the old EAS gateway used for session affinity. llm-hub, the company proxy most of our LLM traffic goes through, pins a session to one upstream key in its account pool using its own header, X-Llmhub-Session. Without that header, each turn of a conversation can land on a different key and miss the prompt cache: the same work takes several times longer and costs several times more. AgentCore should not know about llm-hub, so the header name becomes a setting the host supplies.

What

  • bind_session_id(..., header_names=DEFAULT_SESSION_HEADER_NAMES): every name in the list gets the session id. An empty tuple sends nothing. A bare str raises TypeError, because iterating it would send one header per character.
  • AgentLoopHooks.session_header_names: sets the header names for the loop's built-in binding. Like sticky_session_enabled, it is ignored when bind_session is supplied.
  • DEFAULT_SESSION_HEADER_NAMES is exported. The default is unchanged, so this is fully backward compatible.
  • Ships in the unreleased 0.11.1 alongside fix(providers): forward default_headers to Anthropic/Bedrock clients #38 (not yet tagged or published). The version stays at 0.11.1, so this PR carries the skip-version-bump label. The change is additive: one new keyword with a default and one new hook field with a default.

Consumer follow-up

ApodexHarness passes ("x-upstream-session-id", "X-Llmhub-Session") from its _bind adapter and hook wiring.

Tests

  • Unit test: multiple header names, an empty tuple, and rejection of a bare str.
  • Loop test: a header name set on the hook reaches the provider call's extra_headers.
  • Full suite: 1576 passed. ruff, pyright, and the unconsumed-fields and version-bump checks pass locally.

🤖 Generated with Claude Code

zhanghanduo and others added 2 commits September 24, 2026 10:21
bind_session_id and AgentLoopHooks gain header_names/session_header_names so a
host can stamp its gateway's affinity header (e.g. X-Llmhub-Session) alongside
or instead of x-upstream-session-id. Default unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@zhanghanduo zhanghanduo added the skip-version-bump Change cannot affect consumers; waives the version-bump check label Sep 24, 2026
@zhanghanduo
zhanghanduo merged commit 9397501 into main Sep 24, 2026
5 checks passed
@zhanghanduo
zhanghanduo deleted the feat/session-header-names branch September 24, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-version-bump Change cannot affect consumers; waives the version-bump check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant