Skip to content

feat(agent): Responses API transport for Responses-only models - #267

Open
darylfung96 wants to merge 3 commits into
VectifyAI:mainfrom
darylfung96:feat/responses-api
Open

darylfung96 wants to merge 3 commits into
VectifyAI:mainfrom
darylfung96:feat/responses-api

Conversation

@darylfung96

@darylfung96 darylfung96 commented Sep 21, 2026

Copy link
Copy Markdown

native OpenAI Responses API transport via openai-responses/ model prefix

Problem

Some gateways serve certain models exclusively on /v1/responses and answer /v1/chat/completions with 503 Endpoint is unavailable.
OpenKB talks to LLMs only through LiteLLM Chat Completions, so those models are completely unusable — compile, query, chat, lint, and
skills all fail.

Solution

Opt-in native Responses API transport. Prefixing the model id routes every agent call through the Responses API instead:

  model: openai-responses/<model-id>                                                                                                   

The prefix is OpenKB-only (stripped before anything reaches LiteLLM). Responses are adapted back to the Chat Completions shape, so all
existing call sites work unchanged — including tool calls and run_streamed sessions.

What's changed

  • New openkb/responses.py — message/tool/response_format translation, Chat-Completions-shaped response adapter, Agents-SDK
    OpenAIResponsesModel builder (per-KB creds, env fallback for CLI)
  • agent/compiler.py — _llm_call / _llm_call_async route through litellm.responses / aresponses when prefixed (2-line branches)
  • agent/query.py, agent/linter.py, skill/creator.py, skill/evaluator.py — Agent constructors + run-config builder use the Responses
    model; Chat Completions behavior untouched
  • indexer.py — long-PDF PageIndex path fails fast with a clear error (it requires a Chat Completions model)
  • Docs — config.yaml.example + examples/configuration/ section
  • Tests — tests/test_responses.py, 13 unit tests (translation, adapter, SDK wiring; no network)

Usage

  # .openkb/config.yaml                                                                                                                
  model: openai-responses/<model-id>                                                                                                   

Credentials work as usual (LLM_API_KEY + OPENAI_API_BASE, plus litellm.extra_headers if the gateway needs routing headers).

Limitations

  • Long-PDF PageIndex indexing still requires a Chat Completions model (explicit error, not a silent 503)
  • Verified end-to-end against an OpenAI-compatible gateway (compile + tool-using query); other Responses endpoints should work but are
    untested

Testing

  • pytest tests/test_responses.py — 13 passed
  • Full suite — 1261 passed, ruff check + ruff format clean
  • Live: full add compile and query against a Responses-only model

…efix)

Some gateways serve models exclusively on /v1/responses and 503
/v1/chat/completions. A KB can now opt in with e.g.
model: openai-responses/muse-spark-1.3-contributor.

- New openkb/responses.py: message/tool/response_format translation,
  Chat-Completions-shaped adapter, Agents-SDK OpenAIResponsesModel builder
- compiler: route _llm_call/_llm_call_async through litellm.responses
- query/chat/lint/skills/decks: Agent constructors + run-config builder
  use the Responses model (creds from bundle, else env)
- indexer: clear error for long-PDF PageIndex path (needs completions)
- Docs + 12 unit tests
…through

- Trim module/function docstrings to the why; fix stale blocks claim
- Extract _translate_content shared by both message paths (also fixes
  untranslated blocks on assistant+tool_calls messages)
- _to_dict: explicit continue on failed coercion
- Top-level third-party imports (no cycle); SDK wiring test
The openai-responses/ prefix works with any model id on any
OpenAI-compatible Responses endpoint; examples now use neutral
placeholders instead of a specific model.
@darylfung96 darylfung96 changed the title Add native OpenAI Responses API transport (openai-responses/ model) feat(agent): Responses API transport for Responses-only models Sep 21, 2026
@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

Release risk — 48 / 100 · MEDIUM

into main · ff54396…c974b13 · 10 files · +629 / −9

Note

What's changing

Opt-in Responses transport for Responses-only LLM gateways. Prefix openai-responses/<model-id> and every agent call (compile, query/chat, lint, skills) uses /v1/responses instead of Chat Completions — adapted back to the existing Chat Completions shape.

