feat(provider): support chat completions for openai providers

This commit is contained in:
lpf
2026-05-11 18:14:43 +08:00
parent c1cbec551b
commit 78d546989c
12 changed files with 106 additions and 5 deletions

View File

@@ -260,6 +260,7 @@ type ProviderOAuthConfig struct {
}
type ProviderResponsesConfig struct {
API string `json:"api,omitempty"`
WebSearchEnabled bool `json:"web_search_enabled"`
WebSearchContextSize string `json:"web_search_context_size"`
FileSearchVectorStoreIDs []string `json:"file_search_vector_store_ids"`

View File

@@ -11,6 +11,9 @@ func TestNormalizedViewProjectsCoreAndRuntime(t *testing.T) {
MaxTokens: 12288,
Temperature: 0.35,
TimeoutSec: 90,
Responses: ProviderResponsesConfig{
API: "chat_completions",
},
}
cfg.Agents.Subagents["coder"] = SubagentConfig{
Enabled: true,
@@ -40,4 +43,7 @@ func TestNormalizedViewProjectsCoreAndRuntime(t *testing.T) {
if got := view.Runtime.Providers["openai"].Temperature; got != 0.35 {
t.Fatalf("expected provider temperature in normalized runtime view, got %v", got)
}
if got := view.Runtime.Providers["openai"].Responses.API; got != "chat_completions" {
t.Fatalf("expected provider responses.api in normalized runtime view, got %q", got)
}
}

View File

@@ -515,6 +515,13 @@ func validateProviderConfig(path string, p ProviderConfig) []error {
if p.OAuth.CooldownSec < 0 {
errs = append(errs, fmt.Errorf("%s.oauth.cooldown_sec must be >= 0", path))
}
if p.Responses.API != "" {
switch strings.TrimSpace(p.Responses.API) {
case "responses", "chat_completions":
default:
errs = append(errs, fmt.Errorf("%s.responses.api must be one of: responses, chat_completions", path))
}
}
if p.Responses.WebSearchContextSize != "" {
switch p.Responses.WebSearchContextSize {
case "low", "medium", "high":

View File

@@ -247,3 +247,27 @@ func TestValidateProviderHybridRequiresOAuthProvider(t *testing.T) {
t.Fatalf("expected oauth.provider validation error, got %v", errs)
}
}
func TestValidateProviderResponsesAPIRejectsUnknownValue(t *testing.T) {
t.Parallel()
cfg := DefaultConfig()
pc := cfg.Models.Providers["openai"]
pc.Responses.API = "legacy"
cfg.Models.Providers["openai"] = pc
errs := Validate(cfg)
if len(errs) == 0 {
t.Fatalf("expected validation errors")
}
found := false
for _, err := range errs {
if strings.Contains(err.Error(), "models.providers.openai.responses.api") {
found = true
break
}
}
if !found {
t.Fatalf("expected responses.api validation error, got %v", errs)
}
}