Skip to content

fix(ollama): route models by advertised capability - #11088

Merged
diegosouzapw merged 2880 commits into
diegosouzapw:mainfrom
yourspraveen:fix/ollama-local-model-capabilities
Aug 23, 2026
Merged

fix(ollama): route models by advertised capability#11088
diegosouzapw merged 2880 commits into
diegosouzapw:mainfrom
yourspraveen:fix/ollama-local-model-capabilities

Conversation

@yourspraveen

@yourspraveen yourspraveen commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #11087

Summary

  • enrich Ollama model discovery with bounded /api/show capability probes
  • persist image, embedding, chat, vision, tools, and thinking metadata per connection
  • route local image and embedding requests only through connections advertising the requested model and endpoint
  • preserve existing SSRF guard and proxy behavior for discovery requests

Validation

  • node --import tsx/esm --test tests/unit/ollama-local-capabilities-routing.test.ts
  • focused related route tests (15 passed)
  • npm run typecheck:core
  • npm run lint (0 errors; 6 pre-existing warnings)
  • npm run test:vitest (34 files, 291 tests passed)
  • npm run check:cycles
  • npm run check:any-budget:t11
  • npm run check:tracked-artifacts

The regression test uses placeholder loopback hosts and generated connection IDs; no internal hostnames or connection UUIDs are published.

CI status

⚠️ base-red inherited — the base tip (main @ c68cda7) is already red on the
Lint job. Run 32542442026
on the unmodified base fails check:file-size with:

  • open-sse/services/accountFallback.ts: 1968 > congelado 1966
  • tests/unit/account-fallback-service.test.ts: 1570 > congelado 1563

Neither file is touched by this PR. Per the release-green policy these are
mid-cycle ratchet drift, rebaselined at release — not a contributor concern.

The one file-size violation this PR did introduce
(src/app/api/providers/[id]/models/route.ts: 2269 > congelado 2250) is fixed
in 6d66499 by extracting the /api/show probe wiring into
discovery/helpers.ts::enrichOllamaLocalModels(); the route file is back to its
frozen 2249 lines with no behavior change.

The Build job failure is environmental, not a code defect: fork PRs are
deliberately excluded from the self-hosted omni-release runner by the
runs-on guard in ci.yml, so this run fell back to ubuntu-latest, where the
Turbopack production build was killed after 20 min (The operation was canceled.). The same commit's base built fine in 40 min on the 32-core
self-hosted runner. See the OMNIROUTE_USE_TURBOPACK=0 note in
scripts/build/build-next-isolated.mjs re: memory-constrained machines.

The Unit Tests (2/8) failure is a CI flake, not a defect. The shard reports
3530 passed / 1 failed, and the single failure is in
tests/unit/build/should-promote-latest-5301.test.ts — a release-script test
untouched by this PR:

✖ a pre-release VERSION never promotes latest (5.640152ms)
  Error: spawnSync bash EPIPE
    spawnargs: [ 'scripts/ci/should-promote-latest.sh', '3.8.40-rc.1' ],
    status: 0,
    stdout: 'false\n',

status: 0 with stdout: 'false\n' shows the script ran to completion and
returned the correct answer (a pre-release must not promote latest);
execFileSync raised EPIPE on the closed pipe regardless. Nothing in this
PR touches scripts/ci/ or tests/unit/build/.

Ollama version requirements

/api/show has existed since early Ollama, but the capabilities array it
returns is version-gated. Discovery degrades safely on older servers — the Zod
schema marks capabilities optional, a non-2xx/throwing probe yields null,
and applyOllamaShowCapabilities returns the model unenriched — so old servers
get exactly the pre-PR behavior, never an error.

Capability First Ollama release
completion, embedding, vision, tools, insert v0.6.4 (2025-04-02)
thinking v0.9.0 (2025-05-29)
image v0.14.0 (2026-01-10)

So the embeddings half of this fix needs Ollama ≥ 0.6.4 and the image half needs
≥ 0.14.0; below those the routing simply falls through to the previous path.

