diff --git a/src/common/stores/llms/llms.parameters.ts b/src/common/stores/llms/llms.parameters.ts index 7f4c0e620..167194c8c 100644 --- a/src/common/stores/llms/llms.parameters.ts +++ b/src/common/stores/llms/llms.parameters.ts @@ -88,6 +88,22 @@ export const DModelParameterRegistry = { } as const, } as const, + llmVndAntWebSearch: { + label: 'Web Search', + type: 'enum' as const, + description: 'Enable web search for real-time information', + values: ['auto', 'off'] as const, + // No initialValue - undefined means off (same as 'off') + } as const, + + llmVndAntWebFetch: { + label: 'Web Fetch', + type: 'enum' as const, + description: 'Enable fetching content from web pages and PDFs', + values: ['auto', 'off'] as const, + // No initialValue - undefined means off (same as 'off') + } as const, + llmVndGeminiAspectRatio: { label: 'Aspect Ratio', type: 'enum' as const, diff --git a/src/modules/aix/server/api/aix.wiretypes.ts b/src/modules/aix/server/api/aix.wiretypes.ts index 34f18a0b2..2fee11516 100644 --- a/src/modules/aix/server/api/aix.wiretypes.ts +++ b/src/modules/aix/server/api/aix.wiretypes.ts @@ -406,6 +406,8 @@ export namespace AixWire_API { topP: z.number().min(0).max(1).optional(), forceNoStream: z.boolean().optional(), vndAntThinkingBudget: z.number().nullable().optional(), + vndAntWebSearch: z.enum(['auto', 'off']).optional(), + vndAntWebFetch: z.enum(['auto', 'off']).optional(), vndGeminiAspectRatio: z.enum(['1:1', '2:3', '3:2', '3:4', '4:3', '9:16', '16:9', '21:9']).optional(), vndGeminiGoogleSearch: z.enum(['unfiltered', '1d', '1w', '1m', '6m', '1y']).optional(), vndGeminiShowThoughts: z.boolean().optional(), diff --git a/src/modules/aix/server/dispatch/chatGenerate/adapters/anthropic.messageCreate.ts b/src/modules/aix/server/dispatch/chatGenerate/adapters/anthropic.messageCreate.ts index cf4806bb8..354acba1b 100644 --- a/src/modules/aix/server/dispatch/chatGenerate/adapters/anthropic.messageCreate.ts +++ b/src/modules/aix/server/dispatch/chatGenerate/adapters/anthropic.messageCreate.ts @@ -141,12 +141,38 @@ export function aixToAnthropicMessageCreate(model: AixAPI_Model, _chatGenerate: // --- Tools --- // Allow/deny auto-adding hosted tools when custom tools are present - // const hasCustomTools = chatGenerate.tools?.some(t => t.type === 'function_call'); - // const hasRestrictivePolicy = chatGenerate.toolsPolicy?.type === 'any' || chatGenerate.toolsPolicy?.type === 'function_call'; - // const skipHostedToolsDueToCustomTools = hasCustomTools && hasRestrictivePolicy; + const hasCustomTools = chatGenerate.tools?.some(t => t.type === 'function_call'); + const hasRestrictivePolicy = chatGenerate.toolsPolicy?.type === 'any' || chatGenerate.toolsPolicy?.type === 'function_call'; + const skipHostedToolsDueToCustomTools = hasCustomTools && hasRestrictivePolicy; // Hosted tools - // ... + if (!skipHostedToolsDueToCustomTools) { + const hostedTools: NonNullable = []; + + // Web Search Tool + if (model.vndAntWebSearch === 'auto') { + hostedTools.push({ + type: 'web_search_20250305', + name: 'web_search', + max_uses: 5, // Allow up to 5 progressive searches + }); + } + + // Web Fetch Tool + if (model.vndAntWebFetch === 'auto') { + hostedTools.push({ + type: 'web_fetch_20250910', + name: 'web_fetch', + max_uses: 5, // Allow up to 5 fetches + citations: { enabled: true }, // Enable citations + }); + } + + // Merge hosted tools with custom tools + if (hostedTools.length > 0) { + payload.tools = payload.tools ? [...payload.tools, ...hostedTools] : hostedTools; + } + } // Preemptive error detection with server-side payload validation before sending it upstream diff --git a/src/modules/aix/server/dispatch/chatGenerate/chatGenerate.dispatch.ts b/src/modules/aix/server/dispatch/chatGenerate/chatGenerate.dispatch.ts index 679f41ae5..24edb9832 100644 --- a/src/modules/aix/server/dispatch/chatGenerate/chatGenerate.dispatch.ts +++ b/src/modules/aix/server/dispatch/chatGenerate/chatGenerate.dispatch.ts @@ -36,15 +36,28 @@ export function createChatGenerateDispatch(access: AixAPI_Access, model: AixAPI_ } { switch (access.dialect) { - case 'anthropic': + case 'anthropic': { + const anthropicRequest = anthropicAccess(access, model.id, '/v1/messages'); + + // Add web fetch beta header if enabled + if (model.vndAntWebFetch === 'auto') { + const currentBeta = anthropicRequest.headers['anthropic-beta'] as string || ''; + const betaFeatures = currentBeta ? currentBeta.split(',') : []; + if (!betaFeatures.includes('web-fetch-2025-09-10')) { + betaFeatures.push('web-fetch-2025-09-10'); + anthropicRequest.headers['anthropic-beta'] = betaFeatures.join(','); + } + } + return { request: { - ...anthropicAccess(access, model.id, '/v1/messages'), + ...anthropicRequest, body: aixToAnthropicMessageCreate(model, chatGenerate, streaming), }, demuxerFormat: streaming ? 'fast-sse' : null, chatGenerateParse: streaming ? createAnthropicMessageParser() : createAnthropicMessageParserNS(), }; + } case 'gemini': /** diff --git a/src/modules/llms/models-modal/LLMParametersEditor.tsx b/src/modules/llms/models-modal/LLMParametersEditor.tsx index c7a56c11c..23ee07745 100644 --- a/src/modules/llms/models-modal/LLMParametersEditor.tsx +++ b/src/modules/llms/models-modal/LLMParametersEditor.tsx @@ -80,6 +80,18 @@ const _xaiSearchModeOptions = [ { value: 'off', label: 'Off', description: 'Never perform a search' }, ] as const; +const _antWebSearchOptions = [ + { value: 'auto', label: 'On', description: 'Enable web search for real-time information' }, + { value: 'off', label: 'Off', description: 'Disabled (default)' }, + { value: _UNSPECIFIED, label: 'Off', description: 'Disabled (default)' }, +] as const; + +const _antWebFetchOptions = [ + { value: 'auto', label: 'On', description: 'Enable fetching web content and PDFs' }, + { value: 'off', label: 'Off', description: 'Disabled (default)' }, + { value: _UNSPECIFIED, label: 'Off', description: 'Disabled (default)' }, +] as const; + const _imageGenerationOptions = [ { value: _UNSPECIFIED, label: 'Off', description: 'Default (disabled)' }, { value: 'mq', label: 'Standard', description: 'Quick gen' }, @@ -132,6 +144,8 @@ export function LLMParametersEditor(props: { llmTemperature = FALLBACK_LLM_PARAM_TEMPERATURE, // fallback for undefined, result is number | null llmForceNoStream, llmVndAntThinkingBudget, + llmVndAntWebSearch, + llmVndAntWebFetch, llmVndGeminiAspectRatio, llmVndGeminiGoogleSearch, llmVndGeminiShowThoughts, @@ -252,6 +266,32 @@ export function LLMParametersEditor(props: { /> )} + {showParam('llmVndAntWebSearch') && ( + { + if (value === _UNSPECIFIED || !value || value === 'off') onRemoveParameter('llmVndAntWebSearch'); + else onChangeParameter({ llmVndAntWebSearch: value }); + }} + options={_antWebSearchOptions} + /> + )} + + {showParam('llmVndAntWebFetch') && ( + { + if (value === _UNSPECIFIED || !value || value === 'off') onRemoveParameter('llmVndAntWebFetch'); + else onChangeParameter({ llmVndAntWebFetch: value }); + }} + options={_antWebFetchOptions} + /> + )} + {showParam('llmVndGeminiAspectRatio') && ( 200K: $6/$22.50. Using lower tier as base. chatPrice: { input: 3, output: 15, cache: { cType: 'ant-bp', read: 0.30, write: 3.75, duration: 300 } }, benchmark: { cbaElo: 1438 + 1 }, // FALLBACK-UNTIL-AVAILABLE: claude-opus-4-1-20250805 + 1 @@ -95,6 +123,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 64000, trainingDataCutoff: 'Jul 2025', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 1, output: 5, cache: { cType: 'ant-bp', read: 0.10, write: 1.25, duration: 300 } }, }, @@ -107,6 +139,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 32000, trainingDataCutoff: 'Mar 2025', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 15, output: 75, cache: { cType: 'ant-bp', read: 1.50, write: 18.75, duration: 300 } }, benchmark: { cbaElo: 1438 }, // claude-opus-4-1-20250805 }, @@ -121,6 +157,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 32000, trainingDataCutoff: 'Mar 2025', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 15, output: 75, cache: { cType: 'ant-bp', read: 1.50, write: 18.75, duration: 300 } }, benchmark: { cbaElo: 1411 }, // claude-opus-4-20250514 }, @@ -132,6 +172,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 64000, trainingDataCutoff: 'Mar 2025', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 3, output: 15, cache: { cType: 'ant-bp', read: 0.30, write: 3.75, duration: 300 } }, benchmark: { cbaElo: 1386 }, // claude-sonnet-4-20250514 }, @@ -145,6 +189,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 64000, trainingDataCutoff: 'Nov 2024', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 3, output: 15, cache: { cType: 'ant-bp', read: 0.30, write: 3.75, duration: 300 } }, benchmark: { cbaElo: 1369 }, // claude-3-7-sonnet-20250219 }, @@ -184,6 +232,10 @@ export const hardcodedAnthropicModels: (ModelDescriptionSchema & { isLegacy?: bo maxCompletionTokens: 8192, trainingDataCutoff: 'Jul 2024', interfaces: [LLM_IF_OAI_Chat, LLM_IF_OAI_Vision, LLM_IF_OAI_Fn, LLM_IF_ANT_PromptCaching], + parameterSpecs: [ + { paramId: 'llmVndAntWebSearch' }, + { paramId: 'llmVndAntWebFetch' }, + ], chatPrice: { input: 0.80, output: 4.00, cache: { cType: 'ant-bp', read: 0.08, write: 1.00, duration: 300 } }, benchmark: { cbaElo: 1319, cbaMmlu: 75.2 }, // claude-3-5-haiku-20241022 },