Skip to content

Commit 17cbc17

Browse files
JesssullivanOutBot CI
andauthored
feat: Add ExtraFields support to OpenAI providers for custom parameters (#1)
Adds support for arbitrary extra fields in OpenAI and OpenAI-compatible providers to enable custom parameters required by OpenAI-compatible APIs like Z.AI GLM. The OpenAI Go SDK's ChatCompletionNewParams provides a SetExtraFields() method, but Fantasy had no way to utilize it. This change adds an ExtraFields field to ProviderOptions and calls SetExtraFields() when extra fields are present. Use case: Custom OpenAI-compatible APIs (like Z.AI GLM) require additional parameters such as thinking mode configuration that aren't part of OpenAI's API spec: ```json { "extra_fields": { "thinking": { "budget_tokens": 26214, "type": "enabled" } } } ``` Changes: - Add \`ExtraFields map[string]any\` field to ProviderOptions in both openai and openaicompat providers - Call \`params.SetExtraFields()\` in PrepareCallFunc when ExtraFields present - Minimal, non-breaking change using omitempty JSON tag This enables Crush (charmbracelet/crush#1171) and other Fantasy consumers to pass custom parameters to OpenAI-compatible APIs without modifying Fantasy for each specific API's custom fields. Tested: Build successful, no breaking changes to existing functionality. Co-authored-by: OutBot CI <[email protected]>
1 parent 38c3539 commit 17cbc17

File tree

4 files changed

+17
-0
lines changed

4 files changed

+17
-0
lines changed

providers/openai/language_model_hooks.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ func DefaultPrepareCallFunc(model fantasy.LanguageModel, params *openai.ChatComp
9999
}
100100
params.Metadata = metadata
101101
}
102+
103+
// Apply extra fields for custom OpenAI-compatible APIs (e.g., Z.AI GLM thinking mode)
104+
if providerOptions.ExtraFields != nil && len(providerOptions.ExtraFields) > 0 {
105+
params.SetExtraFields(providerOptions.ExtraFields)
106+
}
102107
if providerOptions.PromptCacheKey != nil {
103108
params.PromptCacheKey = param.NewOpt(*providerOptions.PromptCacheKey)
104109
}

providers/openai/provider_options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ type ProviderOptions struct {
4747
SafetyIdentifier *string `json:"safety_identifier"`
4848
ServiceTier *string `json:"service_tier"`
4949
StructuredOutputs *bool `json:"structured_outputs"`
50+
// ExtraFields allows passing arbitrary additional parameters to OpenAI-compatible APIs
51+
// that require custom fields not part of the standard OpenAI API specification.
52+
ExtraFields map[string]any `json:"extra_fields,omitempty"`
5053
}
5154

5255
// Options implements the ProviderOptions interface.

providers/openaicompat/language_model_hooks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ func PrepareCallFunc(_ fantasy.LanguageModel, params *openaisdk.ChatCompletionNe
4141
if providerOptions.User != nil {
4242
params.User = param.NewOpt(*providerOptions.User)
4343
}
44+
45+
// Apply extra fields for custom OpenAI-compatible APIs (e.g., Z.AI GLM thinking mode)
46+
if providerOptions.ExtraFields != nil && len(providerOptions.ExtraFields) > 0 {
47+
params.SetExtraFields(providerOptions.ExtraFields)
48+
}
49+
4450
return nil, nil
4551
}
4652

providers/openaicompat/provider_options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import (
1010
type ProviderOptions struct {
1111
User *string `json:"user"`
1212
ReasoningEffort *openai.ReasoningEffort `json:"reasoning_effort"`
13+
// ExtraFields allows passing arbitrary additional parameters to custom OpenAI-compatible APIs
14+
// that require custom fields not part of the standard OpenAI API specification.
15+
ExtraFields map[string]any `json:"extra_fields,omitempty"`
1316
}
1417

1518
// ReasoningData represents reasoning data for OpenAI-compatible provider.

0 commit comments

Comments
 (0)