feat(codersdk): generate chat model provider options schema from Go structs (#22568)
This commit is contained in:
@@ -427,6 +427,7 @@ SITE_GEN_FILES := \
|
||||
site/src/api/typesGenerated.ts \
|
||||
site/src/api/rbacresourcesGenerated.ts \
|
||||
site/src/api/countriesGenerated.ts \
|
||||
site/src/api/chatModelOptionsGenerated.json \
|
||||
site/src/theme/icons.json
|
||||
|
||||
site/out/index.html: \
|
||||
@@ -721,6 +722,7 @@ gen/mark-fresh:
|
||||
coderd/rbac/scopes_constants_gen.go \
|
||||
site/src/api/rbacresourcesGenerated.ts \
|
||||
site/src/api/countriesGenerated.ts \
|
||||
site/src/api/chatModelOptionsGenerated.json \
|
||||
docs/admin/integrations/prometheus.md \
|
||||
docs/reference/cli/index.md \
|
||||
docs/admin/security/audit-logs.md \
|
||||
@@ -917,6 +919,10 @@ site/src/api/countriesGenerated.ts: site/node_modules/.installed scripts/typegen
|
||||
./scripts/biome_format.sh src/api/countriesGenerated.ts
|
||||
touch "$@"
|
||||
|
||||
site/src/api/chatModelOptionsGenerated.json: scripts/modeloptionsgen/main.go codersdk/chats.go
|
||||
go run ./scripts/modeloptionsgen/main.go | tail -n +2 > "$@"
|
||||
cd site && pnpm biome format --write src/api/chatModelOptionsGenerated.json
|
||||
|
||||
scripts/metricsdocgen/generated_metrics: $(GO_SRC_FILES)
|
||||
go run ./scripts/metricsdocgen/scanner > $@
|
||||
|
||||
|
||||
+76
-76
@@ -246,134 +246,134 @@ type ChatModelProviderOptions struct {
|
||||
|
||||
// ChatModelOpenAIProviderOptions configures OpenAI provider behavior.
|
||||
type ChatModelOpenAIProviderOptions struct {
|
||||
Include []string `json:"include,omitempty"`
|
||||
Instructions *string `json:"instructions,omitempty"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty"`
|
||||
LogProbs *bool `json:"log_probs,omitempty"`
|
||||
TopLogProbs *int64 `json:"top_log_probs,omitempty"`
|
||||
MaxToolCalls *int64 `json:"max_tool_calls,omitempty"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
|
||||
User *string `json:"user,omitempty"`
|
||||
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
|
||||
ReasoningSummary *string `json:"reasoning_summary,omitempty"`
|
||||
MaxCompletionTokens *int64 `json:"max_completion_tokens,omitempty"`
|
||||
TextVerbosity *string `json:"text_verbosity,omitempty"`
|
||||
Prediction map[string]any `json:"prediction,omitempty"`
|
||||
Store *bool `json:"store,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
PromptCacheKey *string `json:"prompt_cache_key,omitempty"`
|
||||
SafetyIdentifier *string `json:"safety_identifier,omitempty"`
|
||||
ServiceTier *string `json:"service_tier,omitempty"`
|
||||
StructuredOutputs *bool `json:"structured_outputs,omitempty"`
|
||||
StrictJSONSchema *bool `json:"strict_json_schema,omitempty"`
|
||||
Include []string `json:"include,omitempty" description:"Model names to include in discovery" hidden:"true"`
|
||||
Instructions *string `json:"instructions,omitempty" description:"System-level instructions prepended to the conversation" hidden:"true"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty" description:"Token IDs mapped to bias values from -100 to 100" hidden:"true"`
|
||||
LogProbs *bool `json:"log_probs,omitempty" description:"Whether to return log probabilities of output tokens" hidden:"true"`
|
||||
TopLogProbs *int64 `json:"top_log_probs,omitempty" description:"Number of most likely tokens to return log probabilities for" hidden:"true"`
|
||||
MaxToolCalls *int64 `json:"max_tool_calls,omitempty" description:"Maximum number of tool calls per response"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty" description:"Whether the model may make multiple tool calls in parallel"`
|
||||
User *string `json:"user,omitempty" description:"Unique identifier for the end user for abuse monitoring" hidden:"true"`
|
||||
ReasoningEffort *string `json:"reasoning_effort,omitempty" description:"Controls the level of reasoning effort" enum:"none,minimal,low,medium,high,xhigh"`
|
||||
ReasoningSummary *string `json:"reasoning_summary,omitempty" description:"Controls whether reasoning tokens are summarized in the response"`
|
||||
MaxCompletionTokens *int64 `json:"max_completion_tokens,omitempty" description:"Upper bound on tokens the model may generate"`
|
||||
TextVerbosity *string `json:"text_verbosity,omitempty" description:"Controls the verbosity of the text response" enum:"low,medium,high"`
|
||||
Prediction map[string]any `json:"prediction,omitempty" description:"Predicted output content to speed up responses" hidden:"true"`
|
||||
Store *bool `json:"store,omitempty" description:"Whether to store the output for model distillation or evals" hidden:"true"`
|
||||
Metadata map[string]any `json:"metadata,omitempty" description:"Arbitrary metadata to attach to the request" hidden:"true"`
|
||||
PromptCacheKey *string `json:"prompt_cache_key,omitempty" description:"Key for enabling cross-request prompt caching" hidden:"true"`
|
||||
SafetyIdentifier *string `json:"safety_identifier,omitempty" description:"Developer-specific safety identifier for the request" hidden:"true"`
|
||||
ServiceTier *string `json:"service_tier,omitempty" description:"Latency tier to use for processing the request"`
|
||||
StructuredOutputs *bool `json:"structured_outputs,omitempty" description:"Whether to enable structured JSON output mode" hidden:"true"`
|
||||
StrictJSONSchema *bool `json:"strict_json_schema,omitempty" description:"Whether to enforce strict adherence to the JSON schema" hidden:"true"`
|
||||
}
|
||||
|
||||
// ChatModelAnthropicThinkingOptions configures Anthropic thinking budget.
|
||||
type ChatModelAnthropicThinkingOptions struct {
|
||||
BudgetTokens *int64 `json:"budget_tokens,omitempty"`
|
||||
BudgetTokens *int64 `json:"budget_tokens,omitempty" description:"Maximum number of tokens the model may use for thinking"`
|
||||
}
|
||||
|
||||
// ChatModelAnthropicProviderOptions configures Anthropic provider behavior.
|
||||
type ChatModelAnthropicProviderOptions struct {
|
||||
SendReasoning *bool `json:"send_reasoning,omitempty"`
|
||||
Thinking *ChatModelAnthropicThinkingOptions `json:"thinking,omitempty"`
|
||||
Effort *string `json:"effort,omitempty"`
|
||||
DisableParallelToolUse *bool `json:"disable_parallel_tool_use,omitempty"`
|
||||
SendReasoning *bool `json:"send_reasoning,omitempty" description:"Whether to include reasoning content in the response"`
|
||||
Thinking *ChatModelAnthropicThinkingOptions `json:"thinking,omitempty" description:"Configuration for extended thinking"`
|
||||
Effort *string `json:"effort,omitempty" description:"Controls the level of reasoning effort" enum:"low,medium,high,max"`
|
||||
DisableParallelToolUse *bool `json:"disable_parallel_tool_use,omitempty" description:"Whether to disable parallel tool execution"`
|
||||
}
|
||||
|
||||
// ChatModelGoogleThinkingConfig configures Google thinking behavior.
|
||||
type ChatModelGoogleThinkingConfig struct {
|
||||
ThinkingBudget *int64 `json:"thinking_budget,omitempty"`
|
||||
IncludeThoughts *bool `json:"include_thoughts,omitempty"`
|
||||
ThinkingBudget *int64 `json:"thinking_budget,omitempty" description:"Maximum number of tokens the model may use for thinking"`
|
||||
IncludeThoughts *bool `json:"include_thoughts,omitempty" description:"Whether to include thinking content in the response"`
|
||||
}
|
||||
|
||||
// ChatModelGoogleSafetySetting configures Google safety filtering.
|
||||
type ChatModelGoogleSafetySetting struct {
|
||||
Category string `json:"category,omitempty"`
|
||||
Threshold string `json:"threshold,omitempty"`
|
||||
Category string `json:"category,omitempty" description:"The harm category to configure"`
|
||||
Threshold string `json:"threshold,omitempty" description:"The blocking threshold for the harm category"`
|
||||
}
|
||||
|
||||
// ChatModelGoogleProviderOptions configures Google provider behavior.
|
||||
type ChatModelGoogleProviderOptions struct {
|
||||
ThinkingConfig *ChatModelGoogleThinkingConfig `json:"thinking_config,omitempty"`
|
||||
CachedContent string `json:"cached_content,omitempty"`
|
||||
SafetySettings []ChatModelGoogleSafetySetting `json:"safety_settings,omitempty"`
|
||||
Threshold string `json:"threshold,omitempty"`
|
||||
ThinkingConfig *ChatModelGoogleThinkingConfig `json:"thinking_config,omitempty" description:"Configuration for extended thinking"`
|
||||
CachedContent string `json:"cached_content,omitempty" description:"Resource name of a cached content object" hidden:"true"`
|
||||
SafetySettings []ChatModelGoogleSafetySetting `json:"safety_settings,omitempty" description:"Safety filtering settings for harmful content categories" hidden:"true"`
|
||||
Threshold string `json:"threshold,omitempty" hidden:"true"`
|
||||
}
|
||||
|
||||
// ChatModelOpenAICompatProviderOptions configures OpenAI-compatible behavior.
|
||||
type ChatModelOpenAICompatProviderOptions struct {
|
||||
User *string `json:"user,omitempty"`
|
||||
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
|
||||
User *string `json:"user,omitempty" description:"Unique identifier for the end user for abuse monitoring" hidden:"true"`
|
||||
ReasoningEffort *string `json:"reasoning_effort,omitempty" description:"Controls the level of reasoning effort" enum:"none,minimal,low,medium,high,xhigh"`
|
||||
}
|
||||
|
||||
// ChatModelOpenRouterReasoningOptions configures OpenRouter reasoning behavior.
|
||||
type ChatModelOpenRouterReasoningOptions struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
Exclude *bool `json:"exclude,omitempty"`
|
||||
MaxTokens *int64 `json:"max_tokens,omitempty"`
|
||||
Effort *string `json:"effort,omitempty"`
|
||||
Enabled *bool `json:"enabled,omitempty" description:"Whether reasoning is enabled"`
|
||||
Exclude *bool `json:"exclude,omitempty" description:"Whether to exclude reasoning content from the response"`
|
||||
MaxTokens *int64 `json:"max_tokens,omitempty" description:"Maximum number of tokens for reasoning output"`
|
||||
Effort *string `json:"effort,omitempty" description:"Controls the level of reasoning effort" enum:"low,medium,high"`
|
||||
}
|
||||
|
||||
// ChatModelOpenRouterProvider configures OpenRouter routing preferences.
|
||||
type ChatModelOpenRouterProvider struct {
|
||||
Order []string `json:"order,omitempty"`
|
||||
AllowFallbacks *bool `json:"allow_fallbacks,omitempty"`
|
||||
RequireParameters *bool `json:"require_parameters,omitempty"`
|
||||
DataCollection *string `json:"data_collection,omitempty"`
|
||||
Only []string `json:"only,omitempty"`
|
||||
Ignore []string `json:"ignore,omitempty"`
|
||||
Quantizations []string `json:"quantizations,omitempty"`
|
||||
Sort *string `json:"sort,omitempty"`
|
||||
Order []string `json:"order,omitempty" description:"Ordered list of preferred provider names"`
|
||||
AllowFallbacks *bool `json:"allow_fallbacks,omitempty" description:"Whether to allow fallback to other providers"`
|
||||
RequireParameters *bool `json:"require_parameters,omitempty" description:"Whether to require all parameters to be supported by the provider"`
|
||||
DataCollection *string `json:"data_collection,omitempty" description:"Data collection policy preference"`
|
||||
Only []string `json:"only,omitempty" description:"Restrict to only these provider names"`
|
||||
Ignore []string `json:"ignore,omitempty" description:"Provider names to exclude from routing"`
|
||||
Quantizations []string `json:"quantizations,omitempty" description:"Allowed model quantization levels"`
|
||||
Sort *string `json:"sort,omitempty" description:"Sort order for provider selection"`
|
||||
}
|
||||
|
||||
// ChatModelOpenRouterProviderOptions configures OpenRouter provider behavior.
|
||||
type ChatModelOpenRouterProviderOptions struct {
|
||||
Reasoning *ChatModelOpenRouterReasoningOptions `json:"reasoning,omitempty"`
|
||||
ExtraBody map[string]any `json:"extra_body,omitempty"`
|
||||
IncludeUsage *bool `json:"include_usage,omitempty"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty"`
|
||||
LogProbs *bool `json:"log_probs,omitempty"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
|
||||
User *string `json:"user,omitempty"`
|
||||
Provider *ChatModelOpenRouterProvider `json:"provider,omitempty"`
|
||||
Reasoning *ChatModelOpenRouterReasoningOptions `json:"reasoning,omitempty" description:"Configuration for reasoning behavior"`
|
||||
ExtraBody map[string]any `json:"extra_body,omitempty" description:"Additional fields to include in the request body" hidden:"true"`
|
||||
IncludeUsage *bool `json:"include_usage,omitempty" description:"Whether to include token usage information in the response" hidden:"true"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty" description:"Token IDs mapped to bias values from -100 to 100" hidden:"true"`
|
||||
LogProbs *bool `json:"log_probs,omitempty" description:"Whether to return log probabilities of output tokens" hidden:"true"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty" description:"Whether the model may make multiple tool calls in parallel"`
|
||||
User *string `json:"user,omitempty" description:"Unique identifier for the end user for abuse monitoring" hidden:"true"`
|
||||
Provider *ChatModelOpenRouterProvider `json:"provider,omitempty" description:"Routing preferences for provider selection" hidden:"true"`
|
||||
}
|
||||
|
||||
// ChatModelVercelReasoningOptions configures Vercel reasoning behavior.
|
||||
type ChatModelVercelReasoningOptions struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
MaxTokens *int64 `json:"max_tokens,omitempty"`
|
||||
Effort *string `json:"effort,omitempty"`
|
||||
Exclude *bool `json:"exclude,omitempty"`
|
||||
Enabled *bool `json:"enabled,omitempty" description:"Whether reasoning is enabled"`
|
||||
MaxTokens *int64 `json:"max_tokens,omitempty" description:"Maximum number of tokens for reasoning output"`
|
||||
Effort *string `json:"effort,omitempty" description:"Controls the level of reasoning effort" enum:"none,minimal,low,medium,high,xhigh"`
|
||||
Exclude *bool `json:"exclude,omitempty" description:"Whether to exclude reasoning content from the response"`
|
||||
}
|
||||
|
||||
// ChatModelVercelGatewayProviderOptions configures Vercel routing behavior.
|
||||
type ChatModelVercelGatewayProviderOptions struct {
|
||||
Order []string `json:"order,omitempty"`
|
||||
Models []string `json:"models,omitempty"`
|
||||
Order []string `json:"order,omitempty" description:"Ordered list of preferred provider names"`
|
||||
Models []string `json:"models,omitempty" description:"Model identifiers to route across"`
|
||||
}
|
||||
|
||||
// ChatModelVercelProviderOptions configures Vercel provider behavior.
|
||||
type ChatModelVercelProviderOptions struct {
|
||||
Reasoning *ChatModelVercelReasoningOptions `json:"reasoning,omitempty"`
|
||||
ProviderOptions *ChatModelVercelGatewayProviderOptions `json:"providerOptions,omitempty"`
|
||||
User *string `json:"user,omitempty"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty"`
|
||||
LogProbs *bool `json:"logprobs,omitempty"`
|
||||
TopLogProbs *int64 `json:"top_logprobs,omitempty"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty"`
|
||||
ExtraBody map[string]any `json:"extra_body,omitempty"`
|
||||
Reasoning *ChatModelVercelReasoningOptions `json:"reasoning,omitempty" description:"Configuration for reasoning behavior"`
|
||||
ProviderOptions *ChatModelVercelGatewayProviderOptions `json:"providerOptions,omitempty" description:"Gateway routing options for provider selection" hidden:"true"`
|
||||
User *string `json:"user,omitempty" description:"Unique identifier for the end user for abuse monitoring" hidden:"true"`
|
||||
LogitBias map[string]int64 `json:"logit_bias,omitempty" description:"Token IDs mapped to bias values from -100 to 100" hidden:"true"`
|
||||
LogProbs *bool `json:"logprobs,omitempty" description:"Whether to return log probabilities of output tokens" hidden:"true"`
|
||||
TopLogProbs *int64 `json:"top_logprobs,omitempty" description:"Number of most likely tokens to return log probabilities for" hidden:"true"`
|
||||
ParallelToolCalls *bool `json:"parallel_tool_calls,omitempty" description:"Whether the model may make multiple tool calls in parallel"`
|
||||
ExtraBody map[string]any `json:"extra_body,omitempty" description:"Additional fields to include in the request body" hidden:"true"`
|
||||
}
|
||||
|
||||
// ChatModelCallConfig configures per-call model behavior defaults.
|
||||
type ChatModelCallConfig struct {
|
||||
MaxOutputTokens *int64 `json:"max_output_tokens,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
TopP *float64 `json:"top_p,omitempty"`
|
||||
TopK *int64 `json:"top_k,omitempty"`
|
||||
PresencePenalty *float64 `json:"presence_penalty,omitempty"`
|
||||
FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"`
|
||||
ProviderOptions *ChatModelProviderOptions `json:"provider_options,omitempty"`
|
||||
MaxOutputTokens *int64 `json:"max_output_tokens,omitempty" description:"Upper bound on tokens the model may generate"`
|
||||
Temperature *float64 `json:"temperature,omitempty" description:"Sampling temperature between 0 and 2"`
|
||||
TopP *float64 `json:"top_p,omitempty" description:"Nucleus sampling probability cutoff"`
|
||||
TopK *int64 `json:"top_k,omitempty" description:"Number of highest-probability tokens to keep for sampling"`
|
||||
PresencePenalty *float64 `json:"presence_penalty,omitempty" description:"Penalty for tokens that have already appeared in the output"`
|
||||
FrequencyPenalty *float64 `json:"frequency_penalty,omitempty" description:"Penalty for tokens based on their frequency in the output"`
|
||||
ProviderOptions *ChatModelProviderOptions `json:"provider_options,omitempty" description:"Provider-specific option overrides"`
|
||||
}
|
||||
|
||||
// CreateChatModelConfigRequest creates a chat model config.
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
)
|
||||
|
||||
// SchemaField describes a single form field in the generated schema.
|
||||
type SchemaField struct {
|
||||
JSONName string `json:"json_name"`
|
||||
GoName string `json:"go_name"`
|
||||
Type string `json:"type"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Required bool `json:"required"`
|
||||
Enum []string `json:"enum,omitempty"`
|
||||
InputType string `json:"input_type"`
|
||||
Hidden bool `json:"hidden,omitempty"`
|
||||
}
|
||||
|
||||
// FieldGroup holds the fields for a struct or provider.
|
||||
type FieldGroup struct {
|
||||
Fields []SchemaField `json:"fields"`
|
||||
}
|
||||
|
||||
// Schema is the top-level output structure.
|
||||
type Schema struct {
|
||||
General FieldGroup `json:"general"`
|
||||
Providers map[string]FieldGroup `json:"providers"`
|
||||
ProviderAliases map[string]string `json:"provider_aliases"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
schema := Schema{
|
||||
Providers: make(map[string]FieldGroup),
|
||||
ProviderAliases: map[string]string{
|
||||
"azure": "openai",
|
||||
"bedrock": "anthropic",
|
||||
},
|
||||
}
|
||||
|
||||
// General options from ChatModelCallConfig, excluding
|
||||
// the provider_options field which is handled separately.
|
||||
schema.General = extractFields(
|
||||
reflect.TypeOf(codersdk.ChatModelCallConfig{}),
|
||||
"",
|
||||
map[string]bool{"ProviderOptions": true},
|
||||
)
|
||||
|
||||
// Provider-specific options. Each entry maps a provider key
|
||||
// to the concrete options struct used for that provider.
|
||||
providerTypes := []struct {
|
||||
key string
|
||||
typ reflect.Type
|
||||
}{
|
||||
{"openai", reflect.TypeOf(codersdk.ChatModelOpenAIProviderOptions{})},
|
||||
{"anthropic", reflect.TypeOf(codersdk.ChatModelAnthropicProviderOptions{})},
|
||||
{"google", reflect.TypeOf(codersdk.ChatModelGoogleProviderOptions{})},
|
||||
{"openaicompat", reflect.TypeOf(codersdk.ChatModelOpenAICompatProviderOptions{})},
|
||||
{"openrouter", reflect.TypeOf(codersdk.ChatModelOpenRouterProviderOptions{})},
|
||||
{"vercel", reflect.TypeOf(codersdk.ChatModelVercelProviderOptions{})},
|
||||
}
|
||||
|
||||
for _, p := range providerTypes {
|
||||
schema.Providers[p.key] = extractFields(p.typ, "", nil)
|
||||
}
|
||||
|
||||
out, err := json.MarshalIndent(schema, "", "\t")
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "marshal schema: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Print the generated header and JSON body.
|
||||
_, _ = fmt.Println("// Code generated by scripts/modeloptionsgen. DO NOT EDIT.")
|
||||
_, _ = fmt.Println(string(out))
|
||||
}
|
||||
|
||||
// extractFields walks the struct fields of t and returns a FieldGroup.
|
||||
// prefix is used to build dot-separated json_name values for nested
|
||||
// structs. skip lists Go field names to exclude from output.
|
||||
func extractFields(t reflect.Type, prefix string, skip map[string]bool) FieldGroup {
|
||||
var fields []SchemaField
|
||||
|
||||
for i := range t.NumField() {
|
||||
f := t.Field(i)
|
||||
|
||||
if skip != nil && skip[f.Name] {
|
||||
continue
|
||||
}
|
||||
|
||||
jsonTag := f.Tag.Get("json")
|
||||
if jsonTag == "" || jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
jsonName := strings.Split(jsonTag, ",")[0]
|
||||
if jsonName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fullJSONName := jsonName
|
||||
if prefix != "" {
|
||||
fullJSONName = prefix + "." + jsonName
|
||||
}
|
||||
|
||||
// Determine the underlying type, dereferencing pointers.
|
||||
ft := f.Type
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
// Check the hidden tag before recursing into nested structs
|
||||
// so that entire sub-objects can be marked hidden.
|
||||
hidden := f.Tag.Get("hidden") == "true"
|
||||
|
||||
// If the field is a struct (not a map), recurse to flatten
|
||||
// its children using dot-separated names — unless the
|
||||
// entire struct is marked hidden, in which case emit it
|
||||
// as a single opaque field.
|
||||
if ft.Kind() == reflect.Struct && !hidden {
|
||||
nested := extractFields(ft, fullJSONName, nil)
|
||||
fields = append(fields, nested.Fields...)
|
||||
continue
|
||||
}
|
||||
|
||||
typeName := goTypeToSchemaType(f.Type)
|
||||
description := f.Tag.Get("description")
|
||||
enumTag := f.Tag.Get("enum")
|
||||
|
||||
var enumValues []string
|
||||
if enumTag != "" {
|
||||
enumValues = strings.Split(enumTag, ",")
|
||||
}
|
||||
|
||||
required := !strings.Contains(jsonTag, "omitempty")
|
||||
inputType := inferInputType(typeName, enumValues)
|
||||
|
||||
fields = append(fields, SchemaField{
|
||||
JSONName: fullJSONName,
|
||||
GoName: goFieldPath(prefix, f.Name, t, fullJSONName),
|
||||
Type: typeName,
|
||||
Description: description,
|
||||
Required: required,
|
||||
Enum: enumValues,
|
||||
InputType: inputType,
|
||||
Hidden: hidden,
|
||||
})
|
||||
}
|
||||
|
||||
return FieldGroup{Fields: fields}
|
||||
}
|
||||
|
||||
// goFieldPath builds a dot-separated Go field name for nested fields.
|
||||
// For top-level fields it returns just the field name. For nested
|
||||
// fields it reconstructs the parent struct field name from the prefix
|
||||
// by looking at the enclosing type's fields.
|
||||
func goFieldPath(prefix, name string, _ reflect.Type, fullJSONName string) string {
|
||||
if prefix == "" {
|
||||
return name
|
||||
}
|
||||
// Build the Go path by walking the JSON name segments. Each
|
||||
// segment maps to a struct field that we already traversed
|
||||
// during recursion, so we reconstruct the path from the JSON
|
||||
// parts. The parent extractFields call sets the prefix to the
|
||||
// parent json name, so we can derive the Go path from the
|
||||
// json segments by title-casing each part.
|
||||
parts := strings.Split(fullJSONName, ".")
|
||||
goNames := make([]string, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
goNames = append(goNames, jsonSegmentToGoName(p))
|
||||
}
|
||||
return strings.Join(goNames, ".")
|
||||
}
|
||||
|
||||
// jsonSegmentToGoName converts a snake_case JSON segment to a
|
||||
// PascalCase Go field name using common conventions.
|
||||
func jsonSegmentToGoName(seg string) string {
|
||||
words := strings.Split(seg, "_")
|
||||
var b strings.Builder
|
||||
for _, w := range words {
|
||||
if w == "" {
|
||||
continue
|
||||
}
|
||||
// Handle common acronyms.
|
||||
upper := strings.ToUpper(w)
|
||||
switch upper {
|
||||
case "ID", "URL", "IP", "HTTP", "JSON", "API", "UI":
|
||||
_, _ = b.WriteString(upper)
|
||||
default:
|
||||
_, _ = b.WriteString(strings.ToUpper(w[:1]))
|
||||
_, _ = b.WriteString(w[1:])
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// goTypeToSchemaType maps a Go reflect.Type to a JSON schema type
|
||||
// string.
|
||||
func goTypeToSchemaType(t reflect.Type) string {
|
||||
// Dereference pointers.
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
return "string"
|
||||
case reflect.Bool:
|
||||
return "boolean"
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return "integer"
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return "number"
|
||||
case reflect.Slice:
|
||||
return "array"
|
||||
case reflect.Map:
|
||||
return "object"
|
||||
default:
|
||||
return "string"
|
||||
}
|
||||
}
|
||||
|
||||
// inferInputType decides the appropriate frontend input widget for
|
||||
// a field based on its schema type and enum values.
|
||||
func inferInputType(typeName string, enum []string) string {
|
||||
if len(enum) > 0 {
|
||||
return "select"
|
||||
}
|
||||
switch typeName {
|
||||
case "boolean":
|
||||
return "select"
|
||||
case "array", "object":
|
||||
return "json"
|
||||
default:
|
||||
return "input"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://unpkg.com/knip@5/schema.json",
|
||||
"entry": ["./src/index.tsx", "./src/serviceWorker.ts"],
|
||||
"project": ["./src/**/*.ts", "./src/**/*.tsx", "./e2e/**/*.ts"],
|
||||
"ignore": ["**/*Generated.ts"],
|
||||
"ignore": ["**/*Generated.ts", "src/api/chatModelOptions.ts"],
|
||||
"ignoreBinaries": ["protoc"],
|
||||
"ignoreDependencies": [
|
||||
"@types/react-virtualized-auto-sizer",
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import schema from "./chatModelOptionsGenerated.json";
|
||||
|
||||
/**
|
||||
* Describes a single configurable field for a chat model provider.
|
||||
* Generated from Go struct tags via `scripts/modeloptionsgen`.
|
||||
*/
|
||||
export interface FieldSchema {
|
||||
/** The JSON key used in API payloads (may use dot-notation for nested fields). */
|
||||
json_name: string;
|
||||
/** The corresponding Go struct field name. */
|
||||
go_name: string;
|
||||
/** The JSON Schema type of this field. */
|
||||
type: "string" | "integer" | "number" | "boolean" | "array" | "object";
|
||||
/** Human-readable description of the field. May be absent for some fields. */
|
||||
description?: string;
|
||||
/** Whether this field is required when configuring the provider. */
|
||||
required: boolean;
|
||||
/** Hint for how the frontend should render the input control. */
|
||||
input_type: "input" | "select" | "json";
|
||||
/** If present, the field value must be one of these options. */
|
||||
enum?: string[];
|
||||
/** If true, this field should not be rendered in admin UI forms. */
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A group of fields belonging to a single provider or the general section.
|
||||
*/
|
||||
export interface ProviderSchema {
|
||||
fields: FieldSchema[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level schema describing all configurable chat model options.
|
||||
*
|
||||
* - `general` contains provider-independent fields (e.g. temperature).
|
||||
* - `providers` maps canonical provider names to their specific fields.
|
||||
* - `provider_aliases` maps alternate names to canonical provider names
|
||||
* (e.g. "azure" → "openai").
|
||||
*/
|
||||
export interface ModelOptionsSchema {
|
||||
general: ProviderSchema;
|
||||
providers: Record<string, ProviderSchema>;
|
||||
provider_aliases: Record<string, string>;
|
||||
}
|
||||
|
||||
/** The imported schema, typed as {@link ModelOptionsSchema}. */
|
||||
export const modelOptionsSchema: ModelOptionsSchema =
|
||||
schema as ModelOptionsSchema;
|
||||
|
||||
/**
|
||||
* Get the general (provider-independent) fields such as temperature
|
||||
* and max_output_tokens.
|
||||
*/
|
||||
export function getGeneralFields(): FieldSchema[] {
|
||||
return modelOptionsSchema.general.fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get provider-specific fields for a given provider name.
|
||||
* Handles aliases (e.g. "azure" → "openai", "bedrock" → "anthropic").
|
||||
* Returns an empty array for unknown providers.
|
||||
*/
|
||||
export function getProviderFields(provider: string): FieldSchema[] {
|
||||
const resolved = resolveProvider(provider);
|
||||
return modelOptionsSchema.providers[resolved]?.fields ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a provider name through the alias table.
|
||||
* If the name is an alias it returns the canonical provider;
|
||||
* otherwise the original name is returned unchanged.
|
||||
*
|
||||
* @example
|
||||
* resolveProvider("azure") // "openai"
|
||||
* resolveProvider("bedrock") // "anthropic"
|
||||
* resolveProvider("openai") // "openai"
|
||||
*/
|
||||
export function resolveProvider(provider: string): string {
|
||||
return modelOptionsSchema.provider_aliases[provider] ?? provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all canonical provider names (excludes aliases).
|
||||
* The order matches the JSON schema and is not guaranteed to be stable
|
||||
* across regenerations.
|
||||
*/
|
||||
export function getProviderNames(): string[] {
|
||||
return Object.keys(modelOptionsSchema.providers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a provider is known, either as a canonical name or an alias.
|
||||
*/
|
||||
export function isKnownProvider(provider: string): boolean {
|
||||
const resolved = resolveProvider(provider);
|
||||
return resolved in modelOptionsSchema.providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a snake_case segment to camelCase.
|
||||
* Only the first character after each underscore is uppercased;
|
||||
* the leading character stays lowercase.
|
||||
*/
|
||||
function snakeToCamel(s: string): string {
|
||||
return s.replace(/_([a-z0-9])/g, (_, ch: string) => ch.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a dot-notation `json_name` into a form field key namespaced
|
||||
* under the given provider.
|
||||
*
|
||||
* Each dot-separated segment is converted from snake_case to camelCase
|
||||
* and joined back with dots, then prefixed with the provider name.
|
||||
*
|
||||
* This bridges between the JSON schema (snake_case, flat `json_name`)
|
||||
* and a typical React form state tree (camelCase, dot-separated paths).
|
||||
*
|
||||
* @example
|
||||
* toFormFieldKey("anthropic", "thinking.budget_tokens")
|
||||
* // "anthropic.thinking.budgetTokens"
|
||||
*
|
||||
* toFormFieldKey("openai", "max_completion_tokens")
|
||||
* // "openai.maxCompletionTokens"
|
||||
*/
|
||||
export function toFormFieldKey(provider: string, jsonName: string): string {
|
||||
const camelSegments = jsonName.split(".").map(snakeToCamel);
|
||||
return `${provider}.${camelSegments.join(".")}`;
|
||||
}
|
||||
|
||||
/** Get only the visible (non-hidden) fields for a provider. */
|
||||
export function getVisibleProviderFields(provider: string): FieldSchema[] {
|
||||
return getProviderFields(provider).filter((f) => !f.hidden);
|
||||
}
|
||||
|
||||
/** Get only the visible (non-hidden) general fields. */
|
||||
export function getVisibleGeneralFields(): FieldSchema[] {
|
||||
return getGeneralFields().filter((f) => !f.hidden);
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
{
|
||||
"general": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "max_output_tokens",
|
||||
"go_name": "MaxOutputTokens",
|
||||
"type": "integer",
|
||||
"description": "Upper bound on tokens the model may generate",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "temperature",
|
||||
"go_name": "Temperature",
|
||||
"type": "number",
|
||||
"description": "Sampling temperature between 0 and 2",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "top_p",
|
||||
"go_name": "TopP",
|
||||
"type": "number",
|
||||
"description": "Nucleus sampling probability cutoff",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "top_k",
|
||||
"go_name": "TopK",
|
||||
"type": "integer",
|
||||
"description": "Number of highest-probability tokens to keep for sampling",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "presence_penalty",
|
||||
"go_name": "PresencePenalty",
|
||||
"type": "number",
|
||||
"description": "Penalty for tokens that have already appeared in the output",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "frequency_penalty",
|
||||
"go_name": "FrequencyPenalty",
|
||||
"type": "number",
|
||||
"description": "Penalty for tokens based on their frequency in the output",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
}
|
||||
]
|
||||
},
|
||||
"providers": {
|
||||
"anthropic": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "send_reasoning",
|
||||
"go_name": "SendReasoning",
|
||||
"type": "boolean",
|
||||
"description": "Whether to include reasoning content in the response",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "thinking.budget_tokens",
|
||||
"go_name": "Thinking.BudgetTokens",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of tokens the model may use for thinking",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "effort",
|
||||
"go_name": "Effort",
|
||||
"type": "string",
|
||||
"description": "Controls the level of reasoning effort",
|
||||
"required": false,
|
||||
"enum": ["low", "medium", "high", "max"],
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "disable_parallel_tool_use",
|
||||
"go_name": "DisableParallelToolUse",
|
||||
"type": "boolean",
|
||||
"description": "Whether to disable parallel tool execution",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
}
|
||||
]
|
||||
},
|
||||
"google": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "thinking_config.thinking_budget",
|
||||
"go_name": "ThinkingConfig.ThinkingBudget",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of tokens the model may use for thinking",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "thinking_config.include_thoughts",
|
||||
"go_name": "ThinkingConfig.IncludeThoughts",
|
||||
"type": "boolean",
|
||||
"description": "Whether to include thinking content in the response",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "cached_content",
|
||||
"go_name": "CachedContent",
|
||||
"type": "string",
|
||||
"description": "Resource name of a cached content object",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "safety_settings",
|
||||
"go_name": "SafetySettings",
|
||||
"type": "array",
|
||||
"description": "Safety filtering settings for harmful content categories",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "threshold",
|
||||
"go_name": "Threshold",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"openai": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "include",
|
||||
"go_name": "Include",
|
||||
"type": "array",
|
||||
"description": "Model names to include in discovery",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "instructions",
|
||||
"go_name": "Instructions",
|
||||
"type": "string",
|
||||
"description": "System-level instructions prepended to the conversation",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "logit_bias",
|
||||
"go_name": "LogitBias",
|
||||
"type": "object",
|
||||
"description": "Token IDs mapped to bias values from -100 to 100",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "log_probs",
|
||||
"go_name": "LogProbs",
|
||||
"type": "boolean",
|
||||
"description": "Whether to return log probabilities of output tokens",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "top_log_probs",
|
||||
"go_name": "TopLogProbs",
|
||||
"type": "integer",
|
||||
"description": "Number of most likely tokens to return log probabilities for",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "max_tool_calls",
|
||||
"go_name": "MaxToolCalls",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of tool calls per response",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "parallel_tool_calls",
|
||||
"go_name": "ParallelToolCalls",
|
||||
"type": "boolean",
|
||||
"description": "Whether the model may make multiple tool calls in parallel",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "user",
|
||||
"go_name": "User",
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the end user for abuse monitoring",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning_effort",
|
||||
"go_name": "ReasoningEffort",
|
||||
"type": "string",
|
||||
"description": "Controls the level of reasoning effort",
|
||||
"required": false,
|
||||
"enum": ["none", "minimal", "low", "medium", "high", "xhigh"],
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning_summary",
|
||||
"go_name": "ReasoningSummary",
|
||||
"type": "string",
|
||||
"description": "Controls whether reasoning tokens are summarized in the response",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "max_completion_tokens",
|
||||
"go_name": "MaxCompletionTokens",
|
||||
"type": "integer",
|
||||
"description": "Upper bound on tokens the model may generate",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "text_verbosity",
|
||||
"go_name": "TextVerbosity",
|
||||
"type": "string",
|
||||
"description": "Controls the verbosity of the text response",
|
||||
"required": false,
|
||||
"enum": ["low", "medium", "high"],
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "prediction",
|
||||
"go_name": "Prediction",
|
||||
"type": "object",
|
||||
"description": "Predicted output content to speed up responses",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "store",
|
||||
"go_name": "Store",
|
||||
"type": "boolean",
|
||||
"description": "Whether to store the output for model distillation or evals",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "metadata",
|
||||
"go_name": "Metadata",
|
||||
"type": "object",
|
||||
"description": "Arbitrary metadata to attach to the request",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "prompt_cache_key",
|
||||
"go_name": "PromptCacheKey",
|
||||
"type": "string",
|
||||
"description": "Key for enabling cross-request prompt caching",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "safety_identifier",
|
||||
"go_name": "SafetyIdentifier",
|
||||
"type": "string",
|
||||
"description": "Developer-specific safety identifier for the request",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "service_tier",
|
||||
"go_name": "ServiceTier",
|
||||
"type": "string",
|
||||
"description": "Latency tier to use for processing the request",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "structured_outputs",
|
||||
"go_name": "StructuredOutputs",
|
||||
"type": "boolean",
|
||||
"description": "Whether to enable structured JSON output mode",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "strict_json_schema",
|
||||
"go_name": "StrictJSONSchema",
|
||||
"type": "boolean",
|
||||
"description": "Whether to enforce strict adherence to the JSON schema",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"openaicompat": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "user",
|
||||
"go_name": "User",
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the end user for abuse monitoring",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning_effort",
|
||||
"go_name": "ReasoningEffort",
|
||||
"type": "string",
|
||||
"description": "Controls the level of reasoning effort",
|
||||
"required": false,
|
||||
"enum": ["none", "minimal", "low", "medium", "high", "xhigh"],
|
||||
"input_type": "select"
|
||||
}
|
||||
]
|
||||
},
|
||||
"openrouter": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "reasoning.enabled",
|
||||
"go_name": "Reasoning.Enabled",
|
||||
"type": "boolean",
|
||||
"description": "Whether reasoning is enabled",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.exclude",
|
||||
"go_name": "Reasoning.Exclude",
|
||||
"type": "boolean",
|
||||
"description": "Whether to exclude reasoning content from the response",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.max_tokens",
|
||||
"go_name": "Reasoning.MaxTokens",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of tokens for reasoning output",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.effort",
|
||||
"go_name": "Reasoning.Effort",
|
||||
"type": "string",
|
||||
"description": "Controls the level of reasoning effort",
|
||||
"required": false,
|
||||
"enum": ["low", "medium", "high"],
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "extra_body",
|
||||
"go_name": "ExtraBody",
|
||||
"type": "object",
|
||||
"description": "Additional fields to include in the request body",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "include_usage",
|
||||
"go_name": "IncludeUsage",
|
||||
"type": "boolean",
|
||||
"description": "Whether to include token usage information in the response",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "logit_bias",
|
||||
"go_name": "LogitBias",
|
||||
"type": "object",
|
||||
"description": "Token IDs mapped to bias values from -100 to 100",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "log_probs",
|
||||
"go_name": "LogProbs",
|
||||
"type": "boolean",
|
||||
"description": "Whether to return log probabilities of output tokens",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "parallel_tool_calls",
|
||||
"go_name": "ParallelToolCalls",
|
||||
"type": "boolean",
|
||||
"description": "Whether the model may make multiple tool calls in parallel",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "user",
|
||||
"go_name": "User",
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the end user for abuse monitoring",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "provider",
|
||||
"go_name": "Provider",
|
||||
"type": "string",
|
||||
"description": "Routing preferences for provider selection",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"vercel": {
|
||||
"fields": [
|
||||
{
|
||||
"json_name": "reasoning.enabled",
|
||||
"go_name": "Reasoning.Enabled",
|
||||
"type": "boolean",
|
||||
"description": "Whether reasoning is enabled",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.max_tokens",
|
||||
"go_name": "Reasoning.MaxTokens",
|
||||
"type": "integer",
|
||||
"description": "Maximum number of tokens for reasoning output",
|
||||
"required": false,
|
||||
"input_type": "input"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.effort",
|
||||
"go_name": "Reasoning.Effort",
|
||||
"type": "string",
|
||||
"description": "Controls the level of reasoning effort",
|
||||
"required": false,
|
||||
"enum": ["none", "minimal", "low", "medium", "high", "xhigh"],
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "reasoning.exclude",
|
||||
"go_name": "Reasoning.Exclude",
|
||||
"type": "boolean",
|
||||
"description": "Whether to exclude reasoning content from the response",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "providerOptions",
|
||||
"go_name": "ProviderOptions",
|
||||
"type": "string",
|
||||
"description": "Gateway routing options for provider selection",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "user",
|
||||
"go_name": "User",
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the end user for abuse monitoring",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "logit_bias",
|
||||
"go_name": "LogitBias",
|
||||
"type": "object",
|
||||
"description": "Token IDs mapped to bias values from -100 to 100",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "logprobs",
|
||||
"go_name": "LogProbs",
|
||||
"type": "boolean",
|
||||
"description": "Whether to return log probabilities of output tokens",
|
||||
"required": false,
|
||||
"input_type": "select",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "top_logprobs",
|
||||
"go_name": "TopLogProbs",
|
||||
"type": "integer",
|
||||
"description": "Number of most likely tokens to return log probabilities for",
|
||||
"required": false,
|
||||
"input_type": "input",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"json_name": "parallel_tool_calls",
|
||||
"go_name": "ParallelToolCalls",
|
||||
"type": "boolean",
|
||||
"description": "Whether the model may make multiple tool calls in parallel",
|
||||
"required": false,
|
||||
"input_type": "select"
|
||||
},
|
||||
{
|
||||
"json_name": "extra_body",
|
||||
"go_name": "ExtraBody",
|
||||
"type": "object",
|
||||
"description": "Additional fields to include in the request body",
|
||||
"required": false,
|
||||
"input_type": "json",
|
||||
"hidden": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"provider_aliases": {
|
||||
"azure": "openai",
|
||||
"bedrock": "anthropic"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user