Default Chat Completions path is untouched. Long-PDF PageIndex indexing fails fast if the KB model uses the prefix.

Findings

  1. MEDIUM — One new transport sits under every agent surface
    A bug in message/tool adaptation hits Compile, Query, Lint, and Skills together · responses.py:1

  2. MEDIUM — Chat Completions-only kwargs are dropped (debug-logged)
    stop, penalties, seed, logprobs, etc. have no Responses equivalent — silent behaviour change vs Completions · responses.py (_DROPPED_PARAMS)

  3. LOW — PageIndex path rejects Responses models with a clear error
    Avoids a silent 503; operators must convert PDF→Markdown or switch model · indexer.py:195

  4. CI checks are not reported on this PR branch
    Author reports 13 unit + 1261 suite locally — nothing visible on the PR checks tab · feat/responses-api

Before merge

  • Confirm CI green on this head (or paste the suite output in the PR)
  • Re-verify a tool-using query against a Responses-only gateway (author claims done — keep a note of the gateway)
  • Scan call sites that pass dropped Completions kwargs (stop / penalties) under the prefix

Release plan

Control point Opt-in model prefix — only KBs with openai-responses/ take the new path · Completions unchanged
During release watch Responses gateway 4xx/5xx and agent tool-call failures on prefixed KBs
After release confirm compile + tool-using query on one Responses-only model; PageIndex error message is actionable
Already working Completions path unchanged · 13 unit tests in test_responses.py
Not verified other Responses endpoints beyond the author's gateway · CI on this PR · streaming outside Agents SDK path

Blast radius — 7 services touched (1 new), 1 impacted

Compile agent touched (~2) · Query / Chat agent touched (~2) · Wiki linter touched (~1) · Skills touched (~4) · KB store & indexing touched (~1) · KB config touched (files only) · Responses new (+16) · HTTP API & CLI impacted · tests: +14 entities in 1 file

Service map — Compile agent, Query / Chat agent, Wiki linter, Skills, KB store & indexing, KB config, HTTP API & CLI, Responses painted

Compile agent · touched · 1 files · ~2
Query / Chat agent · touched · 1 files · ~2
  • query.py — ~build_query_agent, ~build_run_config_from_bundle
  • callers inside this service (unchanged): skill_runner.py
Wiki linter · touched · 1 files · ~1
Skills · touched · 2 files · ~4
KB store & indexing · touched · 1 files · ~1
KB config · touched · 2 files · files only
Responses · new · 1 files · +16
  • responses.py — +is_responses_model, +split_responses_model, +messages_to_responses_input, +_translate_content, +_translate_content_block, +_stringify_content, +response_format_to_text, +extract_output_text +8 more
HTTP API & CLI · impacted · 5 references into changed code
  • api.py (build_run_config_from_bundle)
  • api_helpers.py (build_query_agent)
  • api_helpers.py (build_run_config_from_bundle)
  • cli.py (build_run_config_from_bundle)
  • cli.py (index_long_document)
Deployables / files — secondary
Service Lives in Notable files
Responses transport openkb/ responses.py (new)
Compile openkb/agent/ compiler.py
Query / chat openkb/agent/ query.py
Wiki linter openkb/agent/ linter.py
Skills openkb/skill/ creator · evaluator
PageIndex openkb/ indexer.py
Docs / config repo root config.yaml.example · examples
Tests tests/ test_responses.py (new)
Score breakdown — 8 axes
Axis Reading Evidence
Path criticality Shared agent path — LLM transport under compile/query/lint/skills responses.py
Blast radius Shared across services — one transport fans out to four agents + indexer guard compiler · query · linter · skills
Reversibility Config rollback — remove openai-responses/ prefix; Completions path unchanged config.yaml.example
Change size Medium — 10 files · +629 / −9 · one new module + tests 10 files
Verification Partial — 13 unit tests + author full suite · no CI checks on PR test_responses.py
Rollout control Gated — opt-in model prefix only openai-responses/
Cohort rollout Not needed — prefix is per-KB opt-in
Observability Partial — dropped params debug-logged · no new metrics/spans called out _DROPPED_PARAMS

