feat: Add OpenAI Responses API (#282)

* feat: Add OpenAI Responses API

* fix: Make temperature optional

* chore: Increase default value of max tokens
This commit is contained in:
Petr Mironychev
2025-12-01 12:14:55 +01:00
committed by GitHub
parent e1fa01d123
commit a466332822
26 changed files with 3261 additions and 4 deletions

View File

@ -173,6 +173,25 @@ ChatAssistantSettings::ChatAssistantSettings()
thinkingMaxTokens.setRange(-1, 200000);
thinkingMaxTokens.setDefaultValue(16000);
// OpenAI Responses API Settings
openAIResponsesReasoningEffort.setSettingsKey(Constants::CA_OPENAI_RESPONSES_REASONING_EFFORT);
openAIResponsesReasoningEffort.setLabelText(Tr::tr("Reasoning effort:"));
openAIResponsesReasoningEffort.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox);
openAIResponsesReasoningEffort.addOption("None");
openAIResponsesReasoningEffort.addOption("Minimal");
openAIResponsesReasoningEffort.addOption("Low");
openAIResponsesReasoningEffort.addOption("Medium");
openAIResponsesReasoningEffort.addOption("High");
openAIResponsesReasoningEffort.setDefaultValue("Medium");
openAIResponsesReasoningEffort.setToolTip(
Tr::tr("Constrains effort on reasoning for OpenAI gpt-5 and o-series models:\n\n"
"None: No reasoning (gpt-5.1 only)\n"
"Minimal: Minimal reasoning effort (o-series only)\n"
"Low: Low reasoning effort\n"
"Medium: Balanced reasoning (default for most models)\n"
"High: Maximum reasoning effort (gpt-5-pro only supports this)\n\n"
"Note: Reducing effort = faster responses + fewer tokens"));
autosave.setDefaultValue(true);
autosave.setLabelText(Tr::tr("Enable autosave when message received"));
@ -270,6 +289,9 @@ ChatAssistantSettings::ChatAssistantSettings()
thinkingGrid.addRow({thinkingBudgetTokens});
thinkingGrid.addRow({thinkingMaxTokens});
auto openAIResponsesGrid = Grid{};
openAIResponsesGrid.addRow({openAIResponsesReasoningEffort});
auto chatViewSettingsGrid = Grid{};
chatViewSettingsGrid.addRow({textFontFamily, textFontSize});
chatViewSettingsGrid.addRow({codeFontFamily, codeFontSize});
@ -293,9 +315,13 @@ ChatAssistantSettings::ChatAssistantSettings()
Column{enableChatTools}},
Space{8},
Group{
title(Tr::tr("Extended Thinking (if provider/model supports)")),
title(Tr::tr("Extended Thinking (Claude)")),
Column{enableThinkingMode, Row{thinkingGrid, Stretch{1}}}},
Space{8},
Group{
title(Tr::tr("OpenAI Responses API")),
Column{Row{openAIResponsesGrid, Stretch{1}}}},
Space{8},
Group{
title(Tr::tr("General Parameters")),
Row{genGrid, Stretch{1}},
@ -352,6 +378,7 @@ void ChatAssistantSettings::resetSettingsToDefaults()
resetAspect(enableThinkingMode);
resetAspect(thinkingBudgetTokens);
resetAspect(thinkingMaxTokens);
resetAspect(openAIResponsesReasoningEffort);
resetAspect(linkOpenFiles);
resetAspect(enableChatTools);
resetAspect(textFontFamily);

View File

@ -70,6 +70,9 @@ public:
Utils::IntegerAspect thinkingBudgetTokens{this};
Utils::IntegerAspect thinkingMaxTokens{this};
// OpenAI Responses API Settings
Utils::SelectionAspect openAIResponsesReasoningEffort{this};
// Visuals settings
Utils::SelectionAspect textFontFamily{this};
Utils::IntegerAspect textFontSize{this};

View File

@ -151,7 +151,7 @@ CodeCompletionSettings::CodeCompletionSettings()
maxTokens.setSettingsKey(Constants::CC_MAX_TOKENS);
maxTokens.setLabelText(Tr::tr("Max Tokens:"));
maxTokens.setRange(-1, 900000);
maxTokens.setDefaultValue(100);
maxTokens.setDefaultValue(500);
// Advanced Parameters
useTopP.setSettingsKey(Constants::CC_USE_TOP_P);
@ -313,6 +313,25 @@ CodeCompletionSettings::CodeCompletionSettings()
contextWindow.setRange(-1, 10000);
contextWindow.setDefaultValue(2048);
// OpenAI Responses API Settings
openAIResponsesReasoningEffort.setSettingsKey(Constants::CC_OPENAI_RESPONSES_REASONING_EFFORT);
openAIResponsesReasoningEffort.setLabelText(Tr::tr("Reasoning effort:"));
openAIResponsesReasoningEffort.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox);
openAIResponsesReasoningEffort.addOption("None");
openAIResponsesReasoningEffort.addOption("Minimal");
openAIResponsesReasoningEffort.addOption("Low");
openAIResponsesReasoningEffort.addOption("Medium");
openAIResponsesReasoningEffort.addOption("High");
openAIResponsesReasoningEffort.setDefaultValue("Medium");
openAIResponsesReasoningEffort.setToolTip(
Tr::tr("Constrains effort on reasoning for OpenAI gpt-5 and o-series models:\n\n"
"None: No reasoning (gpt-5.1 only)\n"
"Minimal: Minimal reasoning effort (o-series only)\n"
"Low: Low reasoning effort\n"
"Medium: Balanced reasoning (default for most models)\n"
"High: Maximum reasoning effort (gpt-5-pro only supports this)\n\n"
"Note: Reducing effort = faster responses + fewer tokens"));
resetToDefaults.m_buttonText = Tr::tr("Reset Page to Defaults");
readSettings();
@ -338,6 +357,9 @@ CodeCompletionSettings::CodeCompletionSettings()
ollamaGrid.addRow({ollamaLivetime});
ollamaGrid.addRow({contextWindow});
auto openAIResponsesGrid = Grid{};
openAIResponsesGrid.addRow({openAIResponsesReasoningEffort});
auto contextGrid = Grid{};
contextGrid.addRow({Row{readFullFile}});
contextGrid.addRow({Row{readFileParts, readStringsBeforeCursor, readStringsAfterCursor}});
@ -398,6 +420,8 @@ CodeCompletionSettings::CodeCompletionSettings()
Group{title(Tr::tr("Quick Refactor Settings")),
Column{useOpenFilesInQuickRefactor, quickRefactorSystemPrompt}},
Space{8},
Group{title(Tr::tr("OpenAI Responses API")), Column{Row{openAIResponsesGrid, Stretch{1}}}},
Space{8},
Group{title(Tr::tr("Ollama Settings")), Column{Row{ollamaGrid, Stretch{1}}}},
Stretch{1}};
});
@ -458,6 +482,7 @@ void CodeCompletionSettings::resetSettingsToDefaults()
resetAspect(maxChangesCacheSize);
resetAspect(ollamaLivetime);
resetAspect(contextWindow);
resetAspect(openAIResponsesReasoningEffort);
resetAspect(useUserMessageTemplateForCC);
resetAspect(userMessageTemplateForCC);
resetAspect(systemPromptForNonFimModels);

