Skip to content

fix(ollama): preserve configured API during discovery#93729

Merged
vincentkoc merged 3 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-93710
Jun 16, 2026
Merged

fix(ollama): preserve configured API during discovery#93729
vincentkoc merged 3 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-93710

Conversation

@zhangguiping-xydt

@zhangguiping-xydt zhangguiping-xydt commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Ollama dynamic discovery and dynamic model preparation overwrote an explicit provider API like openai-completions with api: "ollama", sending requests through the native /api/chat path instead of the configured OpenAI-compatible route.
  • Solution: Keep native Ollama base URL normalization for discovery probes, but preserve the user's explicitly configured provider API and base URL on the final provider/runtime model when the API is non-native.
  • What changed: Updated the Ollama discovery merge and dynamic model conversion paths, with regression tests for catalog discovery, explicit configured models, native Ollama normalization, and prepareDynamicModel/resolveDynamicModel.
  • What did NOT change: Native Ollama discovery probing, default api: "ollama" behavior, other providers, core routing, or plugin SDK contracts.

Fixes #93710

Real behavior proof

  • Behavior addressed: Explicit models.providers.ollama.api: "openai-completions" and baseUrl: ".../v1" remain configured after Ollama discovery even though the live builder uses native api: "ollama" and a native base URL for /api/tags probing.
  • Real environment tested: macOS 26.5, Node v24.15.0, OpenClaw 2026.6.2, worktree SHA 67cb1a0
  • Exact steps or command run after this patch:
    node --import tsx --input-type=module -e 'import { resolveOllamaDiscoveryResult } from "./extensions/ollama/src/discovery-shared.ts"; const result = await resolveOllamaDiscoveryResult({ ctx: { config: { models: { providers: { ollama: { baseUrl: "http://192.168.20.14:11434/v1", api: "openai-completions", models: [] } } } }, env: { OLLAMA_API_KEY: "test-key" }, resolveProviderApiKey: () => ({ apiKey: "test-key" }) }, pluginConfig: {}, buildProvider: async () => ({ baseUrl: "http://192.168.20.14:11434", api: "ollama", models: [{ id: "qwen3-coder:cloud", name: "qwen3-coder:cloud" }] }) }); const provider = result?.provider; console.log(JSON.stringify({ configuredApi: "openai-completions", configuredBaseUrl: "http://192.168.20.14:11434/v1", discoveredBuilderApi: "ollama", discoveredBuilderBaseUrl: "http://192.168.20.14:11434", resolvedProviderApi: provider?.api, resolvedBaseUrl: provider?.baseUrl, resolvedModelIds: provider?.models?.map((model) => model.id) ?? [] }, null, 2));'
    node scripts/run-vitest.mjs extensions/ollama/provider-discovery.test.ts
    node scripts/run-vitest.mjs extensions/ollama/index.test.ts
    pnpm check:test-types
    node scripts/run-oxlint.mjs --deny=warn --ignore-path=.oxlintignore extensions/ollama/index.test.ts extensions/ollama/index.ts extensions/ollama/provider-discovery.test.ts extensions/ollama/src/discovery-shared.ts
    git diff --check
  • Evidence after fix:
    {
      "configuredApi": "openai-completions",
      "configuredBaseUrl": "http://192.168.20.14:11434/v1",
      "discoveredBuilderApi": "ollama",
      "discoveredBuilderBaseUrl": "http://192.168.20.14:11434",
      "resolvedProviderApi": "openai-completions",
      "resolvedBaseUrl": "http://192.168.20.14:11434/v1",
      "resolvedModelIds": [
        "qwen3-coder:cloud"
      ]
    }
    node scripts/run-vitest.mjs extensions/ollama/provider-discovery.test.ts
    Test Files  1 passed (1)
    Tests  18 passed (18)
    
    node scripts/run-vitest.mjs extensions/ollama/index.test.ts
    Test Files  1 passed (1)
    Tests  52 passed (52)
    
    pnpm check:test-types
    completed successfully
    
    node scripts/run-oxlint.mjs --deny=warn --ignore-path=.oxlintignore extensions/ollama/index.test.ts extensions/ollama/index.ts extensions/ollama/provider-discovery.test.ts extensions/ollama/src/discovery-shared.ts
    completed successfully
    
    git diff --check
    completed successfully
    
  • Observed result after fix: The resolved Ollama provider keeps api: "openai-completions" and baseUrl: "http://192.168.20.14:11434/v1", while native discovery still probes the normalized Ollama API base at http://192.168.20.14:11434.
  • What was not tested: Full gateway startup and a live external Ollama daemon were not used; the issue is a provider-local discovery merge regression and was verified through the real OpenClaw plugin discovery function plus focused Ollama plugin tests.

Regression Test Plan

  • Coverage level: Provider plugin regression tests
  • Target test file: extensions/ollama/provider-discovery.test.ts, extensions/ollama/index.test.ts
  • Scenario locked in: Explicit models.providers.ollama.api: "openai-completions" and baseUrl: ".../v1" are preserved through catalog discovery and prepareDynamicModel/resolveDynamicModel even when buildOllamaProvider() returns native api: "ollama" and a native base URL.
  • Why this is the smallest reliable guardrail: It covers the two Ollama-owned merge boundaries that previously replaced the explicit API/base URL without touching core routing or other providers.

