ability-cli 0.3.2 → 0.3.3
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 -3
- package/dist/index.js +130 -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` |
|
|
@@ -167,13 +170,17 @@ GET `/ability-service/api/agent/v1/ability/abilityInfo`。
|
|
|
167
170
|
|
|
168
171
|
#### `raw call`
|
|
169
172
|
|
|
170
|
-
POST `/ability-service/api/agent/v1/ability/call
|
|
173
|
+
POST `/ability-service/api/agent/v1/ability/call`。
|
|
171
174
|
|
|
172
175
|
| 选项 | 说明 |
|
|
173
176
|
|------|------|
|
|
174
|
-
| `--file <path>` |
|
|
177
|
+
| `--file <path>` | 请求体 JSON 文件(可选);与 `--ability-id` / `--tool-name` 合并时 **CLI 优先** |
|
|
178
|
+
| `--ability-id <id>` | 能力 ID;与 `--tool-name` **至少填其一**(也可仅在 JSON 内提供其一) |
|
|
179
|
+
| `--tool-name <name>` | 工具名;与 `--ability-id` **至少填其一**(二者同时填时仅用 `abilityId`) |
|
|
175
180
|
| `--json` | JSON 输出 |
|
|
176
181
|
|
|
182
|
+
无 `--file` 时与 `exec` 类似,会组装最小请求体(含 `traceId`、`deviceId`、`timeoutMillis`、`params` 等默认值),仍须通过 CLI 或 JSON 解析出 `abilityId` / `toolName`。
|
|
183
|
+
|
|
177
184
|
#### `raw category-list`
|
|
178
185
|
|
|
179
186
|
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,106 @@ 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>", "\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) => {
|
|
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 ?? randomUUID().replace(/-/g, ""),
|
|
381
|
+
sessionId: opts.sessionId ?? "",
|
|
382
|
+
toolCallId: opts.toolCallId ?? "",
|
|
383
|
+
taskId: opts.taskId ?? "",
|
|
384
|
+
messageId: opts.messageId ?? "",
|
|
385
|
+
deviceId: ctx.deviceId ?? "",
|
|
386
|
+
timeoutMillis,
|
|
387
|
+
params
|
|
388
|
+
};
|
|
389
|
+
applyAbilityOrToolToPayload(opts, body);
|
|
390
|
+
if (opts.responseType) body.responseType = opts.responseType;
|
|
391
|
+
if (opts.mockToken) body.mockToken = opts.mockToken;
|
|
392
|
+
const res = await apiPost(ctx, agentPath.abilityCall, body);
|
|
393
|
+
handleApiResponse(res, opts.json, (data) => {
|
|
394
|
+
printSuccess("\u80FD\u529B\u6267\u884C\u5B8C\u6210");
|
|
395
|
+
printJson(data);
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
297
400
|
// src/commands/raw.ts
|
|
298
401
|
function registerRawCommand(program2) {
|
|
299
402
|
const raw = program2.command("raw").description("\u539F\u59CB\u63A5\u53E3\u76F4\u901A\uFF08\u8054\u8C03/\u6392\u969C\uFF09");
|
|
@@ -330,11 +433,34 @@ function registerRawCommand(program2) {
|
|
|
330
433
|
});
|
|
331
434
|
raw.command("call").description("POST \u6267\u884C\u80FD\u529B\uFF08Agent API\uFF09").addHelpText(
|
|
332
435
|
"after",
|
|
333
|
-
"\n\u63D0\u793A\uFF1A\
|
|
334
|
-
).
|
|
436
|
+
"\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"
|
|
437
|
+
).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
438
|
const merged = { ...program2.opts(), ...opts };
|
|
336
439
|
const ctx = buildAgentRequestContext(merged);
|
|
337
|
-
const
|
|
440
|
+
const cliCfg = loadConfig();
|
|
441
|
+
const timeoutMillis = cliCfg.defaults.timeout ?? 3e4;
|
|
442
|
+
let data;
|
|
443
|
+
if (opts.file) {
|
|
444
|
+
const raw2 = fs3.readFileSync(opts.file, "utf-8");
|
|
445
|
+
const parsed = JSON.parse(raw2);
|
|
446
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
447
|
+
throw new Error("\u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
|
|
448
|
+
}
|
|
449
|
+
data = parsed;
|
|
450
|
+
applyAbilityOrToolToPayload(opts, data);
|
|
451
|
+
} else {
|
|
452
|
+
data = {
|
|
453
|
+
traceId: randomUUID2().replace(/-/g, ""),
|
|
454
|
+
sessionId: "",
|
|
455
|
+
toolCallId: "",
|
|
456
|
+
taskId: "",
|
|
457
|
+
messageId: "",
|
|
458
|
+
deviceId: ctx.deviceId ?? "",
|
|
459
|
+
timeoutMillis,
|
|
460
|
+
params: {}
|
|
461
|
+
};
|
|
462
|
+
applyAbilityOrToolToPayload(opts, data);
|
|
463
|
+
}
|
|
338
464
|
const res = await apiPost(ctx, agentPath.abilityCall, data);
|
|
339
465
|
handleApiResponse(res, opts.json, (data2) => printJson(data2));
|
|
340
466
|
});
|
|
@@ -416,70 +542,6 @@ function registerInspectCommand(program2) {
|
|
|
416
542
|
});
|
|
417
543
|
}
|
|
418
544
|
|
|
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
545
|
// src/commands/sign.ts
|
|
484
546
|
import chalk2 from "chalk";
|
|
485
547
|
|