merge: sync main and address review feedback

This commit is contained in:
Johnson-LYS
2026-08-10 17:17:22 +08:00
22 changed files with 2031 additions and 97 deletions

View File

@@ -26,6 +26,7 @@ PR #1 曾把 reasoning 模型的 `defaultTemperature` / `defaultTopP` 写为 `nu
| `provider.schema.json` | `compute/providers/*.json``compute/coding-plans/*.json` | `defaultTemperature`/`defaultTopP` 必须是 number禁止 null/string`additionalProperties: false` | | `provider.schema.json` | `compute/providers/*.json``compute/coding-plans/*.json` | `defaultTemperature`/`defaultTopP` 必须是 number禁止 null/string`additionalProperties: false` |
| `manifest.schema.json` | `manifest.json` | `presetDataVersion` 必须是递增整数 | | `manifest.schema.json` | `manifest.json` | `presetDataVersion` 必须是递增整数 |
| `service-map.schema.json` | `compute/service-map.json` | 每条映射须含 `modelName` + `providerId` | | `service-map.schema.json` | `compute/service-map.json` | 每条映射须含 `modelName` + `providerId` |
| `smart-model-catalog.schema.json` | `compute/smart-routing/model-catalog.json` | 智能路由三档量级、接入面、exact model 能力和稳定优先级 |
| `providers-index.schema.json` | 两个 `_index.json` | `order` 数组无重复 | | `providers-index.schema.json` | 两个 `_index.json` | `order` 数组无重复 |
| `pricing.schema.json` | `compute/pricing.json` | `markupRatio` / `usdToCny` 为正数 | | `pricing.schema.json` | `compute/pricing.json` | `markupRatio` / `usdToCny` 为正数 |
@@ -62,6 +63,17 @@ PR #1 曾把 reasoning 模型的 `defaultTemperature` / `defaultTopP` 写为 `nu
否则老客户端会因未知字段校验失败死锁。 否则老客户端会因未知字段校验失败死锁。
### 智能路由目录的边界
`compute/smart-routing/model-catalog.json` 是路由器直接消费的、按接入面核对过的策略快照:
- `tier``routingPriority``eligibleForAgent``defaultReference` 属于路由策略;
- `capabilities`、上下文和 reasoning 是该 `providerId + model` 接入面的可用能力快照;
- 它不声明 API key、baseUrl、登录状态、用户额度或实时计价`desirecore-cloud` 的连接与计费状态仍由登录后的 Provider 接口动态下发;
- Codex、Claude 条目必须能在对应 `compute/providers/*.json` 中按 exact model 找到,测试会阻止已下线模型继续参与路由。
客户端把本文件作为可热更新主数据源,并保留同 Schema 的内置离线兜底。调整 Provider 或 model-spec 的能力事实时,应同步审阅本目录,避免路由快照漂移。
--- ---
## 本地校验 ## 本地校验
@@ -78,7 +90,7 @@ CIGitHub Actions会在每个 PR 自动运行 `validate` 和 `test`,不
## 数据修改流程 ## 数据修改流程
1. 编辑 `compute/providers/<name>.json``compute/coding-plans/<name>.json``compute/service-map.json` 1. 编辑 `compute/providers/<name>.json``compute/coding-plans/<name>.json``compute/service-map.json``compute/smart-routing/model-catalog.json`
2. 编辑 `compute/providers/_index.json``coding-plans/_index.json`(新增/删除 provider 时) 2. 编辑 `compute/providers/_index.json``coding-plans/_index.json`(新增/删除 provider 时)
3. **必须**递增 `manifest.json#presetDataVersion`,并更新 `updatedAt` 3. **必须**递增 `manifest.json#presetDataVersion`,并更新 `updatedAt`
4. `npm run validate` 本地确认通过 4. `npm run validate` 本地确认通过
@@ -95,3 +107,4 @@ CIGitHub Actions会在每个 PR 自动运行 `validate` 和 `test`,不
- **构建期同步**`npm run sync-config-center` 把数据复制到 desirecore 主仓 `lib/agent-service/defaults/` - **构建期同步**`npm run sync-config-center` 把数据复制到 desirecore 主仓 `lib/agent-service/defaults/`
- **运行时同步**:客户端启动后后台 git fetch 本仓库,每 30 分钟检查一次远程更新 - **运行时同步**:客户端启动后后台 git fetch 本仓库,每 30 分钟检查一次远程更新
- **版本比对**`presetDataVersion`(递增整数)+ digestSHA-256双重校验 - **版本比对**`presetDataVersion`(递增整数)+ digestSHA-256双重校验
- **智能路由目录**:新客户端按文件 mtime 热加载 `compute/smart-routing/model-catalog.json`;缺失或校验失败时使用随客户端发布的内置 JSON

View File

@@ -85,6 +85,49 @@ describe('真实数据全量校验', () => {
assert.equal(result.ok, true, JSON.stringify(result.errors, null, 2)) assert.equal(result.ok, true, JSON.stringify(result.errors, null, 2))
}) })
it('智能路由模型目录应通过 smart-model-catalog schema', () => {
const result = validateFile(
join(ROOT, 'compute', 'smart-routing', 'model-catalog.json'),
validators,
)
assert.equal(result.ok, true, JSON.stringify(result.errors, null, 2))
const catalog = JSON.parse(readFileSync(
join(ROOT, 'compute', 'smart-routing', 'model-catalog.json'),
'utf8',
))
assert.deepEqual(catalog.tiers.map((tier) => tier.id), [
'flagship',
'balanced',
'lightweight',
])
assert.deepEqual(catalog.providers.map((provider) => provider.provider), [
'openai-codex',
'anthropic-claude',
'desirecore-cloud',
])
assert.equal(
catalog.providers.flatMap((provider) => provider.models).length,
37,
)
for (const provider of catalog.providers.filter((item) => item.provider !== 'desirecore-cloud')) {
const providerFile = JSON.parse(readFileSync(
join(ROOT, 'compute', 'providers', `${provider.provider}.json`),
'utf8',
))
assert.equal(providerFile.id, provider.providerId)
const publishedModels = new Set(providerFile.models.map((model) => model.modelName))
for (const model of provider.models) {
assert.equal(
publishedModels.has(model.model),
true,
`${provider.providerId}/${model.model} 必须存在于对应接入面 Provider 清单`,
)
}
}
})
it('两个 _index.json 应通过 providers-index schema', () => { it('两个 _index.json 应通过 providers-index schema', () => {
const r1 = validateFile(join(ROOT, 'compute', 'providers', '_index.json'), validators) const r1 = validateFile(join(ROOT, 'compute', 'providers', '_index.json'), validators)
const r2 = validateFile(join(ROOT, 'compute', 'coding-plans', '_index.json'), validators) const r2 = validateFile(join(ROOT, 'compute', 'coding-plans', '_index.json'), validators)
@@ -102,6 +145,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-5',
'claude-sonnet-5',
])
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(model.extra.serverSideWebSearch.searchRequestPriceUsd, 0.01)
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(model.extra.serverSideWebSearch.searchRequestPriceUsd, 0.01)
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'))
@@ -135,6 +238,28 @@ describe('真实数据全量校验', () => {
} }
}) })
it('新增模型应保留官方输出上限和工作流分类', () => {
const loadSpecs = (provider) => JSON.parse(readFileSync(
join(ROOT, 'compute', 'model-specs', `${provider}.json`),
'utf8',
)).specs
const gemini = loadSpecs('google').find((item) => item.id === 'gemini-3.1-flash-lite-image')
assert.ok(gemini)
assert.equal(gemini.spec.maxOutputTokens, 4096)
assert.ok(gemini.spec.capabilities.includes('image_editing'))
const sonnet = loadSpecs('anthropic').filter((item) => item.id === 'claude-sonnet-5')
assert.equal(sonnet.length, 1, 'claude-sonnet-5 应且仅应有一条规格')
assert.ok(sonnet[0].spec.capabilities.includes('computer_use'))
assert.ok(sonnet[0].spec.serviceType.includes('computer_use'))
const grok = loadSpecs('xai').find((item) => item.id === 'grok-4.5')
assert.ok(grok)
assert.ok(grok.spec.capabilities.includes('reasoning'))
assert.ok(grok.spec.serviceType.includes('reasoning'))
})
it('MiMo V2.5 ASR 应有独立精确规格,避免回落到 MiMo V2.5 family', () => { it('MiMo V2.5 ASR 应有独立精确规格,避免回落到 MiMo V2.5 family', () => {
const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'xiaomi.json'), 'utf8')) const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'xiaomi.json'), 'utf8'))
const specs = specFile.specs.filter((item) => item.id === 'mimo-v2.5-asr') const specs = specFile.specs.filter((item) => item.id === 'mimo-v2.5-asr')
@@ -145,9 +270,61 @@ describe('真实数据全量校验', () => {
assert.ok(specs[0].spec.capabilities.includes('asr')) assert.ok(specs[0].spec.capabilities.includes('asr'))
}) })
it('MiMo V2.5 仅非 Pro 型号应声明多模态能力', () => {
const provider = JSON.parse(readFileSync(join(ROOT, 'compute', 'providers', 'xiaomi.json'), 'utf8'))
const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'xiaomi.json'), 'utf8'))
const specFor = (modelId) => specFile.specs.find((item) => item.id === modelId)
const mimoV25 = specFor('mimo-v2.5')
assert.ok(mimoV25, 'model-specs 缺少 mimo-v2.5')
assert.ok(mimoV25.spec.capabilities.includes('vision'))
assert.ok(mimoV25.spec.serviceType.includes('vision'))
for (const modelId of ['mimo-v2.5-pro', 'mimo-v2-pro']) {
const modelSpec = specFor(modelId)
assert.ok(modelSpec, `model-specs 缺少 ${modelId}`)
assert.equal(modelSpec.spec.capabilities.includes('vision'), false)
assert.equal(modelSpec.spec.serviceType.includes('vision'), false)
}
const pro = provider.models.find((item) => item.modelName === 'mimo-v2.5-pro')
assert.ok(pro, 'provider 缺少 mimo-v2.5-pro')
assert.equal(pro.capabilities.includes('vision'), false)
assert.equal(pro.serviceType.includes('vision'), false)
})
it('Qwen3.8 Max Preview 应在 Token Plan 中提供完整的推理与视觉规格', () => {
const tokenPlan = JSON.parse(readFileSync(join(ROOT, 'compute', 'coding-plans', 'dashscope-token-plan.json'), 'utf8'))
const specFile = JSON.parse(readFileSync(join(ROOT, 'compute', 'model-specs', 'qwen.json'), 'utf8'))
const modelId = 'qwen3.8-max-preview'
const model = tokenPlan.models.find((item) => item.modelName === modelId)
assert.ok(model, `Token Plan 缺少 ${modelId}`)
assert.equal(model.contextWindow, 983616)
assert.equal(model.defaultTemperature, 0.6)
assert.ok(model.capabilities.includes('reasoning'))
assert.ok(model.capabilities.includes('vision'))
assert.ok(model.serviceType.includes('reasoning'))
assert.ok(model.serviceType.includes('vision'))
assert.deepEqual(model.extra.reasoning.supportedEfforts, ['low', 'high', 'xhigh'])
assert.equal(model.extra.reasoning.defaultEffort, 'xhigh')
assert.equal(model.extra.thinkingOnly, true)
assert.equal(model.extra.thinkingMaxTokens, 262144)
assert.equal(model.extra.preserveThinkingDefault, true)
assert.equal(model.extra.supportsParallelToolCalls, false)
const specs = specFile.specs.filter((item) => item.id === modelId)
assert.equal(specs.length, 1, `model-specs 中 ${modelId} 应且仅应有一条规格`)
assert.equal(specs[0].spec.contextWindow, 1000000)
assert.equal(specs[0].spec.defaultTemperature, 0.6)
assert.equal(specs[0].spec.supportsReasoning, true)
assert.ok(specs[0].spec.capabilities.includes('vision'))
})
it('所有 Provider 应按供应商归属计价,模型来源不覆盖供应商币种', () => { it('所有 Provider 应按供应商归属计价,模型来源不覆盖供应商币种', () => {
const expectedCurrencies = { const expectedCurrencies = {
anthropic: 'USD', anthropic: 'USD',
'anthropic-claude': 'USD',
baichuan: 'CNY', baichuan: 'CNY',
baidu: 'CNY', baidu: 'CNY',
cohere: 'USD', cohere: 'USD',
@@ -220,6 +397,28 @@ describe('真实数据全量校验', () => {
}) })
}) })
describe('智能路由模型目录 schema 反例', () => {
const validate = compile('smart-model-catalog')
it('拒绝未声明的策略字段,避免新旧客户端静默分叉', () => {
const data = JSON.parse(readFileSync(
join(ROOT, 'compute', 'smart-routing', 'model-catalog.json'),
'utf8',
))
data.providers[0].models[0].unknownRoutingPolicy = true
assert.equal(validate(data), false)
})
it('拒绝当前客户端未声明支持的目录版本', () => {
const data = JSON.parse(readFileSync(
join(ROOT, 'compute', 'smart-routing', 'model-catalog.json'),
'utf8',
))
data.version = 2
assert.equal(validate(data), false)
})
})
// ==================== Runtime 清单反例 ==================== // ==================== Runtime 清单反例 ====================
describe('runtime-recommended schema 反例', () => { describe('runtime-recommended schema 反例', () => {

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

@@ -26,6 +26,42 @@
} }
}, },
"models": [ "models": [
{
"modelName": "qwen3.8-max-preview",
"displayName": "Qwen3.8 Max Preview (Token Plan)",
"serviceType": [
"chat",
"reasoning",
"vision"
],
"description": "百炼 Token Plan通义千问 3.8 Max 预览版,支持文本与视觉输入,始终开启深度思考",
"contextWindow": 983616,
"maxOutputTokens": 65536,
"capabilities": [
"chat",
"reasoning",
"deep_thinking",
"code",
"vision",
"tool_use",
"agent",
"long_context"
],
"defaultTemperature": 0.6,
"extra": {
"reasoning": {
"supportedEfforts": ["low", "high", "xhigh"],
"defaultEffort": "xhigh"
},
"supportsThinking": true,
"thinkingDefault": true,
"thinkingOnly": true,
"thinkingMaxTokens": 262144,
"preserveThinkingDefault": true,
"supportsParallelToolCalls": false
},
"source": "preset"
},
{ {
"modelName": "qwen3.7-max", "modelName": "qwen3.7-max",
"displayName": "Qwen3.7 Max (Token Plan)", "displayName": "Qwen3.7 Max (Token Plan)",

View File

@@ -1,20 +1,6 @@
{ {
"description": "Anthropic Claude 系列模型规格。参数来源config-center compute/providers/anthropic.json。", "description": "Anthropic Claude 系列模型规格。参数来源config-center compute/providers/anthropic.json。",
"specs": [ "specs": [
{
"id": "claude-sonnet-5",
"displayName": "Claude Sonnet 5",
"family": "claude-sonnet-5",
"match": { "exact": ["claude-sonnet-5"], "patterns": ["claude-sonnet-5*"] },
"spec": {
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": ["chat", "reasoning", "code", "tool_use", "agent", "vision", "long_context"],
"serviceType": ["chat"],
"supportsReasoning": true,
"description": "Anthropic 最强 Sonnet 级模型支持自适应思考effort: low/medium/high/max"
}
},
{ {
"id": "claude-fable-5", "id": "claude-fable-5",
"displayName": "Claude Fable 5", "displayName": "Claude Fable 5",
@@ -29,6 +15,20 @@
"description": "Anthropic 最强模型,基于 Mythos 架构,支持自主知识工作" "description": "Anthropic 最强模型,基于 Mythos 架构,支持自主知识工作"
} }
}, },
{
"id": "claude-opus-5",
"displayName": "Claude Opus 5",
"family": "claude-opus",
"match": { "patterns": ["claude-opus-5*"] },
"spec": {
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": ["chat", "reasoning", "code", "vision", "tool_use", "long_context"],
"serviceType": ["chat"],
"supportsReasoning": true,
"description": "Claude Opus 5Anthropic Opus 系列当前旗舰思考默认开启effort 支持到 max"
}
},
{ {
"id": "claude-opus-4-8", "id": "claude-opus-4-8",
"displayName": "Claude Opus 4.8", "displayName": "Claude Opus 4.8",
@@ -58,6 +58,20 @@
"description": "Anthropic 当前最强通用模型,适合复杂推理和智能体编码任务" "description": "Anthropic 当前最强通用模型,适合复杂推理和智能体编码任务"
} }
}, },
{
"id": "claude-sonnet-5",
"displayName": "Claude Sonnet 5",
"family": "claude-sonnet",
"match": { "patterns": ["claude-sonnet-5*"] },
"spec": {
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": ["chat", "reasoning", "code", "vision", "tool_use", "computer_use", "long_context"],
"serviceType": ["chat", "computer_use"],
"supportsReasoning": true,
"description": "Claude Sonnet 5速度与智能平衡思考默认开启effort 支持到 max"
}
},
{ {
"id": "claude-sonnet-4-6", "id": "claude-sonnet-4-6",
"displayName": "Claude Sonnet 4.6", "displayName": "Claude Sonnet 4.6",

View File

@@ -8,8 +8,8 @@
"match": { "exact": ["gemini-3.1-flash-lite-image"], "patterns": ["gemini-3.1-flash-lite-image*"] }, "match": { "exact": ["gemini-3.1-flash-lite-image"], "patterns": ["gemini-3.1-flash-lite-image*"] },
"spec": { "spec": {
"contextWindow": 65536, "contextWindow": 65536,
"maxOutputTokens": 65536, "maxOutputTokens": 4096,
"capabilities": ["chat", "vision", "image_generation"], "capabilities": ["chat", "vision", "image_generation", "image_editing"],
"serviceType": ["image_gen"], "serviceType": ["image_gen"],
"description": "Nano Banana 2 LiteGoogle 最快的文生图模型" "description": "Nano Banana 2 LiteGoogle 最快的文生图模型"
} }

View File

@@ -1,6 +1,22 @@
{ {
"description": "阿里通义千问 Qwen 系列模型规格。参数来源config-center compute/providers/dashscope.json。", "description": "阿里通义千问 Qwen 系列模型规格。参数来源config-center compute/providers/dashscope.json。",
"specs": [ "specs": [
{
"id": "qwen3.8-max-preview",
"displayName": "Qwen3.8 Max Preview",
"family": "qwen3.8",
"match": { "exact": ["qwen3.8-max-preview"], "patterns": ["qwen3.8-max-preview*"] },
"spec": {
"contextWindow": 1000000,
"maxOutputTokens": 65536,
"capabilities": ["chat", "reasoning", "code", "multilingual", "tool_use", "long_context", "agent", "vision"],
"serviceType": ["chat"],
"defaultTemperature": 0.6,
"defaultTopP": 0.95,
"supportsReasoning": true,
"description": "通义千问 Qwen3.8 Max 预览版100 万上下文,支持视觉理解"
}
},
{ {
"id": "qwen3.7-max", "id": "qwen3.7-max",
"displayName": "Qwen3.7 Max", "displayName": "Qwen3.7 Max",

View File

@@ -10,7 +10,7 @@
"contextWindow": 500000, "contextWindow": 500000,
"maxOutputTokens": 128000, "maxOutputTokens": 128000,
"capabilities": ["chat", "reasoning", "code", "tool_use", "vision", "long_context"], "capabilities": ["chat", "reasoning", "code", "tool_use", "vision", "long_context"],
"serviceType": ["chat"], "serviceType": ["chat", "reasoning"],
"supportsReasoning": true, "supportsReasoning": true,
"description": "xAI 最新旗舰模型,编程和 STEM 领域前沿" "description": "xAI 最新旗舰模型,编程和 STEM 领域前沿"
} }

View File

@@ -18,8 +18,7 @@
"chat", "chat",
"reasoning", "reasoning",
"tool_use", "tool_use",
"code", "code"
"vision"
], ],
"serviceType": [ "serviceType": [
"chat", "chat",
@@ -27,7 +26,7 @@
], ],
"defaultTemperature": 1, "defaultTemperature": 1,
"supportsReasoning": true, "supportsReasoning": true,
"description": "小米 MiMo 旗舰推理模型,支持文本/图像/工具调用" "description": "小米 MiMo 旗舰推理模型,支持文本/工具调用"
} }
}, },
{ {
@@ -78,8 +77,7 @@
"chat", "chat",
"reasoning", "reasoning",
"tool_use", "tool_use",
"code", "code"
"vision"
], ],
"serviceType": [ "serviceType": [
"chat", "chat",

View File

@@ -4,6 +4,7 @@
"openai", "openai",
"openai-codex", "openai-codex",
"anthropic", "anthropic",
"anthropic-claude",
"deepseek", "deepseek",
"dashscope", "dashscope",
"volcengine", "volcengine",

View File

@@ -0,0 +1,149 @@
{
"id": "provider-anthropic-claude-plan-001",
"provider": "anthropic-claude",
"brandGroup": "anthropic",
"label": "Claude 订阅 (Claude Code)",
"baseUrl": "https://api.anthropic.com",
"apiFormat": "anthropic-messages",
"apiKeyRef": "anthropic-claude-oauth-token",
"apiKeyVerified": false,
"enabled": false,
"status": "unconfigured",
"priceCurrency": "USD",
"accessMode": "coding-plan",
"credentialSource": "claude-oauth",
"requiredClientVersion": "10.0.83",
"codingPlan": {
"quotas": {},
"usageTracking": {
"method": "none",
"consoleUrl": "https://claude.ai/settings/usage"
}
},
"services": [
"chat",
"reasoning"
],
"models": [
{
"modelName": "claude-fable-5",
"displayName": "Claude Fable 5",
"serviceType": [
"chat"
],
"description": "Claude 订阅额度计费Anthropic 最高能力公开模型面向长程智能体与高难推理1M 上下文",
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": [
"chat",
"reasoning",
"code",
"vision",
"tool_use",
"agent",
"long_context"
],
"extra": {
"adaptiveThinking": true,
"reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
}
},
"source": "preset"
},
{
"modelName": "claude-opus-5",
"displayName": "Claude Opus 5",
"serviceType": [
"chat"
],
"description": "Claude 订阅额度计费Opus 系列当前旗舰复杂智能体编码与长程任务首选1M 上下文",
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": [
"chat",
"reasoning",
"code",
"vision",
"tool_use",
"agent",
"long_context"
],
"extra": {
"adaptiveThinking": true,
"thinkingOnByDefault": true,
"reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
}
},
"source": "preset"
},
{
"modelName": "claude-sonnet-5",
"displayName": "Claude Sonnet 5",
"serviceType": [
"chat"
],
"description": "Claude 订阅额度计费,速度与智能平衡模型,支持长上下文智能体任务",
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": [
"chat",
"reasoning",
"code",
"vision",
"tool_use",
"agent",
"long_context"
],
"extra": {
"adaptiveThinking": true,
"reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
}
},
"source": "preset"
},
{
"modelName": "claude-haiku-4-5",
"displayName": "Claude Haiku 4.5",
"serviceType": [
"chat"
],
"description": "Claude 订阅额度计费最快模型具备接近前沿模型的智能水平200K 上下文",
"contextWindow": 200000,
"maxOutputTokens": 64000,
"capabilities": [
"chat",
"code",
"vision",
"tool_use"
],
"source": "preset"
}
],
"tombstones": [
"claude-opus-4-8"
]
}

View File

@@ -35,23 +35,40 @@
"inputPrice": 10, "inputPrice": 10,
"outputPrice": 50, "outputPrice": 50,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 1,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 12.5, "write5m": 12.5,
"write1h": 20, "write1h": 20,
"read": 1 "read": 1
}, },
"adaptiveThinking": true, "adaptiveThinking": true,
"reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
},
"samplingParametersDeprecated": true, "samplingParametersDeprecated": true,
"pricingNotes": "Prices are per 1M tokens. Full 1M context is billed at standard pricing." "pricingNotes": "Prices are per 1M tokens. Full 1M context is billed at standard pricing."
} }
}, },
{ {
"modelName": "claude-opus-4-8", "modelName": "claude-opus-5",
"displayName": "Claude Opus 4.8", "displayName": "Claude Opus 5",
"serviceType": [ "serviceType": [
"chat" "chat"
], ],
"description": "Anthropic Opus 复杂智能体编码与企业任务模型1M 上下文", "description": "Anthropic Opus 系列当前旗舰,复杂智能体编码与长程任务能力显著强于 Opus 4.8,价格不变1M 上下文",
"contextWindow": 1000000, "contextWindow": 1000000,
"maxOutputTokens": 128000, "maxOutputTokens": 128000,
"capabilities": [ "capabilities": [
@@ -66,13 +83,32 @@
"inputPrice": 5, "inputPrice": 5,
"outputPrice": 25, "outputPrice": 25,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 2,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 6.25, "write5m": 6.25,
"write1h": 10, "write1h": 10,
"read": 0.5 "read": 0.5
}, },
"promptCacheMinTokens": 512,
"adaptiveThinking": true, "adaptiveThinking": true,
"defaultEffort": "high", "thinkingOnByDefault": true,
"reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
},
"defaultEffort": "xhigh",
"samplingParametersDeprecated": true, "samplingParametersDeprecated": true,
"pricingNotes": "Prices are per 1M tokens. Full 1M context is billed at standard pricing." "pricingNotes": "Prices are per 1M tokens. Full 1M context is billed at standard pricing."
} }
@@ -100,6 +136,13 @@
"inputPrice": 2, "inputPrice": 2,
"outputPrice": 10, "outputPrice": 10,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "anthropic-messages",
"fallbackPriority": 3,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search_20260318"
},
"cachePricing": { "cachePricing": {
"write5m": 2.5, "write5m": 2.5,
"write1h": 4, "write1h": 4,
@@ -110,67 +153,20 @@
"standardInputPrice": 3, "standardInputPrice": 3,
"standardOutputPrice": 15, "standardOutputPrice": 15,
"adaptiveThinking": true, "adaptiveThinking": true,
"defaultEffort": "high", "reasoning": {
"supportedEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"defaultEffort": "xhigh"
},
"defaultEffort": "xhigh",
"samplingParametersDeprecated": true "samplingParametersDeprecated": true
} }
}, },
{
"modelName": "claude-opus-4-7",
"displayName": "Claude Opus 4.7",
"serviceType": [
"chat"
],
"description": "Anthropic 当前最强通用模型,适合复杂推理和智能体编码任务",
"contextWindow": 1000000,
"maxOutputTokens": 128000,
"capabilities": [
"chat",
"reasoning",
"code",
"vision",
"tool_use"
],
"inputPrice": 5,
"outputPrice": 25,
"extra": {
"cachePricing": {
"write5m": 6.25,
"write1h": 10,
"read": 0.5
},
"pricingNotes": "Prices are per 1M tokens. Opus 4.7 includes the full 1M context window at standard pricing."
}
},
{
"modelName": "claude-sonnet-4-6",
"displayName": "Claude Sonnet 4.6",
"serviceType": [
"chat",
"computer_use"
],
"description": "Anthropic 高智能高速度模型,适合编码、工具使用和智能体任务",
"contextWindow": 1000000,
"maxOutputTokens": 64000,
"capabilities": [
"chat",
"reasoning",
"code",
"vision",
"tool_use",
"computer_use"
],
"inputPrice": 3,
"outputPrice": 15,
"defaultTemperature": 1,
"extra": {
"cachePricing": {
"write5m": 3.75,
"write1h": 6,
"read": 0.3
},
"pricingNotes": "Prices are per 1M tokens. Sonnet 4.6 includes the full 1M context window at standard pricing."
}
},
{ {
"modelName": "claude-haiku-4-5", "modelName": "claude-haiku-4-5",
"displayName": "Claude Haiku 4.5", "displayName": "Claude Haiku 4.5",
@@ -200,5 +196,10 @@
"pricingNotes": "Prices are per 1M tokens." "pricingNotes": "Prices are per 1M tokens."
} }
} }
],
"tombstones": [
"claude-opus-4-8",
"claude-opus-4-7",
"claude-sonnet-4-6"
] ]
} }

View File

@@ -33,6 +33,32 @@
"qwen3-max-trans" "qwen3-max-trans"
], ],
"models": [ "models": [
{
"modelName": "qwen3.8-max-preview",
"displayName": "阿里云 Qwen3.8-Max (Preview)",
"serviceType": [
"chat",
"vision"
],
"description": "通义千问3.8 Max 预览版,面向复杂推理与长程 Agent 任务的旗舰模型100万上下文支持视觉理解、内置工具和 Function Calling",
"contextWindow": 1000000,
"maxOutputTokens": 65536,
"capabilities": [
"chat",
"reasoning",
"code",
"multilingual",
"long_context",
"tool_use",
"agent",
"vision"
],
"inputPrice": 12,
"outputPrice": 36,
"defaultTemperature": 0.6,
"defaultTopP": 0.95,
"extra": {}
},
{ {
"modelName": "qwen3.7-max", "modelName": "qwen3.7-max",
"displayName": "阿里云 Qwen3.7-Max", "displayName": "阿里云 Qwen3.7-Max",

View File

@@ -46,6 +46,13 @@
"inputPrice": 5, "inputPrice": 5,
"outputPrice": 30, "outputPrice": 30,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 1,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"cachedInputPrice": 0.5, "cachedInputPrice": 0.5,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -79,6 +86,13 @@
"inputPrice": 30, "inputPrice": 30,
"outputPrice": 180, "outputPrice": 180,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 2,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"responsesOnly": true, "responsesOnly": true,
"reasoningEffort": [ "reasoningEffort": [
"medium", "medium",
@@ -110,6 +124,13 @@
"inputPrice": 2.5, "inputPrice": 2.5,
"outputPrice": 15, "outputPrice": 15,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 3,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"cachedInputPrice": 0.25, "cachedInputPrice": 0.25,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -140,6 +161,13 @@
"inputPrice": 30, "inputPrice": 30,
"outputPrice": 180, "outputPrice": 180,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 4,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"responsesOnly": true, "responsesOnly": true,
"reasoningEffort": [ "reasoningEffort": [
"medium", "medium",
@@ -172,6 +200,13 @@
"inputPrice": 0.75, "inputPrice": 0.75,
"outputPrice": 4.5, "outputPrice": 4.5,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 5,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"cachedInputPrice": 0.075, "cachedInputPrice": 0.075,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -201,6 +236,13 @@
"inputPrice": 0.2, "inputPrice": 0.2,
"outputPrice": 1.25, "outputPrice": 1.25,
"extra": { "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 6,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
},
"cachedInputPrice": 0.02, "cachedInputPrice": 0.02,
"reasoningEffort": [ "reasoningEffort": [
"none", "none",
@@ -395,7 +437,15 @@
], ],
"inputPrice": 1.25, "inputPrice": 1.25,
"outputPrice": 10, "outputPrice": 10,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 7,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-5-pro", "modelName": "gpt-5-pro",
@@ -477,7 +527,15 @@
"outputPrice": 8, "outputPrice": 8,
"defaultTemperature": 1, "defaultTemperature": 1,
"defaultTopP": 1, "defaultTopP": 1,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 8,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-4.1-mini", "modelName": "gpt-4.1-mini",
@@ -499,7 +557,15 @@
"outputPrice": 1.6, "outputPrice": 1.6,
"defaultTemperature": 1, "defaultTemperature": 1,
"defaultTopP": 1, "defaultTopP": 1,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 9,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
}
}
}, },
{ {
"modelName": "gpt-4.1-nano", "modelName": "gpt-4.1-nano",
@@ -754,7 +820,15 @@
], ],
"inputPrice": 1.1, "inputPrice": 1.1,
"outputPrice": 4.4, "outputPrice": 4.4,
"extra": {} "extra": {
"serverSideWebSearch": {
"enabled": true,
"dialect": "openai-responses",
"fallbackPriority": 10,
"searchRequestPriceUsd": 0.01,
"toolType": "web_search"
}
}
} }
], ],
"tombstones": [ "tombstones": [

View File

@@ -31,8 +31,7 @@
"chat", "chat",
"reasoning", "reasoning",
"tool_use", "tool_use",
"code", "code"
"vision"
], ],
"extra": {} "extra": {}
}, },

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -83,8 +83,8 @@
}, },
"credentialSource": { "credentialSource": {
"type": "string", "type": "string",
"enum": ["codex-cli"], "enum": ["codex-cli", "claude-oauth"],
"description": "凭证托管来源。codex-cli密钥由客户端本地 Codex CLI 凭证检测器托管(读取 ~/.codex/auth.json 自动刷新写回fresh token 同步 secrets.json。需 requiredClientVersion ≥ 引入此字段的客户端版本——老客户端不识别本字段,必须先发版铺开 compute.json 韧性(容忍未知字段)再推送本数据" "description": "凭证托管来源。codex-cli密钥由客户端本地 Codex CLI 凭证检测器托管(读取 ~/.codex/auth.json 自动刷新写回fresh token 同步 secrets.jsonclaude-oauthClaude 订阅接入,由客户端 claude-auth 检测器托管——首选复用本机 Claude Code 登录Agent SDK 自读,不写不刷新),或应用内 OAuth / setup-token 兜底;模型调用经 compat-proxy 内 claude-agent-sdk 后端履约,不直连。需 requiredClientVersion ≥ 引入此字段的客户端版本——老客户端不识别本字段,必须先发版铺开 compute.json 韧性(容忍未知字段)再推送本数据"
}, },
"codingPlan": { "codingPlan": {
"type": "object", "type": "object",

View File

@@ -0,0 +1,273 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://desirecore.net/schemas/smart-model-catalog.json",
"title": "SmartModelCatalog",
"description": "智能路由量级、Provider 和模型能力目录Config Center、内置兜底与未来接口共用此契约。",
"type": "object",
"required": [
"version",
"updatedAt",
"source",
"tiers",
"providers"
],
"properties": {
"$schema": {
"type": "string",
"description": "本数据对应的 JSON Schema 标识。"
},
"version": {
"type": "integer",
"minimum": 1,
"maximum": 1,
"description": "目录结构版本;当前客户端只接受 v1不兼容的新语义必须递增版本并由新客户端接入。"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"description": "本目录最近一次人工/自动核对时间。"
},
"source": {
"type": "string",
"enum": [
"builtin",
"config-center",
"provider-api"
],
"description": "目录来源config-center=配置中心下发builtin=客户端离线兜底provider-api=未来接口实时数据。"
},
"tiers": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"items": {
"type": "object",
"required": [
"id",
"label",
"labelEn",
"description",
"defaultReasoning"
],
"properties": {
"id": {
"type": "string",
"enum": [
"flagship",
"balanced",
"lightweight"
],
"description": "智能路由量级flagship=最高能力balanced=质量与成本平衡lightweight=最快最省。"
},
"label": {
"type": "string",
"minLength": 1,
"description": "中文量级标签。"
},
"labelEn": {
"type": "string",
"minLength": 1,
"description": "英文量级标签。"
},
"description": {
"type": "string",
"minLength": 1,
"description": "该量级的任务选择目标。"
},
"defaultReasoning": {
"type": "string",
"enum": [
"auto",
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max"
],
"description": "该量级在模型支持时优先采用的默认思考深度。"
}
},
"additionalProperties": false
},
"description": "三档量级的自描述定义。"
},
"providers": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"providerId",
"provider",
"displayName",
"models"
],
"properties": {
"providerId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "compute.json 中的 Provider 唯一 ID。"
},
"provider": {
"type": "string",
"minLength": 1,
"maxLength": 120,
"description": "Provider 协议标识。"
},
"displayName": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Provider 展示名称。"
},
"models": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"model",
"displayName",
"tier",
"routingPriority",
"serviceTypes",
"capabilities",
"contextWindow",
"maxOutputTokens",
"supportedReasoning",
"defaultReasoning",
"eligibleForAgent",
"defaultReference"
],
"properties": {
"model": {
"type": "string",
"minLength": 1,
"maxLength": 300,
"description": "传给对应 Provider 的真实 modelName禁止使用 smart 等虚拟名称。"
},
"displayName": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "客户端展示名称。"
},
"tier": {
"type": "string",
"enum": [
"flagship",
"balanced",
"lightweight"
],
"description": "此模型在智能路由中的能力量级。"
},
"routingPriority": {
"type": "integer",
"minimum": 0,
"maximum": 10000,
"description": "同一量级内的稳定选择顺序,数值越小越优先;凭据与硬能力校验仍先于此排序。"
},
"serviceTypes": {
"type": "array",
"minItems": 1,
"maxItems": 16,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[a-z0-9_]+$",
"description": "可用于任务硬约束匹配的规范能力标签,例如 vision、code、tool_use、long_context。"
},
"description": "模型服务类型快照,例如 chat、reasoning、image_gen、video_gen。"
},
"capabilities": {
"type": "array",
"maxItems": 64,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"pattern": "^[a-z0-9_]+$",
"description": "可用于任务硬约束匹配的规范能力标签,例如 vision、code、tool_use、long_context。"
},
"description": "模型能力快照;任务 requiredCapabilities 必须全部命中。"
},
"contextWindow": {
"type": [
"integer",
"null"
],
"minimum": 1,
"maximum": 10000000,
"description": "上下文窗口 token 数;非文本模型或未知时为 null。"
},
"maxOutputTokens": {
"type": [
"integer",
"null"
],
"minimum": 1,
"maximum": 1000000,
"description": "最大输出 token 数;未知或不适用时为 null。"
},
"supportedReasoning": {
"type": "array",
"minItems": 1,
"maxItems": 8,
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"auto",
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max"
],
"description": "本次 Run 或当前 assignment 的思考深度;最终值仍受目标 Provider × Model 能力矩阵约束。"
},
"description": "该 Provider × Model 接入面声明的可用 reasoning 档位。"
},
"defaultReasoning": {
"type": "string",
"enum": [
"auto",
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max"
],
"description": "未显式指定时的模型参考 reasoning路由还会结合量级默认值并做能力协商。"
},
"eligibleForAgent": {
"type": "boolean",
"description": "是否可作为 Agent 主模型。图像/视频生成、ASR/TTS 等专用模型为 false。"
},
"defaultReference": {
"type": "boolean",
"description": "是否为 Provider/defaultServiceMap 给出的默认参考。它只影响同级排序,不是强制答案。"
}
},
"additionalProperties": false
},
"description": "该接入面当前已核对的模型目录。"
}
},
"additionalProperties": false
},
"description": "参与智能路由和能力匹配的 Provider 目录。"
}
},
"additionalProperties": false
}

View File

@@ -46,6 +46,7 @@ function pickSchemaKey(absPath) {
if (rel === 'manifest.json') return 'manifest' if (rel === 'manifest.json') return 'manifest'
if (rel === 'compute/pricing.json') return 'pricing' if (rel === 'compute/pricing.json') return 'pricing'
if (rel === 'compute/service-map.json') return 'service-map' if (rel === 'compute/service-map.json') return 'service-map'
if (rel === 'compute/smart-routing/model-catalog.json') return 'smart-model-catalog'
if (rel === 'compute/providers/_index.json') return 'providers-index' if (rel === 'compute/providers/_index.json') return 'providers-index'
if (rel === 'runtimes/recommended.json') return 'runtime-recommended' if (rel === 'runtimes/recommended.json') return 'runtime-recommended'
if (rel === 'runtimes/versions-fallback.json') return 'runtime-versions-fallback' if (rel === 'runtimes/versions-fallback.json') return 'runtime-versions-fallback'