Root Cause

  • Root cause: buildOllamaProvider() correctly normalizes the configured base URL for native Ollama discovery, but the catalog and dynamic-model merge paths reused that native discovery provider as the final runtime provider/model config, replacing the user's OpenAI-compatible API/base URL pair.
  • Missing detection / guardrail: Existing tests covered base URL normalization and dynamic model discovery separately, but did not assert that a user-configured OpenAI-compatible API and /v1 base URL survived discovery-backed paths.

@openclaw-barnacle openclaw-barnacle Bot added extensions: ollama size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 16, 2026
@clawsweeper

clawsweeper Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed June 16, 2026, 2:39 PM ET / 18:39 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

PR surface: Source +31, Tests +87. Total +118 across 4 files.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Review metrics: none identified.

Merge readiness
Not assessed.
Failure reason: invalid structured output.

This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict.
Keep any merge decision on the normal maintainer review path until ClawSweeper can complete a fresh review.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • Review did not complete, so no work-lane recommendation was made.
Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against 617c9d4b7fb4.

Evidence reviewed

PR surface:

Source +31, Tests +87. Total +118 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 39 8 +31
Tests 2 90 3 +87
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 129 11 +118

What I checked:

  • failure reason: invalid structured output.
  • codex failure detail: Codex review failed for this PR with exit 0 and wrote invalid JSON or schema-invalid output to /home/runner/work/clawsweeper/clawsweeper/artifacts/event/codex/93729.json: decision.rootCauseCluster.currentItemRelationship fixed_by_candidate requires a canonical PR.
  • codex stderr: No stderr captured.
  • codex stdout: a/src/discovery-shared.ts"],"confidence":"high"},{"person":"takhoffman","role":"adjacent reviewer","reason":"Adjacent Ollama cloud discovery work in commit 5f5e3b4 records approval by takhoffman and changed the same discovery-shared surface.","commits":["5f5e3b45110e38cb57ef9261eecaf9a044644a7d"],"files":["extensions/ollama/src/discovery-shared.ts","extensions/ollama/provider-discovery.test.ts"],"confidence":"medium"},{"person":"shakkernerd","role":"adjacent test contributor","reason":"Recent history includes an Ollama discovery catalog cache test isolation change in the same provider-discovery test area.","commits":["dbb62f21f4e99f6f6bcd68d5c3950be5528e3cc1"],"files":["extensions/ollama/provider-discovery.test.ts"],"confidence":"medium"}],"risks":["The PR body does not include a full gateway startup or live external Ollama daemon proof, so end-to-end routing confidence.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@vincentkoc vincentkoc self-assigned this Jun 16, 2026
@vincentkoc vincentkoc changed the title Preserve configured Ollama API during discovery fix(ollama): preserve configured API during discovery Jun 16, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Land-ready maintainer repair complete.

The branch now preserves the configured API/base URL through live Ollama discovery and selects native /api/chat streaming only for models whose resolved API is ollama; configured OpenAI-compatible models stay on the compatible transport.

Verification:

  • node scripts/run-vitest.mjs extensions/ollama/index.test.ts extensions/ollama/provider-discovery.test.ts extensions/ollama/src/stream.test.ts — 172 passed
  • focused oxfmt/oxlint + git diff --check — passed
  • fresh branch autoreview — clean
  • live patched OpenClaw catalog run against Ollama 0.30.4 with installed smollm2:135m returned:
    {"api":"openai-completions","baseUrl":"http://127.0.0.1:11434/v1","models":["smollm2:135m"]}
  • real Ollama /api/chat and /v1/chat/completions inference calls both completed with smollm2:135m
  • exact head ff36b743e7cb8cbcabf1d6d775ac8519e5300286 — all relevant checks complete

The remaining checks-node-agentic-plugin-sdk failure is unrelated: it fails src/plugin-sdk/provider-catalog-shared.test.ts native-streaming-usage assertions, outside this Ollama plugin change.

Known proof gap: full OpenClaw one-shot model-run attempts did not exit in this source-worktree environment, so the real proof is the changed live discovery path plus real native/compatible Ollama endpoints and focused route-selection coverage.

@vincentkoc
vincentkoc merged commit f0b5d78 into openclaw:main Jun 16, 2026
172 of 175 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 17, 2026
* fix(ollama): preserve configured API during discovery

* fix(ollama): keep compatible discovery base URL

* fix(ollama): route compatible APIs through configured transport

---------

Co-authored-by: Vincent Koc <[email protected]>
crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
* fix(ollama): preserve configured API during discovery

* fix(ollama): keep compatible discovery base URL

* fix(ollama): route compatible APIs through configured transport

---------

Co-authored-by: Vincent Koc <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: ollama proof: supplied External PR includes structured after-fix real behavior proof. size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ollama plugin overrides api to native protocol ignoring config api setting

2 participants