mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
feat(ai): AI model handling with reasoning support (#8539)
This commit is contained in:
Binary file not shown.
@@ -245,6 +245,7 @@ const registerChatIpc = ({ mainWindow, resolveModel, pickDefaultModelId, isAiEna
|
||||
abortSignal: controller.signal
|
||||
});
|
||||
|
||||
let streamError = null;
|
||||
for await (const part of result.fullStream) {
|
||||
if (controller.signal.aborted) break;
|
||||
switch (part.type) {
|
||||
@@ -271,11 +272,17 @@ const registerChatIpc = ({ mainWindow, resolveModel, pickDefaultModelId, isAiEna
|
||||
send('main:ai-chat-tool-done', { requestId, toolName: part.toolName });
|
||||
break;
|
||||
}
|
||||
case 'error': {
|
||||
streamError = part.error;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamError) throw streamError;
|
||||
|
||||
activeStreams.delete(requestId);
|
||||
|
||||
if (controller.signal.aborted) {
|
||||
|
||||
@@ -12,6 +12,7 @@ const {
|
||||
clearSdkCache,
|
||||
isKnownProviderId,
|
||||
isBuiltInModelId,
|
||||
isReasoningModel,
|
||||
validateApiKeyForProvider,
|
||||
providerLabel
|
||||
} = require('./providers');
|
||||
@@ -162,7 +163,7 @@ const registerAiIpc = (mainWindow) => {
|
||||
system,
|
||||
prompt,
|
||||
maxOutputTokens: maxTokens ?? 1024,
|
||||
temperature: temperature ?? 0.3
|
||||
...(isReasoningModel(modelId) ? {} : { temperature: temperature ?? 0.3 })
|
||||
});
|
||||
return { text };
|
||||
} catch (err) {
|
||||
@@ -344,7 +345,7 @@ const registerAiIpc = (mainWindow) => {
|
||||
model,
|
||||
system,
|
||||
maxOutputTokens: maxTokens ?? 2048,
|
||||
temperature: temperature ?? 0.7,
|
||||
...(isReasoningModel(modelId) ? {} : { temperature: temperature ?? 0.7 }),
|
||||
abortSignal: controller.signal
|
||||
};
|
||||
if (messages) {
|
||||
|
||||
@@ -40,16 +40,27 @@ const PROVIDERS = {
|
||||
* Static model catalog for built-in providers. User-defined custom models for
|
||||
* OpenAI-compatible endpoints are layered on top at lookup time.
|
||||
*/
|
||||
// `reasoning: true` marks models whose SDK path rejects temperature/stopSequences
|
||||
// (OpenAI Responses API reasoning models) or accepts them only when thinking is
|
||||
// off (Anthropic Claude 4+). Callers doing latency-critical work like
|
||||
// autocomplete drop those params for reasoning models to silence warnings.
|
||||
const MODEL_DEFINITIONS = {
|
||||
// OpenAI
|
||||
'gpt-4o-mini': { provider: 'openai', modelId: 'gpt-4o-mini', label: 'GPT-4o Mini' },
|
||||
'gpt-4o': { provider: 'openai', modelId: 'gpt-4o', label: 'GPT-4o' },
|
||||
'gpt-5': { provider: 'openai', modelId: 'gpt-5', label: 'GPT-5' },
|
||||
'gpt-5-mini': { provider: 'openai', modelId: 'gpt-5-mini', label: 'GPT-5 Mini' },
|
||||
'gpt-5': { provider: 'openai', modelId: 'gpt-5', label: 'GPT-5', reasoning: true },
|
||||
'gpt-5-mini': { provider: 'openai', modelId: 'gpt-5-mini', label: 'GPT-5 Mini', reasoning: true },
|
||||
// Anthropic
|
||||
'claude-opus-4-7': { provider: 'anthropic', modelId: 'claude-opus-4-7', label: 'Claude Opus 4.7' },
|
||||
'claude-sonnet-4-6': { provider: 'anthropic', modelId: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6' },
|
||||
'claude-haiku-4-5': { provider: 'anthropic', modelId: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5' }
|
||||
'claude-opus-4-7': { provider: 'anthropic', modelId: 'claude-opus-4-7', label: 'Claude Opus 4.7', reasoning: true },
|
||||
'claude-sonnet-4-6': { provider: 'anthropic', modelId: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6', reasoning: true },
|
||||
'claude-haiku-4-5': { provider: 'anthropic', modelId: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5', reasoning: true }
|
||||
};
|
||||
|
||||
const isReasoningModel = (modelId) => Boolean(MODEL_DEFINITIONS[modelId]?.reasoning);
|
||||
|
||||
const isOpenAiReasoningModel = (modelId) => {
|
||||
const def = MODEL_DEFINITIONS[modelId];
|
||||
return Boolean(def?.reasoning && def?.provider === 'openai');
|
||||
};
|
||||
|
||||
// Cache SDK instances. Built-in keyed by `${providerId}:${apiKey}`; compat
|
||||
@@ -208,7 +219,9 @@ const getModel = (modelId, { aiPreferences, getApiKey }) => {
|
||||
throw new Error(`${providerLabel(def.providerId, aiPreferences)} is missing a Base URL. Set one in Preferences > AI.`);
|
||||
}
|
||||
|
||||
return getSdk({ providerId: def.providerId, apiKey, baseURL: def.baseURL })(def.sdkModelId);
|
||||
const sdk = getSdk({ providerId: def.providerId, apiKey, baseURL: def.baseURL });
|
||||
if (isOpenAiCompatibleProviderId(def.providerId)) return sdk.chat(def.sdkModelId);
|
||||
return sdk(def.sdkModelId);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -273,6 +286,8 @@ module.exports = {
|
||||
getCompatEndpoint,
|
||||
isKnownProviderId,
|
||||
isBuiltInModelId,
|
||||
isReasoningModel,
|
||||
isOpenAiReasoningModel,
|
||||
validateApiKeyForProvider,
|
||||
providerLabel
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user