fix: only send prompt_cache_key for OpenAI provider
The prompt_cache_key field is an OpenAI-specific feature for prefix-based prompt caching. When sent to other providers like Gemini that use the OpenAI-compatible HTTP provider, it causes a 400 error because Gemini's API rejects unknown fields. This adds a supportPromptCache flag to the provider struct, enabled only for the OpenAI protocol, so the field is no longer sent to providers that don't support it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
094d65916d
commit
bee6f75b2c
3 changed files with 24 additions and 7 deletions
|
|
@ -84,7 +84,9 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
if apiBase == "" {
|
if apiBase == "" {
|
||||||
apiBase = getDefaultAPIBase(protocol)
|
apiBase = getDefaultAPIBase(protocol)
|
||||||
}
|
}
|
||||||
return NewHTTPProviderWithMaxTokensField(cfg.APIKey, apiBase, cfg.Proxy, cfg.MaxTokensField), modelID, nil
|
p := NewHTTPProviderWithMaxTokensField(cfg.APIKey, apiBase, cfg.Proxy, cfg.MaxTokensField)
|
||||||
|
p.SetSupportPromptCache(true) // OpenAI supports prompt_cache_key
|
||||||
|
return p, modelID, nil
|
||||||
|
|
||||||
case "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
case "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
||||||
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
"ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras",
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@ func (p *HTTPProvider) Chat(
|
||||||
return p.delegate.Chat(ctx, messages, tools, model, options)
|
return p.delegate.Chat(ctx, messages, tools, model, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSupportPromptCache enables or disables sending the prompt_cache_key field.
|
||||||
|
func (p *HTTPProvider) SetSupportPromptCache(v bool) {
|
||||||
|
p.delegate.SetSupportPromptCache(v)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *HTTPProvider) GetDefaultModel() string {
|
func (p *HTTPProvider) GetDefaultModel() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,11 @@ type (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
apiKey string
|
apiKey string
|
||||||
apiBase string
|
apiBase string
|
||||||
maxTokensField string // Field name for max tokens (e.g., "max_completion_tokens" for o1/glm models)
|
maxTokensField string // Field name for max tokens (e.g., "max_completion_tokens" for o1/glm models)
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
supportPromptCache bool // Only send prompt_cache_key when true (OpenAI-specific feature)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProvider(apiKey, apiBase, proxy string) *Provider {
|
func NewProvider(apiKey, apiBase, proxy string) *Provider {
|
||||||
|
|
@ -62,6 +63,12 @@ func NewProviderWithMaxTokensField(apiKey, apiBase, proxy, maxTokensField string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetSupportPromptCache enables or disables sending the prompt_cache_key field.
|
||||||
|
// Only OpenAI supports this field; other providers (e.g. Gemini) reject unknown fields.
|
||||||
|
func (p *Provider) SetSupportPromptCache(v bool) {
|
||||||
|
p.supportPromptCache = v
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) Chat(
|
func (p *Provider) Chat(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
messages []Message,
|
messages []Message,
|
||||||
|
|
@ -115,8 +122,11 @@ func (p *Provider) Chat(
|
||||||
// with the same key and reuse prefix KV cache across calls.
|
// with the same key and reuse prefix KV cache across calls.
|
||||||
// The key is typically the agent ID — stable per agent, shared across requests.
|
// The key is typically the agent ID — stable per agent, shared across requests.
|
||||||
// See: https://platform.openai.com/docs/guides/prompt-caching
|
// See: https://platform.openai.com/docs/guides/prompt-caching
|
||||||
if cacheKey, ok := options["prompt_cache_key"].(string); ok && cacheKey != "" {
|
// Only sent for providers that support it (e.g. OpenAI); others like Gemini reject unknown fields.
|
||||||
requestBody["prompt_cache_key"] = cacheKey
|
if p.supportPromptCache {
|
||||||
|
if cacheKey, ok := options["prompt_cache_key"].(string); ok && cacheKey != "" {
|
||||||
|
requestBody["prompt_cache_key"] = cacheKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonData, err := json.Marshal(requestBody)
|
jsonData, err := json.Marshal(requestBody)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue