Skip to content

docs: add pipeline-extension recipe and x-headroom-base-url routing docs#1712

Open
Parideboy wants to merge 1 commit into
headroomlabs-ai:mainfrom
Parideboy:docs/1697-pipeline-extension-recipe
Open

docs: add pipeline-extension recipe and x-headroom-base-url routing docs#1712
Parideboy wants to merge 1 commit into
headroomlabs-ai:mainfrom
Parideboy:docs/1697-pipeline-extension-recipe

Conversation

@Parideboy

Copy link
Copy Markdown
Contributor

Description

Issue #1697 asked for two things: (1) a documented recipe for writing a request-normalization headroom.pipeline_extension for quirky upstream providers (the reporter's provider rejects OpenAI-spec content: null + tool_calls assistant messages, and they solved it with a PRE_SEND extension they could only discover by reading source), and (2) shipping the x-headroom-base-url per-request upstream override. The header support already exists on main (headroom/proxy/handlers/openai.py honors it in the dedicated chat/responses handlers and passthrough) and will ship with the next release-please release, so this PR delivers the missing piece: documentation for both.

Adds docs/content/docs/pipeline-extensions.mdx covering the entry-point contract (headroom.pipeline_extension, PipelineStage, fail-open dispatch, discover_pipeline_extensions / pipeline_extensions config), a complete copy-pasteable NullContentNormalizer recipe with pyproject.toml entry-point registration, and a section on per-request upstream routing with x-headroom-base-url (including the HEADROOM_STRIP_INTERNAL_HEADERS interaction).

Fixes #1697

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Performance improvement
  • Code refactoring (no functional changes)

Changes Made

  • New page docs/content/docs/pipeline-extensions.mdx: lifecycle-stage table, request-normalization extension recipe (class + entry-point registration + discovery/fail-open semantics), and x-headroom-base-url per-request routing section with a curl example.
  • docs/content/docs/meta.json: added pipeline-extensions to the nav after configuration.

Testing

  • Unit tests pass (pytest)
  • Linting passes (ruff check .)
  • Type checking passes (mypy headroom)
  • New tests added for new functionality
  • Manual testing performed

Test Output

$ python -c "import json; json.load(open('docs/content/docs/meta.json')); print('META_OK')"
META_OK

$ python -c "
from headroom.pipeline import ENTRY_POINT_GROUP, PipelineStage
print(ENTRY_POINT_GROUP, PipelineStage.PRE_SEND)
"
headroom.pipeline_extension PipelineStage.PRE_SEND

Real Behavior Proof

  • Environment: Windows 11, local checkout at upstream/main (9fbd47b), Python 3.13.
  • Exact command / steps: verified every documented claim against source — headroom/pipeline.py (entry-point group, PipelineStage.PRE_SEND, fail-open dispatch in PipelineExtensionManager.emit, class auto-instantiation in discover_pipeline_extensions), headroom/proxy/server.py (PipelineExtensionManager(discover=config.discover_pipeline_extensions) at proxy startup), headroom/proxy/models.py (pipeline_extensions / discover_pipeline_extensions config fields), headroom/proxy/handlers/openai.py (x-headroom-base-url constant and _resolve_openai_upstream); validated meta.json still parses.
  • Observed result: docs match the code contract on main; nav entry renders between Configuration and Filesystem Contract.
  • Not tested: full docs-site (Next.js) production build; end-to-end run of the example extension against a live quirky provider (the recipe mirrors the pattern the issue reporter confirmed working).

Review Readiness

  • I have performed a self-review
  • This PR is ready for human review

The headroom.pipeline_extension entry-point mechanism and the
x-headroom-base-url per-request upstream override both exist on main but
were undocumented — users only found them by reading source. Add a docs
page with a request-normalization recipe for quirky upstream providers
(content: null + tool_calls rejected by some OpenAI-compatible gateways)
and document per-request upstream routing via x-headroom-base-url.

Fixes headroomlabs-ai#1697

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

PR governance

This PR follows the template and is marked ready for human review.

@github-actions github-actions Bot added the status: ready for review Pull request body is complete and the author marked it ready for human review label Jul 2, 2026

@JerrettDavis JerrettDavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Docs review looks good. I checked the documented entry-point group, PipelineStage names, fail-open extension dispatch, proxy config fields, and x-headroom-base-url handling against the current source, and the new page lines up with the implemented contract. The recipe is concrete without changing runtime behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: ready for review Pull request body is complete and the author marked it ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Document/support pattern for fixing upstream provider quirks via pipeline_extension (e.g. kie.ai rejecting content: null on tool_calls)

2 participants