Fix: Ollama offerings resolve to the built-in OpenAI adapter, not the Ollama adapter - #296
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
pluginfor an Ollama connection is"openai-compatible"—accurate, since
@corbits/ollama-adapterwraps the built-in OpenAIadapter unmodified. But
resolveDefinitionSourcessetsInferenceSource.providerto that samepluginvalue, and thesidecar's adapter registry only recognizes a locally-served offering
under the key
"ollama"(apps/sidecar/src/config.ts). Aplugin-onlysource therefore resolved to the built-in OpenAI adapter instead of
the registered Ollama one — whose stricter
quirksschema has nonumCtxfield and rejects the offering'squirks.defaultbag outright.plugin(wire format) and the adapter-registry dispatch key aredifferent concepts that happened to collide for every provider but
Ollama. The fix keeps
pluginas"openai-compatible"and correctsonly the in-flight
InferenceSource.providera launch pins into itsrun config, in
packages/folded-runs/src/launch.ts'sdeployAtHead—the one and only place in the repo that consumes
resolveDefinitionSources's output.withOllamaAdapterKeyrewritesproviderto"ollama"for any offering whose catalog provider isactually named
"ollama"(looked up via the stock, unmodifiedlistVisibleOfferings), leaving a caller-supplied sources overrideuntouched.
No vendored file changes, and
ModelProviderPluginstays a 4-valueenum —
InferenceSource.provideris a free string, so this needednothing 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
deployAtHeadcall, so it picks up the correctedcode — 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:
Confirmed the outbound request actually carried
options.num_ctx:querying the Ollama host directly (
GET /api/ps) during the runshowed
gpt-oss:20bloaded with"context_length":131072— theexact
numCtxvalue from the offering's quirks table(
OLLAMA_MODEL_DEFAULTS["gpt-oss:20b"]), not Ollama's own muchsmaller default context window.
Test plan
bunx tsc --noEmitonpackages/folded-runsandpackages/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
Follow-ups
packages/folded-runsis slated for deletion. Agent definitions,workflow, deployment, and versioning are moving native to Interchange.
withOllamaAdapterKeylives inpackages/folded-runs/src/launch.tsbecause
deployAtHeadis the one call site today — that placement isright for now, but it must move with that cutover, not get dropped
on the way, or this bug comes back silently.
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.