Skip to content

feat(llm): preserve opaque coding-agent headers - #15367

Merged
ishandhanani merged 9 commits into
ai-dynamo:mainfrom
ishandhanani:idhanani/dyn-agent-context-envelope
Sep 30, 2026
Merged

ishandhanani merged 9 commits into
ai-dynamo:mainfrom
ishandhanani:idhanani/dyn-agent-context-envelope

Conversation

@ishandhanani

@ishandhanani ishandhanani commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Live validation and Perfetto traces

Real Claude Code 2.1.285 and Codex 0.159.1 sessions exercised tool calls, subagents, manual compaction, and post-compaction requests. All 143 eligible header values across 35 successful inference requests matched the saved Dynamo envelopes exactly.

Download either JSON and open it in Perfetto. Click an outer request slice to inspect agent_context.agent_headers. Both files are also available in this gist. The persistent installation ID is redacted in the shared files.

These exports include display-only harness/compaction/window labels from a run-local formatter; those labels are not runtime normalization and are not added by this PR. Tool bars inferred by the existing converter are not measured host tool execution. Codex ran with apps and built-in web search disabled; three initial compatibility failures are excluded from the successful-request counts. This is functional validation, not a performance comparison.

The stock Perfetto converter now preserves the complete raw agent_context on request slices and actual tool events. All 11 converter self-checks pass, and a stock conversion of the saved run retains all 143 header values. Targeted pre-commit checks and Python compilation pass.

Summary

Carry coding-agent headers as opaque observations in the existing AgentContext, instead of defining cross-agent invocation or compaction semantics in Dynamo. Claude Code's gateway protocol makes header names and values open lists; new hints should not require an envelope schema change.

  • Keep existing typed session identity, lineage, terminal state, and input-trigger behavior unchanged.
  • Replace typed AgentCompaction with agent_headers, a map of lowercase wire names to ordered string arrays. Capture the open x-claude-code-* and x-codex-* families plus existing session/subagent compatibility headers. Preserve unknown values, repeated values, empty strings, percent encoding, and embedded JSON without parsing.
  • Carry the same map through preprocessing, worker serialization, and request traces. Expose it to custom policies through SessionContext.agent_headers(); share strings across in-process clones.
  • Leave parsing, normalization, and policy decisions to consumers. No default routing, affinity, or KV-cache behavior changes.
flowchart LR
    H[HTTP headers] --> A[AgentContext: typed identity + raw headers]
    A --> P[Preprocessing and worker wire]
    A --> T[Request traces]
    P --> S[Plugin SessionContext.agent_headers]
Loading

Capture requires an existing recognized session identity. Bounds are 64 values, 16 KiB per value, and 32 KiB total including names. Sensitive-marked, non-text, and over-budget values are omitted whole; unrelated authentication and protocol headers are not captured. These are untrusted observations, not a transparent HTTP relay or request-body metadata store.

Old wire readers ignore the new map; new readers tolerate the old optional compaction field. Trace consumers that used normalized compaction must now interpret native headers. Older frontends cannot provide the new map during rolling upgrades. The Rust AgentCompaction type is removed.

Validation

  • cargo test -p dynamo-llm --lib --no-default-features agent_context: 23 passed, including both wire-compatibility directions, preprocessing, and trace propagation.
  • Targeted runs passed: header capture (3), request tracing (81), HTTP context ingress (2), complete plugin projection (1), plugin metadata contract (1), and external plugin API compatibility (1). Test filters overlap.
  • cargo check -p dynamo-llm --lib --no-default-features, cargo clippy -p dynamo-llm -p dynamo-kv-router --lib --tests --no-default-features -- -D warnings, cargo fmt --all --check, and git diff --check passed.
  • Edited-doc lint: 4 files, 0 errors. Fern configuration check: 0 errors. Site-wide broken-link check reports one existing error in the unchanged deepseek-v4-pro-0813.mdx recipe.
  • cargo bench -p dynamo-kv-router --features bench --bench worker_selection -- 'custom_worker_selection/10_000' --noplot: optimized benchmark completed, 50 samples per case. Point estimates: 647.38 us without the filter, 874.61 us with the keep-all filter. Existing fixture has no session metadata; this is a selection-path smoke check, not a before/after or header-capture performance claim.
  • No live proxy test is included.