FireWeave · advisory · blast radius from a fixed service catalog (OpenKB): services are catalog entries, states from sem diff + resolved refs, diagram only when ≥2 services are painted

@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

🟡 Medium release risk — 47/100

🟩🟩🟩🟨🟨⬜⬜⬜⬜⬜  higher = riskier · into local · main · ff54396…c974b13
🟠 1 high · 🟡 2 medium · ✅ 2 mitigations · ⬆️ 2 upstream · ⬇️ 2 downstream

What's changing

openkb/responses.py adds an opt-in Responses-API transport (model: openai-responses/<id>) used by the compiler, query/lint/skill agents, and both REST endpoint...

No control point gates it — it only activates per-KB via a model-string prefix — and it makes no persisted writes.

Findings

  1. HIGH — extract_output_text can return blank silently
    When a Responses payload has no 'message'-type output item (refusal, unexpected shape), extract_output_text returns '' with no log, so callers treat an empty answer as a normal success. · openkb/responses.py:178 · openkb/responses.py:187

  2. MEDIUM — No control point gates the new transport
    is_responses_model is a plain string-prefix check, not a FireWeave control point, so turning off the Responses path for a misbehaving KB needs a config edit, not a flag flip. · openkb/responses.py:50 · …/agent/compiler.py:429

  3. MEDIUM — One new module now backs every agent path
    Compiler, linter, query, skill-creator, skill-evaluator, the CLI, and the REST query/chat endpoints all funnel through openkb/responses.py once a KB opts in, so one translation bug hits all of them together. · …/agent/query.py:122 · openkb/api.py:281

Before merge

  • Add a log or metric when extract_output_text returns empty text so silent blank answers aren't invisible in production. · openkb/responses.py:187
  • Confirm CI actually runs green on this head commit before merging; the fact sheet shows nothing has run yet.
Release plan — Control point: none on the changed paths · Register in FireWeave · During release: Run one internal KB on an openai-responses/ model first and
Control point none on the changed paths · Register in FireWeave
During release Run one internal KB on an openai-responses/ model first and watch its query/chat error rate and answer lengths.
After release If a gateway's /v1/responses payload shape differs from OpenAI's, extract_output_text may under-extract text silently — watch logs from ear… · openkb/responses.py:169
Already working Change is opt-in per KB model string — is_responses_model only fires for models literally prefixed openai-responses/; every existing KB keeps the untouched li… · openkb/responses.py:50 · Incompatible long-PDF combo fails fast — index_long_document raises a clear ValueError instead of silently mis-behaving when PageIndex indexing is attempted on … · openkb/indexer.py:195
Not verified Whether any production KB already sets model: openai-responses/... is not visible from the repository. · Deployment topology (single instance vs multiple replicas/processes) is not stated, so restart/redeploy behaviour for in-flight requests is unknown. · How the target gateway surfaces /v1/responses errors (4xx/5xx, malformed payloads) is untested — the new tests are pure translation logic with no network calls.

Blast radius · Services touched — OpenKB REST API, OpenKB CLI reaches it · LLM Responses Gateway, PageIndex API depends
Blast radius — services touched
  • LLM Responses Gateway — New /v1/responses call + direct OpenAI SDK client for opted-in models · openkb/responses.py:266
  • PageIndex API — Long-PDF indexing now blocked for Responses-only models · openkb/indexer.py:195
  • OpenKB REST API — query/chat endpoints route through new transport when configured · openkb/api.py:281
  • OpenKB CLI — query/chat/lint/skill/add commands route through new transport when configured · openkb/cli.py:3758
Score breakdown — 8 axes considered

Limited visibility — CI configured but nothing ran on this commit; model listed unknowns. Unscored is not safe.