View File

@ -90,6 +90,9 @@ public:
Utils::StringAspect ollamaLivetime{this};
Utils::IntegerAspect contextWindow{this};
// OpenAI Responses API Settings
Utils::SelectionAspect openAIResponsesReasoningEffort{this};
QString processMessageToFIM(const QString &prefix, const QString &suffix) const;
private:

View File

@ -133,6 +133,25 @@ QuickRefactorSettings::QuickRefactorSettings()
thinkingMaxTokens.setRange(1000, 200000);
thinkingMaxTokens.setDefaultValue(16000);
// OpenAI Responses API Settings
openAIResponsesReasoningEffort.setSettingsKey(Constants::QR_OPENAI_RESPONSES_REASONING_EFFORT);
openAIResponsesReasoningEffort.setLabelText(Tr::tr("Reasoning effort:"));
openAIResponsesReasoningEffort.setDisplayStyle(Utils::SelectionAspect::DisplayStyle::ComboBox);
openAIResponsesReasoningEffort.addOption("None");
openAIResponsesReasoningEffort.addOption("Minimal");
openAIResponsesReasoningEffort.addOption("Low");
openAIResponsesReasoningEffort.addOption("Medium");
openAIResponsesReasoningEffort.addOption("High");
openAIResponsesReasoningEffort.setDefaultValue("Medium");
openAIResponsesReasoningEffort.setToolTip(
Tr::tr("Constrains effort on reasoning for OpenAI gpt-5 and o-series models:\n\n"
"None: No reasoning (gpt-5.1 only)\n"
"Minimal: Minimal reasoning effort (o-series only)\n"
"Low: Low reasoning effort\n"
"Medium: Balanced reasoning (default for most models)\n"
"High: Maximum reasoning effort (gpt-5-pro only supports this)\n\n"
"Note: Reducing effort = faster responses + fewer tokens"));
// Context Settings
readFullFile.setSettingsKey(Constants::QR_READ_FULL_FILE);
readFullFile.setLabelText(Tr::tr("Read Full File"));
@ -238,6 +257,9 @@ QuickRefactorSettings::QuickRefactorSettings()
toolsGrid.addRow({thinkingBudgetTokens});
toolsGrid.addRow({thinkingMaxTokens});
auto openAIResponsesGrid = Grid{};
openAIResponsesGrid.addRow({openAIResponsesReasoningEffort});
auto contextGrid = Grid{};
contextGrid.addRow({Row{readFullFile}});
contextGrid.addRow({Row{readFileParts, readStringsBeforeCursor, readStringsAfterCursor}});
@ -260,6 +282,8 @@ QuickRefactorSettings::QuickRefactorSettings()
Space{8},
Group{title(Tr::tr("Tools Settings")), Column{Row{toolsGrid, Stretch{1}}}},
Space{8},
Group{title(Tr::tr("OpenAI Responses API")), Column{Row{openAIResponsesGrid, Stretch{1}}}},
Space{8},
Group{title(Tr::tr("Context Settings")), Column{Row{contextGrid, Stretch{1}}}},
Space{8},
Group{title(Tr::tr("Display Settings")), Column{Row{displayGrid, Stretch{1}}}},
@ -346,6 +370,7 @@ void QuickRefactorSettings::resetSettingsToDefaults()
resetAspect(useThinking);
resetAspect(thinkingBudgetTokens);
resetAspect(thinkingMaxTokens);
resetAspect(openAIResponsesReasoningEffort);
resetAspect(readFullFile);
resetAspect(readFileParts);
resetAspect(readStringsBeforeCursor);