Summary by CodeRabbit

  • New Features
    • Captured agent headers are preserved as raw values and made available to custom routing policies, plugins, and request traces. Repeated values and unfamiliar or malformed content are retained; sensitive, non-text, or oversized values may be omitted.
    • Header capture does not affect request placement or cached blocks. Consumers can interpret headers as needed.
  • Documentation
    • Updated guidance on supported headers, capture limits, compatibility during rolling upgrades, and Claude Code gateway-hint forwarding.

Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot added feat external-contribution Pull request is from an external contributor labels Sep 29, 2026
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test ce5a8fd

@github-actions github-actions Bot added documentation Improvements or additions to documentation frontend `python -m dynamo.frontend` and `dynamo-run in=http|text|grpc` labels Sep 29, 2026
@ishandhanani
ishandhanani marked this pull request as ready for review September 29, 2026 05:21
@ishandhanani
ishandhanani requested review from a team as code owners September 29, 2026 05:21
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack โ†’

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. ๐ŸŽ‰

โ„น๏ธ Recent review info
โš™๏ธ Run configuration

Configuration used: Repository: ai-dynamo/dynamo/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 049b8f72-4bd3-4ceb-b0e8-44fedeb3941f

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 51b83df and ce5a8fd.

๐Ÿ“’ Files selected for processing (15)
  • docs/fern/pages/developer-guide/knowledge-base/modular-components/router/custom-worker-selection.mdx
  • docs/fern/pages/use-cases/agents/agent-harnesses.mdx
  • docs/fern/pages/use-cases/agents/agent-tracing.md
  • examples/router/custom-policy-example/README.md
  • lib/kv-router/src/scheduling/selector/policy.rs
  • lib/kv-router/src/scheduling/types.rs
  • lib/llm/src/http/service/openai.rs
  • lib/llm/src/kv_router.rs
  • lib/llm/src/preprocessor.rs
  • lib/llm/src/protocols/agents.rs
  • lib/llm/src/protocols/common/extensions.rs
  • lib/llm/src/request_trace/agent_context.rs
  • lib/llm/src/request_trace/integration.rs
  • lib/llm/src/request_trace/record.rs
  • lib/llm/src/request_trace/types.rs

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.


Walkthrough

The change replaces parsed compaction metadata with captured raw agent headers. It preserves selected header values in agent context, forwards them to worker-selection session context, and documents how plugins access and interpret them.

Changes

Agent header capture and access