Axis Reading Evidence
Path criticality Internal — Only internal LLM-transport plumbing (compiler, query/lint/skill agents, indexer) and example config/docs are touched — no auth, payment, checkout, or infra co… …/agent/compiler.py:429
Blast radius Crosses services — The diff adds a genuinely new outbound integration — a raw AsyncOpenAI client and litellm.responses call to a configurable gateway, bypassing the existing Lite… openkb/responses.py:266
Reversibility No state change — Every changed function only calls out to an LLM/gateway and reshapes data in memory; no database, file, or cache write is added. …/agent/compiler.py:429
Change size Medium — 10 files · 638 lines · 4 top-level dirs 10 files · 4 apps
Verification Partial — CI not-reported (CI exists — github-actions — nothing ran on this commit) · tests changed in this PR · 7 source files see full report
Rollout control Ungated — No FireWeave control point exists anywhere in the tree (control-points.json scan is empty) — the only branch is a plain is_responses_model string check. openkb/responses.py:50
Cohort rollout Not needed — no tier-3 path, no shared-surface blast, not a large tier-2 change no plan on base
Observability Partial — 3 of 7 changed source files emit a log or metric see full report

FireWeave · advisory, never blocks the check · claude-sonnet-5 · 4m 29s · Full report

@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

🟡 Medium release risk — 47/100

🟩🟩🟩🟨🟨⬜⬜⬜⬜⬜  higher = riskier · into local · main · ff54396…c974b13
🟠 1 high · 🟡 2 medium · 🟢 1 low · ✅ 2 mitigations · ⬆️ 1 upstream · ⬇️ 2 downstream

What's changing

Adds an opt-in native OpenAI Responses API transport (openkb/responses.py) so any model prefixed openai-responses/ bypasses LiteLLM's chat-completions call...

No FireWeave control point gates it — it's a plain model-string check reached from every CLI and API agent/LLM call site (compile, query, chat, lint, skills); ...

Findings

  1. HIGH — Responses API path has no network test coverage
    tests/test_responses.py is pure translation logic; nothing exercises litellm.responses/aresponses or the new AsyncOpenAI client against a live or recorded endpoint. · tests/test_responses.py:1 · openkb/responses.py:268

  2. MEDIUM — Unsupported params dropped at debug level only
    stop, seed, logprobs and other Chat Completions kwargs are silently discarded in build_responses_params with only a debug log, no warning surfaced. · openkb/responses.py:234 · openkb/responses.py:235

  3. MEDIUM — New direct-to-provider client bypasses LiteLLM
    build_agents_responses_model opens its own AsyncOpenAI client instead of the LiteLLM path every other model uses, so LiteLLM's own retry/logging behavior doesn't apply here. · openkb/responses.py:332 · …/agent/compiler.py:429

Before merge

  • Add a smoke test that exercises responses_completion/aresponses_completion and build_agents_responses_model against a recorded or sandboxed Responses API. · tests/test_responses.py:1
  • Confirm the _DROPPED_PARAMS list matches what real KB configs actually rely on (temperature/seed/logprobs) before enabling for any production KB. · openkb/responses.py:234
