feat(codersdk): generate chat model provider options schema from Go structs#22568
Merged
feat(codersdk): generate chat model provider options schema from Go structs#22568
Conversation
…tructs Adds a codegen script (scripts/modeloptionsgen) that uses Go reflect to introspect the ChatModel*ProviderOptions structs in codersdk/chats.go and emits a JSON schema describing every configurable field. The frontend can import this schema to dynamically render model config forms instead of manually maintaining per-provider field definitions. Changes: - codersdk/chats.go: Add description, enum, and hidden struct tags to all provider option structs. These are the source of truth for field metadata. - scripts/modeloptionsgen/main.go: New Go script that reflects on codersdk structs and outputs JSON with field name, type, description, enum values, input_type hint, and hidden flag. - site/src/api/chatModelOptionsGenerated.json: Generated schema covering 6 general fields and all provider-specific fields across 6 providers. - site/src/api/chatModelOptions.ts: Typed TS module with utility functions (getVisibleProviderFields, resolveProvider, toFormFieldKey, etc.). - Makefile: Wire into make gen so the schema regenerates when chats.go or the generator script changes.
- Vercel reasoning effort: add 'none' and 'xhigh' (valid per Fantasy) - OpenAI strict_json_schema: mark hidden - Anthropic send_reasoning: keep visible - Google stray threshold field: mark hidden - OpenRouter/Vercel logit_bias, log_probs, top_logprobs, extra_body: mark hidden
OpenAI's API supports these values even though Fantasy's consts don't include them yet.
johnstcn
approved these changes
Mar 3, 2026
Member
johnstcn
left a comment
There was a problem hiding this comment.
I'm fine with this impl, but don't forget about https://github.com/coder/guts
modeloptionsgen
Outdated
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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
Adds
make genscript that generates a JSON schema from Go structs for chat model provider configuration fields, eliminating manual frontend duplication.Problem
The frontend manually defines ~75 fields across 6 providers. Adding a new field requires editing multiple files, and the frontend can't track backend changes to field names, types, enums, or descriptions.
Solution
Go struct tags are now the source of truth:
description:"..."— field labelenum:"val1,val2,..."— valid options for select fieldshidden:"true"— exclude from UI forms (infrastructure fields only)The
scripts/modeloptionsgen/main.goscript uses reflection to introspectChatModel*ProviderOptionsstructs, reads these tags, infers input types, flattens nested structs with dot notation, and outputs JSON schema.Changes
codersdk/chats.goscripts/modeloptionsgen/main.gosite/src/api/chatModelOptionsGenerated.jsonsite/src/api/chatModelOptions.tsMakefilemake genGenerated Schema
Visible fields by provider
max_output_tokens,temperature,top_p,top_k,presence_penalty,frequency_penaltymax_tool_calls,parallel_tool_calls,reasoning_effort,reasoning_summary,max_completion_tokens,text_verbosity,service_tier,audiosend_reasoning,thinking.budget_tokens,effort,disable_parallel_tool_usethinking_config.thinking_budget,thinking_config.include_thoughtsreasoning_effortreasoning.effort,reasoning.budget_tokens,parallel_tool_calls,transforms,modelsreasoning.effort,reasoning.budget_tokens,reasoning.content,parallel_tool_calls,headers22 infrastructure fields marked
hidden:"true"(e.g.,logit_bias,metadata,safety_settings,provider,extra_body)Schema structure
{ "general": {"fields": [...]}, "providers": { "openai": {"fields": [...]}, "anthropic": {"fields": [...]}, // ... }, "provider_aliases": {"azure": "openai", "bedrock": "anthropic"} }Each field includes:
json_name,go_name— API and Go identifierstype—"string","integer","number","boolean","array","object"description— human-readable labelrequired— alwaysfalse(all fields optional in DB configs)enum— valid values for select fields (6 fields total)input_type—"select","input", or"json"(UI widget hint)hidden—truefor infrastructure-only fieldsNext Steps
Frontend work to consume this schema and replace manual field definitions will come in a follow-up PR. This PR establishes the codegen pipeline and schema format.