Layer / File(s) Summary
Capture headers and represent them in agent context
lib/llm/src/protocols/agents.rs, lib/llm/src/protocols/common/extensions.rs, lib/llm/src/http/service/openai.rs, docs/fern/pages/use-cases/agents/agent-harnesses.mdx
The code captures selected Claude Code, Codex, session, and OpenAI headers as raw repeated values, subject to exclusions and size limits. AgentContext stores the map instead of parsed compaction metadata. Tests cover capture and serialization behavior, including legacy compaction input.
Forward headers through context and traces
lib/llm/src/preprocessor.rs, lib/llm/src/kv_router.rs, lib/llm/src/request_trace/*, docs/fern/pages/use-cases/agents/agent-tracing.md
Preprocessing and context conversion carry agent_headers through forwarding and request traces. Tests verify that raw header values are retained.
Expose headers to worker-selection plugins
lib/kv-router/src/scheduling/types.rs, lib/kv-router/src/scheduling/selector/policy.rs, docs/fern/pages/developer-guide/knowledge-base/modular-components/router/custom-worker-selection.mdx, examples/router/custom-policy-example/README.md
SessionContext stores shared headers and exposes them through agent_headers(). Tests and documentation cover access, sharing, missing values, and plugin interpretation.

Priority: โฌ‡๏ธ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: โšช Minimal ยท up to ce5a8

The header-capture change has no identified merge-blocking issue after normal checks.

๐Ÿšฅ Pre-merge checks | โœ… 3 | โŒ 1 | โ“ 1

โŒ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check โš ๏ธ Warning The description provides substantial technical context and validation results, but it does not follow the required template. It omits the Overview, Details, Where should the reviewer start?, and requiโ€ฆ Add the required template sections. Complete the Related Issues section by linking the relevant issue or checking the confirmation that no related issue exists. Add reviewer starting points and organize the summary and validation details unโ€ฆ
Docstring Coverage โ“ Inconclusive Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 10 files. (5 skipped:โ€ฆ Write docstrings for the functions missing them to satisfy the coverage threshold.
โœ… Passed checks (3 passed)
Check name Status Explanation
Linked Issues check โœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check โœ… Passed Check skipped because no linked issues were found for this pull request.
Title check โœ… Passed The title clearly and concisely describes the primary change: preserving opaque coding-agent headers.
Full details: Docstring Coverage

Explanation

Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 10 files. (5 skipped: 4 unsupported, 1 too large.)

Full details: Description check

Explanation

The description provides substantial technical context and validation results, but it does not follow the required template. It omits the Overview, Details, Where should the reviewer start?, and required Related Issues sections.

Resolution

Add the required template sections. Complete the Related Issues section by linking the relevant issue or checking the confirmation that no related issue exists. Add reviewer starting points and organize the summary and validation details under the required headings.

  • Fix all pre-merge checks with AI

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/llm/src/protocols/agents.rs Resolved
Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 29, 2026 21:14 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test 2c8ec38

Comment thread lib/kv-router/src/scheduling/types.rs Resolved
Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 29, 2026 22:53 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test dd28ded

Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 29, 2026 23:01 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test e188692

@dynamo-review-agent dynamo-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Previously reported defects still present:

  • Original discussion: The public AgentCompaction type and AgentContext::compaction field remain removed at dynamo-llm 1.6.0. Downstream users importing the type or constructing the public context with that field will still fail to compile, and legacy normalized compaction is discarded rather than forwarded.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field remain removed. Existing downstream Rust users constructing AgentContext, using its builder, or importing AgentCompaction will fail to compile, while older wire payloads silently lose normalized compaction metadata.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field remain removed from the public dynamo_llm::protocols::common::extensions API while the workspace version is still 1.6.0. Downstream users importing the type or constructing/accessing this field fail to compile, and existing callers lose the normalized value. Restore the legacy API during the compatibility window and carry agent_headers additively.

Comment thread lib/kv-router/src/scheduling/types.rs Resolved
@ishandhanani
ishandhanani enabled auto-merge (squash) September 29, 2026 23:11

@dynamo-review-agent dynamo-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Previously reported defects still present:

  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field are removed while dynamo-llm remains at version 1.6.0. Downstream users importing the type or constructing/accessing that field will fail to compile, and old normalized compaction metadata is discarded.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field are removed while the workspace remains at version 1.6.0. Downstream Rust users importing the type or constructing/accessing that field will fail to compile, and legacy wire payloads silently discard normalized compaction metadata.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field remain removed while the workspace version is 1.6.0, breaking downstream users of that public API and dropping normalized legacy compaction data.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field remain removed while dynamo-llm is version 1.6.0. Downstream Rust users importing the type or constructing/accessing that field will fail to compile, and older wire payloads discard normalized compaction metadata.

Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 29, 2026 23:18 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test 6b2c63d

@jthomson04 jthomson04 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Source-only review of 6b2c63d, including the latest documentation changes. No blocking findings. The boolean helper naming suggestion is non-blocking. Tests and CI results were not checked.

@dynamo-review-agent dynamo-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Previously reported defects still present:

  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field are removed while dynamo-llm remains at version 1.6.0. Downstream users importing the type or constructing/accessing that field will fail to compile, and legacy normalized compaction metadata is discarded.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field remain removed while the workspace version is still 1.6.0, so downstream Rust users importing the type or constructing/accessing that field will fail to compile, and legacy normalized compaction payloads are discarded.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field were removed while the workspace remains at version 1.6.0. Downstream Rust consumers importing the type or constructing/accessing that field will fail to compile, and legacy normalized compaction data is deserialized then discarded.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field are removed while dynamo-llm remains at version 1.6.0. Downstream Rust users importing, constructing, or accessing that API will fail to compile, and legacy normalized compaction data is discarded by new readers.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field remain removed while dynamo-llm is version 1.6.0, breaking downstream users of that public API and discarding normalized legacy compaction data.

Signed-off-by: Ishan Dhanani <ishandhanani@gmail.com>
@ishandhanani
ishandhanani requested a review from a team as a code owner September 30, 2026 00:43
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 30, 2026 00:43 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test 6c101c5

@dynamo-review-agent dynamo-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Previously reported defects still present:

  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field remain removed while dynamo-llm is version 1.6.0. Downstream Rust users importing, constructing, or accessing this API will fail to compile, and legacy normalized compaction payloads are accepted then discarded.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field are removed while dynamo-llm remains at version 1.6.0. Downstream Rust users importing, constructing, or accessing this API will fail to compile, and legacy normalized compaction payloads are deserialized then discarded.
  • Original discussion: Verified still present: the public AgentCompaction type and AgentContext::compaction field are removed while the workspace remains at version 1.6.0. Downstream Rust users importing, constructing, or accessing this API will fail to compile, and legacy normalized compaction payloads are deserialized then discarded.

Comment thread lib/kv-router/src/scheduling/types.rs Resolved
Comment thread lib/llm/src/protocols/agents.rs Resolved
@ishandhanani
ishandhanani temporarily deployed to external_collaborator September 30, 2026 01:53 — with GitHub Actions Inactive
@dynamo-ops

Copy link
Copy Markdown
Contributor

/ok to test 57cd701

@dynamo-review-agent dynamo-review-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Previously reported defects still present:

  • Original discussion: The SessionContext::agent_headers rustdoc still duplicates ingress capture limits and interpretation details already documented on AgentContext.agent_headers and in the agent-header documentation. It should retain only the worker-selection-specific contract: plugins receive opaque observations and the default policy does not interpret them.
  • Original discussion: Verified still present in lib/llm/src/protocols/agents.rs: the extra x-claude-code-compaction, x-claude-code-context-compacted, and x-claude-code-prompt-id examples still take the same open-family capture path already covered by the retained repeated/empty x-claude-code-future and verbatim percent-encoded header cases.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field are removed while dynamo-llm remains at version 1.6.0. Downstream Rust users importing the type or constructing/accessing the field will fail to compile, and legacy normalized compaction payloads are accepted then discarded.
  • Original discussion: Verified still present: AgentCompaction and the public AgentContext::compaction field remain removed while dynamo-llm is version 1.6.0. Downstream Rust users importing, constructing, or accessing this public API will fail to compile, and legacy normalized compaction payloads are accepted then discarded.
  • Original discussion: AgentCompaction and the public AgentContext::compaction field remain removed while dynamo-llm is version 1.6.0. Downstream code importing the type or constructing/accessing the field will fail to compile, and old wire payloads silently lose normalized compaction data.

@ishandhanani
ishandhanani merged commit 8c226c9 into ai-dynamo:main Sep 30, 2026
198 of 201 checks passed

This branch was previously deployed

1 inactive deployment
external_collaborator โ€” 57cd701b Deployed Sep 30, 2026 by ishandhanani via ok-to-test #23918
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation external-contribution Pull request is from an external contributor feat frontend `python -m dynamo.frontend` and `dynamo-run in=http|text|grpc` size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants