Skip to content

feat(llm): presets as data (providers.json + user override) - #395

Merged
ModerRAS merged 4 commits into
masterfrom
feat/presets-as-data
Sep 17, 2026
Merged

ModerRAS merged 4 commits into
masterfrom
feat/presets-as-data

Conversation

@ModerRAS

Copy link
Copy Markdown
Owner

Stacked on #394 (fix/opencode-multi-binding-presets) because both touch LlmProviderCatalog. GitHub will retarget the base to master once #394 merges.

Why

Presets were C# data: adding a provider meant a code change and a release, and the seeded model lists silently went stale (MiniMax still pointed at abab-era IDs while the repo's own docs listed M3/M2.7).

What

  • TelegramSearchBot.LLM/Providers/providers.json is now the built-in catalog (embedded resource with generatedAt), loaded by LlmProviderCatalogLoader.
  • Override: %LOCALAPPDATA%/TelegramSearchBot/providers.json wins when present and valid; a missing/invalid override falls back to the built-in copy and reports why (Warning) instead of breaking 预制渠道.
  • LlmProviderCatalog.Presets / GeneratedAt / Source read the loaded document; GeneralBootstrap logs the source + version at startup.
  • Default model seeds refreshed from current vendor docs:
    • Anthropic: claude-opus-5, claude-sonnet-5, claude-haiku-4-5-20251001
    • OpenAI: gpt-6-astra, gpt-5.6-sol, gpt-5.6-terra (Responses: Astra/Sol)
    • Gemini: gemini-3.8-flash, gemini-3.1-pro-preview, gemini-3.5-flash
    • MiniMax: MiniMax-M3, MiniMax-M2.7 (gateway now api.minimaxi.com/v1)
    • DeepSeek: deepseek-flash, deepseek-v4-pro
    • Moonshot: kimi-k3, kimi-k2.7-code
    • OpenCode Zen/Go keep the richer step-2 data (bindings + model rules + entitlement flag).
  • Docs: user guide documents the override file and OpenCode protocol routing.

Validation

  • dotnet build TelegramSearchBot.sln -c Release → 0 errors
  • TelegramSearchBot.LLM.Test → 299/299 (5 new loader tests: override wins, invalid override falls back with warning, empty preset list rejected, built-in resource keeps all 11 presets incl. OpenCode bindings/rules)
  • TelegramSearchBot.Test → 446 passed, 1 skipped

Notes

The presets mapped both OpenCode gateways to LLMProvider.Anthropic with a single
AnthropicMessages binding, but neither gateway is Anthropic-only:
- Go serves /responses (grok-4.6, gpt-5.6-luna) and /chat/completions
- Zen is per-model: claude-* -> messages, gpt-*/grok-* -> responses,
  gemini-* -> Google, everything else -> chat completions

- LlmProviderPreset gains optional Bindings + ModelBindingRules (prefix -> binding)
  and CatalogIsEntitlement to mark subscription gateways
- preset creation builds the extra bindings and assigns seeded models to the
  protocol matched by their name; Zen stays pay-per-token (no auto-seeded models)
- Go seeds the official model list and refreshes its catalog add-only from
  /models, assigning discovered models through the same rules
- AnthropicMessagesTransport applies x-opencode-session (per-chat when known),
  fixing Go's 400 MissingSessionID on the Anthropic-compatible path
- IEditLLMConfHelper: EnsureBinding + AssignModelBinding helpers
- Tests: LlmProviderCatalogTests, AnthropicTransportSessionTests, preset flow
Preset data lived in C# and only changed with a release; model seeds went stale
and adding a provider meant a code change.

- Providers/providers.json becomes the built-in catalog (embedded, with
  generatedAt); LlmProviderCatalogLoader overlays
  %LOCALAPPDATA%/TelegramSearchBot/providers.json when present, falling back to
  the built-in copy with a warning when the override is missing or invalid
- LlmProviderCatalog.Presets/GeneratedAt/Source now read that document
- default model lists refreshed against current vendor docs: Anthropic
  claude-opus-5/sonnet-5/haiku-4-5, OpenAI gpt-6-astra/5.6-sol/5.6-terra,
  Gemini 3.8-flash/3.1-pro-preview/3.5-flash, MiniMax M3/M2.7 (gateway
  api.minimaxi.com), DeepSeek deepseek-flash/v4-pro, Moonshot kimi-k3/k2.7-code
- GeneralBootstrap logs catalog source/version at startup
- Tests: LlmProviderCatalogLoaderTests (override wins, invalid override falls
  back with warning, empty list rejected, built-in keeps all 11 presets and the
  OpenCode bindings/rules)
- Docs: user guide documents the override file and OpenCode protocol routing
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 79092e77-c560-40f6-b317-3e90cd874d64


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.

Base automatically changed from fix/opencode-multi-binding-presets to master September 17, 2026 02:19
Multi-binding channels (OpenCode Zen/Go and anything created from the new
presets) had no admin surface: bindings could only be fixed by editing SQLite,
and 移除模型 deleted the first row matching a model name, which could remove the
wrong binding's row.

- 编辑渠道 gains option 7 (协议绑定): lists the channel bindings with
  protocol/auth/default marker, promotes a chosen binding to default
  (PromoteBinding mirrors channel Gateway/Provider) or walks through
  endpoint -> protocol -> auth to add a new binding via EnsureBinding
- 移除模型 now lists rows through GetModelRowsByChannelId (same
  'model [channel/binding/protocol]' display as 查看模型) and deletes by row id
  (RemoveModelRow), so duplicate model names across bindings cannot collide
- new LLMConf states + handlers; helper/interface additions GetBindings,
  PromoteBinding, GetModelRowsByChannelId, RemoveModelRow
- tests: preset/binding promote + add flows (state machine), promote/mirror,
  row display + row-id delete, bindings ordering; user guide updated
Resolve #395 conflicts after #393/#394 were squash-merged:
- LlmProviderCatalog / IEditLLMConfHelper / EditLLMConfHelper / EditLLMConfTest:
  keep the branch side (step 2 + step 3/4 content is the superset)
- GeneralBootstrap: keep master's startup catalog refresh (#393) and re-add the
  providers.json source log from step 3

Validated after merge: build 0 errors; LLM.Test 310/310; main tests 455 passed / 1 skipped
@github-actions

Copy link
Copy Markdown
Contributor

PR Check Report

Summary

Test Results

Platform Status Details
Ubuntu Passed Tests passed, artifacts uploaded
Windows Passed Tests passed, artifacts uploaded

Code Quality

  • Code formatting check
  • Security vulnerability scan
  • Dependency analysis
  • Code coverage collection

Test Artifacts

  • Test results artifacts count: 2
  • Code coverage uploaded to Codecov

Links


This report is auto-generated by GitHub Actions

@ModerRAS
ModerRAS merged commit fb8ea47 into master Sep 17, 2026
6 checks passed
@ModerRAS
ModerRAS deleted the feat/presets-as-data branch September 17, 2026 02:30
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