ability-cli 0.3.1 → 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 +15 -8
- package/dist/index.js +164 -85
- 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
|
|
@@ -79,7 +81,7 @@ ability-cli doctor
|
|
|
79
81
|
|
|
80
82
|
| 选项 | 说明 |
|
|
81
83
|
|------|------|
|
|
82
|
-
| `--env <env>` | 环境:`test` / `prod`,选用配置文件中哪一套 `profiles`(主要影响 `baseUrl`) |
|
|
84
|
+
| `--env <env>` | 环境:`test` / `stg` / `prod`,选用配置文件中哪一套 `profiles`(主要影响 `baseUrl`) |
|
|
83
85
|
| `--auth-token <token>` | 授权密钥 `sk-…`,写入请求头 `Authorization` |
|
|
84
86
|
| `--base-url <url>` | 网关根地址(真实路径为 `{baseUrl}/ability-service/api/agent/v1/...`) |
|
|
85
87
|
| `--device-id <id>` | 设备 ID,写入请求头 `zy-device-id`,并参与部分接口 query |
|
|
@@ -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`。
|
|
@@ -213,7 +220,7 @@ GET `/ability-service/api/agent/v1/ability/category`。
|
|
|
213
220
|
|
|
214
221
|
#### `doctor`
|
|
215
222
|
|
|
216
|
-
检查配置文件路径、当前环境、解析后的 **`Authorization(sk)`** / **`zy-device-id`** / **`baseUrl
|
|
223
|
+
检查配置文件路径、当前环境、解析后的 **`Authorization(sk)`** / **`zy-device-id`** / **`baseUrl`**。
|
|
217
224
|
|
|
218
225
|
---
|
|
219
226
|
|
|
@@ -223,7 +230,7 @@ GET `/ability-service/api/agent/v1/ability/category`。
|
|
|
223
230
|
|
|
224
231
|
默认路径:**`~/.ability-cli/config.json`**。
|
|
225
232
|
|
|
226
|
-
首次运行若文件不存在,会使用内置默认:当前环境 **`prod`**,`test` / `prod` 各有一套 `baseUrl`;`profiles.*.authToken`(sk)、`defaults.deviceId` 等为空字符串。
|
|
233
|
+
首次运行若文件不存在,会使用内置默认:当前环境 **`prod`**,`test` / `stg` / `prod` 各有一套 `baseUrl`;`profiles.*.authToken`(sk)、`defaults.deviceId` 等为空字符串。
|
|
227
234
|
|
|
228
235
|
通过 `ability-cli config set` 写入后,会按 `env` 更新对应 `profiles[env]` 下的 `baseUrl`、`authToken`(sk)等;`defaults` 下可保存默认设备 ID 等。
|
|
229
236
|
|
|
@@ -231,7 +238,7 @@ GET `/ability-service/api/agent/v1/ability/category`。
|
|
|
231
238
|
|
|
232
239
|
| 变量 | 作用 |
|
|
233
240
|
|------|------|
|
|
234
|
-
| `ABILITY_CLI_ENV` | 选用 `profiles` 的环境键(如 `test` / `prod`) |
|
|
241
|
+
| `ABILITY_CLI_ENV` | 选用 `profiles` 的环境键(如 `test` / `stg` / `prod`) |
|
|
235
242
|
| `ABILITY_CLI_AUTH_TOKEN` | 授权密钥 `sk-…`,对应请求头 `Authorization` |
|
|
236
243
|
| `ABILITY_CLI_DEVICE_ID` | 设备 ID,对应请求头 `zy-device-id`,并参与部分 query |
|
|
237
244
|
| `ABILITY_CLI_BASE_URL` | 网关根地址 |
|
|
@@ -242,7 +249,7 @@ GET `/ability-service/api/agent/v1/ability/category`。
|
|
|
242
249
|
|
|
243
250
|
对 **`authToken` / `deviceId` / `baseUrl`**:**子命令参数 > 全局参数 > 对应环境变量 > 配置文件**(子命令与全局选项先做对象合并,后者覆盖前者)。
|
|
244
251
|
|
|
245
|
-
当前激活的 **profile(test
|
|
252
|
+
当前激活的 **profile(test / stg / prod)** 由 **`ABILITY_CLI_ENV`(若设置)** 与配置文件中的 **`env`** 字段共同决定(环境变量优先)。
|
|
246
253
|
|
|
247
254
|
---
|
|
248
255
|
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,10 @@ var DEFAULT_CONFIG = {
|
|
|
17
17
|
baseUrl: "https://biz-gw.zyqltest.com",
|
|
18
18
|
authToken: ""
|
|
19
19
|
},
|
|
20
|
+
stg: {
|
|
21
|
+
baseUrl: "https://biz-gw-in.zyql.com",
|
|
22
|
+
authToken: ""
|
|
23
|
+
},
|
|
20
24
|
prod: {
|
|
21
25
|
baseUrl: "https://biz-gw.zyql.com",
|
|
22
26
|
authToken: ""
|
|
@@ -34,7 +38,33 @@ function loadConfig(configPath) {
|
|
|
34
38
|
const p = configPath ?? getDefaultConfigPath();
|
|
35
39
|
if (!fs.existsSync(p)) return structuredClone(DEFAULT_CONFIG);
|
|
36
40
|
const raw = fs.readFileSync(p, "utf-8");
|
|
37
|
-
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
const defaults = parsed.defaults ?? {};
|
|
43
|
+
const profiles = parsed.profiles ?? {};
|
|
44
|
+
const mergedProfiles = {
|
|
45
|
+
...structuredClone(DEFAULT_CONFIG).profiles
|
|
46
|
+
};
|
|
47
|
+
for (const [name, profile] of Object.entries(profiles)) {
|
|
48
|
+
const prev = mergedProfiles[name] ?? { baseUrl: "", authToken: "" };
|
|
49
|
+
const incoming = profile ?? {};
|
|
50
|
+
const normalized = { ...incoming };
|
|
51
|
+
if (typeof incoming.baseUrl === "undefined" || incoming.baseUrl.trim() === "") {
|
|
52
|
+
normalized.baseUrl = prev.baseUrl;
|
|
53
|
+
}
|
|
54
|
+
mergedProfiles[name] = {
|
|
55
|
+
...prev,
|
|
56
|
+
...normalized
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
...structuredClone(DEFAULT_CONFIG),
|
|
61
|
+
...parsed,
|
|
62
|
+
defaults: {
|
|
63
|
+
...structuredClone(DEFAULT_CONFIG).defaults,
|
|
64
|
+
...defaults
|
|
65
|
+
},
|
|
66
|
+
profiles: mergedProfiles
|
|
67
|
+
};
|
|
38
68
|
}
|
|
39
69
|
function saveConfig(configPath, config) {
|
|
40
70
|
const dir = path.dirname(configPath);
|
|
@@ -135,7 +165,7 @@ function mergeConfigSetOpts(program2, opts) {
|
|
|
135
165
|
}
|
|
136
166
|
function registerConfigCommand(program2) {
|
|
137
167
|
const cfg = program2.command("config").description("\u7BA1\u7406 CLI \u914D\u7F6E");
|
|
138
|
-
cfg.command("set").description("\u8BBE\u7F6E\u914D\u7F6E\u9879").option("--env <env>", "\u73AF\u5883 (test/prod)").option("--auth-token <token>", "Authorization token\uFF08sk\uFF09").option("--base-url <url>", "\u7F51\u5173\u5730\u5740").option("--device-id <id>", "\u9ED8\u8BA4\u8BBE\u5907ID").option("--timeout <ms>", "\u9ED8\u8BA4\u8C03\u7528\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09\uFF0C\u5199\u5165 defaults.timeout").action((opts) => {
|
|
168
|
+
cfg.command("set").description("\u8BBE\u7F6E\u914D\u7F6E\u9879").option("--env <env>", "\u73AF\u5883 (test/stg/prod)").option("--auth-token <token>", "Authorization token\uFF08sk\uFF09").option("--base-url <url>", "\u7F51\u5173\u5730\u5740").option("--device-id <id>", "\u9ED8\u8BA4\u8BBE\u5907ID").option("--timeout <ms>", "\u9ED8\u8BA4\u8C03\u7528\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09\uFF0C\u5199\u5165 defaults.timeout").action((opts) => {
|
|
139
169
|
const m = mergeConfigSetOpts(program2, opts);
|
|
140
170
|
const configPath = getDefaultConfigPath();
|
|
141
171
|
const config = loadConfig(configPath);
|
|
@@ -160,6 +190,9 @@ function registerConfigCommand(program2) {
|
|
|
160
190
|
});
|
|
161
191
|
}
|
|
162
192
|
|
|
193
|
+
// src/commands/raw.ts
|
|
194
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
195
|
+
|
|
163
196
|
// src/context.ts
|
|
164
197
|
function firstNonEmpty(...vals) {
|
|
165
198
|
for (const v of vals) {
|
|
@@ -252,7 +285,7 @@ async function apiPost(ctx, path2, data) {
|
|
|
252
285
|
}
|
|
253
286
|
|
|
254
287
|
// src/commands/raw.ts
|
|
255
|
-
import
|
|
288
|
+
import fs3 from "fs";
|
|
256
289
|
|
|
257
290
|
// src/agent-paths.ts
|
|
258
291
|
var AGENT_API_PREFIX = "/ability-service/api/agent/v1";
|
|
@@ -264,6 +297,106 @@ var agentPath = {
|
|
|
264
297
|
abilityCall: `${AGENT_API_PREFIX}/ability/call`
|
|
265
298
|
};
|
|
266
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
|
+
|
|
267
400
|
// src/commands/raw.ts
|
|
268
401
|
function registerRawCommand(program2) {
|
|
269
402
|
const raw = program2.command("raw").description("\u539F\u59CB\u63A5\u53E3\u76F4\u901A\uFF08\u8054\u8C03/\u6392\u969C\uFF09");
|
|
@@ -300,11 +433,34 @@ function registerRawCommand(program2) {
|
|
|
300
433
|
});
|
|
301
434
|
raw.command("call").description("POST \u6267\u884C\u80FD\u529B\uFF08Agent API\uFF09").addHelpText(
|
|
302
435
|
"after",
|
|
303
|
-
"\n\u63D0\u793A\uFF1A\
|
|
304
|
-
).
|
|
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) => {
|
|
305
438
|
const merged = { ...program2.opts(), ...opts };
|
|
306
439
|
const ctx = buildAgentRequestContext(merged);
|
|
307
|
-
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
|
+
}
|
|
308
464
|
const res = await apiPost(ctx, agentPath.abilityCall, data);
|
|
309
465
|
handleApiResponse(res, opts.json, (data2) => printJson(data2));
|
|
310
466
|
});
|
|
@@ -386,70 +542,6 @@ function registerInspectCommand(program2) {
|
|
|
386
542
|
});
|
|
387
543
|
}
|
|
388
544
|
|
|
389
|
-
// src/commands/exec.ts
|
|
390
|
-
import { randomUUID } from "crypto";
|
|
391
|
-
import fs3 from "fs";
|
|
392
|
-
|
|
393
|
-
// src/parse-cli-json.ts
|
|
394
|
-
function parseCliJsonString(raw, label) {
|
|
395
|
-
const s = raw.replace(/^\uFEFF/, "").trim();
|
|
396
|
-
if (!s) return {};
|
|
397
|
-
try {
|
|
398
|
-
return JSON.parse(s);
|
|
399
|
-
} catch (e) {
|
|
400
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
401
|
-
let hint = "";
|
|
402
|
-
if (/^\s*\{\s*'/.test(s)) {
|
|
403
|
-
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";
|
|
404
|
-
} else if (/[\u201c\u201d\u2018\u2019]/.test(s)) {
|
|
405
|
-
hint = ' \u68C0\u6D4B\u5230\u5F2F\u5F15\u53F7\uFF08\u201C \u201D \u2018 \u2019\uFF09\u3002\u8BF7\u6539\u4E3A ASCII \u53CC\u5F15\u53F7 " \u3002';
|
|
406
|
-
}
|
|
407
|
-
const preview = s.length > 160 ? `${s.slice(0, 160)}\u2026` : s;
|
|
408
|
-
throw new Error(`${label} \u89E3\u6790\u5931\u8D25\uFF1A${msg}.${hint}
|
|
409
|
-
\u5B9E\u9645\u6536\u5230\u7684\u5F00\u5934\uFF1A${JSON.stringify(preview.slice(0, 80))}`);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// src/commands/exec.ts
|
|
414
|
-
function registerExecCommand(program2) {
|
|
415
|
-
program2.command("exec").description("\u6267\u884C\u80FD\u529B").addHelpText(
|
|
416
|
-
"after",
|
|
417
|
-
"\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"
|
|
418
|
-
).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) => {
|
|
419
|
-
const merged = { ...program2.opts(), ...opts };
|
|
420
|
-
const ctx = buildAgentRequestContext(merged);
|
|
421
|
-
const cliCfg = loadConfig();
|
|
422
|
-
const timeoutMillis = opts.timeout !== void 0 && String(opts.timeout).trim() !== "" ? Number(opts.timeout) : cliCfg.defaults.timeout ?? 3e4;
|
|
423
|
-
let params = {};
|
|
424
|
-
if (opts.params) {
|
|
425
|
-
if (fs3.existsSync(opts.params)) {
|
|
426
|
-
const text = fs3.readFileSync(opts.params, "utf-8");
|
|
427
|
-
params = parseCliJsonString(text, "\u53C2\u6570\u6587\u4EF6");
|
|
428
|
-
} else {
|
|
429
|
-
params = parseCliJsonString(opts.params, "--params");
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
const body = {
|
|
433
|
-
abilityId: Number(opts.abilityId),
|
|
434
|
-
traceId: opts.traceId ?? randomUUID().replace(/-/g, ""),
|
|
435
|
-
sessionId: opts.sessionId ?? "",
|
|
436
|
-
toolCallId: opts.toolCallId ?? "",
|
|
437
|
-
taskId: opts.taskId ?? "",
|
|
438
|
-
messageId: opts.messageId ?? "",
|
|
439
|
-
deviceId: ctx.deviceId ?? "",
|
|
440
|
-
timeoutMillis,
|
|
441
|
-
params
|
|
442
|
-
};
|
|
443
|
-
if (opts.responseType) body.responseType = opts.responseType;
|
|
444
|
-
if (opts.mockToken) body.mockToken = opts.mockToken;
|
|
445
|
-
const res = await apiPost(ctx, agentPath.abilityCall, body);
|
|
446
|
-
handleApiResponse(res, opts.json, (data) => {
|
|
447
|
-
printSuccess("\u80FD\u529B\u6267\u884C\u5B8C\u6210");
|
|
448
|
-
printJson(data);
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
|
|
453
545
|
// src/commands/sign.ts
|
|
454
546
|
import chalk2 from "chalk";
|
|
455
547
|
|
|
@@ -493,7 +585,7 @@ function registerSignCommand(program2) {
|
|
|
493
585
|
// src/commands/doctor.ts
|
|
494
586
|
import chalk3 from "chalk";
|
|
495
587
|
function registerDoctorCommand(program2) {
|
|
496
|
-
program2.command("doctor").description("\u68C0\u67E5\u914D\u7F6E\u5B8C\u6574\u6027
|
|
588
|
+
program2.command("doctor").description("\u68C0\u67E5\u914D\u7F6E\u5B8C\u6574\u6027").action(async () => {
|
|
497
589
|
const merged = program2.opts();
|
|
498
590
|
const ctx = buildAgentRequestContext(merged);
|
|
499
591
|
let ok = true;
|
|
@@ -513,19 +605,6 @@ function registerDoctorCommand(program2) {
|
|
|
513
605
|
console.log(` ${icon} ${chalk3.gray(label + ":")} ${val}`);
|
|
514
606
|
if (!pass) ok = false;
|
|
515
607
|
}
|
|
516
|
-
try {
|
|
517
|
-
const res = await fetch(`${ctx.baseUrl}/time`);
|
|
518
|
-
const body = await res.json();
|
|
519
|
-
if (body.code === 200) {
|
|
520
|
-
console.log(` ${chalk3.green("\u2714")} ${chalk3.gray("\u7F51\u5173\u8FDE\u901A(/time):")} ${body.data}`);
|
|
521
|
-
} else {
|
|
522
|
-
console.log(` ${chalk3.red("\u2716")} ${chalk3.gray("\u7F51\u5173\u8FDE\u901A(/time):")} \u8FD4\u56DE code=${body.code}`);
|
|
523
|
-
ok = false;
|
|
524
|
-
}
|
|
525
|
-
} catch (e) {
|
|
526
|
-
console.log(` ${chalk3.red("\u2716")} ${chalk3.gray("\u7F51\u5173\u8FDE\u901A(/time):")} ${e.message}`);
|
|
527
|
-
ok = false;
|
|
528
|
-
}
|
|
529
608
|
console.log();
|
|
530
609
|
if (ok) {
|
|
531
610
|
console.log(chalk3.green(" \u4E00\u5207\u6B63\u5E38\uFF0C\u53EF\u4EE5\u5F00\u59CB\u4F7F\u7528\uFF01"));
|
|
@@ -543,7 +622,7 @@ function readPackageVersion() {
|
|
|
543
622
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
544
623
|
return pkg.version ?? "0.0.0";
|
|
545
624
|
}
|
|
546
|
-
program.name("ability-cli").description("\u539F\u5B50\u80FD\u529B\u5E73\u53F0 CLI \u5DE5\u5177").version(readPackageVersion()).option("--env <env>", "\u73AF\u5883 (test/prod)\uFF0C\u9009\u62E9 profiles \u4E2D\u54EA\u5957 baseUrl").option("--auth-token <token>", "Authorization\uFF08sk-\u2026\uFF09\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("--base-url <url>", "\u7F51\u5173\u6839\u5730\u5740\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("--device-id <id>", "\u8BBE\u5907 ID\uFF08zy-device-id \u8BF7\u6C42\u5934 / \u90E8\u5206 query\uFF09\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("-v, --verbose", "\u8BE6\u7EC6\u8F93\u51FA");
|
|
625
|
+
program.name("ability-cli").description("\u539F\u5B50\u80FD\u529B\u5E73\u53F0 CLI \u5DE5\u5177").version(readPackageVersion()).option("--env <env>", "\u73AF\u5883 (test/stg/prod)\uFF0C\u9009\u62E9 profiles \u4E2D\u54EA\u5957 baseUrl").option("--auth-token <token>", "Authorization\uFF08sk-\u2026\uFF09\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("--base-url <url>", "\u7F51\u5173\u6839\u5730\u5740\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("--device-id <id>", "\u8BBE\u5907 ID\uFF08zy-device-id \u8BF7\u6C42\u5934 / \u90E8\u5206 query\uFF09\uFF0C\u8986\u76D6\u73AF\u5883\u53D8\u91CF\u4E0E\u914D\u7F6E").option("-v, --verbose", "\u8BE6\u7EC6\u8F93\u51FA");
|
|
547
626
|
registerConfigCommand(program);
|
|
548
627
|
registerRawCommand(program);
|
|
549
628
|
registerSearchCommand(program);
|