feat: configure tiered web search providers (#64)

This commit is contained in:
2026-07-24 00:30:47 +08:00
committed by GitHub
parent e59adbb166
commit 96842d2080
7 changed files with 197 additions and 8 deletions

View File

@@ -102,6 +102,66 @@ describe('真实数据全量校验', () => {
assert.equal(result.ok, true, JSON.stringify(result.errors, null, 2)) assert.equal(result.ok, true, JSON.stringify(result.errors, null, 2))
}) })
it('WebSearch 服务端能力仅标记官方直连 Anthropic/OpenAI 模型', () => {
const anthropic = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'anthropic.json'), 'utf8'))
const openai = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'openai.json'), 'utf8'))
const openaiCodex = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'openai-codex.json'), 'utf8'))
const enabled = (provider) => provider.models
.filter((model) => model.extra?.serverSideWebSearch?.enabled === true)
.map((model) => model.modelName)
assert.deepEqual(enabled(anthropic), [
'claude-fable-5',
'claude-opus-4-8',
'claude-sonnet-5',
'claude-opus-4-7',
'claude-sonnet-4-6',
])
assert.deepEqual(enabled(openai), [
'gpt-5.5',
'gpt-5.5-pro',
'gpt-5.4',
'gpt-5.4-pro',
'gpt-5.4-mini',
'gpt-5.4-nano',
'gpt-5',
'gpt-4.1',
'gpt-4.1-mini',
'o4-mini',
])
assert.deepEqual(enabled(openaiCodex), [])
for (const model of anthropic.models.filter((item) => enabled(anthropic).includes(item.modelName))) {
assert.equal(model.extra.serverSideWebSearch.dialect, 'anthropic-messages')
assert.equal(model.extra.serverSideWebSearch.toolType, 'web_search_20260318')
assert.equal('maxUses' in model.extra.serverSideWebSearch, false)
}
for (const model of openai.models.filter((item) => enabled(openai).includes(item.modelName))) {
assert.equal(model.extra.serverSideWebSearch.dialect, 'openai-responses')
assert.equal(model.extra.serverSideWebSearch.toolType, 'web_search')
assert.equal('maxUses' in model.extra.serverSideWebSearch, false)
}
})
it('Brave Search API 使用显式密钥声明且默认关闭', () => {
const brave = JSON.parse(readFileSync(join(ROOT, 'api-providers', 'web-search', 'brave.json'), 'utf8'))
const index = JSON.parse(readFileSync(join(ROOT, 'api-providers', 'web-search', '_index.json'), 'utf8'))
assert.equal(brave.enabled, false)
assert.equal(brave.endpoint, 'https://api.search.brave.com/res/v1/web/search')
assert.deepEqual(brave.auth, {
type: 'header',
headerName: 'X-Subscription-Token',
apiKeyRef: 'brave',
})
assert.deepEqual(index.order, ['tavily', 'brave', 'serper'])
assert.equal(
validateFile(join(ROOT, 'api-providers', 'web-search', 'brave.json'), validators).ok,
true,
)
})
it('DeepSeek V4 Pro/Flash 应与官方的 1M/384K reasoning profile 一致', () => { it('DeepSeek V4 Pro/Flash 应与官方的 1M/384K reasoning profile 一致', () => {
const provider = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'deepseek.json'), 'utf8')) const provider = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'deepseek.json'), 'utf8'))
const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'deepseek.json'), 'utf8')) const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'deepseek.json'), 'utf8'))

View File

@@ -1,4 +1,4 @@
{ {
"description": "web_search 工具后端加载顺序索引", "description": "web_search 工具后端加载顺序索引",
"order": ["tavily", "serper"] "order": ["tavily", "brave", "serper"]
} }

View File

@@ -0,0 +1,35 @@
{
"id": "brave",
"name": "Brave Search API",
"capability": "web_search",
"enabled": false,
"builtin": true,
"priority": 20,
"endpoint": "https://api.search.brave.com/res/v1/web/search",
"method": "GET",
"auth": {
"type": "header",
"headerName": "X-Subscription-Token",
"apiKeyRef": "brave"
},
"request": {
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip"
},
"queryParams": {
"q": "${query}",
"count": "${maxResults}"
}
},
"response": {
"resultsPath": "web.results",
"item": {
"titlePath": "title",
"urlPath": "url",
"snippetPath": "description",
"pageAgePath": "page_age"
}
},
"timeoutMs": 10000
}

View File

