Release 2.9.3: switch primary to gpt-oss:120b-cloud with mistral vision fallback
- config: primary model → gpt-oss:120b-cloud (faster general chat, 2.72s median) - server-v2: fix vision regex to exclude gpt-oss (gpt(?!-oss) negative lookahead) * gpt-oss was incorrectly matching /gpt/ → image data sent to non-vision model * applied at all 3 _supportsVision check sites (lines 5204, 6362, 7832) - server-v2: vision fallback routing — when primary lacks vision support and user message contains images, automatically route to orchestration.secondary (mistral-large-3:675b-cloud, 4.27s avg, fastest vision cloud model) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
"providers": {
|
||||
"ollama": {
|
||||
"endpoint": "http://localhost:11434",
|
||||
"model": "gemini-3-flash-preview:cloud"
|
||||
"model": "gpt-oss:120b-cloud"
|
||||
},
|
||||
"lm_studio": {
|
||||
"endpoint": "http://host.docker.internal:1234",
|
||||
@@ -45,11 +45,11 @@
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"primary": "gemini-3-flash-preview:cloud",
|
||||
"primary": "gpt-oss:120b-cloud",
|
||||
"roles": {
|
||||
"manager": "gemini-3-flash-preview:cloud",
|
||||
"executor": "gemini-3-flash-preview:cloud",
|
||||
"verifier": "gemini-3-flash-preview:cloud",
|
||||
"manager": "gpt-oss:120b-cloud",
|
||||
"executor": "gpt-oss:120b-cloud",
|
||||
"verifier": "gpt-oss:120b-cloud",
|
||||
"background_task": ""
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5201,7 +5201,7 @@ async function handleChat(
|
||||
? (isBrowserTool ? buildBrowserAck(toolName, toolResult) : buildDesktopAck(toolName, toolResult))
|
||||
: toolResult.result;
|
||||
const _imagingTools3 = new Set(['image_edit', 'image_info', 'image_read', 'python_eval']);
|
||||
const _supportsVision3 = /kimi|openai|claude|gpt|gemini/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _supportsVision3 = /kimi|openai|claude|gemini|gpt(?!-oss)/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _resolvedToolContent3 = _imagingTools3.has(toolName) && typeof toolMessageContent === 'string'
|
||||
? resolveToolImageContent(toolMessageContent, workspacePath, _supportsVision3)
|
||||
: toolMessageContent;
|
||||
@@ -6359,7 +6359,7 @@ RULES:
|
||||
? (isBrowserTool ? buildBrowserAck(toolName, toolResult) : buildDesktopAck(toolName, toolResult))
|
||||
: toolResult.result;
|
||||
const _imagingTools2 = new Set(['image_edit', 'image_info', 'image_read', 'python_eval']);
|
||||
const _supportsVision2 = /kimi|openai|claude|gpt|gemini/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _supportsVision2 = /kimi|openai|claude|gemini|gpt(?!-oss)/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _resolvedContent2 = _imagingTools2.has(toolName) && typeof toolMessageContent === 'string'
|
||||
? resolveToolImageContent(toolMessageContent, workspacePath, _supportsVision2)
|
||||
: toolMessageContent;
|
||||
@@ -6496,8 +6496,20 @@ RULES:
|
||||
);
|
||||
const primaryThinkMode: boolean | 'high' | 'medium' | 'low' = (multiAgentActive && !isActiveAutomationOp) ? true : false;
|
||||
const needsLongOutput = /pptx|powerpoint|presentation|슬라이드|발표|프레젠테이션|게임|코드|스크립트|함수|클래스|구현해|만들어줘|만들어\s*줘|작성해|짜줘|build.*app|create.*app|write.*code|implement.*class|game.*make|전체.*코드|완성된.*코드/i.test(message);
|
||||
// Model priority: explicit request > skill override > config default
|
||||
// Vision fallback: if primary doesn't support vision but messages contain images, use secondary vision model
|
||||
const _visionFallbackModel: string | undefined = (() => {
|
||||
if (/kimi|openai|claude|gemini|gpt(?!-oss)/i.test(String(_activeModelName || ''))) return undefined;
|
||||
const hasImages = messages.some((m: any) =>
|
||||
Array.isArray(m.content) && m.content.some((p: any) => p.type === 'image_url')
|
||||
);
|
||||
if (!hasImages) return undefined;
|
||||
const sec = rawCfgForPreempt.orchestration?.secondary;
|
||||
const secModel = String(sec?.model || '').trim();
|
||||
return (secModel && sec?.vision === true) ? secModel : undefined;
|
||||
})();
|
||||
// Model priority: explicit request > vision fallback > skill override > config default
|
||||
const effectiveModel = String(modelOverride || '').trim()
|
||||
|| _visionFallbackModel
|
||||
|| skillsManager.getModelOverrideForUser(username ? getUserWorkspace(username) : null)
|
||||
|| undefined;
|
||||
// Always use streaming so text tokens appear in real-time. The streaming
|
||||
@@ -7817,7 +7829,7 @@ RULES:
|
||||
? (isBrowserTool ? buildBrowserAck(toolName, toolResult) : buildDesktopAck(toolName, toolResult))
|
||||
: toolResult.result;
|
||||
const _imagingTools = new Set(['image_edit', 'image_info', 'image_read', 'python_eval']);
|
||||
const _supportsVision = /kimi|openai|claude|gpt|gemini/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _supportsVision = /kimi|openai|claude|gemini|gpt(?!-oss)/i.test(String(_activeModelName || primaryProvider || ''));
|
||||
const _resolvedToolContent = _imagingTools.has(toolName) && typeof toolMessageContent === 'string'
|
||||
? resolveToolImageContent(toolMessageContent, workspacePath, _supportsVision)
|
||||
: toolMessageContent;
|
||||
|
||||
Reference in New Issue
Block a user