Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api-providers/image-understanding/_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"description": "image_understanding 工具后端加载顺序索引",
"order": ["configured-vision-openai", "configured-vision-anthropic", "minimax"]
}
32 changes: 32 additions & 0 deletions api-providers/image-understanding/configured-vision-anthropic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"id": "configured-vision-anthropic",
"name": "视觉模型(Anthropic 兼容,复用默认映射)",
"capability": "image_understanding",
"enabled": true,
"builtin": true,
"priority": 20,
"endpoint": "${baseUrl}/messages",
"method": "POST",
"computeServiceType": "vision",
"requiresApiFormat": "anthropic-messages",
"auth": { "type": "header", "headerName": "x-api-key" },
"request": {
"imageMode": "base64",
"headers": { "anthropic-version": "2023-06-01" },
"bodyTemplate": {
"model": "${model}",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{ "type": "image", "source": { "type": "base64", "media_type": "${imageMime}", "data": "${imageBase64}" } },
{ "type": "text", "text": "${prompt}" }
]
}
]
}
},
"response": { "textPath": "content.0.text" },
"timeoutMs": 30000
}
30 changes: 30 additions & 0 deletions api-providers/image-understanding/configured-vision-openai.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"id": "configured-vision-openai",
"name": "视觉模型(OpenAI 兼容,复用默认映射)",
"capability": "image_understanding",
"enabled": true,
"builtin": true,
"priority": 10,
"endpoint": "${baseUrl}/chat/completions",
"method": "POST",
"computeServiceType": "vision",
"requiresApiFormat": "openai-completions",
"auth": { "type": "bearer" },
"request": {
"imageMode": "url",
"bodyTemplate": {
"model": "${model}",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "${prompt}" },
{ "type": "image_url", "image_url": { "url": "${imageUrl}" } }
]
}
]
}
},
"response": { "textPath": "choices.0.message.content" },
"timeoutMs": 30000
}
18 changes: 18 additions & 0 deletions api-providers/image-understanding/minimax.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "minimax",
"name": "MiniMax 图像理解(内测网关)",
"capability": "image_understanding",
"enabled": false,
"builtin": true,
"priority": 30,
"endpoint": "${baseUrl}/understand_image",
"method": "POST",
"baseUrlRef": "internal-testing",
"auth": { "type": "bearer" },
"request": {
"imageMode": "url",
"bodyTemplate": { "prompt": "${prompt}", "image_url": "${imageUrl}" }
},
"response": { "textPath": "text" },
"timeoutMs": 30000
}
4 changes: 4 additions & 0 deletions api-providers/web-search/_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"description": "web_search 工具后端加载顺序索引",
"order": ["tavily", "serper", "minimax"]
}
20 changes: 20 additions & 0 deletions api-providers/web-search/minimax.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id": "minimax",
"name": "MiniMax 搜索(内测网关)",
"capability": "web_search",
"enabled": false,
"builtin": true,
"priority": 30,
"endpoint": "${baseUrl}/web_search",
"method": "POST",
"baseUrlRef": "internal-testing",
"auth": { "type": "bearer" },
"request": {
"bodyTemplate": { "query": "${query}", "num_results": "${maxResults}" }
},
"response": {
"resultsPath": "results",
"item": { "titlePath": "title", "urlPath": "url", "snippetPath": "content" }
},
"timeoutMs": 10000
}
19 changes: 19 additions & 0 deletions api-providers/web-search/serper.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "serper",
"name": "Serper",
"capability": "web_search",
"enabled": false,
"builtin": true,
"priority": 20,
"endpoint": "https://google.serper.dev/search",
"method": "POST",
"auth": { "type": "header", "headerName": "X-API-KEY", "apiKeyRef": "serper" },
"request": {
"bodyTemplate": { "q": "${query}", "num": "${maxResults}" }
},
"response": {
"resultsPath": "organic",
"item": { "titlePath": "title", "urlPath": "link", "snippetPath": "snippet" }
},
"timeoutMs": 10000
}
23 changes: 23 additions & 0 deletions api-providers/web-search/tavily.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "tavily",
"name": "Tavily",
"capability": "web_search",
"enabled": false,
"builtin": true,
"priority": 10,
"endpoint": "https://api.tavily.com/search",
"method": "POST",
"auth": { "type": "bearer", "apiKeyRef": "tavily" },
"request": {
"bodyTemplate": {
"query": "${query}",
"max_results": "${maxResults}",
"search_depth": "basic"
}
},
"response": {
"resultsPath": "results",
"item": { "titlePath": "title", "urlPath": "url", "snippetPath": "content" }
},
"timeoutMs": 10000
}
69 changes: 69 additions & 0 deletions schemas/api-provider.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://desirecore.net/schemas/config-center/api-provider.schema.json",
"title": "ApiProvider",
"description": "api-providers/<capability>/*.json:声明式外部 API 供应商(web_search / image_understanding 工具后端)。镜像 desirecore 主仓 lib/schemas/agent-service/api-provider.ts。",
"type": "object",
"required": ["id", "name", "capability", "enabled", "endpoint", "auth", "request", "response"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "同 capability 下唯一标识" },
"name": { "type": "string", "description": "显示名称" },
"capability": {
"type": "string",
"enum": ["web_search", "image_understanding"],
"description": "服务的工具能力"
},
"enabled": { "type": "boolean", "description": "是否启用" },
"builtin": { "type": "boolean", "description": "是否为内置默认", "default": false },
"priority": { "type": "number", "description": "优先级,越小越优先", "default": 100 },
"endpoint": { "type": "string", "description": "API 端点 URL,支持 ${变量}" },
"method": { "type": "string", "enum": ["POST", "GET"], "description": "HTTP 方法", "default": "POST" },
"computeServiceType": { "type": "string", "description": "复用算力默认映射的服务类型(如 vision)" },
"requiresApiFormat": { "type": "string", "description": "仅当解析出的 provider apiFormat 等于此值时可用" },
"baseUrlRef": { "type": "string", "description": "指向某算力 provider 的 provider 标识,取其 baseUrl 与密钥" },
"auth": {
"type": "object",
"description": "鉴权配置",
"required": ["type"],
"additionalProperties": false,
"properties": {
"type": { "type": "string", "enum": ["bearer", "header", "query", "none"] },
"apiKeyRef": { "type": "string", "description": "secrets.json 中的密钥引用名" },
"headerName": { "type": "string", "description": "type=header 时的请求头名称" },
"queryParam": { "type": "string", "description": "type=query 时的查询参数名" }
}
},
Comment on lines +25 to +36
"request": {
"type": "object",
"description": "请求构造,字符串值支持 ${变量}",
"additionalProperties": false,
"properties": {
"headers": { "type": "object", "additionalProperties": { "type": "string" } },
"bodyTemplate": { "type": "object", "additionalProperties": true },
"queryParams": { "type": "object", "additionalProperties": { "type": "string" } },
"imageMode": { "type": "string", "enum": ["url", "base64"] }
}
},
"response": {
"type": "object",
"description": "响应提取",
"additionalProperties": false,
"properties": {
"resultsPath": { "type": "string", "description": "web_search 结果数组的点路径" },
"item": {
"type": "object",
"additionalProperties": false,
"properties": {
"titlePath": { "type": "string" },
"urlPath": { "type": "string" },
"snippetPath": { "type": "string" },
"pageAgePath": { "type": "string" }
}
},
"textPath": { "type": "string", "description": "image_understanding 结果文本的点路径" }
}
},
"timeoutMs": { "type": "number", "description": "请求超时(毫秒)", "default": 10000 }
}
}
3 changes: 3 additions & 0 deletions scripts/validate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ function pickSchemaKey(absPath) {
if (rel.startsWith('compute/providers/') && rel.endsWith('.json')) return 'provider'
if (rel.startsWith('compute/coding-plans/') && rel.endsWith('.json')) return 'provider'
if (rel.startsWith('compute/model-specs/') && rel.endsWith('.json')) return 'model-spec'
// api-providers/<capability>/*.json:声明式外部 API 供应商(_index.json 复用 providers-index)
if (rel.startsWith('api-providers/') && rel.endsWith('/_index.json')) return 'providers-index'
if (rel.startsWith('api-providers/') && rel.endsWith('.json')) return 'api-provider'
return null
}

Expand Down
Loading