feat(canvas): 云端 Agent - 完成策略分层、节点能力注册与可解释审批改造

This commit is contained in:
ddCat
2026-09-14 17:58:21 +08:00
parent 9727656b2b
commit dca01886f9
65 changed files with 5347 additions and 918 deletions

View File

@@ -258,17 +258,24 @@ for (const [id, name, vendor, baseUrl] of [
add({
id: "openai-images", providerId: "openai-image", name: "OpenAI Images", vendor: "OpenAI", capability: "image",
baseUrl: "https://api.openai.com", auth: bearer, params: imageParams,
notes: "无参考图走 JSON generations;有参考图或蒙版走 multipart edits。quality 的 1k/2k/4k 映射为 OpenAI low/medium/high。",
baseUrl: "https://api.openai.com", auth: bearer, params: imageParams, requiresPublicMediaUrls: true,
notes: "无参考图走 JSON generations;有参考图或蒙版走 JSON edits,并按官方 images 数组传入多张 image_url。quality 的 1k/2k/4k 映射为 OpenAI low/medium/high。",
create: {
method: "POST",
path: "/v1/images/generations",
pathTemplate: conditional(gt(len(ref("request.images")), 0), "/v1/images/edits", "/v1/images/generations"),
contentType: "application/json",
contentTypeTemplate: conditional(gt(len(ref("request.images")), 0), "multipart/form-data", "application/json"),
body: {
model: ref("request.model"),
prompt: ref("request.prompt"),
images: omit(conditional(gt(len(ref("request.images")), 0), map(
filter(sorted(ref("request.images")), "media", ne(ref("media.role"), "mask")),
"media",
{ image_url: ref("media.value") }
))),
mask: omit(conditional(gt(len(filter(ref("request.images"), "media", eq(ref("media.role"), "mask"))), 0), {
image_url: first(map(filter(sorted(ref("request.images")), "media", eq(ref("media.role"), "mask")), "media", ref("media.value")))
})),
n: omit(conditional(gt(ref("request.imageCount"), 0), ref("request.imageCount"), 1)),
size: omit(conditional({ $in: [lower(trim(ref("request.aspectRatio"))), ["", "auto"]] }, null, ref("request.aspectRatio"))),
quality: omit({
@@ -289,14 +296,10 @@ add({
output_format: omit(coalesce(ref("request.providerOptions.openai-image.output_format"), "png")),
output_compression: omit(ref("request.providerOptions.openai-image.output_compression")),
moderation: omit(ref("request.providerOptions.openai-image.moderation")),
response_format: omit(coalesce(ref("request.providerOptions.openai-image.response_format"), "b64_json")),
response_format: omit(ref("request.providerOptions.openai-image.response_format")),
style: omit(ref("request.providerOptions.openai-image.style")),
user: omit(ref("request.providerOptions.openai-image.user"))
},
files: [
{ name: "image", source: filter(ref("request.images"), "media", ne(ref("media.role"), "mask")), filename: "source.png" },
{ name: "mask", source: filter(ref("request.images"), "media", eq(ref("media.role"), "mask")), filename: "mask.png" }
]
}
},
response: {
status: "succeeded",

View File

@@ -40,6 +40,8 @@
| `create.contentType` | `"application/json"` |
| `create.body.model` | `{"$ref":"request.model"}` |
| `create.body.prompt` | `{"$ref":"request.prompt"}` |
| `create.body.images` | `{"$omitEmpty":{"$if":{"condition":{"$gt":[{"$len":{"$ref":"request.images"}},0]},"then":{"$map":{"from":{"$filter":{"from":{"$sortByOrder":{"$ref":"request.images"}},"as":"media","where":{"$ne":[{"$ref":"media.role"},"mask"]}}},"as":"media","in":{"image_url":{"$ref":"media.value"}}}},"else":null}}}` |
| `create.body.mask` | `{"$omitEmpty":{"$if":{"condition":{"$gt":[{"$len":{"$filter":{"from":{"$ref":"request.images"},"as":"media","where":{"$eq":[{"$ref":"media.role"},"mask"]}}}},0]},"then":{"image_url":{"$first":{"$map":{"from":{"$filter":{"from":{"$sortByOrder":{"$ref":"request.images"}},"as":"media","where":{"$eq":[{"$ref":"media.role"},"mask"]}}},"as":"media","in":{"$ref":"media.value"}}}}},"else":null}}}` |
| `create.body.n` | `{"$omitEmpty":{"$if":{"condition":{"$gt":[{"$ref":"request.imageCount"},0]},"then":{"$ref":"request.imageCount"},"else":1}}}` |
| `create.body.size` | `{"$omitEmpty":{"$if":{"condition":{"$in":[{"$lower":{"$trim":{"$ref":"request.aspectRatio"}}},["","auto"]]},"then":null,"else":{"$ref":"request.aspectRatio"}}}}` |
| `create.body.quality` | `{"$omitEmpty":{"$switch":{"cases":[{"when":{"$in":[{"$lower":{"$trim":{"$ref":"request.quality"}}},["1k"]]},"then":"low"},{"when":{"$in":[{"$lower":{"$trim":{"$ref":"request.quality"}}},["2k"]]},"then":"medium"},{"when":{"$in":[{"$lower":{"$trim":{"$ref":"request.quality"}}},["4k"]]},"then":"high"},{"when":{"$in":[{"$lower":{"$trim":{"$ref":"request.quality"}}},["","auto"]]},"then":null}],"default":{"$ref":"request.quality"}}}}` |
@@ -47,15 +49,9 @@
| `create.body.output_format` | `{"$omitEmpty":{"$coalesce":[{"$ref":"request.providerOptions.openai-image.output_format"},"png"]}}` |
| `create.body.output_compression` | `{"$omitEmpty":{"$ref":"request.providerOptions.openai-image.output_compression"}}` |
| `create.body.moderation` | `{"$omitEmpty":{"$ref":"request.providerOptions.openai-image.moderation"}}` |
| `create.body.response_format` | `{"$omitEmpty":{"$coalesce":[{"$ref":"request.providerOptions.openai-image.response_format"},"b64_json"]}}` |
| `create.body.response_format` | `{"$omitEmpty":{"$ref":"request.providerOptions.openai-image.response_format"}}` |
| `create.body.style` | `{"$omitEmpty":{"$ref":"request.providerOptions.openai-image.style"}}` |
| `create.body.user` | `{"$omitEmpty":{"$ref":"request.providerOptions.openai-image.user"}}` |
| `create.files[0].name` | `"image"` |
| `create.files[0].source` | `{"$filter":{"from":{"$ref":"request.images"},"as":"media","where":{"$ne":[{"$ref":"media.role"},"mask"]}}}` |
| `create.files[0].filename` | `"source.png"` |
| `create.files[1].name` | `"mask"` |
| `create.files[1].source` | `{"$filter":{"from":{"$ref":"request.images"},"as":"media","where":{"$eq":[{"$ref":"media.role"},"mask"]}}}` |
| `create.files[1].filename` | `"mask.png"` |
## Provider 扩展键
@@ -85,7 +81,7 @@
## 兼容边界
无参考图走 JSON generations;有参考图或蒙版走 multipart edits。quality 的 1k/2k/4k 映射为 OpenAI low/medium/high。
无参考图走 JSON generations;有参考图或蒙版走 JSON edits,并按官方 images 数组传入多张 image_url。quality 的 1k/2k/4k 映射为 OpenAI low/medium/high。
<!-- YINGCE_MANIFEST_CONTRACT_START -->
## Manifest 完整接口定义
@@ -131,7 +127,7 @@
"agent"
],
"baseUrl": "https://api.openai.com",
"requiresPublicMediaUrls": false,
"requiresPublicMediaUrls": true,
"auth": {
"type": "bearer",
"field": "apiKey"
@@ -214,22 +210,6 @@
}
},
"contentType": "application/json",
"contentTypeTemplate": {
"$if": {
"condition": {
"$gt": [
{
"$len": {
"$ref": "request.images"
}
},
0
]
},
"then": "multipart/form-data",
"else": "application/json"
}
},
"body": {
"model": {
"$ref": "request.model"
@@ -237,6 +217,111 @@
"prompt": {
"$ref": "request.prompt"
},
"images": {
"$omitEmpty": {
"$if": {
"condition": {
"$gt": [
{
"$len": {
"$ref": "request.images"
}
},
0
]
},
"then": {
"$map": {
"from": {
"$filter": {
"from": {
"$sortByOrder": {
"$ref": "request.images"
}
},
"as": "media",
"where": {
"$ne": [
{
"$ref": "media.role"
},
"mask"
]
}
}
},
"as": "media",
"in": {
"image_url": {
"$ref": "media.value"
}
}
}
},
"else": null
}
}
},
"mask": {
"$omitEmpty": {
"$if": {
"condition": {
"$gt": [
{
"$len": {
"$filter": {
"from": {
"$ref": "request.images"
},
"as": "media",
"where": {
"$eq": [
{
"$ref": "media.role"
},
"mask"
]
}
}
}
},
0
]
},
"then": {
"image_url": {
"$first": {
"$map": {
"from": {
"$filter": {
"from": {
"$sortByOrder": {
"$ref": "request.images"
}
},
"as": "media",
"where": {
"$eq": [
{
"$ref": "media.role"
},
"mask"
]
}
}
},
"as": "media",
"in": {
"$ref": "media.value"
}
}
}
}
},
"else": null
}
}
},
"n": {
"$omitEmpty": {
"$if": {
@@ -405,12 +490,7 @@
},
"response_format": {
"$omitEmpty": {
"$coalesce": [
{
"$ref": "request.providerOptions.openai-image.response_format"
},
"b64_json"
]
"$ref": "request.providerOptions.openai-image.response_format"
}
},
"style": {
@@ -423,49 +503,7 @@
"$ref": "request.providerOptions.openai-image.user"
}
}
},
"files": [
{
"name": "image",
"source": {
"$filter": {
"from": {
"$ref": "request.images"
},
"as": "media",
"where": {
"$ne": [
{
"$ref": "media.role"
},
"mask"
]
}
}
},
"filename": "source.png"
},
{
"name": "mask",
"source": {
"$filter": {
"from": {
"$ref": "request.images"
},
"as": "media",
"where": {
"$eq": [
{
"$ref": "media.role"
},
"mask"
]
}
}
},
"filename": "mask.png"
}
]
}
},
"response": {
"status": "succeeded",

File diff suppressed because one or more lines are too long