View File

@ -61,6 +61,9 @@ public:
Utils::IntegerAspect thinkingBudgetTokens{this};
Utils::IntegerAspect thinkingMaxTokens{this};
// OpenAI Responses API Settings
Utils::SelectionAspect openAIResponsesReasoningEffort{this};
// Context Settings
Utils::BoolAspect readFullFile{this};
Utils::BoolAspect readFileParts{this};

View File

@ -182,6 +182,10 @@ const char CC_USE_FREQUENCY_PENALTY[] = "QodeAssist.fimUseFrequencyPenalty";
const char CC_FREQUENCY_PENALTY[] = "QodeAssist.fimFrequencyPenalty";
const char CC_OLLAMA_LIVETIME[] = "QodeAssist.fimOllamaLivetime";
const char CC_OLLAMA_CONTEXT_WINDOW[] = "QodeAssist.ccOllamaContextWindow";
// OpenAI Responses API Settings
const char CC_OPENAI_RESPONSES_REASONING_EFFORT[] = "QodeAssist.ccOpenAIResponsesReasoningEffort";
const char CA_TEMPERATURE[] = "QodeAssist.chatTemperature";
const char CA_MAX_TOKENS[] = "QodeAssist.chatMaxTokens";
const char CA_USE_TOP_P[] = "QodeAssist.chatUseTopP";
@ -197,6 +201,10 @@ const char CA_OLLAMA_CONTEXT_WINDOW[] = "QodeAssist.caOllamaContextWindow";
const char CA_ENABLE_THINKING_MODE[] = "QodeAssist.caEnableThinkingMode";
const char CA_THINKING_BUDGET_TOKENS[] = "QodeAssist.caThinkingBudgetTokens";
const char CA_THINKING_MAX_TOKENS[] = "QodeAssist.caThinkingMaxTokens";
// OpenAI Responses API Settings
const char CA_OPENAI_RESPONSES_REASONING_EFFORT[] = "QodeAssist.caOpenAIResponsesReasoningEffort";
const char CA_TEXT_FONT_FAMILY[] = "QodeAssist.caTextFontFamily";
const char CA_TEXT_FONT_SIZE[] = "QodeAssist.caTextFontSize";
const char CA_CODE_FONT_FAMILY[] = "QodeAssist.caCodeFontFamily";
@ -221,6 +229,10 @@ const char QR_USE_TOOLS[] = "QodeAssist.qrUseTools";
const char QR_USE_THINKING[] = "QodeAssist.qrUseThinking";
const char QR_THINKING_BUDGET_TOKENS[] = "QodeAssist.qrThinkingBudgetTokens";
const char QR_THINKING_MAX_TOKENS[] = "QodeAssist.qrThinkingMaxTokens";
// OpenAI Responses API Settings
const char QR_OPENAI_RESPONSES_REASONING_EFFORT[] = "QodeAssist.qrOpenAIResponsesReasoningEffort";
const char QR_READ_FULL_FILE[] = "QodeAssist.qrReadFullFile";
const char QR_READ_STRINGS_BEFORE_CURSOR[] = "QodeAssist.qrReadStringsBeforeCursor";
const char QR_READ_STRINGS_AFTER_CURSOR[] = "QodeAssist.qrReadStringsAfterCursor";