Skip to content

feat(sdk): support conversation-scoped LLM headers#4066

Open
bozhnyukAlex wants to merge 1 commit into
OpenHands:mainfrom
bozhnyukAlex:feat/run-scoped-llm-headers
Open

feat(sdk): support conversation-scoped LLM headers#4066
bozhnyukAlex wants to merge 1 commit into
OpenHands:mainfrom
bozhnyukAlex:feat/run-scoped-llm-headers

Conversation

@bozhnyukAlex

@bozhnyukAlex bozhnyukAlex commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

HUMAN:
I requested this change so one application request ID follows every LLM call made throughout an agent conversation without mutating shared LLM configuration.


AGENT:

Why

Applications embedding the SDK need to attach correlation, tracing, or routing headers to every LLM request made by one agent conversation. LLM.extra_headers is static configuration, so mutating it for a task risks leaking state when an LLM or agent is reused. Conversation-scoped headers let one request ID follow every LLM call across repeated runs of the same live conversation.

Summary

  • Add nullable, runtime-only llm_extra_headers to ConversationSettings, conversation creation, and the Agent Server start request.
  • Carry a copied, immutable header map through the existing LLMCallContext to chat and Responses API calls, including retries, condensers, sub-agents, and agent hooks.
  • Send remote headers with POST /api/conversations; the existing /run contract remains unchanged.
  • Exclude the headers from persisted conversation metadata and user-visible configuration.
  • Document the behavior in docs(sdk): document conversation-scoped LLM headers docs#617: docs(sdk): document conversation-scoped LLM headers docs#617

Issue Number

Closes #4064.

The implementation follows review feedback by using the existing ConversationSettings architecture and making the headers conversation-scoped.

How to Test

  • make lint
  • uv run pyright — 0 errors
  • Targeted SDK, Agent Server, hooks, task, and delegate tests — 584 passed
  • NO_PROXY=127.0.0.1,localhost uv run pytest -q tests/cross/test_remote_conversation_live_server.py -k remote_conversation_llm_headers_reach_every_run — 1 passed against a real FastAPI/HTTP/WebSocket Agent Server
  • make test-server-schema — generated OpenAPI schema is valid
  • Full uv run pytest -q -n auto — 8259 passed. Four environment/parallel-run failures passed when rerun in isolation; the remaining two local failures are unrelated terminal backslash timeout checks.

The live-server test runs the same remote conversation twice and verifies that both LLM calls receive the same X-Request-ID.

Video/Screenshots

Not applicable; this is an SDK and REST API change covered by an end-to-end live-server test.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The API is generic and does not contain application-specific header names. Conversation-scoped headers override same-named static LLM headers, while SDK-owned headers such as x-litellm-session-id remain authoritative. Header values are not persisted or logged by this implementation. A server restart requires the caller to supply them again when creating a new live conversation.

@bozhnyukAlex
bozhnyukAlex marked this pull request as ready for review July 10, 2026 07:39
@all-hands-bot
all-hands-bot requested a review from neubig July 11, 2026 12:34
@all-hands-bot

Copy link
Copy Markdown
Collaborator

[Automatic Post]: I have assigned @neubig as a reviewer based on git blame information. Thanks in advance for the help!

This comment was posted by an AI agent (OpenHands) on behalf of the user.

@neubig neubig left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I think this is nice functionality to have, but I'd prefer to use our existing architecture for doing this instead of introducing an architectural change, which will also make the PR simpler. Take a look at the ConversationSettings object, and you should be able to put a nullable field there.

Comment thread openhands-agent-server/openhands/agent_server/models.py Outdated
@all-hands-bot

Copy link
Copy Markdown
Collaborator

[Automatic Post]: It has been a while since there was any activity on this PR. @bozhnyukAlex, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up.

This comment was created by an AI agent (OpenHands) on behalf of the repository maintainers.

@bozhnyukAlex
bozhnyukAlex force-pushed the feat/run-scoped-llm-headers branch from 02772e5 to 1b93543 Compare July 19, 2026 21:25
@bozhnyukAlex bozhnyukAlex changed the title feat(sdk): support run-scoped LLM headers feat(sdk): support conversation-scoped LLM headers Jul 19, 2026
Co-authored-by: openhands <openhands@all-hands.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support run-scoped LLM extra headers in Conversation and Agent Server APIs

3 participants