@bty/customer-service-cli 0.5.2 → 0.5.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/CHANGELOG.md +21 -0
- package/README.md +61 -0
- package/dist/bin.js +432 -31
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.4 (2026-06-03)
|
|
4
|
+
|
|
5
|
+
- `ops-agent` 新增 `conversations` 子命令:`ops-agent conversations [--agent-id <id>] [--customer-id <id>] [--page N] [--page-size N]`,对接 `GET /v1/ops-agent/conversations`,按当前 workspace 查询客服助手会话列表,返回 `workspace_id`、`customer_id`、`title`、`agent_id`、`created_at`、`updated_at`。
|
|
6
|
+
- 补充 `ops-agent` 命令注册测试与 API 客户端测试,覆盖会话列表查询命令注册、请求路径、workspace 透传与筛选参数。
|
|
7
|
+
- `product` 新增 `identify-all` 子命令:`product identify-all --agent <id>`,对接 `POST /v1/knowledge/products/identify/all`,为当前 Agent 一键提交所有待增强商品进入增强学习队列。
|
|
8
|
+
- 补充 `product` CLI 测试与 API 客户端测试,覆盖增强学习命令注册、请求路径与请求体。
|
|
9
|
+
- `testset` 新增 `create` 子命令:`testset create --customer-agent-config-id <id> --file <cases.xlsx> [--name <text>] [--description <text>] [--use-type <text>]`,对接 `POST /v1/test_sets/file/upload`,通过 xlsx 模板上传创建测试集。
|
|
10
|
+
|
|
11
|
+
## 0.5.3 (2026-05-28)
|
|
12
|
+
|
|
13
|
+
- 新增 `activity` 主语,覆盖活动 V2(Issue #34)增删改查 + per-tenant 总开关。对接 `customer-servhub-api /v1/activity*`,契约详情参见 [`docs/devkit/specs/2026-05-28-activity-v2-api-reference.md`](../../docs/devkit/specs/2026-05-28-activity-v2-api-reference.md):
|
|
14
|
+
- `activity list --agent <id> [--page N] [--page-size N] [--search <text>]`:列出活动(含 `total`、`v2_activity_enabled`、`items[]`)。
|
|
15
|
+
- `activity by-product --agent <id> --product-id <id>`:按 product_id 反查当前生效活动(仅 enabled,items[].products 恒为 [])。
|
|
16
|
+
- `activity create --data <json|@file>`:创建活动(完整 `IActivityWritePayload`,文件路径加 `@` 前缀走 JSON 解析)。
|
|
17
|
+
- `activity update <activity_id> --data <json|@file>`:整体更新活动(products 整组替换,非增量 diff;customer_agent_config_id 不可变更)。
|
|
18
|
+
- `activity set-enabled <activity_id> --enabled true|false`:列表行 toggle 用,PATCH `/enabled`,仅写 enabled 一个字段。
|
|
19
|
+
- `activity delete <activity_id>`:软删活动 + 级联软删 activity_product 关联。
|
|
20
|
+
- `activity v2-enabled --agent <id> --enabled true|false`:per-tenant 总开关,写 `agent_activity_setting.v2_activity_enabled`,控制 sop V2 链路是否生效。
|
|
21
|
+
- `activity_id` 路径参数本地校验为正整数;`--enabled` 仅接受 `true|false`,非法值直接报错优于让服务端 500。
|
|
22
|
+
- 业务失败统一服务端 200 + `code:400`,CLI 透传为 `exit 1` + `INVALID_PAYLOAD: …` 消息。
|
|
23
|
+
|
|
3
24
|
## 0.5.2 (2026-05-28)
|
|
4
25
|
|
|
5
26
|
**修复:`repair-record` 命令 404 问题**
|
package/README.md
CHANGED
|
@@ -224,6 +224,7 @@ cs-cli workspace points-consumes-daily --start 2026-04-01 --end 2026-04-23
|
|
|
224
224
|
| `product update-sku --agent <id> (--sku <SKU名称> \| --sku-id <id>) --update <json\|@file>` | 更新 SKU 信息(`--sku-id` 优先于 `--sku`) |
|
|
225
225
|
| `product add --agent <id> --data <json\|@file> [--source <type>] [--no-identify]` | 直接传入结构化商品数据(JSON 数组)异步学习(manual / identify 默认开启) |
|
|
226
226
|
| `product learn --agent <id> --url <URL...> [--source <type>] [--no-identify]` | 通过商品 URL 异步学习(manual / identify 默认开启) |
|
|
227
|
+
| `product identify-all --agent <id>` | 一键增强学习当前 Agent 下所有待增强商品 |
|
|
227
228
|
| `product sync-taobao --agent <id> [--skip-hash-check] [--sync-type <full\|incremental>]` | 触发淘宝店铺商品同步 |
|
|
228
229
|
| `product sync-taobao-item --agent <id> --product-id <商品ID>` | 触发单个淘宝商品同步 |
|
|
229
230
|
|
|
@@ -233,6 +234,8 @@ cs-cli workspace points-consumes-daily --start 2026-04-01 --end 2026-04-23
|
|
|
233
234
|
|
|
234
235
|
`product learn` 提交商品详情页 URL 进入异步学习队列(`/v1/knowledge/products/upload`),返回 `flow_id` 和 `knowledge_ids`。`--url` 可多值,用空格分隔;`--source` 默认 `manual`;传 `--no-identify` 可关闭自动识别。
|
|
235
236
|
|
|
237
|
+
`product identify-all` 对接 `POST /v1/knowledge/products/identify/all`,会为当前 Agent 一键提交所有“已可用但尚未增强”的商品进入增强学习队列。它不是全量重学;当没有待增强商品时,服务端会返回“暂无需要识图的商品”。
|
|
238
|
+
|
|
236
239
|
`product sync-taobao` / `product sync-taobao-item` 调用 customer-servhub-api 的授权店铺同步接口,要求 `--agent` 已唯一绑定一个淘宝授权店铺。前者支持 `--sync-type full|incremental`,默认 `full`;后者按 `product_id` 补同步单个淘宝商品。
|
|
237
240
|
|
|
238
241
|
注意:这两个命令仅对已开通“高级工具”的店铺 Agent 生效。未开通高级工具时,即使 `--agent` 已绑定淘宝授权店铺,请求也可能在服务端失败。
|
|
@@ -255,6 +258,47 @@ cs-cli product update-sku --agent <id> --sku-id 6072595054179 --update '{"补充
|
|
|
255
258
|
```
|
|
256
259
|
|
|
257
260
|
|
|
261
|
+
### 活动管理 (`activity`)
|
|
262
|
+
|
|
263
|
+
活动 V2(Issue #34)增删改查 + per-tenant V2 总开关。服务端 `customer-servhub-api /v1/activity*`;契约详情参见 [`docs/devkit/specs/2026-05-28-activity-v2-api-reference.md`](../../docs/devkit/specs/2026-05-28-activity-v2-api-reference.md)。
|
|
264
|
+
|
|
265
|
+
| 命令 | 说明 |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| `activity list --agent <id> [--page N] [--page-size N] [--search <text>]` | 列出活动(返回 `total` / `v2_activity_enabled` / `items[]`) |
|
|
268
|
+
| `activity by-product --agent <id> --product-id <id>` | 按 `product_id` 反查当前生效活动(仅 enabled、product_scope='all' 必入) |
|
|
269
|
+
| `activity create --data <json\|@file>` | 创建活动(payload 见 `IActivityWritePayload`) |
|
|
270
|
+
| `activity update <activity_id> --data <json\|@file>` | 整体更新活动(products 整组替换,非增量) |
|
|
271
|
+
| `activity set-enabled <activity_id> --enabled <true\|false>` | 切换单条活动启用状态(仅写 enabled) |
|
|
272
|
+
| `activity delete <activity_id>` | 软删活动 + 级联软删关联 |
|
|
273
|
+
| `activity v2-enabled --agent <id> --enabled <true\|false>` | per-tenant 启停 V2 链路 |
|
|
274
|
+
|
|
275
|
+
- `--agent <id>` 对应服务端 `customer_agent_config_id`(与 `sa` / `product` 命令同口径)。
|
|
276
|
+
- `activity create` / `update` payload 必填:`customer_agent_config_id`、`activity_name`、`effective_type`、`activity_rule`;`effective_type=time_range` 要求 `start_time` + `end_time`;`product_scope='specific'`(缺省)要求 `products ≥ 1`。
|
|
277
|
+
- 业务失败(参数非法 / 跨 workspace / 不存在)服务端返 HTTP 200 + `code:400`,CLI 转为 `exit 1` 并打印 `INVALID_PAYLOAD: …`。
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# 列出活动
|
|
281
|
+
cs-cli activity list --agent <cfg_id> --search 返现
|
|
282
|
+
|
|
283
|
+
# 按商品反查
|
|
284
|
+
cs-cli activity by-product --agent <cfg_id> --product-id 914494989518
|
|
285
|
+
|
|
286
|
+
# 创建活动(从文件读 payload)
|
|
287
|
+
cs-cli activity create --data @activity.json
|
|
288
|
+
|
|
289
|
+
# 整体更新
|
|
290
|
+
cs-cli activity update 6 --data @activity.json
|
|
291
|
+
|
|
292
|
+
# 列表行 toggle 启用
|
|
293
|
+
cs-cli activity set-enabled 6 --enabled false
|
|
294
|
+
|
|
295
|
+
# 软删活动
|
|
296
|
+
cs-cli activity delete 6
|
|
297
|
+
|
|
298
|
+
# 为某 agent 启用 V2 链路
|
|
299
|
+
cs-cli activity v2-enabled --agent <cfg_id> --enabled true
|
|
300
|
+
```
|
|
301
|
+
|
|
258
302
|
### 工单管理 (`issue`)
|
|
259
303
|
|
|
260
304
|
|
|
@@ -537,6 +581,7 @@ cs-cli change-consumer delivery complete <delivery_id> --status completed \
|
|
|
537
581
|
| 命令 | 说明 |
|
|
538
582
|
| --- | --- |
|
|
539
583
|
| `testset list --customer-agent-config-id <id>` | 列出测试集(分页,Agent ID 必填) |
|
|
584
|
+
| `testset create --customer-agent-config-id <id> --file <cases.xlsx> [--name ...] [--description ...] [--use-type ...]` | 通过 xlsx 模板上传创建测试集 |
|
|
540
585
|
| `testset show <id>` | 测试集详情 |
|
|
541
586
|
| `testset update <id> [--name ...] [--description ...] [--data @file.json]` | 更新测试集元数据(至少一项) |
|
|
542
587
|
| `testset delete <id>` | 软删除测试集 |
|
|
@@ -786,3 +831,19 @@ cs-cli ops-record update <record_id> --data '{"remark":"已完成配置更新","
|
|
|
786
831
|
# 删除运维操作记录
|
|
787
832
|
cs-cli ops-record delete <record_id>
|
|
788
833
|
```
|
|
834
|
+
|
|
835
|
+
### Ops Agent (`ops-agent`)
|
|
836
|
+
|
|
837
|
+
| 命令 | 说明 |
|
|
838
|
+
| --- | --- |
|
|
839
|
+
| `ops-agent conversations [--agent-id <id>] [--customer-id <id>] [--page N] [--page-size N]` | 查询客服助手会话列表 |
|
|
840
|
+
|
|
841
|
+
`ops-agent conversations` 对接 `customer-servhub-api /v1/ops-agent/conversations`,返回字段固定为 `workspace_id`、`customer_id`、`title`、`agent_id`、`created_at`、`updated_at`。命令会自动带当前 `workspace-id`;`--agent-id` 对应 Ops Agent 配置 ID(`customer_agent_config_id`),`--customer-id` 可选。
|
|
842
|
+
|
|
843
|
+
```bash
|
|
844
|
+
# 查询当前 workspace 下某个客服运维助手的会话
|
|
845
|
+
cs-cli ops-agent conversations --agent-id <customer_agent_config_id>
|
|
846
|
+
|
|
847
|
+
# 按 customer 进一步过滤
|
|
848
|
+
cs-cli ops-agent conversations --agent-id <customer_agent_config_id> --customer-id <customer_id>
|
|
849
|
+
```
|
package/dist/bin.js
CHANGED
|
@@ -276,7 +276,7 @@ function toExitCode(err) {
|
|
|
276
276
|
return 1;
|
|
277
277
|
}
|
|
278
278
|
function createRequest(globalTimeout) {
|
|
279
|
-
return async function request(baseUrl,
|
|
279
|
+
return async function request(baseUrl, path6, options) {
|
|
280
280
|
const headers = {
|
|
281
281
|
"Content-Type": "application/json",
|
|
282
282
|
...options.headers
|
|
@@ -304,7 +304,7 @@ function createRequest(globalTimeout) {
|
|
|
304
304
|
if (workspaceId) {
|
|
305
305
|
headers["workspace-id"] = workspaceId;
|
|
306
306
|
}
|
|
307
|
-
let url = `${baseUrl}${
|
|
307
|
+
let url = `${baseUrl}${path6}`;
|
|
308
308
|
if (options.query) {
|
|
309
309
|
const params = new URLSearchParams();
|
|
310
310
|
for (const [key, value] of Object.entries(options.query)) {
|
|
@@ -487,26 +487,66 @@ function buildCookieHeaders() {
|
|
|
487
487
|
return { Cookie: `auth_token=${creds.accessToken}` };
|
|
488
488
|
}
|
|
489
489
|
|
|
490
|
-
// src/client/
|
|
491
|
-
|
|
492
|
-
|
|
490
|
+
// src/client/activity-api.ts
|
|
491
|
+
var PATH_PREFIX = "/v1/activity";
|
|
492
|
+
async function listActivities(opts) {
|
|
493
493
|
const request = createRequest();
|
|
494
|
-
|
|
494
|
+
const query = {
|
|
495
|
+
customer_agent_config_id: opts.customerAgentConfigId,
|
|
496
|
+
page: opts.page ?? 1,
|
|
497
|
+
page_size: opts.pageSize ?? 20
|
|
498
|
+
};
|
|
499
|
+
if (opts.search) query.search = opts.search;
|
|
500
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/list`, {
|
|
495
501
|
method: "GET",
|
|
496
|
-
query
|
|
502
|
+
query
|
|
497
503
|
});
|
|
498
504
|
}
|
|
499
|
-
async function
|
|
505
|
+
async function listActivitiesByProduct(opts) {
|
|
500
506
|
const request = createRequest();
|
|
501
|
-
return request(getCustomerServiceUrl(),
|
|
502
|
-
method: "GET"
|
|
507
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/by-product`, {
|
|
508
|
+
method: "GET",
|
|
509
|
+
query: {
|
|
510
|
+
customer_agent_config_id: opts.customerAgentConfigId,
|
|
511
|
+
product_id: opts.productId
|
|
512
|
+
}
|
|
503
513
|
});
|
|
504
514
|
}
|
|
505
|
-
async function
|
|
515
|
+
async function createActivity(body) {
|
|
506
516
|
const request = createRequest();
|
|
507
|
-
return request(getCustomerServiceUrl(),
|
|
517
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX, {
|
|
518
|
+
method: "POST",
|
|
519
|
+
body
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
async function updateActivity(activityId, body) {
|
|
523
|
+
const request = createRequest();
|
|
524
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/${activityId}`, {
|
|
508
525
|
method: "PUT",
|
|
509
|
-
body
|
|
526
|
+
body
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
async function patchActivityEnabled(activityId, enabled) {
|
|
530
|
+
const request = createRequest();
|
|
531
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/${activityId}/enabled`, {
|
|
532
|
+
method: "PATCH",
|
|
533
|
+
body: { enabled }
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
async function deleteActivity(activityId) {
|
|
537
|
+
const request = createRequest();
|
|
538
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/${activityId}`, {
|
|
539
|
+
method: "DELETE"
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
async function setV2Enabled(opts) {
|
|
543
|
+
const request = createRequest();
|
|
544
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/v2-enabled`, {
|
|
545
|
+
method: "PUT",
|
|
546
|
+
body: {
|
|
547
|
+
customer_agent_config_id: opts.customerAgentConfigId,
|
|
548
|
+
enabled: opts.enabled
|
|
549
|
+
}
|
|
510
550
|
});
|
|
511
551
|
}
|
|
512
552
|
|
|
@@ -540,6 +580,141 @@ function parseDataOption(value) {
|
|
|
540
580
|
}
|
|
541
581
|
}
|
|
542
582
|
|
|
583
|
+
// src/commands/activity.ts
|
|
584
|
+
function parseEnabledFlag(raw) {
|
|
585
|
+
if (raw === "true") return true;
|
|
586
|
+
if (raw === "false") return false;
|
|
587
|
+
throw new Error("--enabled \u4EC5\u63A5\u53D7 true | false");
|
|
588
|
+
}
|
|
589
|
+
function parseActivityId(raw) {
|
|
590
|
+
const n = Number(raw);
|
|
591
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
592
|
+
throw new Error(`\u975E\u6CD5\u7684 activity_id: ${raw}\uFF08\u5FC5\u987B\u4E3A\u6B63\u6574\u6570\uFF09`);
|
|
593
|
+
}
|
|
594
|
+
return n;
|
|
595
|
+
}
|
|
596
|
+
function registerActivityCommand(program2) {
|
|
597
|
+
const activity = program2.command("activity").description(
|
|
598
|
+
"\u6D3B\u52A8 V2 \u7BA1\u7406 \u2014\u2014 \u589E\u5220\u6539\u67E5\u6D3B\u52A8\u3001\u6309\u5546\u54C1\u53CD\u67E5\u3001\u5355\u6761\u542F\u7528 toggle\u3001per-tenant V2 \u603B\u5F00\u5173\u3002\u670D\u52A1\u7AEF\uFF1Acustomer-servhub-api /v1/activity*\uFF1B\u5951\u7EA6\u53C2\u8003 docs/devkit/specs/2026-05-28-activity-v2-api-reference.md"
|
|
599
|
+
);
|
|
600
|
+
activity.command("list").description(
|
|
601
|
+
"\u5217\u51FA\u6D3B\u52A8\uFF08\u5206\u9875 + \u540D\u79F0\u641C\u7D22\uFF09\u3002\u8FD4\u56DE total / v2_activity_enabled / items[]\uFF0Citems \u542B id\u3001activity_name\u3001effective_type\u3001enabled\u3001product_scope\u3001products \u7B49"
|
|
602
|
+
).requiredOption("--agent <id>", "customer_agent_config_id\uFF08agent \u914D\u7F6E ID\uFF0C\u4ECE agent list \u83B7\u53D6\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u22651\uFF09", "1").option("--page-size <number>", "\u6BCF\u9875\u6570\u91CF\uFF081-100\uFF09", "20").option("--search <text>", "\u6309\u6D3B\u52A8\u540D\u6A21\u7CCA\u5339\u914D").action(async (opts) => {
|
|
603
|
+
try {
|
|
604
|
+
const data = await listActivities({
|
|
605
|
+
customerAgentConfigId: opts.agent,
|
|
606
|
+
page: Number(opts.page),
|
|
607
|
+
pageSize: Number(opts.pageSize),
|
|
608
|
+
search: opts.search
|
|
609
|
+
});
|
|
610
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
611
|
+
} catch (err) {
|
|
612
|
+
reportCaughtError(err);
|
|
613
|
+
process.exit(toExitCode(err));
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
activity.command("by-product").description(
|
|
617
|
+
"\u6309 product_id \u53CD\u67E5\u5F53\u524D\u751F\u6548\u6D3B\u52A8\uFF08enabled=true \u4E14\u672A\u8F6F\u5220\uFF1Bproduct_scope='all' \u5FC5\u5165\uFF0C'specific' \u8D70 activity_product \u53CD\u67E5\uFF1B\u54CD\u5E94 items[].products \u6052\u4E3A []\uFF09"
|
|
618
|
+
).requiredOption("--agent <id>", "customer_agent_config_id").requiredOption("--product-id <id>", "\u5916\u90E8\u5546\u54C1 ID\uFF08\u4E0E activity_product.product_id \u540C\u6E90\uFF09").action(async (opts) => {
|
|
619
|
+
try {
|
|
620
|
+
const data = await listActivitiesByProduct({
|
|
621
|
+
customerAgentConfigId: opts.agent,
|
|
622
|
+
productId: opts.productId
|
|
623
|
+
});
|
|
624
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
625
|
+
} catch (err) {
|
|
626
|
+
reportCaughtError(err);
|
|
627
|
+
process.exit(toExitCode(err));
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
activity.command("create").description(
|
|
631
|
+
"\u521B\u5EFA\u6D3B\u52A8\u3002--data \u4E3A\u5B8C\u6574 IActivityWritePayload\uFF08JSON \u6216 @\u6587\u4EF6\uFF09\u3002\u5FC5\u586B\u5B57\u6BB5\uFF1Acustomer_agent_config_id\u3001activity_name\u3001effective_type\u3001activity_rule\uFF1Beffective_type=time_range \u65F6 start_time + end_time \u5FC5\u586B\uFF1Bproduct_scope='specific'\uFF08\u7F3A\u7701\uFF09\u8981\u6C42 products \u2265 1 \u884C"
|
|
632
|
+
).requiredOption("--data <json>", "\u6D3B\u52A8 payload\uFF08JSON \u5B57\u7B26\u4E32\u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF09").action(async (opts) => {
|
|
633
|
+
try {
|
|
634
|
+
const body = parseDataOption(opts.data);
|
|
635
|
+
const data = await createActivity(body);
|
|
636
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
637
|
+
} catch (err) {
|
|
638
|
+
reportCaughtError(err);
|
|
639
|
+
process.exit(toExitCode(err));
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
activity.command("update").description(
|
|
643
|
+
"\u6574\u4F53\u66F4\u65B0\u6D3B\u52A8\uFF08products \u6574\u7EC4\u66FF\u6362\uFF0C\u4E0D\u505A\u589E\u91CF diff\uFF09\u3002customer_agent_config_id \u4E0D\u53EF\u53D8\u66F4\uFF0C\u4E0E\u73B0\u884C\u4E0D\u4E00\u81F4\u4F1A\u4E1A\u52A1\u5931\u8D25 400"
|
|
644
|
+
).argument("<activity_id>", "\u6D3B\u52A8 ID\uFF08\u4ECE activity list \u8FD4\u56DE\u7684 id \u83B7\u53D6\uFF09").requiredOption("--data <json>", "\u5B8C\u6574 IActivityWritePayload\uFF08JSON \u5B57\u7B26\u4E32\u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF09").action(async (activityIdRaw, opts) => {
|
|
645
|
+
try {
|
|
646
|
+
const activityId = parseActivityId(activityIdRaw);
|
|
647
|
+
const body = parseDataOption(opts.data);
|
|
648
|
+
const data = await updateActivity(activityId, body);
|
|
649
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
650
|
+
} catch (err) {
|
|
651
|
+
reportCaughtError(err);
|
|
652
|
+
process.exit(toExitCode(err));
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
activity.command("set-enabled").description(
|
|
656
|
+
"\u5207\u6362\u5355\u6761\u6D3B\u52A8\u542F\u7528\u72B6\u6001\uFF08\u5217\u8868\u884C toggle \u7528\uFF0CPATCH /enabled\uFF09\u3002\u4EC5\u5199 enabled \u4E00\u4E2A\u5B57\u6BB5\uFF0C\u5176\u5B83 payload \u5B57\u6BB5\u5FFD\u7565"
|
|
657
|
+
).argument("<activity_id>", "\u6D3B\u52A8 ID").requiredOption("--enabled <bool>", "true | false").action(async (activityIdRaw, opts) => {
|
|
658
|
+
try {
|
|
659
|
+
const activityId = parseActivityId(activityIdRaw);
|
|
660
|
+
const enabled = parseEnabledFlag(opts.enabled);
|
|
661
|
+
const data = await patchActivityEnabled(activityId, enabled);
|
|
662
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
663
|
+
} catch (err) {
|
|
664
|
+
reportCaughtError(err);
|
|
665
|
+
process.exit(toExitCode(err));
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
activity.command("delete").description("\u8F6F\u5220\u6D3B\u52A8 + \u7EA7\u8054\u8F6F\u5220 activity_product \u5173\u8054").argument("<activity_id>", "\u6D3B\u52A8 ID").action(async (activityIdRaw) => {
|
|
669
|
+
try {
|
|
670
|
+
const activityId = parseActivityId(activityIdRaw);
|
|
671
|
+
const data = await deleteActivity(activityId);
|
|
672
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
673
|
+
} catch (err) {
|
|
674
|
+
reportCaughtError(err);
|
|
675
|
+
process.exit(toExitCode(err));
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
activity.command("v2-enabled").description(
|
|
679
|
+
"per-tenant V2 \u603B\u5F00\u5173 \u2014\u2014 \u5199 agent_activity_setting.v2_activity_enabled\uFF0C\u63A7\u5236 sop V2 \u94FE\u8DEF\u662F\u5426\u751F\u6548"
|
|
680
|
+
).requiredOption("--agent <id>", "customer_agent_config_id").requiredOption("--enabled <bool>", "true | false").action(async (opts) => {
|
|
681
|
+
try {
|
|
682
|
+
const enabled = parseEnabledFlag(opts.enabled);
|
|
683
|
+
const data = await setV2Enabled({
|
|
684
|
+
customerAgentConfigId: opts.agent,
|
|
685
|
+
enabled
|
|
686
|
+
});
|
|
687
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
688
|
+
} catch (err) {
|
|
689
|
+
reportCaughtError(err);
|
|
690
|
+
process.exit(toExitCode(err));
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// src/client/agent-api.ts
|
|
696
|
+
async function listAgents(opts) {
|
|
697
|
+
const wsId = getWorkspaceId(opts.workspaceId);
|
|
698
|
+
const request = createRequest();
|
|
699
|
+
return request(getCustomerServiceUrl(), "/v1/customer-agent/list", {
|
|
700
|
+
method: "GET",
|
|
701
|
+
query: { page: opts.page ?? 1, page_size: opts.pageSize ?? 20, workspace_id: wsId }
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
async function getAgent(configId) {
|
|
705
|
+
const request = createRequest();
|
|
706
|
+
return request(getCustomerServiceUrl(), `/v1/customer-agent/${configId}`, {
|
|
707
|
+
method: "GET"
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
async function updateAgent(configId, data) {
|
|
711
|
+
const request = createRequest();
|
|
712
|
+
return request(getCustomerServiceUrl(), `/v1/customer-agent/${configId}`, {
|
|
713
|
+
method: "PUT",
|
|
714
|
+
body: data
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
|
|
543
718
|
// src/commands/agent.ts
|
|
544
719
|
function registerAgentCommand(program2) {
|
|
545
720
|
const agent = program2.command("agent").description(
|
|
@@ -1168,22 +1343,22 @@ function registerConversationCommand(program2) {
|
|
|
1168
1343
|
var DASHBOARD_PREFIX = "/v1/dashboard";
|
|
1169
1344
|
async function getDashboardSummary(opts) {
|
|
1170
1345
|
const request = createRequest();
|
|
1171
|
-
const
|
|
1346
|
+
const path6 = opts.configId ? `${DASHBOARD_PREFIX}/${opts.configId}/summary` : `${DASHBOARD_PREFIX}/summary`;
|
|
1172
1347
|
const query = {};
|
|
1173
1348
|
if (opts.startDate) query.start_date = opts.startDate;
|
|
1174
1349
|
if (opts.endDate) query.end_date = opts.endDate;
|
|
1175
1350
|
if (opts.channel) query.channel = opts.channel;
|
|
1176
|
-
return request(getCustomerServiceUrl(),
|
|
1351
|
+
return request(getCustomerServiceUrl(), path6, { method: "GET", query });
|
|
1177
1352
|
}
|
|
1178
1353
|
async function getDashboardTrend(opts) {
|
|
1179
1354
|
const request = createRequest();
|
|
1180
|
-
const
|
|
1355
|
+
const path6 = opts.configId ? `${DASHBOARD_PREFIX}/${opts.configId}/trend` : `${DASHBOARD_PREFIX}/trend`;
|
|
1181
1356
|
const query = {};
|
|
1182
1357
|
if (opts.startDate) query.start_date = opts.startDate;
|
|
1183
1358
|
if (opts.endDate) query.end_date = opts.endDate;
|
|
1184
1359
|
if (opts.granularity) query.granularity = opts.granularity;
|
|
1185
1360
|
if (opts.channel) query.channel = opts.channel;
|
|
1186
|
-
return request(getCustomerServiceUrl(),
|
|
1361
|
+
return request(getCustomerServiceUrl(), path6, { method: "GET", query });
|
|
1187
1362
|
}
|
|
1188
1363
|
async function listShopStatistics(opts) {
|
|
1189
1364
|
const request = createRequest();
|
|
@@ -1403,12 +1578,12 @@ function registerDashboardCommand(program2) {
|
|
|
1403
1578
|
channel: opts.channel
|
|
1404
1579
|
});
|
|
1405
1580
|
if (opts.out) {
|
|
1406
|
-
const { path:
|
|
1581
|
+
const { path: path6, bytes } = await writeBinaryToFile(
|
|
1407
1582
|
opts.out,
|
|
1408
1583
|
Buffer.from(result.csv, "utf-8")
|
|
1409
1584
|
);
|
|
1410
1585
|
formatOutput(
|
|
1411
|
-
{ success: true, data: { path:
|
|
1586
|
+
{ success: true, data: { path: path6, bytes, count: result.rows.length } },
|
|
1412
1587
|
program2.opts().table
|
|
1413
1588
|
);
|
|
1414
1589
|
} else {
|
|
@@ -3594,8 +3769,46 @@ function registerMonitorCommand(program2) {
|
|
|
3594
3769
|
});
|
|
3595
3770
|
}
|
|
3596
3771
|
|
|
3772
|
+
// src/client/ops-agent-api.ts
|
|
3773
|
+
async function listOpsAgentConversations(opts) {
|
|
3774
|
+
const workspaceId = getWorkspaceId(opts.workspaceId);
|
|
3775
|
+
const request = createRequest();
|
|
3776
|
+
const query = {
|
|
3777
|
+
page: opts.page ?? 1,
|
|
3778
|
+
page_size: opts.pageSize ?? 20
|
|
3779
|
+
};
|
|
3780
|
+
if (opts.customerId) query.customer_id = opts.customerId;
|
|
3781
|
+
if (opts.agentId) query.agent_id = opts.agentId;
|
|
3782
|
+
return request(getCustomerServiceUrl(), "/v1/ops-agent/conversations", {
|
|
3783
|
+
method: "GET",
|
|
3784
|
+
query,
|
|
3785
|
+
headers: { "workspace-id": workspaceId }
|
|
3786
|
+
});
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
// src/commands/ops-agent.ts
|
|
3790
|
+
function registerOpsAgentCommand(program2) {
|
|
3791
|
+
const opsAgent = program2.command("ops-agent").description("Ops Agent\uFF08\u5BA2\u670D\u52A9\u624B\uFF09\u67E5\u8BE2\u547D\u4EE4");
|
|
3792
|
+
opsAgent.command("conversations").description(
|
|
3793
|
+
"\u67E5\u8BE2\u5BA2\u670D\u52A9\u624B\u4F1A\u8BDD\u5217\u8868\u3002\u8FD4\u56DE workspace_id\u3001customer_id\u3001title\u3001agent_id\u3001created_at\u3001updated_at"
|
|
3794
|
+
).option("--customer-id <id>", "\u6309 customer_id \u7B5B\u9009").option("--agent-id <id>", "\u6309 Ops Agent \u914D\u7F6E ID\uFF08customer_agent_config_id\uFF09\u7B5B\u9009").option("--page <number>", "\u9875\u7801", "1").option("--page-size <number>", "\u6BCF\u9875\u6570\u91CF", "20").action(async (opts) => {
|
|
3795
|
+
try {
|
|
3796
|
+
const data = await listOpsAgentConversations({
|
|
3797
|
+
customerId: opts.customerId,
|
|
3798
|
+
agentId: opts.agentId,
|
|
3799
|
+
page: Number(opts.page),
|
|
3800
|
+
pageSize: Number(opts.pageSize)
|
|
3801
|
+
});
|
|
3802
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
3803
|
+
} catch (err) {
|
|
3804
|
+
reportCaughtError(err);
|
|
3805
|
+
process.exit(toExitCode(err));
|
|
3806
|
+
}
|
|
3807
|
+
});
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3597
3810
|
// src/client/operations-record-api.ts
|
|
3598
|
-
var
|
|
3811
|
+
var PATH_PREFIX2 = "/v1/agent_operations_records";
|
|
3599
3812
|
async function listOperationsRecords(opts) {
|
|
3600
3813
|
const request = createRequest();
|
|
3601
3814
|
const query = {};
|
|
@@ -3603,34 +3816,34 @@ async function listOperationsRecords(opts) {
|
|
|
3603
3816
|
if (opts.agentId) query.agent_id = opts.agentId;
|
|
3604
3817
|
if (opts.page) query.page = opts.page;
|
|
3605
3818
|
if (opts.pageSize) query.page_size = opts.pageSize;
|
|
3606
|
-
return request(getCustomerServiceUrl(),
|
|
3819
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX2, {
|
|
3607
3820
|
method: "GET",
|
|
3608
3821
|
query
|
|
3609
3822
|
});
|
|
3610
3823
|
}
|
|
3611
3824
|
async function getOperationsRecord(recordId) {
|
|
3612
3825
|
const request = createRequest();
|
|
3613
|
-
return request(getCustomerServiceUrl(), `${
|
|
3826
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX2}/${recordId}`, {
|
|
3614
3827
|
method: "GET"
|
|
3615
3828
|
});
|
|
3616
3829
|
}
|
|
3617
3830
|
async function createOperationsRecord(data) {
|
|
3618
3831
|
const request = createRequest();
|
|
3619
|
-
return request(getCustomerServiceUrl(),
|
|
3832
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX2, {
|
|
3620
3833
|
method: "POST",
|
|
3621
3834
|
body: data
|
|
3622
3835
|
});
|
|
3623
3836
|
}
|
|
3624
3837
|
async function updateOperationsRecord(recordId, data) {
|
|
3625
3838
|
const request = createRequest();
|
|
3626
|
-
return request(getCustomerServiceUrl(), `${
|
|
3839
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX2}/${recordId}`, {
|
|
3627
3840
|
method: "PUT",
|
|
3628
3841
|
body: data
|
|
3629
3842
|
});
|
|
3630
3843
|
}
|
|
3631
3844
|
async function deleteOperationsRecord(recordId) {
|
|
3632
3845
|
const request = createRequest();
|
|
3633
|
-
return request(getCustomerServiceUrl(), `${
|
|
3846
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX2}/${recordId}`, {
|
|
3634
3847
|
method: "DELETE"
|
|
3635
3848
|
});
|
|
3636
3849
|
}
|
|
@@ -3806,6 +4019,15 @@ async function syncSingleTaobaoProduct(opts) {
|
|
|
3806
4019
|
}
|
|
3807
4020
|
});
|
|
3808
4021
|
}
|
|
4022
|
+
async function identifyAllProducts(opts) {
|
|
4023
|
+
const request = createRequest();
|
|
4024
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/products/identify/all", {
|
|
4025
|
+
method: "POST",
|
|
4026
|
+
body: {
|
|
4027
|
+
customer_agent_config_id: opts.agentConfigId
|
|
4028
|
+
}
|
|
4029
|
+
});
|
|
4030
|
+
}
|
|
3809
4031
|
|
|
3810
4032
|
// src/commands/product.ts
|
|
3811
4033
|
async function getDbId(agentConfigId) {
|
|
@@ -3943,6 +4165,19 @@ function registerProductCommand(program2) {
|
|
|
3943
4165
|
process.exit(toExitCode(err));
|
|
3944
4166
|
}
|
|
3945
4167
|
});
|
|
4168
|
+
product.command("identify-all").description(
|
|
4169
|
+
"\u4E00\u952E\u589E\u5F3A\u5B66\u4E60\u5F53\u524D Agent \u4E0B\u6240\u6709\u5F85\u589E\u5F3A\u5546\u54C1\u3002\u5BF9\u63A5 POST /v1/knowledge/products/identify/all\uFF0C\u5F02\u6B65\u63D0\u4EA4\u5546\u54C1\u589E\u5F3A\u5B66\u4E60\u4EFB\u52A1"
|
|
4170
|
+
).requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08\u4ECE agent list \u83B7\u53D6\uFF09").action(async (opts) => {
|
|
4171
|
+
try {
|
|
4172
|
+
const data = await identifyAllProducts({
|
|
4173
|
+
agentConfigId: opts.agent
|
|
4174
|
+
});
|
|
4175
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4176
|
+
} catch (err) {
|
|
4177
|
+
reportCaughtError(err);
|
|
4178
|
+
process.exit(toExitCode(err));
|
|
4179
|
+
}
|
|
4180
|
+
});
|
|
3946
4181
|
product.command("sync-taobao").description(
|
|
3947
4182
|
"\u89E6\u53D1\u6DD8\u5B9D\u5E97\u94FA\u5546\u54C1\u540C\u6B65\u3002\u8C03\u7528 customer-servhub-api \u7684\u6388\u6743\u5E97\u94FA\u540C\u6B65\u63A5\u53E3\uFF0C\u6309 Agent \u914D\u7F6E\u627E\u5230\u552F\u4E00\u7ED1\u5B9A\u5E97\u94FA\u540E\u5F02\u6B65\u542F\u52A8\u540C\u6B65\u4EFB\u52A1"
|
|
3948
4183
|
).requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08\u5FC5\u987B\u5DF2\u552F\u4E00\u7ED1\u5B9A\u4E00\u4E2A\u6DD8\u5B9D\u6388\u6743\u5E97\u94FA\uFF09").option("--skip-hash-check", "\u8DF3\u8FC7\u54C8\u5E0C\u6821\u9A8C\uFF0C\u5F3A\u5236\u91CD\u65B0\u540C\u6B65\u5546\u54C1").option("--sync-type <type>", "\u540C\u6B65\u7C7B\u578B\uFF1Afull / incremental\uFF0C\u9ED8\u8BA4 full", "full").action(async (opts) => {
|
|
@@ -3998,7 +4233,7 @@ function registerProductCommand(program2) {
|
|
|
3998
4233
|
}
|
|
3999
4234
|
|
|
4000
4235
|
// src/client/repair-record-api.ts
|
|
4001
|
-
var
|
|
4236
|
+
var PATH_PREFIX3 = "/api/repair-records";
|
|
4002
4237
|
async function listRepairRecords(opts) {
|
|
4003
4238
|
const request = createRequest();
|
|
4004
4239
|
const query = {};
|
|
@@ -4007,21 +4242,21 @@ async function listRepairRecords(opts) {
|
|
|
4007
4242
|
if (opts.workspaceId) query.workspace_id = opts.workspaceId;
|
|
4008
4243
|
if (opts.page) query.page = opts.page;
|
|
4009
4244
|
if (opts.pageSize) query.page_size = opts.pageSize;
|
|
4010
|
-
return request(getCsAdminUrl(),
|
|
4245
|
+
return request(getCsAdminUrl(), PATH_PREFIX3, {
|
|
4011
4246
|
method: "GET",
|
|
4012
4247
|
query
|
|
4013
4248
|
});
|
|
4014
4249
|
}
|
|
4015
4250
|
async function createRepairRecord(data) {
|
|
4016
4251
|
const request = createRequest();
|
|
4017
|
-
return request(getCsAdminUrl(),
|
|
4252
|
+
return request(getCsAdminUrl(), PATH_PREFIX3, {
|
|
4018
4253
|
method: "POST",
|
|
4019
4254
|
body: data
|
|
4020
4255
|
});
|
|
4021
4256
|
}
|
|
4022
4257
|
async function updateRepairRecord(recordId, data) {
|
|
4023
4258
|
const request = createRequest();
|
|
4024
|
-
return request(getCsAdminUrl(), `${
|
|
4259
|
+
return request(getCsAdminUrl(), `${PATH_PREFIX3}/${recordId}`, {
|
|
4025
4260
|
method: "PUT",
|
|
4026
4261
|
body: data
|
|
4027
4262
|
});
|
|
@@ -4292,10 +4527,132 @@ function registerSACommand(program2) {
|
|
|
4292
4527
|
});
|
|
4293
4528
|
}
|
|
4294
4529
|
|
|
4295
|
-
// src/commands/
|
|
4530
|
+
// src/commands/special-project.ts
|
|
4296
4531
|
import fs9 from "fs";
|
|
4297
4532
|
|
|
4533
|
+
// src/client/special-project-api.ts
|
|
4534
|
+
async function createSpecialProject(input) {
|
|
4535
|
+
const request = createRequest();
|
|
4536
|
+
return request(getCsAdminUrl(), "/api/special-projects", {
|
|
4537
|
+
method: "POST",
|
|
4538
|
+
body: input
|
|
4539
|
+
});
|
|
4540
|
+
}
|
|
4541
|
+
async function listSpecialProjects(opts = {}) {
|
|
4542
|
+
const request = createRequest();
|
|
4543
|
+
const query = {};
|
|
4544
|
+
if (opts.ownerUserId !== void 0) query.ownerUserId = opts.ownerUserId;
|
|
4545
|
+
if (opts.status) query.status = opts.status;
|
|
4546
|
+
const result = await request(getCsAdminUrl(), "/api/special-projects", {
|
|
4547
|
+
method: "GET",
|
|
4548
|
+
query
|
|
4549
|
+
});
|
|
4550
|
+
return result.rows ?? [];
|
|
4551
|
+
}
|
|
4552
|
+
async function updateSpecialProject(projectId, patch) {
|
|
4553
|
+
const request = createRequest();
|
|
4554
|
+
return request(
|
|
4555
|
+
getCsAdminUrl(),
|
|
4556
|
+
`/api/special-projects/${projectId}`,
|
|
4557
|
+
{ method: "PATCH", body: patch }
|
|
4558
|
+
);
|
|
4559
|
+
}
|
|
4560
|
+
async function closeSpecialProject(projectId) {
|
|
4561
|
+
return updateSpecialProject(projectId, { status: "\u5DF2\u5B8C\u6210" });
|
|
4562
|
+
}
|
|
4563
|
+
async function upsertSpecialProjects(items, apply) {
|
|
4564
|
+
const request = createRequest();
|
|
4565
|
+
return request(getCsAdminUrl(), "/api/special-projects/batch", {
|
|
4566
|
+
method: "POST",
|
|
4567
|
+
body: { items, apply }
|
|
4568
|
+
});
|
|
4569
|
+
}
|
|
4570
|
+
|
|
4571
|
+
// src/commands/special-project.ts
|
|
4572
|
+
function readJsonArg(value) {
|
|
4573
|
+
if (value.startsWith("@")) {
|
|
4574
|
+
return fs9.readFileSync(value.slice(1), "utf-8");
|
|
4575
|
+
}
|
|
4576
|
+
return value;
|
|
4577
|
+
}
|
|
4578
|
+
function registerSpecialProjectCommand(program2) {
|
|
4579
|
+
const sp = program2.command("special-project").description(
|
|
4580
|
+
"\u4E13\u9879\uFF08special_project\uFF09\u7BA1\u7406 \u2014\u2014 \u5DE5\u4F5C\u8D1F\u8F7D\u770B\u677F\u7684\u4E13\u9879\u6570\u636E\u3002\u4E3B\u529B\u5F55\u5165\u901A\u9053\uFF1A\u65E9\u4F1A\u9010\u5B57\u7A3F \u2192 Agent \u89E3\u6790 \u2192 upsert\uFF08\u5148\u770B diff\uFF0C\u786E\u8BA4\u540E --apply\uFF09"
|
|
4581
|
+
);
|
|
4582
|
+
sp.command("create").description("\u521B\u5EFA\u5355\u4E2A\u4E13\u9879").requiredOption("--name <name>", "\u4E13\u9879\u540D").requiredOption("--owner <id>", "\u627F\u63A5\u5DE5\u7A0B\u5E08 cs_admin_user_id").requiredOption("--daily-effort <personDays>", "\u9884\u4F30\u6BCF\u65E5\u6295\u5165\uFF08\u4EBA\u5929\uFF0C\u5982 0.5\uFF09").requiredOption("--start-date <YYYY-MM-DD>", "\u5F00\u59CB\u65E5\u671F").requiredOption("--duration-days <n>", "\u9884\u4F30\u6709\u6548\u6295\u5165\u5929\u6570").option("--workspace <id>", "\u5173\u8054\u5BA2\u6237 workspace_id\uFF08\u53EF\u7A7A\uFF0C\u5185\u90E8\u4E13\u9879\u4E0D\u586B\uFF09").option("--description <text>", "\u63CF\u8FF0").option("--source-ref <ref>", "\u7A33\u5B9A\u5916\u90E8\u952E\uFF08\u9010\u5B57\u7A3F\u6765\u6E90 id\uFF09\uFF0Cupsert \u5E42\u7B49\u7528").action(async (opts) => {
|
|
4583
|
+
try {
|
|
4584
|
+
const data = await createSpecialProject({
|
|
4585
|
+
name: opts.name,
|
|
4586
|
+
ownerUserId: Number(opts.owner),
|
|
4587
|
+
dailyEffort: Number(opts.dailyEffort),
|
|
4588
|
+
startDate: opts.startDate,
|
|
4589
|
+
durationDays: Number(opts.durationDays),
|
|
4590
|
+
workspaceId: opts.workspace,
|
|
4591
|
+
description: opts.description,
|
|
4592
|
+
sourceRef: opts.sourceRef
|
|
4593
|
+
});
|
|
4594
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4595
|
+
} catch (err) {
|
|
4596
|
+
reportCaughtError(err);
|
|
4597
|
+
process.exit(toExitCode(err));
|
|
4598
|
+
}
|
|
4599
|
+
});
|
|
4600
|
+
sp.command("list").description("\u5217\u51FA\u4E13\u9879").option("--owner <id>", "\u6309\u627F\u63A5\u5DE5\u7A0B\u5E08 cs_admin_user_id \u8FC7\u6EE4").option("--status <status>", "\u6309\u72B6\u6001\u8FC7\u6EE4\uFF08\u8FDB\u884C\u4E2D/\u6682\u505C/\u9700\u786E\u8BA4/\u5DF2\u5B8C\u6210\uFF09").action(async (opts) => {
|
|
4601
|
+
try {
|
|
4602
|
+
const data = await listSpecialProjects({
|
|
4603
|
+
ownerUserId: opts.owner !== void 0 ? Number(opts.owner) : void 0,
|
|
4604
|
+
status: opts.status
|
|
4605
|
+
});
|
|
4606
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4607
|
+
} catch (err) {
|
|
4608
|
+
reportCaughtError(err);
|
|
4609
|
+
process.exit(toExitCode(err));
|
|
4610
|
+
}
|
|
4611
|
+
});
|
|
4612
|
+
sp.command("update <id>").description("\u66F4\u65B0\u4E13\u9879\uFF08\u4EFB\u610F\u5B50\u96C6\uFF1B\u72B6\u6001\u8FC1\u79FB\u53D7\u670D\u52A1\u7AEF\u72B6\u6001\u673A\u7EA6\u675F\uFF09").option("--progress <n>", "\u8FDB\u5EA6 0-100").option("--status <status>", "\u72B6\u6001\uFF08\u8FDB\u884C\u4E2D/\u6682\u505C/\u9700\u786E\u8BA4/\u5DF2\u5B8C\u6210\uFF09").option("--daily-effort <personDays>", "\u6BCF\u65E5\u6295\u5165\uFF08\u4EBA\u5929\uFF09").option("--duration-days <n>", "\u6709\u6548\u6295\u5165\u5929\u6570").option("--description <text>", "\u63CF\u8FF0").action(async (id, opts) => {
|
|
4613
|
+
try {
|
|
4614
|
+
const patch = {};
|
|
4615
|
+
if (opts.progress !== void 0) patch.progress = Number(opts.progress);
|
|
4616
|
+
if (opts.status !== void 0) patch.status = opts.status;
|
|
4617
|
+
if (opts.dailyEffort !== void 0) patch.dailyEffort = Number(opts.dailyEffort);
|
|
4618
|
+
if (opts.durationDays !== void 0) patch.durationDays = Number(opts.durationDays);
|
|
4619
|
+
if (opts.description !== void 0) patch.description = opts.description;
|
|
4620
|
+
const data = await updateSpecialProject(Number(id), patch);
|
|
4621
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4622
|
+
} catch (err) {
|
|
4623
|
+
reportCaughtError(err);
|
|
4624
|
+
process.exit(toExitCode(err));
|
|
4625
|
+
}
|
|
4626
|
+
});
|
|
4627
|
+
sp.command("close <id>").description("\u5173\u95ED\u4E13\u9879\uFF08\u7F6E\u4E3A\u5DF2\u5B8C\u6210\uFF09").action(async (id) => {
|
|
4628
|
+
try {
|
|
4629
|
+
const data = await closeSpecialProject(Number(id));
|
|
4630
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4631
|
+
} catch (err) {
|
|
4632
|
+
reportCaughtError(err);
|
|
4633
|
+
process.exit(toExitCode(err));
|
|
4634
|
+
}
|
|
4635
|
+
});
|
|
4636
|
+
sp.command("upsert").description(
|
|
4637
|
+
"\u6279\u91CF upsert\uFF08\u9010\u5B57\u7A3F\u540C\u6B65\uFF09\u3002--items \u63A5 JSON \u6570\u7EC4\u6216 @\u6587\u4EF6\u3002\u9ED8\u8BA4\u53EA\u6253\u5370 diff \u4E0D\u5199\u5E93\uFF1B\u52A0 --apply \u624D\u843D\u5E93"
|
|
4638
|
+
).requiredOption("--items <json|@file>", "items JSON \u6570\u7EC4\uFF0C\u6216 @path \u8BFB\u6587\u4EF6").option("--apply", "\u843D\u5E93\uFF08\u7F3A\u7701\u53EA\u7B97 diff \u4E0D\u5199\uFF09", false).action(async (opts) => {
|
|
4639
|
+
try {
|
|
4640
|
+
const items = JSON.parse(readJsonArg(opts.items));
|
|
4641
|
+
const data = await upsertSpecialProjects(items, opts.apply === true);
|
|
4642
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
4643
|
+
} catch (err) {
|
|
4644
|
+
reportCaughtError(err);
|
|
4645
|
+
process.exit(toExitCode(err));
|
|
4646
|
+
}
|
|
4647
|
+
});
|
|
4648
|
+
}
|
|
4649
|
+
|
|
4650
|
+
// src/commands/testset.ts
|
|
4651
|
+
import fs11 from "fs";
|
|
4652
|
+
|
|
4298
4653
|
// src/client/testset-api.ts
|
|
4654
|
+
import fs10 from "fs";
|
|
4655
|
+
import path5 from "path";
|
|
4299
4656
|
function unwrapPaginated(raw, fallbackPageSize) {
|
|
4300
4657
|
return {
|
|
4301
4658
|
items: Array.isArray(raw?.data) ? raw?.data : [],
|
|
@@ -4321,6 +4678,28 @@ async function listTestSets(query) {
|
|
|
4321
4678
|
);
|
|
4322
4679
|
return unwrapPaginated(raw, query.pageSize ?? 20);
|
|
4323
4680
|
}
|
|
4681
|
+
async function createTestSetFromFile(input) {
|
|
4682
|
+
const request = createRequest();
|
|
4683
|
+
const fileBytes = fs10.readFileSync(input.filePath);
|
|
4684
|
+
const formData = new FormData();
|
|
4685
|
+
formData.append(
|
|
4686
|
+
"file",
|
|
4687
|
+
new Blob([fileBytes], {
|
|
4688
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
4689
|
+
}),
|
|
4690
|
+
path5.basename(input.filePath)
|
|
4691
|
+
);
|
|
4692
|
+
return request(getCustomerServiceUrl(), "/v1/test_sets/file/upload", {
|
|
4693
|
+
method: "POST",
|
|
4694
|
+
query: {
|
|
4695
|
+
customer_agent_config_id: input.customerAgentConfigId,
|
|
4696
|
+
test_set_name: input.testSetName,
|
|
4697
|
+
test_set_description: input.testSetDescription,
|
|
4698
|
+
use_type: input.useType
|
|
4699
|
+
},
|
|
4700
|
+
body: formData
|
|
4701
|
+
});
|
|
4702
|
+
}
|
|
4324
4703
|
async function getTestSet(id) {
|
|
4325
4704
|
const request = createRequest();
|
|
4326
4705
|
return request(getCustomerServiceUrl(), `/v1/test_sets/${id}`, {
|
|
@@ -4805,7 +5184,7 @@ function readPromptInput(value) {
|
|
|
4805
5184
|
if (!filePath) {
|
|
4806
5185
|
throw new Error("File path cannot be empty after @");
|
|
4807
5186
|
}
|
|
4808
|
-
return
|
|
5187
|
+
return fs11.readFileSync(filePath, "utf-8");
|
|
4809
5188
|
}
|
|
4810
5189
|
return value;
|
|
4811
5190
|
}
|
|
@@ -4838,6 +5217,25 @@ function registerTestsetCommand(program2) {
|
|
|
4838
5217
|
process.exit(toExitCode(err));
|
|
4839
5218
|
}
|
|
4840
5219
|
});
|
|
5220
|
+
testset.command("create").description("\u901A\u8FC7 xlsx \u6587\u4EF6\u521B\u5EFA\u6D4B\u8BD5\u96C6").requiredOption("--customer-agent-config-id <id>", "Agent \u914D\u7F6E ID\uFF08\u5FC5\u586B\uFF0C\u4E0E\u540E\u7AEF\u5951\u7EA6\u5BF9\u9F50\uFF09").requiredOption("--file <path>", "\u6D4B\u8BD5\u96C6 xlsx \u6587\u4EF6\u8DEF\u5F84").option("--name <text>", "\u6D4B\u8BD5\u96C6\u540D\u79F0\uFF1B\u4E0D\u4F20\u5219\u540E\u7AEF\u53D6\u6587\u4EF6\u540D").option("--description <text>", "\u6D4B\u8BD5\u96C6\u63CF\u8FF0").option("--use-type <text>", "\u6587\u4EF6\u7528\u9014\u6807\u8BC6").action(async (opts) => {
|
|
5221
|
+
try {
|
|
5222
|
+
if (!fs11.existsSync(opts.file)) {
|
|
5223
|
+
outputError(1, `\u6587\u4EF6\u4E0D\u5B58\u5728: ${opts.file}`);
|
|
5224
|
+
process.exit(1);
|
|
5225
|
+
}
|
|
5226
|
+
const data = await createTestSetFromFile({
|
|
5227
|
+
customerAgentConfigId: opts.customerAgentConfigId,
|
|
5228
|
+
filePath: opts.file,
|
|
5229
|
+
testSetName: opts.name,
|
|
5230
|
+
testSetDescription: opts.description,
|
|
5231
|
+
useType: opts.useType
|
|
5232
|
+
});
|
|
5233
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
5234
|
+
} catch (err) {
|
|
5235
|
+
reportCaughtError(err);
|
|
5236
|
+
process.exit(toExitCode(err));
|
|
5237
|
+
}
|
|
5238
|
+
});
|
|
4841
5239
|
testset.command("show").description("\u67E5\u770B\u5355\u4E2A\u6D4B\u8BD5\u96C6\u8BE6\u60C5").argument("<id>", "\u6D4B\u8BD5\u96C6 ID").action(async (id) => {
|
|
4842
5240
|
try {
|
|
4843
5241
|
const data = await getTestSet(id);
|
|
@@ -4990,9 +5388,11 @@ registerAuthCommand(program);
|
|
|
4990
5388
|
registerConfigCommand(program);
|
|
4991
5389
|
registerWorkspaceCommand(program);
|
|
4992
5390
|
registerAgentCommand(program);
|
|
5391
|
+
registerOpsAgentCommand(program);
|
|
4993
5392
|
registerSACommand(program);
|
|
4994
5393
|
registerProductCommand(program);
|
|
4995
5394
|
registerKnowledgeCommand(program);
|
|
5395
|
+
registerActivityCommand(program);
|
|
4996
5396
|
registerIssueCommand(program);
|
|
4997
5397
|
registerChatHistoryCommand(program);
|
|
4998
5398
|
registerFaqCommand(program);
|
|
@@ -5004,6 +5404,7 @@ registerRepairRecordCommand(program);
|
|
|
5004
5404
|
registerOperationsRecordCommand(program);
|
|
5005
5405
|
registerChangeConsumerCommand(program);
|
|
5006
5406
|
registerTestsetCommand(program);
|
|
5407
|
+
registerSpecialProjectCommand(program);
|
|
5007
5408
|
process.on("uncaughtException", (err) => {
|
|
5008
5409
|
outputError(3, err.message);
|
|
5009
5410
|
process.exit(3);
|