Skip to content

Migrate tagging CLI from Gemini to OpenRouter with structured output#207

Merged
PatrikBak merged 1 commit into
mainfrom
patrik/tagging-openrouter-migration
Jun 18, 2026
Merged

Migrate tagging CLI from Gemini to OpenRouter with structured output#207
PatrikBak merged 1 commit into
mainfrom
patrik/tagging-openrouter-migration

Conversation

@PatrikBak

Copy link
Copy Markdown
Owner

Moves the draft-tagging CLI off the bespoke Gemini HTTP client and onto OpenRouter (an OpenAI-compatible aggregator) through Microsoft.Extensions.AI. The backend model is now a one-line appsettings.json change.

What changed

  • OpenRouter via IChatClientProgram.cs builds an OpenAI.Chat.ChatClient pointed at OpenRouter and exposes it as IChatClient; OpenRouterSettings holds base URL + model (appsettings) and the API key (user secrets). The old GeminiService/IGeminiService/AddGemini/AiModelConfig are deleted.
  • Schema-bound structured output — both passes return a flat list shape bound via GetResponseAsync<T>(useJsonSchemaResponseFormat: true), retiring the hand-rolled markdown-fence parser (TaggingHelpers) and its parse-failure modes. System message carries the constant instructions + candidate vocabulary (cacheable); the problem rides in the user message.
  • English tagging — runs on the English body (translations come from stronger models than the source-language originals). Prompts and approved-tags.json descriptions are de-Slovaked and sharpened so the Area is judged from mathematical content, not surface keywords (e.g. integers alone ≠ Number Theory; a grid is just a container).
  • Reasoning effort — opt-in ReasoningEffort patched into the request body via RawRepresentationFactory; defaults to medium (the sweet spot from an effort sweep).
  • --retag — redoes a whole folder, stripping and rewriting each sidecar's tags block (with a strip-then-append round-trip covered by tests).
  • Run ergonomics — per-pass timing, a round-cost line read off the key's OpenRouter spend, a thread-safe timestamped CliLog, and a short retry around the occasional OpenRouter routing hiccup.

Notes

  • Internal tooling only — no user-facing change, no news.
  • dotnet format / jb inspectcode clean; full suite (257 tests) green.

🤖 Generated with Claude Code

The tagging CLI now reaches its model through OpenRouter (an
OpenAI-compatible aggregator) via Microsoft.Extensions.AI, so the backend
model is a one-line config change. Responses are schema-bound structured
output, which retires the hand-rolled JSON-fence parser and makes parse
failures during an unattended batch essentially impossible.

Tagging now runs on the English body — translations come from stronger
models than the source-language originals — so the prompts and tag
vocabulary descriptions are de-Slovaked and sharpened so the Area is
judged from mathematical content, not surface keywords.

Adds opt-in reasoning effort (default medium, the sweet spot from an
effort sweep), a --retag flag to redo a whole folder, per-pass timing and
round-cost logging off the key's spend, a thread-safe CliLog, and a short
retry around the occasional OpenRouter routing hiccup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
math-comps Ready Ready Preview, Comment Jun 18, 2026 3:09am

@PatrikBak PatrikBak enabled auto-merge June 18, 2026 03:08
@PatrikBak PatrikBak merged commit 84036b5 into main Jun 18, 2026
5 checks passed
@PatrikBak PatrikBak deleted the patrik/tagging-openrouter-migration branch June 18, 2026 03:11
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