tiangao88 and others added 30 commits August 20, 2026 18:04
) (diegosouzapw#10363)

Obrigado — feature real e bem verificada: POST /v1/images/edits rejeitava o provider built-in openrouter mesmo ele suportando edição por imagem de referência via sua Image API unificada. Traduz a imagem de entrada para o formato input_references documentado do OpenRouter e despacha para /api/v1/images, removendo o prefixo do provider do model id antes de encaminhar.

Nota: o contribuidor não conseguiu rodar o teste localmente (better-sqlite3 ausente no ambiente dele) — rodei aqui.

Validação (worktree própria a partir de origin/release/v3.8.50, merge limpo, 0 conflitos):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- tests/unit/10197-openrouter-image-edits-route.test.ts — 3/3 passando (forward bem-sucedido, credenciais ausentes 401, rate-limit)
Merged — clean extraction from diegosouzapw#10358's genuinely new content (see PR body for the rationale: an unrelated .planning/codebase/ scaffolding dump was dropped). typecheck/file-size/changelog/provider-consistency gates clean, 18/18 tests passing.
…iegosouzapw#10900)

Merged — reimplementation extracting the non-conflicting Recent Requests panel + excludeTests allowlist fix from diegosouzapw#8450 (see PR body for the full scoping rationale, including why the topology UX rework was deliberately excluded — it contradicts the already-shipped diegosouzapw#8428). typecheck/file-size/changelog/complexity/cognitive-complexity/i18n-coverage gates all clean, 2/2 unit + 1/1 vitest passing.
…pw#10904)

Merged — extraction of the one still-uncovered fix from diegosouzapw#8634 (the other two items — mode "search"→CONCISE downgrade, pplx-opus generation — were already applied on this release tip). typecheck/file-size/changelog/complexity/cognitive-complexity gates all clean, 32/32 tests passing.
…dispatcher-timeout-10214

fix(network): bound direct-path response-start timeout and retry on fresh socket (diegosouzapw#10214)
Obrigado — bug real: GET /v1/files aceitava limit negativo sem validação (`-5 || 20` avalia truthy em -5, então Math.min(-5, 10000) = -5 passava direto). Agora valida integer/positivo/tamanho e retorna 400 estruturado para valores inválidos, preservando o default 20 e o máximo 10.000.

Validação (worktree combinado a partir de origin/release/v3.8.50, 0 conflitos):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- tests/integration/files-api-limit-validation.test.ts — 5/5 passando
- tests/integration/files-api.test.ts — 12/12 passando (sem regressão)
- tests/unit/batch_api.test.ts teve 1 falha, confirmada DRIFT pré-existente idêntica no tip puro do release (não relacionada, timing de cancelamento de batch)
…eToGeminiRequest (diegosouzapw#10658)

Obrigado — bug real: a tradução direta claudeToGeminiRequest emitia mensagens consecutivas do mesmo role em contents[], o que a API do Gemini rejeita com HTTP 400 (turnos alternados user/model são obrigatórios). Traz claudeToGeminiRequest à paridade com openaiToGeminiRequest reutilizando mergeConsecutiveSameRoleContents.

Validação (worktree combinado a partir de origin/release/v3.8.50, merge limpo, 0 conflitos):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- tests/unit/claude-to-gemini-consecutive-roles.test.ts — 7/7 passando
- tests/unit/claude-to-gemini-budget-tokens-zero-6813.test.ts — 2/2 passando (sem regressão)
…ols (diegosouzapw#10668)

Obrigado — PR muito bem documentado e verificado. Adiciona o gateway TabiToken (Anthropic-first, /v1/messages, x-api-key) e estende hcnsec de 1 para 4 protocolos (Chat, Responses, Anthropic Messages, Gemini). AlternateFormat ganha o hook urlBuilder opcional (necessário para o path model-scoped do Gemini), compartilhado com o provider gemini nativo em vez de duplicado.

Reconciliado nesta sessão contra o release tip atualizado (base drift real: 343→345 canônicos entre quando o PR foi criado e o merge, mais os PRs diegosouzapw#10673/diegosouzapw#10658 mergeados nesse meio-tempo). Conflitos em contagens de providers (docs, file-size baseline, teste de partição) resolvidos additivamente.

Validação (reconciliação a partir de origin/release/v3.8.50):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- npm run check:provider-consistency — OK (266 REGISTRY entries, 346 providers canônicos, 0 exceções)
- 40/40 testes passando (newapi-gateway-providers, hcnsec-provider, providers-constants-split, alternate-formats)
…ngEfforts (diegosouzapw#10788)

glm-5.1, glm-5.2, deepseek-v4-pro and deepseek-v4-flash declared supportsReasoning:true but no supportedThinkingEfforts, so the catalog's appendSyncedEffortVariants() pass (which only synthesizes -low/-high/-max ids from an already-populated capabilities.effort_tiers) never exposed a selectable effort tier for them, unlike gpt-oss:20b/120b. Add the documented low/medium/high/max vocabulary (see supportsMaxEffortForProvider's isOllamaCloud comment in reasoningEffort.ts).
…00 (diegosouzapw#10849)

v1SearchSchema.provider was a hard-coded z.enum that rejected any id outside
its list before the route's own resolveSearchProvider() check ever ran,
so unknown/short-alias provider ids (grok, brave, serper, ...) always
surfaced a generic "Invalid request" instead of the informative
"Unknown search provider: <id>" message. Relax the schema to a free-form
string and let resolveSearchProvider() own runtime validation (as it
already did for ids that passed the enum). Also extend
SEARCH_PROVIDER_ALIASES with short-form aliases mirroring the existing
jina/jina-ai pattern (brave, serper, perplexity, exa, tavily, google-pse,
linkup, ollama, searchapi, youcom, searxng, zai, duckduckgo), and surface
the first Zod validation issue's field name instead of the generic
message for other still-invalid fields (e.g. search_type).
…apshot (diegosouzapw#10156)

Live SSE frames for a phase:"commentary" message were already dropped
per diegosouzapw#6199, but the terminal response.completed.response.output array was
forwarded verbatim whenever the upstream echoed the same item back
non-empty, since backfillResponsesCompletedOutput only fills an empty
array. Reuse the existing isResponsesCommentaryMessageItem predicate to
filter the terminal snapshot's output array (and, defensively, the
backfill buffer it can be seeded from) so both representations agree.

Regression test added to tests/unit/responses-commentary-passthrough-6199.test.ts
reproducing the exact upstream shape from the issue.
…igravity-multiaccount-quota

fix(domain): treat unreported Antigravity quota fraction as unknown, not exhausted (diegosouzapw#10095)
…ponses-commentary-sse

fix(sse): strip commentary items from Responses response.completed snapshot (diegosouzapw#10156)
…yground-endpoint-selector

fix: route Playground ChatTab Send to the selected endpoint (diegosouzapw#10592)
…bo-log-error-body

fix: log upstream error body in COMBO per-target failure warnings (diegosouzapw#10597)
…-unconditional-stats

fix: skip expensive RTK compression stats computation on no-op runs (diegosouzapw#10765)
…ncode-effort-tiers

fix(open-sse): declare Ollama Cloud reasoning models' supportedThinkingEfforts (diegosouzapw#10788)
…o-oauth-dedup

fix(db): disambiguate Kiro OAuth dedup by profileArn (diegosouzapw#10815)
…ge-scan-cookie-bridge

fix(config): exclude cookie-auth image bridges from unprefixed model scan (diegosouzapw#10848)
…rch-provider-400

fix(api): POST /v1/search names unknown providers instead of opaque 400 (diegosouzapw#10849)
…ta-alias-lookup

fix(sse): canonicalize alias provider ids before quota fetcher lookup (diegosouzapw#10877)
…iegosouzapw#10650)

Obrigado — bug real: MUSIC_PROVIDERS.minimax declara format "minimax-music" e seus modelos são publicados pelo catálogo, mas handleMusicGeneration nunca teve um branch para esse format — todo request minimax/* caía no guard final com "Unsupported music format", modelos anunciados mas inalcançáveis. Handler completo cobrindo os dois output formats (url/hex), envelope base_resp, endpoint regional, e guarda local de credencial ausente.

Validação (worktree própria a partir de origin/release/v3.8.50, merge limpo, 0 conflitos):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- tests/unit/minimax-music-generation.test.ts — 9/9 passando
…fjs (diegosouzapw#10610)

Implements diegosouzapw#10536: upgrade @atjsh/llmlingua-2 2.0.3 → 2.0.5 and drop @tensorflow/tfjs from the LLMLingua SLM optional stack.

Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 20 files):
- 48/48 focused llmlingua/colocate/docker unit tests pass (author-reported, reproduced).
- check-file-size, check-changelog-integrity: OK.
- grep confirms no remaining source imports of @tensorflow/tfjs.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.

Co-authored-by: jonlwheat2-gif <jonlwheat2-gif@users.noreply.github.com>
SCys and others added 19 commits August 23, 2026 07:01
…as resolver (diegosouzapw#11107)

Validated on the combined batch board over tip 8a42aee: static gates clean (changelog, file-size 159 frozen, complexity 2621<=2774, cognitive 1181<=1223, dead-code 408<=416), typecheck:core clean, 107 focused tests green.

Combo precedence preserved when a requested name matches an existing combo or combo/* prefix, and hidden/disabled models are skipped during alias resolution (wildcard + mapped). model-alias-seed-fallback green. Related to diegosouzapw#10124. Thank you @SCys!
…configured (diegosouzapw#11097)

Validated on the combined batch board over tip 8a42aee: static gates clean (changelog, file-size 159 frozen, complexity 2621<=2774, cognitive 1181<=1223, dead-code 408<=416), typecheck:core clean, 107 focused tests green.

Zero-credential /v1/search now actually reaches the fallback-only providers (duckduckgo-free/searxng) instead of erroring before the last-resort block could run — the dead-code path is live. Also carries a one-line suppressHydrationWarning on the logo. Thank you @Egorich-print!
Validated on the combined batch board over tip 0b41259: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.

Comment-only correction verified against the vendor page wording: DeepSeek peak windows are Monday-Friday (35h/week), prices unchanged. Thank you @xyzs996 — precise sourcing, both language footnotes reconciled!
…apw#11166)

Validated on the combined batch board over tip 0b41259: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.

Prime Agent joins the CLI agents catalog with runtime entry + doc counts synced (35 tools; CLI-TOOLS.md row). cli-catalog-acpspawnable 26/26. Thank you @arminanton!
…le input limit (diegosouzapw#11179)

Validated on the combined batch board over tip 0b41259: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.

max_context_window now wins over the pricing-tier context_window in Codex catalog parsing — context-aware fallback stops demoting codex behind smaller targets. Live evidence (390K served past 272K) plus the live-shape regression test. Thank you @excessivechaos!
…214]) (diegosouzapw#11209)

Validated on the combined batch board over tip 0b41259: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.

GLM-family upstreams reject message arrays with no user turn (400 [1214], verified live 2026-08-23); the synthetic user turn keeps Claude Code sessions on opencode-go alive. Thank you @linhdmn!
diegosouzapw#11214)

Validated on the combined batch board over tip 0b41259: static gates clean (changelog, file-size 160 frozen, complexity 2628<=2774, cognitive 1187<=1223, dead-code 408<=416, docs-counts green at 351 providers, provider-consistency 268/351/0), typecheck:core clean, 430+ focused tests green across 5 groups.

muse-spark's all-reasoning empty-answer payloads (41 failures in 2h captured live) now floor the output budget so the model can actually emit content — no more empty-content 502 churn. Thank you @linhdmn!
…souzapw#11159)

Validated on the combined batch board over tip 0b41259: static gates clean, typecheck:core clean, 430+ focused tests green across 5 groups.

postbuild's esbuild spawn now resolves cross-platform (no more ENOENT after a successful Next compile on Windows). build-tool-runner-win-shim suite green. Thank you @aliyosufi — first contribution, welcome!
Validated on the combined batch board over tip 0b41259: static gates clean, typecheck:core clean, 430+ focused tests green across 5 groups.

--tray returns after readiness and survives terminal close, with tray-mode autostart on macOS/Windows/Linux while headless Linux keeps the systemd user service. tray-detached + autostart suites green. Closes diegosouzapw#11229. Thank you @tuandinh0801!
…gosouzapw#11225) (diegosouzapw#11231)

Validated on the combined batch board: gates clean, typecheck clean, focused tests green.

Exactly one Market id rewritten at the createTask seam (google-imagen/nano-banana-2 → nano-banana-2); every other namespaced id forwards byte-identical — the contract is stated and tested precisely. Fixes diegosouzapw#11225. Thank you @xiaoyaner0201!
…entic replay (diegosouzapw#10959) (diegosouzapw#11178)

Merged after conflict resolution onto the post-diegosouzapw#10961 tip (verified no clobber of today's plaintext-wins work — the resolver functions were appended and the chatCore call-site swapped; a first --theirs attempt was caught reverting diegosouzapw#10961 and redone hunk-by-hunk). resolveIncompatibleReasoningAction now defaults single-target incompatible reasoning to drop while combos keep their explicit strategy, with the x-omniroute-reasoning-fallback header override. 21/21 reasoning suites green, typecheck clean. Fixes diegosouzapw#10959. Thank you @adevwithpurpose!
Merged after conflict resolution (validated on the combined batch board + this branch): stale drift files (package.json/package-lock/.gitignore) kept at tip; the two modals merged additively — AWS SigV4 fields coexist with the chatgpt-web-codex tunnel fields and the diegosouzapw#11156 Enter-handler mirror (vitest 2/2 re-run). file-size gate green with the dated AddApiKeyModal 1173 entry (owner-authorized). aws-polly modal + provider-validation-specialty 127/127. Base was mistakenly main; retargeted to release/v3.8.50. Credentials stay in the protected field; nothing logged. Thank you @rafacpti23!
Merged after conflict resolution (validated on the combined batch board + this branch): component integrated with diegosouzapw#10489's health-race semantics (stale-check invalidation, 3-state badge, correct useCallback deps — your validation gate and tutorial are preserved on top); the two pre-gate tests updated to validate-search-before-enable (contract propagation, commented); the docs/superpowers planning files were dropped — project rule keeps planning artifacts out of docs/ (they live in the private _tasks/ repo). Base was mistakenly main; retargeted. qdrant-config-card 7/7 + qdrant-routes integration 18/18. Thank you @rafacpti23 — the pre-enable real-search gate closes a real misconfiguration footgun!
…ovider + sign-in) (diegosouzapw#11205)

Merged after conflict resolution: the 5 conflicting test files were the base-red drains that diegosouzapw#11201 already landed on the tip — kept the tip versions; the feature content is untouched. Validated on the combined batch board + this branch: codex-app-server + codex-gpt56-catalog 25/25, typecheck:core clean, docs-counts green (351 providers), provider-consistency 268/351/0. The opt-in codex-app-server transport (JSON-RPC-over-WS, turn/completed-awaited close, Responses SSE bridge) leaves the default codex path untouched. Thank you @arminanton — a 3.4k-line transport with the docs wave and tests to match!
@diegosouzapw
diegosouzapw merged commit 65e8115 into diegosouzapw:main Aug 23, 2026
8 of 10 checks passed
yourspraveen pushed a commit to yourspraveen/OmniRoute that referenced this pull request Aug 23, 2026
…oviders

diegosouzapw#11088 removed filterChatSelectableModels from importManagedModels for EVERY
provider, but the compensating read-time filter (resolveLocalSyncedEndpointRoute)
is gated on isSelfHostedChatProvider. So non-local providers lost the filter with
nothing replacing it: an OpenAI sync now persists gpt-image-2, sora-2-pro and any
model declaring /v1/images/generations straight into chat selections.

Reproduced on main (which carries diegosouzapw#11088) as well as on this branch, and NOT on
the pristine release tip — so it is a defect in the merged change, not in the
port. Verified by tests/unit/managed-model-import.test.ts, which asserts both
result.discoveredModels and the persisted getSyncedAvailableModels("openai").

Self-hosted providers keep the new behaviour — non-chat models still persist and
are filtered at read time — so diegosouzapw#11087's goal is untouched: the Ollama capability
suite stays 3/3.

Also registers the third getProviderCredentials site diegosouzapw#11088 added in
embeddings/service.ts with the hard-lease inventory ledger (2 -> 3). The site
resolves through getProviderCredentials with the connection allowlist from
resolveLocalSyncedEndpointRoute and handles allRateLimited, so it is fenced like
the two existing sites; the ledger simply had not been told.
diegosouzapw pushed a commit that referenced this pull request Aug 23, 2026
…11088 to the release line (#11271)

Validated on the combined 8-PR board: ollama-local-capabilities-routing 3/3, managed-model-import 9/9 (including the integration with the carried Gemini-3.5-Flash cleanup from #11259), 88/88 across the board's focused suites, typecheck:core + dashboard-typecheck clean, gates within baseline. This brings #11088 to the release line — it had squash-merged to main by base error (mine) — AND fixes the two defects the port caught: the global filter drop that leaked image/video models into OpenAI chat selections (now scoped to self-hosted providers) and the unregistered hard-lease credential site. Exemplary port discipline: byte-identical carry + the corrections in a separate reviewable commit + the superpowers docs deliberately left out. main still needs the same two-line fix. Thank you @yourspraveen!
diegosouzapw pushed a commit that referenced this pull request Aug 24, 2026
…k the release PR

The living release PR #8875 was CONFLICTING, which makes GitHub skip EVERY
pull_request workflow silently (no ci.yml, no semgrep, no DAST). Back-merging
main restores a computable merge ref.

Strategy `-s ours`: main is a stale snapshot of the release line (PR #11088 was
merged into main from a release-tip base, dragging ~5094 files). All 7 main-only
commits were verified as already represented on this branch:

- #11088 ollama capability routing  -> ported here as #11271 (6d4c484)
- #11075 shared passthrough providers -> ported here as #11165 (92ef3c7)
- #10055 getModelsDevPricing memoization -> present (modelsDevSync.ts)
- #10026 hide health-check excluded models -> present and extended (catalog.ts)
- /_tasks anchored gitignore hardening -> present (.gitignore:288)
- nanoid/dompurify Dependabot bumps -> identical versions

main-only files intentionally NOT carried over:

- changelog.d/fixes/10286-gemini-3-5-flash-thinking.md + its regression test:
  the fix landed here as #10450 and was then deliberately superseded by
  2764812 "eliminate Gemini 3.5 Flash". The test fails on this branch by
  design.
- public/providers/hackclub.svg: provider removed here (migration 162).
- docs/superpowers/**/2026-08-23-qdrant-*: planning artifacts belong in _tasks/
  (AGENTS.md), never under docs/.
diegosouzapw added a commit that referenced this pull request Aug 28, 2026
…nc-back step 2/2

The eighteen commits main carries beyond the cycle branch, and what each one
became here:

  already in release/v3.8.51 by its own PR (no-op, verified by content):
    b090b60 / 026e1ca  deps: nanoid 3.3.18 equal, dompurify 3.4.14 newer
    918fba5  .gitignore: /_tasks already anchored
    5f0a394  #10026 hide health-check-excluded models — same helper, 5 call sites
    c68cda7  #11075 shared passthrough providers — superseded by #11071/#11078
  superseded, one piece kept:
    ca23eed  #10055 memoize models.dev pricing — the cycle memoizes on the
                catalog cache version already; only the resetDbInstance() hook is
                ported, wired to that memo
  applied as-is:
    8778ea7  stamp dist/BUILD_SHA before the npm provenance gate (#11721)
    aa52351  decouple the Bun image from the release manifest (#11724)
    925feb2  let the bun digest artifact be absent (#11740)
    b65ef33  size the install-upgrade gate to a measured run
    0ce2123  #11845 converge install/upgrade schemas (migration renumbered in
                the next commit: 163 collides with 163_radar_feed_cache_generated_at)
    b7c07ed  #11855 install-upgrade gate on disk, not tmpfs
    8e2fb04  #11864 drop *.nft.json from the npm tarball (413)
    dea6bb8  #11877 publish npm from a hosted runner (provenance 422)
  handled by the sync script that follows (CHANGELOG protocol):
    b4ec780  Release v3.8.50 — squash of content this branch already carries
    5458026 / c44c0a2  CHANGELOG aggregation, stats and top-25
  applied separately (its own commit, ten files):
    65e8115  #11088 Ollama capability routing — a 5,094-file squash from a
                stale base; only the Ollama files are the change

Every cherry-pick that touched a file this branch had also changed was
resolved by hand and re-run through the tests both sides own for it.
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.