Skip to content

Fix: Ollama offerings resolve to the built-in OpenAI adapter, not the Ollama adapter - #296

Merged
TheGreatAxios merged 4 commits into
mainfrom
cl-6586-ollama-adapter
Aug 22, 2026
Merged

Fix: Ollama offerings resolve to the built-in OpenAI adapter, not the Ollama adapter#296
TheGreatAxios merged 4 commits into
mainfrom
cl-6586-ollama-adapter

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

CL-6586: sending a message to an Ollama-backed agent failed with
unrecoverable inference error: openai adapter: invalid quirks: default must be removed.

The catalog plugin for an Ollama connection is "openai-compatible"
accurate, since @corbits/ollama-adapter wraps the built-in OpenAI
adapter unmodified. But resolveDefinitionSources sets
InferenceSource.provider to that same plugin value, and the
sidecar's adapter registry only recognizes a locally-served offering
under the key "ollama" (apps/sidecar/src/config.ts). A plugin-only
source therefore resolved to the built-in OpenAI adapter instead of
the registered Ollama one — whose stricter quirks schema has no
numCtx field and rejects the offering's quirks.default bag outright.

plugin (wire format) and the adapter-registry dispatch key are
different concepts that happened to collide for every provider but
Ollama. The fix keeps plugin as "openai-compatible" and corrects
only the in-flight InferenceSource.provider a launch pins into its
run config, in packages/folded-runs/src/launch.ts's deployAtHead
the one and only place in the repo that consumes
resolveDefinitionSources's output. withOllamaAdapterKey rewrites
provider to "ollama" for any offering whose catalog provider is
actually named "ollama" (looked up via the stock, unmodified
listVisibleOfferings), leaving a caller-supplied sources override
untouched.

No vendored file changes, and ModelProviderPlugin stays a 4-value
enum — InferenceSource.provider is a free string, so this needed
nothing upstream.

Also corrects credential-test.ts's doc comment, which stated the
"plugin must be openai-compatible, never the provider's own id" rule
as absolute — true for every OpenAI-compatible provider but Ollama.

Verification

Live-verified against the real stack (.worktrees/cl-e2e-main,
tenant connected to a real Ollama instance over Tailscale):

  • A pre-fix Myra instance still shows the original failure:
    This agent could not complete your request due to an unrecoverable inference error: openai adapter: invalid quirks: default must be removed.

  • After applying this fix and creating a fresh "Just start talking"
    workbench (a new deployAtHead call, so it picks up the corrected
    code — an already-deployed run's bytes are baked at deploy time and
    don't pick up a code change), Myra's own opening greeting generated
    successfully, and a follow-up message got a real reply:

    Hi Myra, please confirm you're working by replying with one short
    sentence.

    Myra: Here and ready to help.

  • Confirmed the outbound request actually carried options.num_ctx:
    querying the Ollama host directly (GET /api/ps) during the run
    showed gpt-oss:20b loaded with "context_length":131072 — the
    exact numCtx value from the offering's quirks table
    (OLLAMA_MODEL_DEFAULTS["gpt-oss:20b"]), not Ollama's own much
    smaller default context window.

Test plan

  • bunx tsc --noEmit on packages/folded-runs and
    packages/hub-client (targeted, no repo-wide check)
  • bun test packages/folded-runs/test/launch.test.ts — 27 pass,
    including a new test proving the provider-key correction and
    that a sources override is left untouched
  • Live browser verification against a real Ollama instance (above)

Follow-ups

  • packages/folded-runs is slated for deletion. Agent definitions,
    workflow, deployment, and versioning are moving native to Interchange.
    withOllamaAdapterKey lives in packages/folded-runs/src/launch.ts
    because deployAtHead is the one call site today — that placement is
    right for now, but it must move with that cutover, not get dropped
    on the way, or this bug comes back silently.
  • CL-6588:
    an agent deployed before this fix never picks it up — a launch
    renders its bytes once, and nothing re-renders them when the fix
    lands. Proven live: a pre-fix Myra instance in the same tenant still
    errors after this fix shipped, while a freshly created one works.
    Out of scope here; tracked separately.

CL-6586: an Ollama-backed offering's InferenceSource.provider was
"openai-compatible" (its accurate wire format), but the sidecar's
adapter registry only recognizes a locally-served source under the
key "ollama" — the built-in OpenAI adapter served the request instead
and rejected the offering's quirks.default bag outright.

Covers the not-yet-existing withOllamaAdapterKey correction in
deployAtHead: a catalog-resolved Ollama source should get its
provider field corrected before it's pinned into a run's config; a
caller-supplied sources override should be left untouched.
resolveDefinitionSources sets InferenceSource.provider to the
winning offering's catalog plugin — accurate as the wire format
(openai-compatible for Ollama, since @corbits/ollama-adapter wraps
createOpenAIAdapter unmodified) but wrong as the sidecar's
adapter-registry dispatch key, which recognizes a locally-served
offering only under "ollama" (apps/sidecar/src/config.ts). Left
uncorrected, an Ollama source resolved to the built-in OpenAI
adapter, whose stricter quirks schema rejects the offering's
"default" bag outright.

packages/folded-runs/src/launch.ts's deployAtHead is the one place
in workbench a catalog-resolved InferenceSource[] becomes a run's
pinned config — the only caller of resolveDefinitionSources in the
repo. withOllamaAdapterKey corrects the provider field there for any
offering whose catalog provider is actually named "ollama", leaving
plugin (and everything else) untouched. No vendored file changes and
ModelProviderPlugin stays a 4-value enum: provider is a free string,
so this needs nothing upstream.
The doc comment stated the "plugin must be openai-compatible, never
a provider's own id" rule as absolute — true for every OpenAI-
compatible provider but Ollama, whose registered custom adapter
needs the dispatch key "ollama" (CL-6586). Names the correction site
(withOllamaAdapterKey) so the next reader doesn't rediscover the
same gap.
CL-6586's withOllamaAdapterKey (deployAtHead) calls the real
listVisibleOfferings to find Ollama-backed offerings. packages/tasks
and packages/chat mock @intx/hub-api's resolveDefinitionSources but
never mocked @intx/db, so the real listVisibleOfferings ran against
their hand-rolled fakes and crashed on db.query.model.findMany, which
those fakes never implement.

Mocks @intx/db the same way packages/folded-runs/test/launch.test.ts
already does, returning no offerings — none of these fixtures resolve
against Ollama, so nothing here should ever need its provider field
corrected. The production path stays strict: a missing offering
lookup is not tolerated, only faked out in tests that don't exercise
it.

Also fixes a prettier quote-style nit in launch.test.ts.
@TheGreatAxios
TheGreatAxios merged commit b6db4fd into main Aug 22, 2026
5 checks passed
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