Skip to content

One provider resolver for LLM calls, a record of what each call sends, and no OpenAI key sent to OpenRouter - #28

Merged
bdb-dd merged 1 commit into
mainfrom
public/llm-provider-resolver
Oct 2, 2026
Merged

bdb-dd merged 1 commit into
mainfrom
public/llm-provider-resolver

Conversation

@bdb-dd

@bdb-dd bdb-dd commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Summary

The provider switch (services.azure-openai.use-azure-openai-api) was read at four routing sites, and about thirty call
sites each spelled out the same Azure-or-not branch. This PR makes digdir.llm.provider the only reader of that switch. It
also adds the instrumentation and the tests that show the behaviour is unchanged, and closes a key leak to OpenRouter.

This is the first of two PRs on LLM provider selection; the second reads services.llm.*.

What changes

  • Pins of today's behaviour (tests only):

    • where each provider selector sends a call;
    • every code read of the provider switch;
    • resolved step parameters;
    • the boot-required environment.

    Later changes flip exactly the pins they name.

  • A record of what each LLM call sends. The graph runner records which layer set each step parameter. Each call
    records:

    • its branch and endpoint host;
    • whether a key was present and where it came from (never its value);
    • the model and sampling parameters, as passed and as sent.

    The record is reported to an enclosing sink only. Nothing is added to returned results, which reach MCP clients.

  • No OpenAI-compatible key is sent to openrouter.ai. Both OpenRouter paths used to fall back to OPENAI_API_KEY when
    services.openrouter.api-key was unset. They now refuse for an unset or blank key, naming the path.

  • services.openrouter.model is registered, so the :openrouter search-phrases arm resolves instead of throwing.

  • services.llm.provider, services.llm.api-endpoint and services.llm.api-key are defined.

    • Nothing reads them yet.
    • The environment rows stay on the environment until their reader lands, so verification and the runtime never
      disagree.
  • digdir.llm.provider:

    • one read of the switch, where unset means not Azure, decided once;
    • resolve, for the complete call spec;
    • model-for, for a site that picks its model in one place and calls in another.

    Every call site passes the spec to the client unchanged.

  • A test-only capture compares the resolved parameters of every LLM-calling entry point across a configuration
    matrix. A later change that alters behaviour has to declare it. The capture lives in
    server/test/fixtures/provider-capture/.

Effect on Digdir #13 (Langfuse tracing)

Digdir #13 read the run's configured model through cfg/use-azure-openai?, which this PR removes. It now uses
provider/model-for: the same value, the provider's default model for the tenant, without a second read of the switch.

Testing

  • bb test on this commit: 2520 tests, 11344 assertions, 0 failures. There are 8 errors, all in tests that need a network service the test environment does not provide (Net.java), and they are the same 8 as on the base branch.
  • bb lint: 0 errors, 0 warnings.

…, and no OpenAI key sent to OpenRouter

The provider switch was read at four routing sites, and about thirty call
sites each spelled out the same Azure-or-not branch. This change makes
digdir.llm.provider the only reader, and records enough to show that
behaviour is unchanged before and after.

- Tests pin today's provider selectors, the reads of the provider switch,
  step parameters and the boot-required environment, so each later change
  flips exactly the pins it names.
- The graph runner records which layer set each step parameter, and each
  LLM call records what it sent: branch, endpoint host, whether a key was
  present and where it came from (never its value), and the model and
  sampling parameters as passed and as sent. The record is reported to an
  enclosing sink only; nothing is added to returned results, which reach
  MCP clients.
- The OpenAI-compatible key is never sent to openrouter.ai. Both OpenRouter
  paths used to fall back to OPENAI_API_KEY when
  services.openrouter.api-key was unset; they now refuse, naming the path,
  for an unset or blank key.
- services.openrouter.model is registered, so the :openrouter
  search-phrases arm resolves instead of throwing.
- services.llm.provider, services.llm.api-endpoint and services.llm.api-key
  are defined. Nothing reads them yet; the environment rows stay on the
  environment until their reader lands, so verification and the runtime
  never disagree.
- digdir.llm.provider: one read of the switch (unset means not Azure,
  decided once), resolve for the complete call spec, and model-for for a
  site that picks its model in one place and calls in another. Every call
  site passes the spec to the client unchanged.
- Langfuse tracing (Digdir #13) resolves the configured model through
  provider/model-for: the same value, without a second read of the switch.
- A test-only capture compares the resolved parameters of every
  LLM-calling entry point across a configuration matrix, so a later change
  that alters behaviour has to declare it. A second census needle covers
  services.llm.provider.
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 5ddfb1c7-3ead-4ba9-956c-1ae3f6a76a2d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@bdb-dd
bdb-dd merged commit c592f18 into main Oct 2, 2026
8 checks passed
@bdb-dd
bdb-dd deleted the public/llm-provider-resolver branch October 2, 2026 12:35
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.

1 participant