diff --git a/go.mod b/go.mod index 82468e12..131e1336 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.26.1 require ( charm.land/bubbles/v2 v2.0.0 charm.land/bubbletea/v2 v2.0.2 - charm.land/fantasy v0.16.0 + charm.land/fantasy v0.17.1 charm.land/huh/v2 v2.0.3 charm.land/lipgloss/v2 v2.0.2 github.com/alecthomas/chroma/v2 v2.23.1 diff --git a/go.sum b/go.sum index cb3dbb36..a8cd579a 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ charm.land/bubbles/v2 v2.0.0 h1:tE3eK/pHjmtrDiRdoC9uGNLgpopOd8fjhEe31B/ai5s= charm.land/bubbles/v2 v2.0.0/go.mod h1:rCHoleP2XhU8um45NTuOWBPNVHxnkXKTiZqcclL/qOI= charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0= charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= -charm.land/fantasy v0.16.0 h1:vE/6sR9nPcSD8qXJXX6wR8NXjtWlBVAzwQmTh5pHVrs= -charm.land/fantasy v0.16.0/go.mod h1:VZjpXVh7IgeiIzGQybEnKzd68ofDsRj94+kzH1ZCAfQ= +charm.land/fantasy v0.17.1 h1:SQzfnyJPDuQWt6e//KKmQmEEXdqHMC0IZz10XwkLcEM= +charm.land/fantasy v0.17.1/go.mod h1:FF5ALCCHETacHJPBqU42CtwMInYQ0ul52fdzIHQMbQk= charm.land/huh/v2 v2.0.3 h1:2cJsMqEPwSywGHvdlKsJyQKPtSJLVnFKyFbsYZTlLkU= charm.land/huh/v2 v2.0.3/go.mod h1:93eEveeeqn47MwiC3tf+2atZ2l7Is88rAtmZNZ8x9Wc= charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= diff --git a/internal/models/providers.go b/internal/models/providers.go index 43fe6eef..5e6d0da0 100644 --- a/internal/models/providers.go +++ b/internal/models/providers.go @@ -723,12 +723,45 @@ func createOpenAICodexProvider(ctx context.Context, config *ProviderConfig, mode return nil, fmt.Errorf("failed to create OpenAI Codex model: %w", err) } - // Build provider options for OpenAI Responses API reasoning models. - providerOpts := buildOpenAIProviderOptions(config, modelName) + // Build provider options for Codex API with system prompt as Instructions + providerOpts := buildCodexProviderOptions(config, modelName) return &ProviderResult{Model: model, ProviderOptions: providerOpts}, nil } +// buildCodexProviderOptions returns fantasy.ProviderOptions configured for +// OpenAI Codex API. The Codex API requires the system prompt to be passed +// as 'instructions' rather than as a system message. +func buildCodexProviderOptions(config *ProviderConfig, modelName string) fantasy.ProviderOptions { + store := false + opts := &openai.ResponsesProviderOptions{ + Store: &store, + } + + // Set system prompt as Instructions (required for Codex API) + if config.SystemPrompt != "" { + opts.Instructions = &config.SystemPrompt + } + + // For reasoning models, add reasoning options + if openai.IsResponsesReasoningModel(modelName) { + reasoningSummary := "auto" + opts.ReasoningSummary = &reasoningSummary + opts.Include = []openai.IncludeType{ + openai.IncludeReasoningEncryptedContent, + } + + // Map ThinkingLevel to OpenAI ReasoningEffort + if effort := thinkingLevelToReasoningEffort(config.ThinkingLevel); effort != nil { + opts.ReasoningEffort = effort + } + } + + return fantasy.ProviderOptions{ + openai.Name: opts, + } +} + // createCodexHTTPClient creates an HTTP client with headers required for ChatGPT/Codex API func createCodexHTTPClient(token, accountID string, skipVerify bool) *http.Client { var base http.RoundTripper