ability-cli 0.3.2 → 0.3.4
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 +10 -4
- package/dist/index.js +129 -68
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,6 +62,8 @@ ability-cli inspect --ability-id 20001 --gen-template > params.json
|
|
|
62
62
|
|
|
63
63
|
# 执行能力(对应 POST /ability-service/api/agent/v1/ability/call)
|
|
64
64
|
ability-cli exec --ability-id 20001 --params '{"contact":"张三","message":"你好"}'
|
|
65
|
+
# 或使用工具名(与 ability-id 二选一)
|
|
66
|
+
ability-cli exec --tool-name my_tool --params '{}'
|
|
65
67
|
|
|
66
68
|
# 健康检查
|
|
67
69
|
ability-cli doctor
|
|
@@ -117,7 +119,8 @@ ability-cli doctor
|
|
|
117
119
|
|
|
118
120
|
| 选项 | 说明 |
|
|
119
121
|
|------|------|
|
|
120
|
-
| `--ability-id <id>` |
|
|
122
|
+
| `--ability-id <id>` | **条件必填**:能力 ID;与 `--tool-name` **至少填其一** |
|
|
123
|
+
| `--tool-name <name>` | **条件必填**:工具名;与 `--ability-id` **至少填其一**(二者同时填时仅用 `abilityId`) |
|
|
121
124
|
| `--params <json>` | 参数:JSON 字符串,或指向 JSON 文件的路径 |
|
|
122
125
|
| `--device-id <id>` | 设备 ID;默认可来自全局/环境变量/配置的合并结果 |
|
|
123
126
|
| `--session-id <id>` | `sessionId` |
|
|
@@ -127,7 +130,6 @@ ability-cli doctor
|
|
|
127
130
|
| `--trace-id <id>` | `traceId`;未指定时自动生成 |
|
|
128
131
|
| `--timeout <ms>` | 超时(毫秒);不传则用配置文件 `defaults.timeout`,再默认 `30000` |
|
|
129
132
|
| `--response-type <type>` | `NONE` / `MCP` / `CONVERT`(可选) |
|
|
130
|
-
| `--mock-token <token>` | 模拟调用 token(可选,测试) |
|
|
131
133
|
| `--json` | 以 JSON 展示返回 `data` |
|
|
132
134
|
|
|
133
135
|
### 下层命令:`raw`
|
|
@@ -167,13 +169,17 @@ GET `/ability-service/api/agent/v1/ability/abilityInfo`。
|
|
|
167
169
|
|
|
168
170
|
#### `raw call`
|
|
169
171
|
|
|
170
|
-
POST `/ability-service/api/agent/v1/ability/call
|
|
172
|
+
POST `/ability-service/api/agent/v1/ability/call`。
|
|
171
173
|
|
|
172
174
|
| 选项 | 说明 |
|
|
173
175
|
|------|------|
|
|
174
|
-
| `--file <path>` |
|
|
176
|
+
| `--file <path>` | 请求体 JSON 文件(可选);与 `--ability-id` / `--tool-name` 合并时 **CLI 优先** |
|
|
177
|
+
| `--ability-id <id>` | 能力 ID;与 `--tool-name` **至少填其一**(也可仅在 JSON 内提供其一) |
|
|
178
|
+
| `--tool-name <name>` | 工具名;与 `--ability-id` **至少填其一**(二者同时填时仅用 `abilityId`) |
|
|
175
179
|
| `--json` | JSON 输出 |
|
|
176
180
|
|
|
181
|
+
无 `--file` 时与 `exec` 类似,会组装最小请求体(含 `traceId`、`deviceId`、`timeoutMillis`、`params` 等默认值),仍须通过 CLI 或 JSON 解析出 `abilityId` / `toolName`。
|
|
182
|
+
|
|
177
183
|
#### `raw category-list`
|
|
178
184
|
|
|
179
185
|
GET `/ability-service/api/agent/v1/ability/category`。
|
package/dist/index.js
CHANGED
|
@@ -190,6 +190,9 @@ function registerConfigCommand(program2) {
|
|
|
190
190
|
});
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
// src/commands/raw.ts
|
|
194
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
195
|
+
|
|
193
196
|
// src/context.ts
|
|
194
197
|
function firstNonEmpty(...vals) {
|
|
195
198
|
for (const v of vals) {
|
|
@@ -282,7 +285,7 @@ async function apiPost(ctx, path2, data) {
|
|
|
282
285
|
}
|
|
283
286
|
|
|
284
287
|
// src/commands/raw.ts
|
|
285
|
-
import
|
|
288
|
+
import fs3 from "fs";
|
|
286
289
|
|
|
287
290
|
// src/agent-paths.ts
|
|
288
291
|
var AGENT_API_PREFIX = "/ability-service/api/agent/v1";
|
|
@@ -294,6 +297,105 @@ var agentPath = {
|
|
|
294
297
|
abilityCall: `${AGENT_API_PREFIX}/ability/call`
|
|
295
298
|
};
|
|
296
299
|
|
|
300
|
+
// src/commands/exec.ts
|
|
301
|
+
import { randomUUID } from "crypto";
|
|
302
|
+
import fs2 from "fs";
|
|
303
|
+
|
|
304
|
+
// src/parse-cli-json.ts
|
|
305
|
+
function parseCliJsonString(raw, label) {
|
|
306
|
+
const s = raw.replace(/^\uFEFF/, "").trim();
|
|
307
|
+
if (!s) return {};
|
|
308
|
+
try {
|
|
309
|
+
return JSON.parse(s);
|
|
310
|
+
} catch (e) {
|
|
311
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
312
|
+
let hint = "";
|
|
313
|
+
if (/^\s*\{\s*'/.test(s)) {
|
|
314
|
+
hint = " JSON \u952E\u540D\u987B\u7528\u82F1\u6587\u53CC\u5F15\u53F7\uFF1B\u5F53\u524D\u5185\u5BB9\u5728 { \u540E\u51FA\u73B0\u4E86\u5355\u5F15\u53F7\u3002\u6700\u7A33\u59A5\uFF1A\u5C06 JSON \u5B58\u4E3A params.json\uFF08UTF-8\uFF09\uFF0C\u518D\u4F7F\u7528 --params params.json\u3002";
|
|
315
|
+
} else if (/[\u201c\u201d\u2018\u2019]/.test(s)) {
|
|
316
|
+
hint = ' \u68C0\u6D4B\u5230\u5F2F\u5F15\u53F7\uFF08\u201C \u201D \u2018 \u2019\uFF09\u3002\u8BF7\u6539\u4E3A ASCII \u53CC\u5F15\u53F7 " \u3002';
|
|
317
|
+
}
|
|
318
|
+
const preview = s.length > 160 ? `${s.slice(0, 160)}\u2026` : s;
|
|
319
|
+
throw new Error(`${label} \u89E3\u6790\u5931\u8D25\uFF1A${msg}.${hint}
|
|
320
|
+
\u5B9E\u9645\u6536\u5230\u7684\u5F00\u5934\uFF1A${JSON.stringify(preview.slice(0, 80))}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/commands/exec.ts
|
|
325
|
+
function pickAbilityOrTool(opts) {
|
|
326
|
+
const rawId = opts.abilityId !== void 0 ? String(opts.abilityId).trim() : "";
|
|
327
|
+
const rawName = opts.toolName !== void 0 ? String(opts.toolName).trim() : "";
|
|
328
|
+
if (!rawId && !rawName) {
|
|
329
|
+
throw new Error(
|
|
330
|
+
"\u5FC5\u987B\u63D0\u4F9B abilityId \u6216 toolName\uFF08\u547D\u4EE4\u884C --ability-id / --tool-name\uFF0C\u6216\u8BF7\u6C42 JSON \u5185\u5B57\u6BB5\uFF09"
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
if (rawId) {
|
|
334
|
+
const n = Number(rawId);
|
|
335
|
+
if (!Number.isFinite(n)) {
|
|
336
|
+
throw new Error(`--ability-id \u4E0D\u662F\u5408\u6CD5\u6570\u5B57: ${rawId}`);
|
|
337
|
+
}
|
|
338
|
+
return { abilityId: n };
|
|
339
|
+
}
|
|
340
|
+
return { toolName: rawName };
|
|
341
|
+
}
|
|
342
|
+
function applyAbilityOrToolToPayload(opts, data) {
|
|
343
|
+
const cliId = opts.abilityId !== void 0 && String(opts.abilityId).trim() !== "" ? String(opts.abilityId).trim() : "";
|
|
344
|
+
const cliName = opts.toolName !== void 0 && String(opts.toolName).trim() !== "" ? String(opts.toolName).trim() : "";
|
|
345
|
+
const fileId = data.abilityId != null && String(data.abilityId).trim() !== "" ? String(data.abilityId).trim() : "";
|
|
346
|
+
const fileName = data.toolName != null && String(data.toolName).trim() !== "" ? String(data.toolName).trim() : "";
|
|
347
|
+
const rawId = cliId || fileId;
|
|
348
|
+
const rawName = cliName || fileName;
|
|
349
|
+
const target = pickAbilityOrTool({
|
|
350
|
+
abilityId: rawId || void 0,
|
|
351
|
+
toolName: rawName || void 0
|
|
352
|
+
});
|
|
353
|
+
if (target.abilityId !== void 0) {
|
|
354
|
+
data.abilityId = target.abilityId;
|
|
355
|
+
delete data.toolName;
|
|
356
|
+
} else {
|
|
357
|
+
data.toolName = target.toolName;
|
|
358
|
+
delete data.abilityId;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function registerExecCommand(program2) {
|
|
362
|
+
program2.command("exec").description("\u6267\u884C\u80FD\u529B").addHelpText(
|
|
363
|
+
"after",
|
|
364
|
+
"\n\u63D0\u793A\uFF1A\u5FC5\u987B\u63D0\u4F9B --ability-id \u4E0E --tool-name \u4E8C\u8005\u4E4B\u4E00\uFF1B\u5176\u4F59\u9009\u9879\u8BF4\u660E\u4E2D\u5E26\u300C\u3010\u5FC5\u586B\u3011\u300D\u7684\u4E5F\u5FC5\u987B\u63D0\u4F9B\u3002\n"
|
|
365
|
+
).option("--ability-id <id>", "\u3010\u6761\u4EF6\u5FC5\u586B\u3011\u80FD\u529B ID\uFF1B\u4E0E --tool-name \u81F3\u5C11\u586B\u5176\u4E00").option("--tool-name <name>", "\u3010\u6761\u4EF6\u5FC5\u586B\u3011\u5DE5\u5177\u540D\uFF1B\u4E0E --ability-id \u81F3\u5C11\u586B\u5176\u4E00").option("--params <json>", "\u80FD\u529B\u5165\u53C2 params\uFF1AJSON \u5B57\u7B26\u4E32\u6216\u6587\u4EF6\u8DEF\u5F84").option("--device-id <id>", "\u8BF7\u6C42\u4F53 deviceId\uFF1B\u672A\u6307\u5B9A\u65F6\u7528\u5168\u5C40/\u73AF\u5883\u53D8\u91CF/\u914D\u7F6E\u89E3\u6790\u7ED3\u679C").option("--session-id <id>", "sessionId").option("--tool-call-id <id>", "toolCallId").option("--task-id <id>", "taskId").option("--message-id <id>", "messageId").option("--trace-id <id>", "traceId\uFF1B\u672A\u6307\u5B9A\u65F6\u81EA\u52A8\u751F\u6210").option("--timeout <ms>", "timeoutMillis\uFF08\u6BEB\u79D2\uFF09\uFF1B\u4E0D\u4F20\u5219\u7528 defaults.timeout\uFF0C\u9ED8\u8BA4 30000").option("--response-type <type>", "responseType\uFF1ANONE | MCP | CONVERT").option("--json", "JSON \u8F93\u51FA").action(async (opts) => {
|
|
366
|
+
const merged = { ...program2.opts(), ...opts };
|
|
367
|
+
const ctx = buildAgentRequestContext(merged);
|
|
368
|
+
const cliCfg = loadConfig();
|
|
369
|
+
const timeoutMillis = opts.timeout !== void 0 && String(opts.timeout).trim() !== "" ? Number(opts.timeout) : cliCfg.defaults.timeout ?? 3e4;
|
|
370
|
+
let params = {};
|
|
371
|
+
if (opts.params) {
|
|
372
|
+
if (fs2.existsSync(opts.params)) {
|
|
373
|
+
const text = fs2.readFileSync(opts.params, "utf-8");
|
|
374
|
+
params = parseCliJsonString(text, "\u53C2\u6570\u6587\u4EF6");
|
|
375
|
+
} else {
|
|
376
|
+
params = parseCliJsonString(opts.params, "--params");
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const body = {
|
|
380
|
+
traceId: opts.traceId !== void 0 && String(opts.traceId).trim() !== "" ? String(opts.traceId).trim() : randomUUID().replace(/-/g, ""),
|
|
381
|
+
sessionId: opts.sessionId !== void 0 ? String(opts.sessionId) : "",
|
|
382
|
+
toolCallId: opts.toolCallId !== void 0 ? String(opts.toolCallId) : "",
|
|
383
|
+
taskId: opts.taskId !== void 0 ? String(opts.taskId) : "",
|
|
384
|
+
messageId: opts.messageId !== void 0 ? String(opts.messageId) : "",
|
|
385
|
+
deviceId: ctx.deviceId ?? "",
|
|
386
|
+
timeoutMillis,
|
|
387
|
+
params
|
|
388
|
+
};
|
|
389
|
+
applyAbilityOrToolToPayload(opts, body);
|
|
390
|
+
if (opts.responseType) body.responseType = opts.responseType;
|
|
391
|
+
const res = await apiPost(ctx, agentPath.abilityCall, body);
|
|
392
|
+
handleApiResponse(res, opts.json, (data) => {
|
|
393
|
+
printSuccess("\u80FD\u529B\u6267\u884C\u5B8C\u6210");
|
|
394
|
+
printJson(data);
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
297
399
|
// src/commands/raw.ts
|
|
298
400
|
function registerRawCommand(program2) {
|
|
299
401
|
const raw = program2.command("raw").description("\u539F\u59CB\u63A5\u53E3\u76F4\u901A\uFF08\u8054\u8C03/\u6392\u969C\uFF09");
|
|
@@ -330,11 +432,34 @@ function registerRawCommand(program2) {
|
|
|
330
432
|
});
|
|
331
433
|
raw.command("call").description("POST \u6267\u884C\u80FD\u529B\uFF08Agent API\uFF09").addHelpText(
|
|
332
434
|
"after",
|
|
333
|
-
"\n\u63D0\u793A\uFF1A\
|
|
334
|
-
).
|
|
435
|
+
"\n\u63D0\u793A\uFF1A\u987B\u80FD\u901A\u8FC7\u547D\u4EE4\u884C\u6216 JSON \u89E3\u6790\u51FA abilityId / toolName\uFF08\u4E8C\u8005\u5176\u4E00\uFF09\uFF1B\u65E0 --file \u65F6\u5FC5\u987B\u63D0\u4F9B --ability-id \u6216 --tool-name\u3002\n"
|
|
436
|
+
).option("--file <path>", "\u8BF7\u6C42\u4F53 JSON \u6587\u4EF6\uFF08\u53EF\u9009\uFF1B\u4E0E CLI \u5B57\u6BB5\u5408\u5E76\uFF0CCLI \u4F18\u5148\uFF09").option("--ability-id <id>", "\u80FD\u529B ID\uFF1B\u4E0E --tool-name \u81F3\u5C11\u5176\u4E00\uFF08\u53EF\u4E0E --file \u7EC4\u5408\uFF09").option("--tool-name <name>", "\u5DE5\u5177\u540D\uFF1B\u4E0E --ability-id \u81F3\u5C11\u5176\u4E00\uFF08\u53EF\u4E0E --file \u7EC4\u5408\uFF09").option("--json", "JSON \u8F93\u51FA").action(async (opts) => {
|
|
335
437
|
const merged = { ...program2.opts(), ...opts };
|
|
336
438
|
const ctx = buildAgentRequestContext(merged);
|
|
337
|
-
const
|
|
439
|
+
const cliCfg = loadConfig();
|
|
440
|
+
const timeoutMillis = cliCfg.defaults.timeout ?? 3e4;
|
|
441
|
+
let data;
|
|
442
|
+
if (opts.file) {
|
|
443
|
+
const raw2 = fs3.readFileSync(opts.file, "utf-8");
|
|
444
|
+
const parsed = JSON.parse(raw2);
|
|
445
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
446
|
+
throw new Error("\u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
|
|
447
|
+
}
|
|
448
|
+
data = parsed;
|
|
449
|
+
applyAbilityOrToolToPayload(opts, data);
|
|
450
|
+
} else {
|
|
451
|
+
data = {
|
|
452
|
+
traceId: randomUUID2().replace(/-/g, ""),
|
|
453
|
+
sessionId: "",
|
|
454
|
+
toolCallId: "",
|
|
455
|
+
taskId: "",
|
|
456
|
+
messageId: "",
|
|
457
|
+
deviceId: ctx.deviceId ?? "",
|
|
458
|
+
timeoutMillis,
|
|
459
|
+
params: {}
|
|
460
|
+
};
|
|
461
|
+
applyAbilityOrToolToPayload(opts, data);
|
|
462
|
+
}
|
|
338
463
|
const res = await apiPost(ctx, agentPath.abilityCall, data);
|
|
339
464
|
handleApiResponse(res, opts.json, (data2) => printJson(data2));
|
|
340
465
|
});
|
|
@@ -416,70 +541,6 @@ function registerInspectCommand(program2) {
|
|
|
416
541
|
});
|
|
417
542
|
}
|
|
418
543
|
|
|
419
|
-
// src/commands/exec.ts
|
|
420
|
-
import { randomUUID } from "crypto";
|
|
421
|
-
import fs3 from "fs";
|
|
422
|
-
|
|
423
|
-
// src/parse-cli-json.ts
|
|
424
|
-
function parseCliJsonString(raw, label) {
|
|
425
|
-
const s = raw.replace(/^\uFEFF/, "").trim();
|
|
426
|
-
if (!s) return {};
|
|
427
|
-
try {
|
|
428
|
-
return JSON.parse(s);
|
|
429
|
-
} catch (e) {
|
|
430
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
431
|
-
let hint = "";
|
|
432
|
-
if (/^\s*\{\s*'/.test(s)) {
|
|
433
|
-
hint = " JSON \u952E\u540D\u987B\u7528\u82F1\u6587\u53CC\u5F15\u53F7\uFF1B\u5F53\u524D\u5185\u5BB9\u5728 { \u540E\u51FA\u73B0\u4E86\u5355\u5F15\u53F7\u3002\u6700\u7A33\u59A5\uFF1A\u5C06 JSON \u5B58\u4E3A params.json\uFF08UTF-8\uFF09\uFF0C\u518D\u4F7F\u7528 --params params.json\u3002";
|
|
434
|
-
} else if (/[\u201c\u201d\u2018\u2019]/.test(s)) {
|
|
435
|
-
hint = ' \u68C0\u6D4B\u5230\u5F2F\u5F15\u53F7\uFF08\u201C \u201D \u2018 \u2019\uFF09\u3002\u8BF7\u6539\u4E3A ASCII \u53CC\u5F15\u53F7 " \u3002';
|
|
436
|
-
}
|
|
437
|
-
const preview = s.length > 160 ? `${s.slice(0, 160)}\u2026` : s;
|
|
438
|
-
throw new Error(`${label} \u89E3\u6790\u5931\u8D25\uFF1A${msg}.${hint}
|
|
439
|
-
\u5B9E\u9645\u6536\u5230\u7684\u5F00\u5934\uFF1A${JSON.stringify(preview.slice(0, 80))}`);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// src/commands/exec.ts
|
|
444
|
-
function registerExecCommand(program2) {
|
|
445
|
-
program2.command("exec").description("\u6267\u884C\u80FD\u529B").addHelpText(
|
|
446
|
-
"after",
|
|
447
|
-
"\n\u63D0\u793A\uFF1A\u9009\u9879\u8BF4\u660E\u4E2D\u4EE5\u300C\u3010\u5FC5\u586B\u3011\u300D\u5F00\u5934\u7684\u5FC5\u987B\u63D0\u4F9B\uFF0C\u5176\u4F59\u5747\u4E3A\u53EF\u9009\u3002\n"
|
|
448
|
-
).requiredOption("--ability-id <id>", "\u3010\u5FC5\u586B\u3011\u80FD\u529B ID").option("--params <json>", "\u53C2\u6570 JSON \u5B57\u7B26\u4E32\u6216\u6587\u4EF6\u8DEF\u5F84").option("--device-id <id>", "\u8BBE\u5907ID").option("--message-id <id>", "messageId").option("--trace-id <id>", "traceId").option("--timeout <ms>", "\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09\uFF1B\u4E0D\u4F20\u5219\u7528\u914D\u7F6E\u6587\u4EF6 defaults.timeout\uFF0C\u9ED8\u8BA4 30000").option("--response-type <type>", "\u8FD4\u56DE\u503C\u5904\u7406\u65B9\u5F0F: NONE | MCP | CONVERT").option("--json", "JSON \u8F93\u51FA").action(async (opts) => {
|
|
449
|
-
const merged = { ...program2.opts(), ...opts };
|
|
450
|
-
const ctx = buildAgentRequestContext(merged);
|
|
451
|
-
const cliCfg = loadConfig();
|
|
452
|
-
const timeoutMillis = opts.timeout !== void 0 && String(opts.timeout).trim() !== "" ? Number(opts.timeout) : cliCfg.defaults.timeout ?? 3e4;
|
|
453
|
-
let params = {};
|
|
454
|
-
if (opts.params) {
|
|
455
|
-
if (fs3.existsSync(opts.params)) {
|
|
456
|
-
const text = fs3.readFileSync(opts.params, "utf-8");
|
|
457
|
-
params = parseCliJsonString(text, "\u53C2\u6570\u6587\u4EF6");
|
|
458
|
-
} else {
|
|
459
|
-
params = parseCliJsonString(opts.params, "--params");
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
const body = {
|
|
463
|
-
abilityId: Number(opts.abilityId),
|
|
464
|
-
traceId: opts.traceId ?? randomUUID().replace(/-/g, ""),
|
|
465
|
-
sessionId: opts.sessionId ?? "",
|
|
466
|
-
toolCallId: opts.toolCallId ?? "",
|
|
467
|
-
taskId: opts.taskId ?? "",
|
|
468
|
-
messageId: opts.messageId ?? "",
|
|
469
|
-
deviceId: ctx.deviceId ?? "",
|
|
470
|
-
timeoutMillis,
|
|
471
|
-
params
|
|
472
|
-
};
|
|
473
|
-
if (opts.responseType) body.responseType = opts.responseType;
|
|
474
|
-
if (opts.mockToken) body.mockToken = opts.mockToken;
|
|
475
|
-
const res = await apiPost(ctx, agentPath.abilityCall, body);
|
|
476
|
-
handleApiResponse(res, opts.json, (data) => {
|
|
477
|
-
printSuccess("\u80FD\u529B\u6267\u884C\u5B8C\u6210");
|
|
478
|
-
printJson(data);
|
|
479
|
-
});
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
|
|
483
544
|
// src/commands/sign.ts
|
|
484
545
|
import chalk2 from "chalk";
|
|
485
546
|
|