Release plan — Control point: none on the changed paths · Register in FireWeave · During release: Watch debug logs for 'dropping unsupported param' and for em
Control point none on the changed paths · Register in FireWeave
During release Watch debug logs for 'dropping unsupported param' and for empty/truncated outputs on the first KBs that set model: openai-responses/<id>. · openkb/responses.py:235 · Verify credentials/timeout/extra_headers reach the dedicated AsyncOpenAI client correctly for both bundle-backed (API) and env-fallback (CL… · openkb/responses.py:332
After release Confirm compile/query/chat/lint/skill flows are unchanged for existing (non-prefixed) model configs, since every agent builder now branches… · …/agent/compiler.py:429
Already working Change is opt-in via an explicit model prefix — is_responses_model only trips on a model string literally prefixed openai-responses/, so every existing KB config keeps… · …/agent/compiler.py:429 · PageIndex misuse fails fast with a caught error — index_long_document raises a clear ValueError before calling PageIndex for a Responses-only model, and cli.py's add-com… · openkb/indexer.py:195
Not verified Whether any current OpenKB deployment already sets model: openai-responses/<id> in production, or this ships unused until an operator opts in. · Deployment topology (single process vs multiple API replicas, restart/redeploy behavior) is not visible in this repository. · Whether CI actually ran tests/test_responses.py on the head commit — the fact sheet notes nothing has run on this commit yet.

Blast radius · Services touched — OpenKB CLI, OpenKB API reaches it · OpenAI Responses API depends
Blast radius — services touched
  • OpenAI Responses API — New direct integration: dedicated AsyncOpenAI client + litellm.responses/aresponses to /v1/responses · openkb/responses.py:268
  • OpenKB CLI — compile/query/chat/lint/skill commands pick up new transport when configured · openkb/cli.py:530
  • OpenKB API — /query /chat /lint /skill /add routes pick up new transport when configured · openkb/api.py:271
Score breakdown — 8 axes considered

Limited visibility — CI configured but nothing ran on this commit; model listed unknowns. Unscored is not safe.

Axis Reading Evidence
Path criticality Internal — Touched files are internal LLM-transport plumbing (agent builders, compiler, indexer) with no auth, money, checkout or secrets handling, and openkb/responses.p… openkb/responses.py:1
Blast radius Crosses services — openkb/responses.py adds a new external integration — a dedicated AsyncOpenAI client and litellm.responses/aresponses talking directly to the provider's /v1/re… openkb/responses.py:332
Reversibility No state change — Agree with the locked base: the change only swaps which transport function is called and adapts the response object shape back — no persisted or in-memory stat… openkb/responses.py:205
Change size Medium — 10 files · 638 lines · 4 top-level dirs 10 files · 4 apps
Verification Partial — CI not-reported (CI exists — github-actions — nothing ran on this commit) · tests changed in this PR · 7 source files see full report
Rollout control Ungated — The repository's control-point scan is empty and the new transport is switched purely by a model-string prefix check, with no controlPoints.getBooleanValue gat… openkb/responses.py:50
Cohort rollout Not needed — no tier-3 path, no shared-surface blast, not a large tier-2 change no plan on base
Observability Partial — 3 of 7 changed source files emit a log or metric see full report

FireWeave · advisory, never blocks the check · claude-sonnet-5 · 4m 42s · Full report

@kalyan-fireweave

Copy link
Copy Markdown

⏳ Release risk — analysing…

into local · main · ff54396…c974b13

FireWeave is reading this change. This comment updates in place when the score is ready.

FireWeave · advisory, never blocks the check · prompt b7

@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

🟡 Medium release risk — 41/100

🟩🟩🟩🟨🟨⬜⬜⬜⬜⬜  higher = riskier · into local · main · ff54396…c974b13
🟠 1 high · 🟡 2 medium · ✅ 2 mitigations · ⬆️ 2 upstream

What's changing

Adds a new Responses-API transport (openkb/responses.py) that compiler, linter, query and skill agents switch to when a KB sets model: openai-responses/<id>.

No state is written; the new path is opt-in via config only, not behind a FireWeave control point, and its live API call sites are untested.

Findings

  1. HIGH — No kill switch for the new transport
    is_responses_model routes compiler/linter/query/skill calls to the new code path with no FireWeave control point anywhere in the repo to disable it without a config change. · …/agent/compiler.py:429 · config.yaml.example:2

  2. MEDIUM — Live Responses API calls are untested
    tests/test_responses.py exercises build_responses_params, adapt_response and translation helpers but never calls responses_completion/aresponses_completion, so the actual litellm.responses/aresponses call sites are unve… · openkb/responses.py:264 · openkb/responses.py:270

  3. MEDIUM — Unsupported params dropped, debug-only log
    stop, seed, logprobs, frequency_penalty and others are silently discarded when routed through the Responses API, logged only at debug level so the behavior change is easy to miss in production. · openkb/responses.py:231 · openkb/responses.py:235

Before merge

  • Add a test that calls responses_completion/aresponses_completion against a mocked litellm.responses/aresponses to cover the actual call site, not just the helpers. · openkb/responses.py:264
Release plan — Control point: none on the changed paths · Register in FireWeave · During release: Have the first KB\(s\) that opt into openai-responses/<id
Control point none on the changed paths · Register in FireWeave
During release Have the first KB(s) that opt into openai-responses/<id> watch compile/query/lint/skill logs closely since there is no control point to dis… · …/agent/compiler.py:429
After release Verify streaming (Runner.run_streamed) works end to end on the OpenAIResponsesModel path for query/chat agents, since the README claims sup… · …/configuration/README.md:30
Already working Change is opt-in via explicit model prefix — is_responses_model only returns true for models literally prefixed openai-responses/, so every existing KB config keeps… · openkb/responses.py:50 · Long-PDF indexing fails fast on mismatch — index_long_document raises a clear ValueError before calling PageIndex when the KB's model is Responses-only, instead o… · openkb/indexer.py:195
Not verified Deployment topology is not mapped, so it's unknown whether the CLI, FastAPI API and any background job run as one process or several, and whether a config fix … · Whether any KB in production already uses or is likely to imminently use the openai-responses/ prefix. · Whether the actual target gateway's /v1/responses implementation matches the shapes this diff's translation code assumes (only unit-tested locally, no live or …

Blast radius · Services touched — LLM Gateway, PageIndex depends
Blast radius — services touched
  • LLM Gateway — New direct call path: litellm.responses/aresponses and a raw AsyncOpenAI client, alongside the existing LitellmModel path · openkb/responses.py:267
  • Also touches PageIndex — no change in behaviour.
Score breakdown — 8 axes considered

Limited visibility — CI configured but nothing ran on this commit; model listed unknowns. Unscored is not safe.

Axis Reading Evidence
Path criticality Internal — Changed files are internal agent/model-wiring and indexing code (compiler, linter, query, skill builders, indexer) with no auth, payment, or core-data-model ma… …/agent/compiler.py:429
Blast radius Several in one service — is_responses_model/responses_agent_model are reached from the CLI, the FastAPI routes and the skill runner — several entry points, all inside the single openkb… …/agent/query.py:122
Reversibility No state change — openkb/responses.py only translates message shapes and calls an LLM API in-memory; it holds no persisted or in-memory state and performs no writes. openkb/responses.py:264
Change size Medium — 10 files · 638 lines · 4 top-level dirs 10 files · 4 apps
Verification Partial — CI not-reported (CI exists — github-actions — nothing ran on this commit) · tests changed in this PR · 7 source files see full report
Rollout control Ungated — control-points.json shows zero control points anywhere in this tree, so the new Responses branch is switched only by editing model in config.yaml, not by any F… …/agent/compiler.py:429
Cohort rollout Not needed — no tier-3 path, no shared-surface blast, not a large tier-2 change no plan on base
Observability Partial — 3 of 7 changed source files emit a log or metric see full report

FireWeave · advisory, never blocks the check · claude-sonnet-5 · 3m 12s · Full report

@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

🟡 Medium release risk — 47/100

🟩🟩🟩🟨🟨⬜⬜⬜⬜⬜  higher = riskier · into local · main · ff54396…c974b13
🟠 1 high · 🟡 3 medium · 🟢 1 low · ✅ 1 mitigation · ⬆️ 2 upstream · ⬇️ 1 downstream

What's changing

Adds an opt-in openai-responses/<model> transport used by every agent call site — compile, query, chat, lint, skill create/eval — plus a hard-fail guard in l...

No FireWeave control point gates it; it activates purely from a model-name prefix in a KB's config.yaml, reached by both the CLI and the separate web fronten...

Findings

  1. HIGH — New transport wired into every agent call site
    responses_agent_model/is_responses_model are called from compile, query, chat, lint, skill-create and skill-eval, so a bug in the new adapter affects the whole product surface once a KB opts in. · …/agent/compiler.py:429 · …/agent/query.py:122

  2. MEDIUM — No control point on the new code path
    There is no @fireweave-controlpoint anywhere in the tree; the new transport can only be disabled by editing a KB's config.yaml, not by a runtime switch. · …/agent/compiler.py:429 · config.yaml.example:1

  3. MEDIUM — Message/tool translation only unit-tested
    messages_to_responses_input/extract_output_text are new adapter logic exercised only against hand-built fixtures, per the test file's own "no network" note — real provider response shapes are unverified. · tests/test_responses.py:1 · openkb/responses.py:66

Before merge

  • Confirm CI actually runs on this head commit — the fact sheet notes it is configured but has not run. · tests/test_responses.py:1
  • Exercise one real Responses-only gateway end-to-end (compile, a tool-calling query turn, and a truncated response) before anyone configures it. · openkb/responses.py:264
Release plan — Control point: none on the changed paths · Register in FireWeave · During release: Have the first KB\(s\) that set `model: openai-responses/
Control point none on the changed paths · Register in FireWeave
During release Have the first KB(s) that set model: openai-responses/<id> be low-traffic, and watch for TruncatedResponseError and JSON-decode failure… · …/skill/evaluator.py:238
After release Watch openkb add failure logs for the new ValueError on long-PDF indexing after any KB switches its model to a Responses-prefixed one. · openkb/indexer.py:195
Watch Watch adoption of the openai-responses/ prefix; there is no way to kill it centrally if it misbehaves. · …/agent/compiler.py:429
Already working Change is opt-in per KB — Every call site branches on is_responses_model(model); a KB whose model: is unchanged (e.g. gpt-5.4) takes the ex… · …/agent/compiler.py:429
Not verified Whether the adapter has been run against a real /v1/responses gateway anywhere — the repository only shows offline unit tests. · Deployment topology for the API/frontend (single vs multi-replica, how config.yaml changes roll out) — task states 'not mapped'. · Whether any existing KB configs already use a model string that could collide with the openai-responses/ prefix convention.

Blast radius · Services touched — OpenKB Web UI reaches it · LLM Gateway, PageIndex depends
Blast radius — services touched
  • LLM Gateway — Called via litellm.responses/AsyncOpenAI instead of Chat Completions · openkb/responses.py:267
  • PageIndex — Now hard-skipped for Responses-model KBs indexing long PDFs · openkb/indexer.py:195
  • OpenKB Web UI — Chat/query turns route through the new transport for opted-in KBs · …/api/chat.ts:349
Score breakdown — 8 axes considered

Limited visibility — CI configured but nothing ran on this commit; model listed unknowns. Unscored is not safe.

Axis Reading Evidence
Path criticality Internal — The changed files are internal LLM-transport plumbing (model-string routing, message translation) with no auth, payment, or infra markers, and the file names a… openkb/responses.py:50
Blast radius Crosses services — The changed transport-selection code is reached from a separate web frontend app (frontend/) via the API and from the CLI, both funneling through the same quer… …/api/chat.ts:349
Reversibility No state change — The new module only transforms in-memory messages and makes an outbound LLM call; no persisted or in-memory state is written anywhere in the diff. openkb/responses.py:264
Change size Medium — 10 files · 638 lines · 4 top-level dirs 10 files · 4 apps
Verification Partial — CI not-reported (CI exists — github-actions — nothing ran on this commit) · tests changed in this PR · 7 source files see full report
Rollout control Ungated — The scan found zero FireWeave control points in the repository, and the new transport is selected unconditionally by a model-string prefix check with no flag i… …/agent/compiler.py:429
Cohort rollout Not needed — no tier-3 path, no shared-surface blast, not a large tier-2 change no plan on base
Observability Partial — 3 of 7 changed source files emit a log or metric see full report

FireWeave · advisory, never blocks the check · claude-sonnet-5 · 4m 37s · Full report

@kalyan-fireweave

kalyan-fireweave commented Sep 22, 2026

Copy link
Copy Markdown

🟡 Medium release risk — 47/100

🟩🟩🟩🟨🟨⬜⬜⬜⬜⬜  higher = riskier · into local · main · ff54396…c974b13
🟡 2 medium · 🟢 1 low · ✅ 2 mitigations · ⬆️ 2 upstream · ⬇️ 2 downstream

What's changing

Adds an opt-in openai-responses/ model prefix that routes compile/query/lint/skill LLM calls through a new direct OpenAI Responses API transport instead of L...

No FireWeave control point exists anywhere in this repo, no state is persisted, and the new path is only exercised when a KB explicitly sets that model prefix.

Findings

  1. MEDIUM — New direct third-party transport, only unit-tested at the e...
    openkb/responses.py bypasses LiteLLM via a dedicated AsyncOpenAI client and litellm.responses/aresponses; only the pure translation helpers are unit-tested, not the dispatch branches that invoke it. · openkb/responses.py:24 · openkb/responses.py:332

  2. MEDIUM — Four agent model-wiring call sites untested for the new bra...
    build_query_agent, build_lint_agent, build_skill_create_agent and the three eval-set agents all gained a responses_agent_model(...) or f"litellm/{model}" branch with no test exercising the truthy side. · …/agent/query.py:122 · …/skill/creator.py:183

  3. LOW — Unsupported params silently dropped
    seed, logprobs, frequency_penalty and others are dropped with only a debug log when a Responses-only model is used, giving no user-visible signal if a caller relied on them. · openkb/responses.py:33 · openkb/responses.py:234

Before merge

  • Add a mocked test for the is_responses_model branch inside _llm_call/_llm_call_async, exercising responses_completion end-to-end. · …/agent/compiler.py:429
  • Add a test per agent builder (query/lint/skill-create/eval) covering the responses_agent_model truthy branch, not just the helper functions. · …/agent/query.py:122
  • Confirm CI actually runs on this commit — GitHub Actions is configured but has not executed for this head SHA.
Release plan — Control point: none on the changed paths · Register in FireWeave · During release: Watch for empty/truncated answers or exceptions on KBs that
Control point none on the changed paths · Register in FireWeave
During release Watch for empty/truncated answers or exceptions on KBs that opt into an openai-responses/ model, which would indicate a translation mismatc… · openkb/responses.py:216
After release Check whether any KB relies on seed/logprobs/frequency_penalty with a Responses-only model; if so, upgrade the debug log to a visible warni… · openkb/responses.py:33
Already working Feature is opt-in per KB, off by default — The new transport only activates when model: is explicitly prefixed with openai-responses/; every existing KB confi… · openkb/responses.py:50 · Long-PDF indexing fails fast before any write — index_long_document raises ValueError for Responses-only models before PageIndexClient.collection().add(...) is e… · openkb/indexer.py:195
Not verified Whether any KB in production already sets model: openai-responses/<id>, since the new path is entirely opt-in and its real-world exposure isn't visible from th… · Deployment topology (single vs. multi-replica, whether the FastAPI server and CLI run in the same process) is not shown, so behavior of the per-request AsyncOp… · Whether the frontend Settings UI currently exposes or validates the openai-responses/ prefix for end users, or whether this is config-file-only for now.

Blast radius · Services touched — OpenKB HTTP API, OpenKB Frontend reaches it · OpenAI Responses API, PageIndex depends
Blast radius — services touched
  • OpenAI Responses API — New direct call path bypassing LiteLLM chat completions · openkb/responses.py:267
  • PageIndex — Blocked early for Responses-only models before any PDF is added · openkb/indexer.py:195
  • OpenKB HTTP API — query/chat endpoints now route through the new model wiring · openkb/api.py:281
  • OpenKB Frontend — Calls the HTTP API endpoints that reach the changed model wiring · …/api/chat.ts:333
Score breakdown — 8 axes considered

Limited visibility — CI configured but nothing ran on this commit; model listed unknowns. Unscored is not safe.

Axis Reading Evidence
Path criticality Internal — All non-doc/test files touched are internal agent/indexer/config plumbing with no auth, payment, or infra marker in their names or content. …/agent/compiler.py:429
Blast radius Crosses services — The diff adds a brand-new external integration (a dedicated AsyncOpenAI client and litellm.responses/aresponses transport never used before in this codebase) a… openkb/responses.py:24
Reversibility No state change — Every changed line is request/response translation or in-memory dispatch — no file, database, or PageIndex write is added; the one new write path (PageIndex ad… openkb/responses.py:264
Change size Medium — 10 files · 638 lines · 4 top-level dirs 10 files · 4 apps
Verification Partial — CI not-reported (CI exists — github-actions — nothing ran on this commit) · tests changed in this PR · 7 source files see full report
Rollout control Ungated — FireWeave's own scan finds zero control points anywhere in this repository, and the diff reads no getBooleanValue-style call, so the new transport can only be … openkb/responses.py:50
Cohort rollout Not needed — no tier-3 path, no shared-surface blast, not a large tier-2 change no plan on base
Observability Partial — 3 of 7 changed source files emit a log or metric see full report

FireWeave · advisory, never blocks the check · claude-sonnet-5 · 3m 29s · Full report

This branch has not been deployed

No deployments
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.

2 participants