@manturhub/cli 0.9.5 → 0.9.6
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/README.md +1 -1
- package/bin/cli.js +2 -0
- package/lib/api.js +18 -3
- package/lib/setup.js +1 -0
- package/lib/skill.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ manturhub quote 电商文案生成
|
|
|
31
31
|
manturhub run 电商文案生成 --json '{"product_info":"便携榨汁杯,USB 充电,300ml","scene":"product_title","tone":"lively"}'
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
CLI 会在付费调用前按算子实时 schema 校验未知字段、必填项、类型和枚举,校验失败不会发起 invoke
|
|
34
|
+
CLI 会在付费调用前按算子实时 schema 校验未知字段、必填项、类型和枚举,校验失败不会发起 invoke。校验通过后会显示本次预计消耗和计费依据,获得确认才调用;完成后在最终 JSON 的 \`_billing\` 返回实际消耗和退款,并同步显示到终端。批量参数按整批请求试算;多次调用应逐笔汇总 \`charged_dumplings\` 和 \`refunded_dumplings\`,不得自行估算。
|
|
35
35
|
|
|
36
36
|
面向用户的列表、详情、报价、确认和结算统一显示中文算子名,也可直接用中文名调用。英文算子 ID 仅保留在 `--json` 机器输出和内部 API 请求中,供 Agent 与脚本稳定使用。
|
|
37
37
|
|
package/bin/cli.js
CHANGED
|
@@ -436,6 +436,7 @@ async function main() {
|
|
|
436
436
|
`⏳ 异步任务 ${r.json.job_id || ""} 已提交,轮询结果中(预计 ${r.json.estimated_seconds || "?"}s;加 --no-wait 可只拿 job_id)…\n`
|
|
437
437
|
);
|
|
438
438
|
const final = await pollJob(pollUrl, {
|
|
439
|
+
initialBilling: r.json._billing,
|
|
439
440
|
onTick: (j) =>
|
|
440
441
|
process.stderr.write(
|
|
441
442
|
` ${j.status || "?"}${j.elapsed_ms ? " " + Math.round(j.elapsed_ms / 1000) + "s" : ""}\n`
|
|
@@ -517,6 +518,7 @@ async function main() {
|
|
|
517
518
|
}
|
|
518
519
|
const r = await apiFetch(pu);
|
|
519
520
|
console.log(JSON.stringify(r.json, null, 2));
|
|
521
|
+
printBillingResult(r.json);
|
|
520
522
|
if (!r.ok) process.exit(1);
|
|
521
523
|
break;
|
|
522
524
|
}
|
package/lib/api.js
CHANGED
|
@@ -65,16 +65,31 @@ export async function apiFetch(
|
|
|
65
65
|
// 异步算子:轮询 invoke 返回的 poll_url 直到任务出终态(succeeded/failed/…),返回最终 json。
|
|
66
66
|
// 未知 shape(无 status 字段)按终态处理,直接返回让上层打印。
|
|
67
67
|
const ACTIVE = new Set(["queued", "running", "pending", "processing", "in_progress"]);
|
|
68
|
-
export
|
|
68
|
+
export function retainBilling(result, fallbackBilling) {
|
|
69
|
+
if (!fallbackBilling || !result || typeof result !== "object" || Array.isArray(result)) return result;
|
|
70
|
+
return result._billing ? result : { ...result, _billing: fallbackBilling };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function pollJob(
|
|
74
|
+
pollUrl,
|
|
75
|
+
{ intervalMs = 8000, maxMs = 1200000, onTick, initialBilling } = {}
|
|
76
|
+
) {
|
|
69
77
|
const start = Date.now();
|
|
70
78
|
let last = null;
|
|
79
|
+
let lastBilling = initialBilling || null;
|
|
71
80
|
while (Date.now() - start < maxMs) {
|
|
72
81
|
const r = await apiFetch(pollUrl, { timeoutMs: 30000 });
|
|
73
82
|
last = r.json;
|
|
83
|
+
if (r.json?._billing) lastBilling = r.json._billing;
|
|
74
84
|
const s = r.json && r.json.status;
|
|
75
85
|
if (onTick) onTick(r.json);
|
|
76
|
-
if (!r.ok || !s || !ACTIVE.has(s))
|
|
86
|
+
if (!r.ok || !s || !ACTIVE.has(s)) {
|
|
87
|
+
return retainBilling(r.json, lastBilling); // 终态(或报错/未知 shape)→ 返回
|
|
88
|
+
}
|
|
77
89
|
await new Promise((res) => setTimeout(res, intervalMs));
|
|
78
90
|
}
|
|
79
|
-
return
|
|
91
|
+
return retainBilling(
|
|
92
|
+
{ ...(last || {}), status: (last && last.status) || "timeout", _timeout: true },
|
|
93
|
+
lastBilling
|
|
94
|
+
);
|
|
80
95
|
}
|
package/lib/setup.js
CHANGED
|
@@ -17,6 +17,7 @@ function guideBlock() {
|
|
|
17
17
|
- 列出可用算子:\`manturhub ls\`(按类:\`manturhub ls --cat image|video|audio|text|data\`)
|
|
18
18
|
- 查实时价格:\`manturhub quote <算子ID>\`(不要在 Skill / 文档里写死价格)
|
|
19
19
|
- 调用算子:优先把参数写入 JSON 文件,再运行 \`manturhub run <算子ID> --json-file params.json\`;简短可信参数也可用 \`--json '{...}'\`(异步算子会轮询到结果,**别重复调用以免重复扣费**)
|
|
20
|
+
- 统计费用:只读取每次最终 JSON 的 \`_billing.charged_dumplings\` / \`refunded_dumplings\`,多次调用逐笔求和;禁止自行估算
|
|
20
21
|
- 上传本地文件:\`manturhub upload <文件>\` → 公网 URL(算子只接受公网 URL,本地路径非法)
|
|
21
22
|
- 查余额:\`manturhub balance\`
|
|
22
23
|
- 查某算子的精确入参字段:\`manturhub describe <算子ID>\`
|
package/lib/skill.js
CHANGED
|
@@ -31,13 +31,14 @@ description: 调用 ManturHub 算子广场的 AI 能力与行业数据(文生图
|
|
|
31
31
|
| \`manturhub suite ls\` | 列出 Agent 套件(多角色团队工作区,如小说→短剧制作团队) |
|
|
32
32
|
| \`manturhub suite install <slug> [目录]\` | 安装套件为工作目录;Key 仍保存在 CLI 用户级配置中 |
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## 六条铁律(不照做就会踩坑)
|
|
35
35
|
|
|
36
36
|
1. **先 \`manturhub ls\` 摸清能力,再 \`manturhub describe <算子ID>\` 查精确入参** —— CLI 会在付费调用前校验字段、类型和枚举,填参数仍应以实时 schema 为准。
|
|
37
37
|
2. **本地文件先 \`manturhub upload <文件>\`** 换成公网 URL,再把 URL 填进 run 的参数。算子不接受本地路径,只接受公网 URL。
|
|
38
38
|
3. **异步算子直接等 \`run\` 返回** —— \`run\` 已自动轮询到 succeeded 才返回最终结果,**不要重复 run(会重复扣费 + 重复出活)**。视频可能要几分钟,耐心等。真想后台拿 \`job_id\` 用 \`--no-wait\`,之后 \`manturhub status <poll_url>\` 查。
|
|
39
39
|
4. **花钱心里有数** —— 每次 run 前先 \`manturhub quote <算子ID>\`;余额不足时去当前 ManturHub 站点的 \`/pricing\`;异步任务失败平台自动退费。
|
|
40
40
|
5. **能用平台 Skill 就别手搓流程** —— 完整业务(如「FPV 运镜视频」「短剧改编」)平台常有现成 Skill 模板,优先用,省得自己一步步编排还踩坑。
|
|
41
|
+
6. **费用只认返回值,禁止估算** —— 每次 run 完成后读取最终 JSON 的 \`_billing.charged_dumplings\` 和 \`_billing.refunded_dumplings\`;多次或批量调用逐笔求和。最终报告必须写真实合计,不能按文件数、时长或余额印象自行估算。
|
|
41
42
|
|
|
42
43
|
## 典型流程
|
|
43
44
|
|