best-geo-test 2.0.0-beta.2 → 2.0.2-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/capabilities/capabilities.json +95 -10
- package/dist/index.cjs +1 -1
- package/guides/answer-card.json +1 -1
- package/guides/article-task.json +2 -1
- package/guides/article.json +5 -4
- package/guides/knowledge.json +6 -5
- package/guides/material.json +2 -1
- package/guides/publication.json +20 -8
- package/guides/question-task.json +2 -1
- package/guides/scheduled-monitor.json +2 -1
- package/guides/video.json +2 -1
- package/package.json +1 -1
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
"maxLength": 255
|
|
236
236
|
},
|
|
237
237
|
"maxItems": 100,
|
|
238
|
-
"description": "
|
|
238
|
+
"description": "问题文本数组,不是换行字符串。每条里不能带换行,带了会被服务端拒绝——一条问题就是一个数组元素"
|
|
239
239
|
},
|
|
240
240
|
"tags": {
|
|
241
241
|
"type": "array",
|
|
@@ -3566,14 +3566,14 @@
|
|
|
3566
3566
|
"mode": "read",
|
|
3567
3567
|
"guide": "publication",
|
|
3568
3568
|
"requiresPlan": false,
|
|
3569
|
-
"description": "
|
|
3569
|
+
"description": "当前能用的自媒体发布平台。文章平台、视频平台、图文平台是三批,建发布任务前先按 contentType 取对应的那批——拿文章平台去发视频或图文会被拒。返回里的 **limitConfig 是这个平台对内容的字数/张数要求**:文章平台是 titleMaxLength 标题上限 / contentMinLength 正文下限 / contentMaxLength 正文上限(0 表示该项不限;为 null 表示这个平台不限字数),**视频任务不查字数**,视频平台这一项恒为 null;**图文平台**看的是标题长度(titleMinLength / titleMaxLength)、描述长度(summaryMinLength / summaryMaxLength,对应答案卡的发布描述),建图文任务时按它校验答案卡;**图片张数上限以 plan 阶段的报错为准**(各图文平台不同,不要只凭 imageMaxCount 判断)。**remark 是投稿要求备注**(比如不收带外链的稿子)。不满足要求的内容建任务时会被拒,挑内容前先看这里。",
|
|
3570
3570
|
"inputSchema": {
|
|
3571
3571
|
"type": "object",
|
|
3572
3572
|
"properties": {
|
|
3573
3573
|
"contentType": {
|
|
3574
3574
|
"type": "string",
|
|
3575
|
-
"enum": ["article", "video"],
|
|
3576
|
-
"description": "
|
|
3575
|
+
"enum": ["article", "video", "image"],
|
|
3576
|
+
"description": "只看发文章的、发视频的还是发图文的(图文内容来自 AI 答案卡)。不传就是全部"
|
|
3577
3577
|
}
|
|
3578
3578
|
},
|
|
3579
3579
|
"additionalProperties": false
|
|
@@ -3620,7 +3620,7 @@
|
|
|
3620
3620
|
"mode": "read",
|
|
3621
3621
|
"guide": "publication",
|
|
3622
3622
|
"requiresPlan": false,
|
|
3623
|
-
"description": "发布记录:每条内容在每个平台的实际下场。限定在当前 GEO 项目内。这是「发出去了没有、发到哪个链接、失败为什么」的唯一出处——用户问「小红书那篇发了吗」就查这里。status 同时给数值和 statusLabel,念给用户用后者。",
|
|
3623
|
+
"description": "发布记录:每条内容在每个平台的实际下场。限定在当前 GEO 项目内。这是「发出去了没有、发到哪个链接、失败为什么」的唯一出处——用户问「小红书那篇发了吗」就查这里。contentType 区分 article / video / image,图文记录没有 articleId,来源答案卡在 answerCardTaskId,title 是答案卡的发布标题。status 同时给数值和 statusLabel,念给用户用后者。",
|
|
3624
3624
|
"inputSchema": {
|
|
3625
3625
|
"type": "object",
|
|
3626
3626
|
"properties": {
|
|
@@ -3657,7 +3657,7 @@
|
|
|
3657
3657
|
"mode": "read",
|
|
3658
3658
|
"guide": "publication",
|
|
3659
3659
|
"requiresPlan": false,
|
|
3660
|
-
"description": "
|
|
3660
|
+
"description": "单个媒体的实时状态与当前价格。**报价给用户前必须查这条**——列表是分页快照,遇上刚调过价就会和实际扣费对不上。**单位注意**:这里的价格字段是 points,单位是算力(1 元 = 100 算力);mediaPlatforms.list 的 price 和 plan 摘要里的金额单位都是元。给用户报价时统一换算成元,例如 points=5000 就是 50 元。",
|
|
3661
3661
|
"inputSchema": {
|
|
3662
3662
|
"type": "object",
|
|
3663
3663
|
"properties": {
|
|
@@ -3885,12 +3885,64 @@
|
|
|
3885
3885
|
"additionalProperties": false
|
|
3886
3886
|
}
|
|
3887
3887
|
},
|
|
3888
|
+
{
|
|
3889
|
+
"name": "publicationTasks.createImage",
|
|
3890
|
+
"mode": "write",
|
|
3891
|
+
"guide": "publication",
|
|
3892
|
+
"requiresPlan": true,
|
|
3893
|
+
"description": "建图文发布任务:把 AI 答案卡(answerCards)做好的图发到图文平台(抖音图文、视频号图文等)。和 createArticle 同一套结构,只把 articleId 换成 answerCardTaskId,平台要用 contentType=image 那批——拿文章或视频平台发图文会被拒。**执行后会真的发出去,CLI 撤不回来**。费用按发布记录条数算——一张答案卡发 3 个账号就是 3 条。**挑已生成完成(status=8)且发布标题(publishTitle)不为空的答案卡**,图要出齐(服务端只校验图是否出齐和标题,不校验 status,但没完成的卡多半图不全);缺标题先用 answerCards.savePublishInfo 补。标题、描述、图片张数按平台自己的 limitConfig 校验,同一张卡发不同平台,张数上限可能不同。**不用问 aigc**:网页端图文已经没有「AI 创作声明」,不传就是不打。",
|
|
3894
|
+
"inputSchema": {
|
|
3895
|
+
"type": "object",
|
|
3896
|
+
"properties": {
|
|
3897
|
+
"name": { "type": "string", "minLength": 1, "maxLength": 100, "description": "任务名,给用户认的" },
|
|
3898
|
+
"projectId": { "type": "integer", "minimum": 1, "description": "发哪个 GEO 项目的内容" },
|
|
3899
|
+
"aigc": { "type": "boolean", "description": "要不要打「AI 创作」声明。图文可以不传,默认 false" },
|
|
3900
|
+
"items": {
|
|
3901
|
+
"type": "array",
|
|
3902
|
+
"minItems": 1,
|
|
3903
|
+
"description": "每项是「一张答案卡 + 它要发到哪些图文平台的哪些账号」",
|
|
3904
|
+
"items": {
|
|
3905
|
+
"type": "object",
|
|
3906
|
+
"properties": {
|
|
3907
|
+
"answerCardTaskId": { "type": "integer", "minimum": 1, "description": "答案卡任务 id,来自 answerCards.list" },
|
|
3908
|
+
"platforms": {
|
|
3909
|
+
"type": "array",
|
|
3910
|
+
"minItems": 1,
|
|
3911
|
+
"items": {
|
|
3912
|
+
"type": "object",
|
|
3913
|
+
"properties": {
|
|
3914
|
+
"platform": { "type": "string", "description": "图文平台标识,填 publicationPlatforms.list(contentType=image)返回的 platform 值" },
|
|
3915
|
+
"publishAccountIds": {
|
|
3916
|
+
"type": "array",
|
|
3917
|
+
"minItems": 1,
|
|
3918
|
+
"items": { "type": "integer", "minimum": 1 },
|
|
3919
|
+
"description": "用哪些账号发。一个账号一条发布记录"
|
|
3920
|
+
},
|
|
3921
|
+
"publishTime": {
|
|
3922
|
+
"type": "string",
|
|
3923
|
+
"description": "定时发布时间,ISO 格式如 2026-09-01T09:00:00+08:00。**不传 = 立即发布**。不能填过去的时间"
|
|
3924
|
+
}
|
|
3925
|
+
},
|
|
3926
|
+
"required": ["platform", "publishAccountIds"],
|
|
3927
|
+
"additionalProperties": false
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
},
|
|
3931
|
+
"required": ["answerCardTaskId", "platforms"],
|
|
3932
|
+
"additionalProperties": false
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
},
|
|
3936
|
+
"required": ["name", "projectId", "items"],
|
|
3937
|
+
"additionalProperties": false
|
|
3938
|
+
}
|
|
3939
|
+
},
|
|
3888
3940
|
{
|
|
3889
3941
|
"name": "publicationTasks.delete",
|
|
3890
3942
|
"mode": "write",
|
|
3891
3943
|
"guide": "publication",
|
|
3892
3944
|
"requiresPlan": true,
|
|
3893
|
-
"description": "
|
|
3945
|
+
"description": "删发布任务。普通任务只删任务和它名下**还没发出去**的记录——已经发布成功的稿子留在平台上不受影响,要撤那些得去各平台自己删。**例外:外部导入的任务**(publicationTasks.list 里 typeLabel=外部导入)会连同名下已发布的记录一起删掉,收录统计也会跟着减少,计划摘要里会单独写出来,必须念给用户。一次只能删当前 GEO 项目的。",
|
|
3894
3946
|
"inputSchema": {
|
|
3895
3947
|
"type": "object",
|
|
3896
3948
|
"properties": {
|
|
@@ -3938,6 +3990,39 @@
|
|
|
3938
3990
|
"additionalProperties": false
|
|
3939
3991
|
}
|
|
3940
3992
|
},
|
|
3993
|
+
{
|
|
3994
|
+
"name": "publicationTasks.importLinks",
|
|
3995
|
+
"mode": "write",
|
|
3996
|
+
"guide": "publication",
|
|
3997
|
+
"requiresPlan": true,
|
|
3998
|
+
"description": "导入用户**已经在外面发出去**的文章链接,登记成一个「外部导入」发布任务,让这些链接参与收录匹配和统计。不扣费,也不会往任何平台发东西。articleId 和 title 必须且只能给一个:链接发的是系统里已有的文章就给 articleId;在外面写的给 title,会新建一篇只有标题的外部文章(之后不能再拿去发布或投稿)。计划里会逐条写明哪条能导、哪条跳过及原因(链接无效、网站暂不支持提取文章 ID、已经导入或发布过),念给用户再确认;一条都导不了时 plan 直接报错。",
|
|
3999
|
+
"inputSchema": {
|
|
4000
|
+
"type": "object",
|
|
4001
|
+
"properties": {
|
|
4002
|
+
"projectId": { "type": "integer", "minimum": 1, "description": "GEO 项目 id,来自 projects.list" },
|
|
4003
|
+
"urls": {
|
|
4004
|
+
"type": "array",
|
|
4005
|
+
"minItems": 1,
|
|
4006
|
+
"maxItems": 20,
|
|
4007
|
+
"items": { "type": "string", "minLength": 1 },
|
|
4008
|
+
"description": "外部文章链接,一次最多 20 条,用户给的原样传入"
|
|
4009
|
+
},
|
|
4010
|
+
"articleId": {
|
|
4011
|
+
"type": "integer",
|
|
4012
|
+
"minimum": 1,
|
|
4013
|
+
"description": "链接对应系统里已有的哪篇文章,来自 articles.list,必须属于当前 GEO 项目。和 title 二选一"
|
|
4014
|
+
},
|
|
4015
|
+
"title": {
|
|
4016
|
+
"type": "string",
|
|
4017
|
+
"minLength": 1,
|
|
4018
|
+
"maxLength": 255,
|
|
4019
|
+
"description": "外面写的文章标题,用来新建一篇外部文章。和 articleId 二选一"
|
|
4020
|
+
}
|
|
4021
|
+
},
|
|
4022
|
+
"required": ["projectId", "urls"],
|
|
4023
|
+
"additionalProperties": false
|
|
4024
|
+
}
|
|
4025
|
+
},
|
|
3941
4026
|
{
|
|
3942
4027
|
"name": "mediaPublications.create",
|
|
3943
4028
|
"mode": "write",
|
|
@@ -3982,7 +4067,7 @@
|
|
|
3982
4067
|
"name": "textToImages.models",
|
|
3983
4068
|
"mode": "read",
|
|
3984
4069
|
"guide": "material",
|
|
3985
|
-
"description": "列出可用的 AI 出图档位。不同档位计费不同(返回里的 toolScore 是计费口径),建图之前先调这个看有哪些能用。",
|
|
4070
|
+
"description": "列出可用的 AI 出图档位。不同档位计费不同(返回里的 toolScore 是计费口径),建图之前先调这个看有哪些能用。maxInputImages 是这个档位最多能喂几张输入图(0 表示不支持参考图),答案卡选参考图前要用它算上限。",
|
|
3986
4071
|
"inputSchema": { "type": "object", "properties": {}, "additionalProperties": false }
|
|
3987
4072
|
},
|
|
3988
4073
|
{
|
|
@@ -4486,7 +4571,7 @@
|
|
|
4486
4571
|
"visualMode": {
|
|
4487
4572
|
"type": "integer",
|
|
4488
4573
|
"enum": [1, 2, 3],
|
|
4489
|
-
"description": "视觉方式:1 AI 智能匹配(后端从可用模板里自动挑一套,不用再给 templateId 或 customStylePrompt)/ 2 指定模板(需一并给 templateId)/ 3 自定义风格(需一并给 customStylePrompt
|
|
4574
|
+
"description": "视觉方式:1 AI 智能匹配(后端从可用模板里自动挑一套,不用再给 templateId 或 customStylePrompt)/ 2 指定模板(需一并给 templateId)/ 3 自定义风格(需一并给 customStylePrompt)。1 和 2 要把模板图喂给模型,所选档位的 maxInputImages 为 0 时只能用 3"
|
|
4490
4575
|
},
|
|
4491
4576
|
"templateId": {
|
|
4492
4577
|
"type": "integer",
|
|
@@ -4515,7 +4600,7 @@
|
|
|
4515
4600
|
"type": "integer",
|
|
4516
4601
|
"minimum": 1
|
|
4517
4602
|
},
|
|
4518
|
-
"description": "参考素材图 id 列表,有序,用 images.list
|
|
4603
|
+
"description": "参考素材图 id 列表,有序,用 images.list 查。**真实上限看所选档位**:textToImages.models 里该档位的 maxInputImages;visualMode=1 或 2 时模板图要先占 1 张,用户能给的再少 1 张。超了 plan 能过、apply 会被拒,所以 plan 前先算好"
|
|
4519
4604
|
}
|
|
4520
4605
|
},
|
|
4521
4606
|
"required": ["projectId", "sourceType", "visualMode", "richness", "modelCode"],
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var jt=Object.defineProperty;var Vt=(e,t,n)=>t in e?jt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var se=(e,t,n)=>Vt(e,typeof t!="symbol"?t+"":t,n);var ae="https://nbgeo.aimusiclj.com",Oe="best-geo-test",$e="best-geo-test",Ne="bg-test-cli-",Pe="2.0.
|
|
2
|
+
"use strict";var jt=Object.defineProperty;var Vt=(e,t,n)=>t in e?jt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var se=(e,t,n)=>Vt(e,typeof t!="symbol"?t+"":t,n);var ae="https://nbgeo.aimusiclj.com",Oe="best-geo-test",$e="best-geo-test",Ne="bg-test-cli-",Pe="2.0.2-beta";var B=2,k=Pe,D=$e,p=Oe,Le="dev",J=Bt(Ft());function Ft(){var e;return(e=process.env.BEST_GEO_API_BASE)!=null?e:ae}var Q=Ne,De=300*1e3,Ue=30*1e3,Me=300*1e3;function Bt(e){return e.replace(/\/+$/,"")}var tt=require("node:child_process");var Ge=require("node:crypto"),X=require("node:os");var d=require("node:fs"),je=require("node:os"),A=require("node:path");var le=require("node:crypto");var _=class extends Error{constructor(n,r,o){super(o);se(this,"reason",n);se(this,"path",r);this.name="LocalConfigError"}},qt={schemaVersion:1,device:null,activeCredential:null,pendingCredential:null};function q(){var e;return(e=process.env.BEST_GEO_CONFIG_DIR)!=null?e:(0,A.join)((0,je.homedir)(),`.${p}`)}function O(){return(0,A.join)(q(),"config.json")}function C(){var n,r,o;let e=O(),t;try{if(!(0,d.existsSync)(e))return null;Gt(e),t=(0,d.readFileSync)(e,"utf8")}catch(i){throw i instanceof _?i:Ve(i,e)}try{let i=JSON.parse(t);if(typeof i!="object"||i==null||i.schemaVersion!==1)throw new Error("unexpected shape");return{schemaVersion:1,device:(n=i.device)!=null?n:null,activeCredential:(r=i.activeCredential)!=null?r:null,pendingCredential:(o=i.pendingCredential)!=null?o:null}}catch{throw new _("corrupted",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E0D\u5B8C\u6574\u6216\u683C\u5F0F\u4E0D\u5BF9\uFF1A${e}`)}}function Kt(e){let t=q(),n=O(),r=(0,A.join)(t,`.config.json.${(0,le.randomBytes)(6).toString("hex")}.tmp`);try{(0,d.existsSync)(t)||(0,d.mkdirSync)(t,{recursive:!0,mode:448});let o=(0,d.openSync)(r,"wx",384);try{(0,d.writeSync)(o,`${JSON.stringify(e,null,2)}
|
|
3
3
|
`),(0,d.fsyncSync)(o)}finally{(0,d.closeSync)(o)}(0,d.renameSync)(r,n)}catch(o){if((0,d.existsSync)(r))try{(0,d.unlinkSync)(r)}catch{}throw Ve(o,n)}}function T(e){var n;let t=e((n=C())!=null?n:{...qt});return Kt(t),t}function Gt(e){var r;if(process.platform==="win32")return;let t=(0,d.statSync)(e),n=(r=process.getuid)==null?void 0:r.call(process);if(n!=null&&t.uid!==n)throw new _("not_owner",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7528\u6237\uFF1A${e}`);if((t.mode&63)!==0)throw new _("permissions_too_open",e,`\u672C\u673A\u914D\u7F6E\u6587\u4EF6\u6743\u9650\u8FC7\u5BBD\uFF08\u540C\u673A\u5176\u4ED6\u7528\u6237\u53EF\u8BFB\uFF09\uFF1A${e}`)}function Ve(e,t){let n=e==null?void 0:e.code;return n==="EACCES"||n==="EPERM"||n==="EROFS"?new _("denied",t,`\u6CA1\u6709\u6743\u9650\u8BFB\u5199\u672C\u673A\u914D\u7F6E\uFF1A${t}`):e instanceof Error?e:new Error(String(e))}var Fe=3600*1e3;function Be(){return(0,A.join)(q(),"pending-uploads")}var Ht=/^plan_[0-9a-zA-Z]+$/;function de(e){return Ht.test(e)?(0,A.join)(Be(),`${e}.json`):null}function W(e){var n;let t=de(e);if(t==null||!(0,d.existsSync)(t))return null;try{let r=JSON.parse((0,d.readFileSync)(t,"utf8"));return Date.now()-((n=r==null?void 0:r.createdAt)!=null?n:0)<Fe?r:null}catch{return null}}function qe(e,t){let n=de(e);if(n==null)throw new Error(`\u4E0D\u5408\u6CD5\u7684\u8BA1\u5212 ID:${e}`);let r=Be();(0,d.mkdirSync)(r,{recursive:!0,mode:448}),zt(r);let o=(0,A.join)(r,`.${e}.${(0,le.randomBytes)(6).toString("hex")}.tmp`);try{(0,d.writeFileSync)(o,JSON.stringify(t),{mode:384}),(0,d.renameSync)(o,n)}catch(i){if((0,d.existsSync)(o))try{(0,d.unlinkSync)(o)}catch{}throw i}}function Ke(e){let t=de(e);if(t!=null)try{(0,d.unlinkSync)(t)}catch{}}function zt(e){let t=(0,A.join)(q(),"pending-uploads.json");try{(0,d.existsSync)(t)&&(0,d.unlinkSync)(t)}catch{}let n;try{n=(0,d.readdirSync)(e)}catch{return}for(let r of n){if(r.endsWith(".tmp")){try{let i=(0,A.join)(e,r);Date.now()-(0,d.statSync)(i).mtimeMs>=Fe&&(0,d.unlinkSync)(i)}catch{}continue}if(!r.endsWith(".json"))continue;let o=r.slice(0,-5);if(W(o)==null)try{(0,d.unlinkSync)((0,A.join)(e,r))}catch{}}}function He(){var t,n;let e=(t=C())==null?void 0:t.device;return(n=e==null?void 0:e.deviceId)!=null&&n.startsWith(Q)?e.deviceId:null}function Y(){var r,o;let e={deviceName:(0,X.hostname)().slice(0,50),platform:`${(0,X.platform)()}-${process.arch}`},t=(r=C())==null?void 0:r.device;if((o=t==null?void 0:t.deviceId)!=null&&o.startsWith(Q))return t.deviceName===e.deviceName&&t.platform===e.platform?t:T(i=>({...i,device:{...t,...e}})).device;let n={deviceId:`${Q}${(0,Ge.randomUUID)()}`,...e};return T(i=>({...i,device:n})).device}function ze(){return`cli_${Date.now().toString(36)}${Math.random().toString(36).slice(2,8)}`}function E(e,t=ze()){return{ok:!0,code:"OK",requestId:t,data:e}}function l(e,t,n={}){var r;return{ok:!1,code:e,message:t,requestId:(r=n.requestId)!=null?r:ze(),...n.data==null?{}:{data:n.data},...n.nextAction==null?{}:{nextAction:n.nextAction}}}function a(e){process.stdout.write(`${JSON.stringify(e)}
|
|
4
4
|
`),e.ok||(process.exitCode=1)}async function x(e,t={}){var i,s;let n=new URL(`${J}/v1/agent-cli${e}`);for(let[c,f]of Object.entries((i=t.query)!=null?i:{}))if(f!=null)for(let m of Array.isArray(f)?f:[f])n.searchParams.append(c,String(m));let r={"X-GEO-CLI-Version":k,"X-GEO-Protocol-Version":String(B),"X-GEO-CLI-Package":D};t.projectId!=null&&(r["X-Geo-Product-Id"]=String(t.projectId));let o=null;try{o=He()}catch{}o&&(r["X-Device-ID"]=o),t.apiKey&&(r.Authorization=`Bearer ${t.apiKey}`),t.body!=null&&(r["Content-Type"]="application/json");try{let c=await fetch(n,{method:(s=t.method)!=null?s:"GET",headers:r,body:t.body==null?void 0:JSON.stringify(t.body),signal:AbortSignal.timeout(t.isWrite?Me:Ue)}),f=await c.text();try{let m=JSON.parse(f);return Jt(m)?m:l("SERVER_ERROR",`\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u975E\u9884\u671F\u5185\u5BB9\uFF08HTTP ${c.status}\uFF09`,{data:{transportFailure:!0}})}catch{return l("SERVER_ERROR",`\u670D\u52A1\u7AEF\u8FD4\u56DE\u4E86\u975E\u9884\u671F\u5185\u5BB9\uFF08HTTP ${c.status}\uFF09`,{data:{transportFailure:!0}})}}catch(c){return c instanceof Error&&(c.name==="TimeoutError"||c.name==="AbortError")?l("SERVER_ERROR",t.isWrite?"\u670D\u52A1\u7AEF\u5904\u7406\u8D85\u65F6,\u8FD9\u6B21\u5199\u5165\u7ED3\u679C\u672A\u77E5":"\u670D\u52A1\u7AEF\u54CD\u5E94\u8D85\u65F6",{data:{transportFailure:!0},nextAction:t.isWrite?{type:"ask_user",message:"\u8D85\u65F6\u4E0D\u4EE3\u8868\u6CA1\u5199\u8FDB\u53BB \u2014\u2014 \u670D\u52A1\u7AEF\u53EF\u80FD\u8FD8\u5728\u5904\u7406\u3002**\u5148\u7528\u5BF9\u5E94\u7684\u67E5\u8BE2\u80FD\u529B\u786E\u8BA4\u4E00\u904D**,\u786E\u5B9E\u6CA1\u6709\u518D\u91CD\u65B0 plan;\u76F4\u63A5\u91CD\u8BD5\u4F1A\u5EFA\u51FA\u91CD\u590D\u7684\u4E00\u4EFD,\u800C\u4E14\u4F1A\u518D\u6263\u4E00\u6B21\u8D39\u3002"}:{type:"ask_user",message:"\u670D\u52A1\u7AEF\u54CD\u5E94\u592A\u6162\u3002\u7A0D\u540E\u91CD\u8BD5\u540C\u4E00\u6761\u547D\u4EE4\u5373\u53EF,\u67E5\u8BE2\u4E0D\u4F1A\u4EA7\u751F\u4EFB\u4F55\u5199\u5165"}}):l("SERVER_ERROR",`\u65E0\u6CD5\u8FDE\u63A5\u670D\u52A1\u7AEF\uFF1A${c instanceof Error?c.message:String(c)}`,{data:{transportFailure:!0},nextAction:{type:"ask_user",message:"\u8BF7\u786E\u8BA4\u7F51\u7EDC\u53EF\u7528\uFF0C\u4EE5\u53CA\u670D\u52A1\u7AEF\u5730\u5740\u914D\u7F6E\u6B63\u786E"}})}}function Jt(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.ok=="boolean"&&typeof t.code=="string"}function Qt(e){var t;return!e.ok&&((t=e.data)==null?void 0:t.transportFailure)===!0}function ce(e){return e.ok||Qt(e)?!1:["AUTH_EXPIRED","DEVICE_MISMATCH","ACCESS_DENIED","AUTH_REQUIRED","VALIDATION_FAILED"].includes(e.code)}function U(){var e,t,n;return(n=(t=(e=C())==null?void 0:e.activeCredential)==null?void 0:t.apiKey)!=null?n:null}function Z(){var e,t;return(t=(e=C())==null?void 0:e.activeCredential)!=null?t:null}function Je(){var e,t;return(t=(e=C())==null?void 0:e.pendingCredential)!=null?t:null}function Qe(e){T(t=>({...t,pendingCredential:{apiKey:e,startedAt:new Date().toISOString()}}))}function pe(){T(e=>({...e,pendingCredential:null}))}function ue(e){return T(t=>{let n=t.pendingCredential;return n?{...t,activeCredential:{apiKey:n.apiKey,...e},pendingCredential:null}:t}).activeCredential}function We(){T(e=>({...e,activeCredential:null,pendingCredential:null}))}var R=require("node:crypto"),Ze=require("node:http");function Xe(e){let t=`
|
|
5
5
|
(function () {
|
package/guides/answer-card.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"step": 1,
|
|
12
12
|
"action": "确定内容来源与视觉方式",
|
|
13
|
-
"note": "内容来源二选一:sourceType=1 用已有文章(给 articleId,从 articles.list 查)、sourceType=2 用自定义正文(给 content,至少 20 个有效字符)。视觉方式三选一:visualMode=1 让 AI 自动挑模板(最省事)、=2 指定模板(先用 answerCards.templates 查可用模板拿 templateId)、=3 自定义风格(给 customStylePrompt)。richness 决定页数档位,模型档位用 textToImages.models 查 modelCode
|
|
13
|
+
"note": "内容来源二选一:sourceType=1 用已有文章(给 articleId,从 articles.list 查)、sourceType=2 用自定义正文(给 content,至少 20 个有效字符)。视觉方式三选一:visualMode=1 让 AI 自动挑模板(最省事)、=2 指定模板(先用 answerCards.templates 查可用模板拿 templateId)、=3 自定义风格(给 customStylePrompt)。richness 决定页数档位,模型档位用 textToImages.models 查 modelCode。**参考图上限看档位**:每个档位最多能喂 maxInputImages 张图;visualMode=1 或 2 时模板图先占 1 张,用户能选的再少 1 张;maxInputImages 为 0 的档位只能用 visualMode=3。超了 plan 能过、apply 才被拒,plan 前就要算好。"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"step": 2,
|
package/guides/article-task.json
CHANGED
|
@@ -70,7 +70,8 @@
|
|
|
70
70
|
"VALIDATION_FAILED": "参数不合法,按 capabilities 里的 inputSchema 修正后重试。提示词/模型不存在、提示词类型不对、项目下没有知识资料、图片数量不够配图,都走这个码,message 里写明了是哪一种。",
|
|
71
71
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次——旧 planId 已经不能用了。",
|
|
72
72
|
"PLAN_COST_CHANGED": "扣费方式在确认期间变了。重新 plan,把新的费用说明再念给用户。",
|
|
73
|
-
"
|
|
73
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足——建任务要按篇数扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
74
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经建出来了,先用 articleTasks.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
74
75
|
},
|
|
75
76
|
"completionCriteria": "读:已经如实说明任务跑到哪一步、写出来多少篇、审核通过多少。写:plan 摘要已原样念给用户、用户明确同意、apply 成功,并告诉了他任务在后台跑、大概要等一会儿。"
|
|
76
77
|
}
|
package/guides/article.json
CHANGED
|
@@ -73,16 +73,17 @@
|
|
|
73
73
|
"不要把 articles.update 当成追加。正文/标签/摘要都是整体覆盖,只传一段新内容会把原来的全冲掉",
|
|
74
74
|
"不要在用户没同意 plan 摘要之前就 apply。他说「帮我写篇文章」不等于同意了你写的这一篇",
|
|
75
75
|
"不要为了省事把 articles.create 连着调好几次试效果——每调一次都真的建出一篇,多出来的还得让用户一篇篇去网页删;而且按篇计费",
|
|
76
|
-
"
|
|
76
|
+
"已经建好的文章改不了所属 GEO 项目,用户要换项目就让他去网页的文章管理。换文件夹用 articles.moveFolder,不用去网页",
|
|
77
77
|
"不要凭印象填 folderId。合法 id 只能来自 folders.list,猜一个过去会被服务端拒掉"
|
|
78
78
|
],
|
|
79
79
|
"errorRecovery": {
|
|
80
|
-
"ACCESS_DENIED": "这条数据不在当前 GEO
|
|
81
|
-
"VALIDATION_FAILED": "参数不合法,按 capabilities 里的 inputSchema 修正后重试。message
|
|
80
|
+
"ACCESS_DENIED": "这条数据不在当前 GEO 项目里,或者已经不存在了(读不到一律当不存在,不区分「没有」和「不是你的」)。用当前项目的列表能力重新查;要换项目先问用户。",
|
|
81
|
+
"VALIDATION_FAILED": "参数不合法,按 capabilities 里的 inputSchema 修正后重试。message 里写明了是哪个字段;长度类还会给出当前值和上限。",
|
|
82
82
|
"PLAN_STALE": "这篇文章在用户确认期间被别人改过。重新 articles.get 读当前内容、重新 plan,把新摘要再给用户确认一次。不要拿旧 planId 重试。",
|
|
83
83
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次——旧 planId 已经不能用了。",
|
|
84
84
|
"PLAN_COST_CHANGED": "扣费方式在确认期间变了。重新 plan,把新的费用说明再念给用户。",
|
|
85
|
-
"
|
|
85
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足。这条链路上新建、复制、生成摘要、生成封面都会扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
86
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经写进去了,先用 articles.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
86
87
|
},
|
|
87
88
|
"completionCriteria": "读:已经如实呈现用户关心的文章列表(含总数)或指定那一篇的信息,用户要正文时才给了正文。写:plan 摘要已原样念给用户、用户明确同意、apply 成功,并把结果(文章 ID、还差不差封面)告诉了他。"
|
|
88
89
|
}
|
package/guides/knowledge.json
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"step": 5,
|
|
35
35
|
"action": "改名称或标签走 knowledge.update",
|
|
36
36
|
"capability": "knowledge.update",
|
|
37
|
-
"note": "同样先 plan 再 apply
|
|
37
|
+
"note": "同样先 plan 再 apply。只能改这两样。加文档用 knowledge.addFiles;改所属项目、删文档要去网页。"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"step": 6,
|
|
@@ -60,11 +60,12 @@
|
|
|
60
60
|
"用户说「补进 XX 知识库」时不要新建库。那是 knowledge.addFiles 的活"
|
|
61
61
|
],
|
|
62
62
|
"errorRecovery": {
|
|
63
|
-
"ACCESS_DENIED": "这条数据不在当前 GEO
|
|
64
|
-
"VALIDATION_FAILED": "参数不合法。常见原因:files 为空、某个文档缺 name 或 file
|
|
63
|
+
"ACCESS_DENIED": "这条数据不在当前 GEO 项目里,或者已经不存在了(读不到一律当不存在,不区分「没有」和「不是你的」)。用当前项目的列表能力重新查;要换项目先问用户。",
|
|
64
|
+
"VALIDATION_FAILED": "参数不合法。常见原因:files 为空、某个文档缺 name 或 file、知识库名称为空或只有空格。按提示补齐后重试。**还有一种与参数无关的情况**:站点还没配置这个功能的价格——这时按 nextAction 说的让用户联系服务商,别去改参数重试,改了也过不去。分辨方法是看 nextAction.message。",
|
|
65
65
|
"PLAN_STALE": "确认期间这个知识库被别人改过。重新 plan,把新摘要再给用户确认一次。",
|
|
66
66
|
"PLAN_COST_CHANGED": "确认之后扣费方式变了(比如管理员把这个功能改成从另一种账户扣)。用户上次点头同意的不是现在这笔,**别直接重试 apply**。重新 plan,把新的费用说明再给用户确认一次。注意:响应里**不含**「原来是什么、现在是什么」,别向用户复述具体是从哪种变成了哪种。",
|
|
67
|
-
"
|
|
67
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足。knowledge.create 和 knowledge.addFiles 都按文档扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
68
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经写进去了,先用 knowledge.get / knowledge.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
68
69
|
},
|
|
69
70
|
"completionCriteria": "查询类:已如实呈现知识库列表或指定那个的文档解析状态。新建类:用户看过摘要并明确同意后才执行,且执行后说清了「正在解析、暂不可用」。",
|
|
70
71
|
"writeFlow": {
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
"计划 30 分钟内有效,只能执行一次。",
|
|
80
81
|
"notice 里会写清这次要新增几个文档、按文档计费扣几次——按下去之前用户就该知道。",
|
|
81
82
|
"摘要里的 files 只列文档名,不回显正文。用户要核对内容,让他看自己给你的原始资料。",
|
|
82
|
-
"knowledge.update
|
|
83
|
+
"knowledge.update 只能改名称和标签。加文档用 knowledge.addFiles;改所属项目、删文档要去网页做。"
|
|
83
84
|
]
|
|
84
85
|
}
|
|
85
86
|
}
|
package/guides/material.json
CHANGED
|
@@ -78,7 +78,8 @@
|
|
|
78
78
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次——旧 planId 已经不能用了,文件也要重新走一遍上传。",
|
|
79
79
|
"UPLOAD_FAILED": "文件传到一半断了。素材记录还没建,什么都没留下——把情况告诉用户,重新走一遍 plan 就行,不要反复重试 apply。",
|
|
80
80
|
"PLAN_COST_CHANGED": "扣费方式在确认期间变了。重新 plan,把新的费用说明再念给用户。",
|
|
81
|
-
"
|
|
81
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足——传图片会扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
82
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经建出来了,先用 images.list / videos.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
82
83
|
},
|
|
83
84
|
"completionCriteria": "查询类:已如实呈现用户关心的素材列表或指定那一条的信息。写入类(新建/改名/改标签):用户看过 plan 摘要并明确同意后才执行,执行完把结果告诉了他。",
|
|
84
85
|
"writeFlow": {
|
package/guides/publication.json
CHANGED
|
@@ -32,46 +32,58 @@
|
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"step": 5,
|
|
35
|
-
"action": "建发布任务:publicationTasks.createArticle / createVideo",
|
|
35
|
+
"action": "建发布任务:publicationTasks.createArticle / createVideo / createImage",
|
|
36
36
|
"capability": "publicationTasks.createArticle",
|
|
37
|
-
"note": "**先 plan,把计划里逐条列的「哪篇发到哪个号、什么时候发」念给用户,等他确认再 apply**。执行之后稿子会真的发出去,CLI 撤不回来。aigc(要不要打 AI
|
|
37
|
+
"note": "**先 plan,把计划里逐条列的「哪篇发到哪个号、什么时候发」念给用户,等他确认再 apply**。执行之后稿子会真的发出去,CLI 撤不回来。aigc(要不要打 AI 创作声明)发文章、视频时必须问用户,别替他决定;**图文不用问**,网页端图文已经没有这个声明,不传就是不打。定时发布传 publishTime,不传就是立即发。费用按发布记录条数算——一篇发 3 个号就是 3 条,跟用户说清楚这个口径。**plan 阶段就会查字数**:报「不满足平台的字数要求」时,错误信息里点名了是哪篇文章投哪个平台、差多少字——把这句原样念给用户,让他定是改文章还是不发那个平台,别自己挑一个继续重试(这种失败重试多少次都过不去)。"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"step": 6,
|
|
41
|
+
"action": "发图文:内容来自 AI 答案卡,用 publicationTasks.createImage",
|
|
42
|
+
"capability": "publicationTasks.createImage",
|
|
43
|
+
"note": "流程和发文章一样(先 plan、念逐条明细、用户确认再 apply),区别在三处:① 平台用 publicationPlatforms.list 带 contentType=image,图文平台和文章、视频平台是三批,混用会被拒;② 每项给的是 answerCardTaskId 而不是 articleId,**挑答案卡要选 status=8(已完成)且 publishTitle 不为空的**——还在生成、部分失败或没填发布标题的发不了,缺标题先用 answerCards.savePublishInfo 补;③ 图片张数、标题和描述长度由平台规则校验,张数上限以 plan 的报错为准,同一张卡发不同平台,张数上限可能不同,plan 报「不满足平台要求」时把错误原样念给用户,让他定改卡还是不发那个平台。发出去之后在 publicationRecords.list 里 contentType=image,title 是答案卡的发布标题,answerCardTaskId 是来源答案卡。"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"step": 7,
|
|
41
47
|
"action": "任务建完后查进展,别反复重建",
|
|
42
48
|
"capability": "publicationRecords.list",
|
|
43
49
|
"note": "发布是异步的,apply 完不会马上有链接。等一会儿用 publicationRecords.list 看。每建一次任务就是一批新的发布,重建 = 重复发稿 + 重复扣费。"
|
|
44
50
|
},
|
|
45
51
|
{
|
|
46
|
-
"step":
|
|
52
|
+
"step": 8,
|
|
47
53
|
"action": "要停下来用 publicationTasks.pause,改主意了用 delete",
|
|
48
54
|
"capability": "publicationTasks.pause",
|
|
49
|
-
"note": "两个都只对**还没发出去**的记录有效(删除会连暂停中的一起删掉)。已经发成功的稿子留在平台上,CLI
|
|
55
|
+
"note": "两个都只对**还没发出去**的记录有效(删除会连暂停中的一起删掉)。已经发成功的稿子留在平台上,CLI 撤不回来——用户要撤那些,只能去各平台自己删,这一点必须说明白,别让他以为暂停就等于撤回。另外建任务时费用就按记录条数扣过了,删除不改变这笔扣费,用户点删除前得知道。**例外是外部导入的任务**(typeLabel=外部导入):它不能暂停或恢复;删除时会连同名下已发布的记录一起删掉,收录统计也会跟着减少,计划摘要会单独写出来,一定要念给用户。"
|
|
50
56
|
},
|
|
51
57
|
{
|
|
52
|
-
"step":
|
|
58
|
+
"step": 9,
|
|
53
59
|
"action": "媒体投稿:先 mediaPlatforms.list 看有哪些媒体,报价前用 mediaPlatforms.get 查实时价",
|
|
54
60
|
"capability": "mediaPlatforms.get",
|
|
55
61
|
"note": "**报价必须用 get 那条**。列表是分页快照,遇上刚调过价就会和实际扣费对不上——用户按你报的数点了头,扣的却是另一个数。"
|
|
56
62
|
},
|
|
57
63
|
{
|
|
58
|
-
"step":
|
|
64
|
+
"step": 10,
|
|
59
65
|
"action": "投稿:mediaPublications.create(一家)/ batchCreate(多家,最多 20)",
|
|
60
66
|
"capability": "mediaPublications.batchCreate",
|
|
61
67
|
"note": "**计划里逐家列出了媒体名和单价,要一家一家念给用户听,再给合计**——这是按明细收费的操作,用户确认的就是这份账单,只说「一共多少钱」不够。批量允许部分成功:某家失败不影响别家,失败的那家不扣费。一次只能投一篇文章,投多篇就一篇一篇来。"
|
|
62
68
|
},
|
|
63
69
|
{
|
|
64
|
-
"step":
|
|
70
|
+
"step": 11,
|
|
65
71
|
"action": "查投稿进展用 mediaPublications.list,要整体情况用 mediaPublications.summary",
|
|
66
72
|
"capability": "mediaPublications.summary",
|
|
67
73
|
"note": "投稿动辄上百条。用户问「投出去的都怎么样了」直接用 summary,念 items 里的 statusLabel(「已拒稿 × 15」),别念 counts 里的数值。投稿有 failReason,被拒稿时把它念出来——这条链路和自媒体发布不同,是有失败原因的。**被拒稿的还要看 refundStatusLabel**:拒稿会原路退款,但退款偶尔会没退成(显示「待退款」,系统会自动补退)——用户问「钱退了吗」看的是这个字段,不是 status。"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"step": 12,
|
|
77
|
+
"action": "用户在外面自己发过的文章,要算进收录统计:publicationTasks.importLinks",
|
|
78
|
+
"capability": "publicationTasks.importLinks",
|
|
79
|
+
"note": "这是**登记**,不是发布:不扣费,也不会往任何平台发东西。先问清这些链接发的是系统里已有的哪篇文章(用 articles.list 找到 articleId),不是的话问用户要标题(title)新建一篇外部文章——两个只给一个。plan 里逐条写明哪条能导、哪条跳过,**把跳过的和原因念给用户**,别只报「导入 N 条」。「网站暂不支持」的链接导进来也匹配不上收录,不要换个写法重试。导入后在 publicationTasks.list 里是一个「外部导入」任务,apply 结果里的 results 是逐条最终结果,以它为准告诉用户导进去了几条。"
|
|
68
80
|
}
|
|
69
81
|
],
|
|
70
82
|
"askUserWhen": [
|
|
71
83
|
"分不清他要问的是自媒体发布还是媒体投稿",
|
|
72
84
|
"他有多个 GEO 项目,而没说这次问的是哪个",
|
|
73
85
|
"他说「发一下」但没说发哪篇、发到哪个平台、用哪个账号",
|
|
74
|
-
"
|
|
86
|
+
"发文章、视频时要不要打「AI 创作」声明(aigc)——这是他的合规选择,不能替他定(图文不用问,默认不打)",
|
|
75
87
|
"他说「明天发」这类相对时间,而你不确定具体是几点"
|
|
76
88
|
],
|
|
77
89
|
"forbidden": [
|
|
@@ -67,7 +67,8 @@
|
|
|
67
67
|
"PLAN_STALE": "任务在用户确认期间被动过(多半是别人也导了一批)。重新 questionTasks.get 读当前状态、重新 plan,把新摘要再给用户确认一次。",
|
|
68
68
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次——旧 planId 已经不能用了。",
|
|
69
69
|
"PLAN_COST_CHANGED": "扣费方式在确认期间变了。重新 plan,把新的费用说明再念给用户。",
|
|
70
|
-
"
|
|
70
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足——创建和重试都要扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
71
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经建出来了,先用 questionTasks.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
71
72
|
},
|
|
72
73
|
"completionCriteria": "读:已经如实说明任务跑到哪一步、生成了哪些问题。写:plan 摘要已原样念给用户、用户明确同意、apply 成功,并告诉了他任务在后台跑(新建/重试)或者哪些问题已经进了问题库(导入)。"
|
|
73
74
|
}
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"PLAN_COST_CHANGED": "扣费方式在确认期间变了。重新 plan,把新的费用说明再念给用户。",
|
|
92
92
|
"PLAN_STALE": "计划在用户确认期间被改过。重新 get 读当前配置、重新 plan,把新摘要再给用户确认一次——runNow 也一样,因为摘要里承诺的提问次数可能已经变了。",
|
|
93
93
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次,旧 planId 已经不能用了。",
|
|
94
|
-
"
|
|
94
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足——云端采集要扣费。把 message 原样转达给用户,让他确认账户余额或联系管理员充值,不要重试 apply——余额不够重试也不会成功。",
|
|
95
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。runNow 时最常见的原因是**这个计划已经有一次执行在跑**——用 runs 看最近一次的状态,跑完了再重新 plan runNow,别连着重试。其他情况多半是站点侧配置缺失或服务端临时故障,把 message 和 requestId 一起转达给用户。"
|
|
95
96
|
}
|
|
96
97
|
}
|
package/guides/video.json
CHANGED
|
@@ -73,7 +73,8 @@
|
|
|
73
73
|
"PLAN_STALE": "确认期间来源数字人任务合成完了、回填了真实时长,那份按兜底秒数算出来的报价已经不作数。重新 plan,把新的金额再念给用户确认一次——底板只是进度在动不会触发这个码,所以不用担心一直撞。",
|
|
74
74
|
"PLAN_EXPIRED": "计划超过 30 分钟没执行。重新 plan,把新摘要再给用户确认一次。",
|
|
75
75
|
"PLAN_COST_CHANGED": "单价在确认期间被改过。重新 plan,把新的费用说明再念给用户。",
|
|
76
|
-
"
|
|
76
|
+
"QUOTA_EXCEEDED": "账户余额(积分/算力)不足:提交时虽然不扣费,但会校验余额够不够,不够会挡在这里。把 message 原样转达给用户,让他确认余额或联系管理员充值,不要重试 apply。",
|
|
77
|
+
"SERVER_ERROR": "服务端出错,**不是余额问题**(余额不足是 QUOTA_EXCEEDED)。常见原因是站点侧配置缺失或服务端临时故障。**apply 阶段先别重试**——可能已经提交了,先用 dhVideos.list / clipTasks.list 确认;把 message 和 requestId 一起转达给用户,让他联系服务商。"
|
|
77
78
|
},
|
|
78
79
|
"completionCriteria": "查询类:已如实呈现任务状态或资源列表;任务没跑完就说清它还在哪个阶段,不要拿空的 videoUrl 当「失败」。写入类:用户看过 plan 摘要(含费用说明)并明确同意,apply 已返回任务号,并告诉了用户去哪儿查进度。",
|
|
79
80
|
"writeFlow": {
|