@@ -4,7 +4,7 @@
"capability": "web_search", "capability": "web_search",
"enabled": false, "enabled": false,
"builtin": true, "builtin": true,
"priority": 20, "priority": 30,
"endpoint": "https://google.serper.dev/search", "endpoint": "https://google.serper.dev/search",
"method": "POST", "method": "POST",
"auth": { "type": "header", "headerName": "X-API-KEY", "apiKeyRef": "serper" }, "auth": { "type": "header", "headerName": "X-API-KEY", "apiKeyRef": "serper" },

View File

@@ -35,6 +35,12 @@
"inputPrice": 10, "inputPrice": 10,
"outputPrice": 50, "outputPrice": 50,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 1,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 12.5, "write5m": 12.5,
"write1h": 20, "write1h": 20,
@@ -66,6 +72,12 @@
"inputPrice": 5, "inputPrice": 5,
"outputPrice": 25, "outputPrice": 25,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 2,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 6.25, "write5m": 6.25,
"write1h": 10, "write1h": 10,
@@ -100,6 +112,12 @@
"inputPrice": 2, "inputPrice": 2,
"outputPrice": 10, "outputPrice": 10,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 3,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 2.5, "write5m": 2.5,
"write1h": 4, "write1h": 4,
@@ -133,6 +151,12 @@
"inputPrice": 5, "inputPrice": 5,
"outputPrice": 25, "outputPrice": 25,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 4,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 6.25, "write5m": 6.25,
"write1h": 10, "write1h": 10,
@@ -163,6 +187,12 @@
"outputPrice": 15, "outputPrice": 15,
"defaultTemperature": 1, "defaultTemperature": 1,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 5,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 3.75, "write5m": 3.75,
"write1h": 6, "write1h": 6,

View File

@@ -46,6 +46,12 @@
"inputPrice": 5, "inputPrice": 5,
"outputPrice": 30, "outputPrice": 30,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 1,
"toolType": "web_search"
},
"cachedInputPrice": 0.5, "cachedInputPrice": 0.5,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -79,6 +85,12 @@
"inputPrice": 30, "inputPrice": 30,
"outputPrice": 180, "outputPrice": 180,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 2,
"toolType": "web_search"
},
"responsesOnly": true, "responsesOnly": true,
"reasoningEffort": [ "reasoningEffort": [
"medium", "medium",
@@ -110,6 +122,12 @@
"inputPrice": 2.5, "inputPrice": 2.5,
"outputPrice": 15, "outputPrice": 15,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 3,
"toolType": "web_search"
},
"cachedInputPrice": 0.25, "cachedInputPrice": 0.25,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -140,6 +158,12 @@
"inputPrice": 30, "inputPrice": 30,
"outputPrice": 180, "outputPrice": 180,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 4,
"toolType": "web_search"
},
"responsesOnly": true, "responsesOnly": true,
"reasoningEffort": [ "reasoningEffort": [
"medium", "medium",
@@ -172,6 +196,12 @@
"inputPrice": 0.75, "inputPrice": 0.75,
"outputPrice": 4.5, "outputPrice": 4.5,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 5,
"toolType": "web_search"
},
"cachedInputPrice": 0.075, "cachedInputPrice": 0.075,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -201,6 +231,12 @@
"inputPrice": 0.2, "inputPrice": 0.2,
"outputPrice": 1.25, "outputPrice": 1.25,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 6,
"toolType": "web_search"
},
"cachedInputPrice": 0.02, "cachedInputPrice": 0.02,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -395,7 +431,14 @@
], ],
"inputPrice": 1.25, "inputPrice": 1.25,
"outputPrice": 10, "outputPrice": 10,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 7,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-5-pro", "modelName": "gpt-5-pro",
@@ -477,7 +520,14 @@
"outputPrice": 8, "outputPrice": 8,
"defaultTemperature": 1, "defaultTemperature": 1,
"defaultTopP": 1, "defaultTopP": 1,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 8,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-4.1-mini", "modelName": "gpt-4.1-mini",
@@ -499,7 +549,14 @@
"outputPrice": 1.6, "outputPrice": 1.6,
"defaultTemperature": 1, "defaultTemperature": 1,
"defaultTopP": 1, "defaultTopP": 1,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 9,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-4.1-nano", "modelName": "gpt-4.1-nano",
@@ -754,7 +811,14 @@
], ],
"inputPrice": 1.1, "inputPrice": 1.1,
"outputPrice": 4.4, "outputPrice": 4.4,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 10,
"toolType": "web_search"
}
}
} }
], ],
"tombstones": [ "tombstones": [

View File

@@ -1,6 +1,6 @@
{ {
"version": "1.0.0", "version": "1.0.0",
"presetDataVersion": 79, "presetDataVersion": 80,
"updatedAt": "2026-07-20", "updatedAt": "2026-07-23",
"description": "DesireCore 官方配置中心" "description": "DesireCore 官方配置中心"
} }