@bty/customer-service-cli 0.6.7 → 0.6.9
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 +8 -1
- package/README.md +1 -1
- package/dist/bin.js +151 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.6.9 (2026-08-24)
|
|
4
4
|
|
|
5
|
+
- 新增 `channel-metric` 命令组,查询千牛等渠道店铺客服的每日排行指标(`channel_metric_snapshot`):
|
|
6
|
+
- `channel-metric query --workspace-id <ws> --start <date> --end <date> [--agent <id>] [--platform <channel>]`:按 workspace + 日期区间(+ 可选 agent / 渠道)查询指标,按日期×渠道分组输出。
|
|
7
|
+
- `channel-metric backfill --channel <channel> --start <date> --end <date> [--workspace-id <ws>...]`:手动补数据,采集指定日期区间的渠道指标;`--workspace-id` 可重复传,缺省采集所有已开启配置的 workspace。
|
|
5
8
|
- 新增 `media upload` 命令与 `product supplement` 子命令组,支持商品「补充知识」图片/视频维护,与前端上传行为一致:
|
|
6
9
|
- `media upload --file <path> --type image|video [--path-prefix /ai/knowledge/supplement] [--dry-run]`:本地图片/视频先经 `/v1/upload_sts` 取 STS 凭证上传到公开 OSS(`resource_bucket`),返回公网 URL;已是 http(s) URL 直接拒绝(无需上传)。上传 key 与前端一致:`${prefix}/${timestamp}_${filename}`。图片上限 10MB、视频上限 200MB,超限/类型不符在发起上传请求前直接失败。
|
|
7
10
|
- `product supplement list --agent <id> --product-id <id>`:读取并解析商品「补充知识」条目(容错解析数组 / JSON 字符串 / 多层编码)。
|
|
@@ -9,6 +12,10 @@
|
|
|
9
12
|
- `product supplement append-media --agent <id> --product-id <id> --index <n> [--image ...] [--video ...] [--dry-run] [--backup <path>]`:仅向目标下标条目追加媒体,其它条目原样保留;去重合并,未提供任何媒体时报错。
|
|
10
13
|
- Dashboard 命令使用客服 API 原域名下的 `/observability` 网关前缀,无需新增地址配置。
|
|
11
14
|
|
|
15
|
+
## 0.6.8 (2026-08-10)
|
|
16
|
+
|
|
17
|
+
- `conversation transfer-human` 新增 `--only-abnormal`:默认仍返回全部转人工会话;开启后仅保留异常会话,排除正常 SOP 转人工、`专家agent无法回答`、`存在无法处理的消息类型:...` 三类正常情况。
|
|
18
|
+
|
|
12
19
|
## 0.6.7 (2026-07-30)
|
|
13
20
|
|
|
14
21
|
> 版本号说明:registry 实际发布序列 0.6.2 → 0.6.4 → 0.6.5 → 0.6.6(0.6.3 从未发布,0.6.4–0.6.6 由其它分支占用),故本条目落 0.6.7。
|
package/README.md
CHANGED
|
@@ -520,7 +520,7 @@ Agent 关联的通用规则知识库(`suffix_type=_common`),与 FAQ / 商
|
|
|
520
520
|
| `conversation list [--agent <id>] [--equipment-id <设备ID>] [--user <用户名>] [--start <日期>] [--end <日期>]` | 搜索会话 |
|
|
521
521
|
| `conversation records <conversation_id> [--page-size N] [--direction prev|next]` | 获取会话聊天记录 |
|
|
522
522
|
| `conversation context-search --query <文本> [--start <时间>] [--end <时间>]` | 通过上下文内容模糊搜索对话记录(返回匹配消息详情,时间范围最多 3 天) |
|
|
523
|
-
| `conversation transfer-human --agent <customer_agent_config_id> --start <时间> --end
|
|
523
|
+
| `conversation transfer-human --agent <customer_agent_config_id> --start <时间> --end <时间> [--only-abnormal]` | 查询转人工会话及对应转人工消息记录(时间范围最多 7 天,自动 cursor 翻页;`--only-abnormal` 仅保留异常会话) |
|
|
524
524
|
|
|
525
525
|
|
|
526
526
|
### Agent 调试 (`debug`)
|
package/dist/bin.js
CHANGED
|
@@ -526,6 +526,7 @@ async function listActivities(opts) {
|
|
|
526
526
|
page_size: opts.pageSize ?? 20
|
|
527
527
|
};
|
|
528
528
|
if (opts.search) query.search = opts.search;
|
|
529
|
+
if (opts.state) query.state = opts.state;
|
|
529
530
|
return request(getCustomerServiceUrl(), `${PATH_PREFIX}/list`, {
|
|
530
531
|
method: "GET",
|
|
531
532
|
query
|
|
@@ -615,6 +616,11 @@ function parseEnabledFlag(raw) {
|
|
|
615
616
|
if (raw === "false") return false;
|
|
616
617
|
throw new Error("--enabled \u4EC5\u63A5\u53D7 true | false");
|
|
617
618
|
}
|
|
619
|
+
var VALID_LIST_STATES = ["all", "pending", "ongoing", "ended"];
|
|
620
|
+
function parseStateFlag(raw) {
|
|
621
|
+
if (VALID_LIST_STATES.includes(raw)) return raw;
|
|
622
|
+
throw new Error(`--state \u4EC5\u63A5\u53D7 ${VALID_LIST_STATES.join(" | ")}`);
|
|
623
|
+
}
|
|
618
624
|
function parseActivityId(raw) {
|
|
619
625
|
const n = Number(raw);
|
|
620
626
|
if (!Number.isInteger(n) || n <= 0) {
|
|
@@ -627,14 +633,18 @@ function registerActivityCommand(program2) {
|
|
|
627
633
|
"\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"
|
|
628
634
|
);
|
|
629
635
|
activity.command("list").description(
|
|
630
|
-
"\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"
|
|
631
|
-
).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").
|
|
636
|
+
"\u5217\u51FA\u6D3B\u52A8\uFF08\u5206\u9875 + \u540D\u79F0\u641C\u7D22 + \u72B6\u6001\u8FC7\u6EE4\uFF09\u3002\u8FD4\u56DE total / v2_activity_enabled / items[]\uFF0Citems \u542B id\u3001activity_name\u3001effective_type\u3001enabled\u3001product_scope\u3001products \u7B49\uFF1Btotal \u4E0E state/search \u8FC7\u6EE4\u540C\u53E3\u5F84"
|
|
637
|
+
).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").option(
|
|
638
|
+
"--state <state>",
|
|
639
|
+
"\u5C55\u793A\u72B6\u6001\u8FC7\u6EE4\uFF1Aall | pending | ongoing | ended\uFF08\u7F3A\u7701=all\uFF0C\u542B\u65F6\u95F4\u5F02\u5E38\u6761\u76EE\uFF1Blong_term \u6052 ongoing\uFF09"
|
|
640
|
+
).action(async (opts) => {
|
|
632
641
|
try {
|
|
633
642
|
const data = await listActivities({
|
|
634
643
|
customerAgentConfigId: opts.agent,
|
|
635
644
|
page: Number(opts.page),
|
|
636
645
|
pageSize: Number(opts.pageSize),
|
|
637
|
-
search: opts.search
|
|
646
|
+
search: opts.search,
|
|
647
|
+
state: opts.state === void 0 ? void 0 : parseStateFlag(opts.state)
|
|
638
648
|
});
|
|
639
649
|
formatOutput({ success: true, data }, program2.opts().table);
|
|
640
650
|
} catch (err) {
|
|
@@ -1085,6 +1095,115 @@ function registerChangeConsumerCommand(program2) {
|
|
|
1085
1095
|
});
|
|
1086
1096
|
}
|
|
1087
1097
|
|
|
1098
|
+
// src/commands/channel-metric.ts
|
|
1099
|
+
import Table2 from "cli-table3";
|
|
1100
|
+
|
|
1101
|
+
// src/client/channel-metric-api.ts
|
|
1102
|
+
var CHANNEL_METRIC_PREFIX = "/v1/channel-metric";
|
|
1103
|
+
async function backfillChannelMetrics(opts) {
|
|
1104
|
+
const request = createRequest();
|
|
1105
|
+
const body = {
|
|
1106
|
+
channel: opts.channel,
|
|
1107
|
+
start_date: opts.startDate,
|
|
1108
|
+
end_date: opts.endDate
|
|
1109
|
+
};
|
|
1110
|
+
if (opts.workspaceIds && opts.workspaceIds.length > 0) {
|
|
1111
|
+
body.workspace_ids = opts.workspaceIds;
|
|
1112
|
+
}
|
|
1113
|
+
return request(getObservabilityUrl(), `${CHANNEL_METRIC_PREFIX}/backfill`, {
|
|
1114
|
+
method: "POST",
|
|
1115
|
+
body
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
async function queryChannelMetrics(opts) {
|
|
1119
|
+
const request = createRequest();
|
|
1120
|
+
const query = {
|
|
1121
|
+
workspace_id: opts.workspaceId,
|
|
1122
|
+
start_date: opts.startDate,
|
|
1123
|
+
end_date: opts.endDate
|
|
1124
|
+
};
|
|
1125
|
+
if (opts.configId) query.config_id = opts.configId;
|
|
1126
|
+
if (opts.channel) query.channel = opts.channel;
|
|
1127
|
+
return request(getObservabilityUrl(), `${CHANNEL_METRIC_PREFIX}/metrics`, {
|
|
1128
|
+
method: "GET",
|
|
1129
|
+
query
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// src/commands/channel-metric.ts
|
|
1134
|
+
function collect(value, previous) {
|
|
1135
|
+
return previous.concat([value]);
|
|
1136
|
+
}
|
|
1137
|
+
function renderGroupedTable(groups) {
|
|
1138
|
+
let total = 0;
|
|
1139
|
+
for (const group of groups) {
|
|
1140
|
+
process.stdout.write(`
|
|
1141
|
+
=== ${group.stat_date} \xB7 ${group.channel}\uFF08${group.items.length} \u4E2A\u8D26\u53F7\uFF09===
|
|
1142
|
+
`);
|
|
1143
|
+
const first = group.items[0];
|
|
1144
|
+
const headers = (first?.metrics_json ?? []).map((field) => field.label);
|
|
1145
|
+
const table = new Table2({ head: ["account_id", ...headers] });
|
|
1146
|
+
for (const row of group.items) {
|
|
1147
|
+
table.push([
|
|
1148
|
+
String(row.account_id),
|
|
1149
|
+
...row.metrics_json.map(
|
|
1150
|
+
(field) => field.value === void 0 || field.value === null ? "-" : String(field.value)
|
|
1151
|
+
)
|
|
1152
|
+
]);
|
|
1153
|
+
}
|
|
1154
|
+
process.stdout.write(`${table.toString()}
|
|
1155
|
+
`);
|
|
1156
|
+
total += group.items.length;
|
|
1157
|
+
}
|
|
1158
|
+
process.stdout.write(`
|
|
1159
|
+
\u5171 ${total} \u6761\u8BB0\u5F55
|
|
1160
|
+
`);
|
|
1161
|
+
}
|
|
1162
|
+
function registerChannelMetricCommand(program2) {
|
|
1163
|
+
const channelMetric = program2.command("channel-metric").description("\u6E20\u9053\u76D1\u63A7\u6307\u6807\u67E5\u8BE2 \u2014\u2014 \u67E5\u8BE2\u5343\u725B\u7B49\u6E20\u9053\u5E97\u94FA\u5BA2\u670D\u7684\u6BCF\u65E5\u6392\u884C\u6307\u6807\uFF08channel_metric_snapshot\uFF09");
|
|
1164
|
+
channelMetric.command("query").description(
|
|
1165
|
+
"\u6309 workspace + \u65E5\u671F\u533A\u95F4\uFF08+ \u53EF\u9009 agent / \u6E20\u9053\uFF09\u67E5\u8BE2\u6307\u6807\uFF0C\u6309\u65E5\u671F\xD7\u6E20\u9053\u5206\u7EC4\u8F93\u51FA\u3002\u4E0D\u4F20 --agent \u8F93\u51FA\u8BE5 workspace \u4E0B\u5168\u90E8 agent\uFF0C\u4E0D\u4F20 --platform \u8F93\u51FA\u5168\u90E8\u6E20\u9053"
|
|
1166
|
+
).requiredOption("--workspace-id <workspace_id>", "\u5DE5\u4F5C\u7A7A\u95F4 ID\uFF08\u5FC5\u4F20\uFF0C\u4E0E\u670D\u52A1\u7AEF\u5F52\u5C5E\u6821\u9A8C\u4E00\u81F4\uFF09").option("--agent <agent_id>", "Agent \u914D\u7F6E ID\uFF1B\u7F3A\u7701\u67E5\u8BE2\u8BE5 workspace \u4E0B\u5168\u90E8 agent").requiredOption("--start <date>", "\u8D77\u59CB\u65E5\u671F\uFF08YYYY-MM-DD\uFF09").requiredOption("--end <date>", "\u7ED3\u675F\u65E5\u671F\uFF08YYYY-MM-DD\uFF09").option("--platform <channel>", "\u6E20\u9053\uFF08platform\uFF09\uFF0C\u5982 qianniu\uFF1B\u7F3A\u7701\u67E5\u8BE2\u5168\u90E8\u6E20\u9053").action(async (opts) => {
|
|
1167
|
+
try {
|
|
1168
|
+
setRuntimeWorkspaceId(opts.workspaceId);
|
|
1169
|
+
const data = await queryChannelMetrics({
|
|
1170
|
+
workspaceId: opts.workspaceId,
|
|
1171
|
+
configId: opts.agent,
|
|
1172
|
+
startDate: opts.start,
|
|
1173
|
+
endDate: opts.end,
|
|
1174
|
+
channel: opts.platform
|
|
1175
|
+
});
|
|
1176
|
+
const groups = data?.groups ?? [];
|
|
1177
|
+
if (groups.length === 0) {
|
|
1178
|
+
process.stdout.write("(empty)\n");
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
renderGroupedTable(groups);
|
|
1182
|
+
} catch (err) {
|
|
1183
|
+
reportCaughtError(err);
|
|
1184
|
+
process.exit(toExitCode(err));
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
channelMetric.command("backfill").description(
|
|
1188
|
+
"\u624B\u52A8\u8865\u6570\u636E\uFF1A\u91C7\u96C6\u6307\u5B9A\u65E5\u671F\u533A\u95F4\u7684\u6E20\u9053\u6307\u6807\u3002\u53EF\u6307\u5B9A workspace\uFF08\u53EF\u91CD\u590D\u4F20\uFF09\uFF1B\u4E0D\u4F20 --workspace-id = \u91C7\u96C6\u6240\u6709\u5DF2\u5F00\u542F\u914D\u7F6E\u7684 workspace"
|
|
1189
|
+
).requiredOption("--channel <channel>", "\u6E20\u9053\uFF08platform\uFF09\uFF0C\u5982 qianniu").requiredOption("--start <date>", "\u8D77\u59CB\u65E5\u671F\uFF08YYYY-MM-DD\uFF09").requiredOption("--end <date>", "\u7ED3\u675F\u65E5\u671F\uFF08YYYY-MM-DD\uFF09").option("--workspace-id <workspace_id>", "\u5DE5\u4F5C\u7A7A\u95F4 ID\uFF08\u53EF\u91CD\u590D\u4F20\uFF1B\u7F3A\u7701 = \u91C7\u96C6\u6240\u6709\u5DF2\u5F00\u542F\u914D\u7F6E\u7684 ws\uFF09", collect).action(async (opts) => {
|
|
1190
|
+
try {
|
|
1191
|
+
const workspaceIds = opts.workspaceId?.length ? opts.workspaceId : void 0;
|
|
1192
|
+
setRuntimeWorkspaceId(workspaceIds?.[0]);
|
|
1193
|
+
const data = await backfillChannelMetrics({
|
|
1194
|
+
channel: opts.channel,
|
|
1195
|
+
startDate: opts.start,
|
|
1196
|
+
endDate: opts.end,
|
|
1197
|
+
workspaceIds
|
|
1198
|
+
});
|
|
1199
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
1200
|
+
} catch (err) {
|
|
1201
|
+
reportCaughtError(err);
|
|
1202
|
+
process.exit(toExitCode(err));
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1088
1207
|
// src/client/chat-history-api.ts
|
|
1089
1208
|
async function listChatHistory(opts) {
|
|
1090
1209
|
const request = createRequest();
|
|
@@ -1228,6 +1347,11 @@ function registerConfigCommand(program2) {
|
|
|
1228
1347
|
var MAX_CONTEXT_SEARCH_RANGE_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
1229
1348
|
var MAX_TRANSFER_HUMAN_RANGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
1230
1349
|
var MAX_TRANSFER_HUMAN_CURSOR_PAGES = 500;
|
|
1350
|
+
var NORMAL_TRANSFER_EVENTS = /* @__PURE__ */ new Set([
|
|
1351
|
+
"\u9700\u8981\u4EBA\u5DE5\u63A5\u7BA1, SOP\u5F15\u64CE\u8BF7\u6C42\u8F6C\u4EBA\u5DE5\u5904\u7406",
|
|
1352
|
+
"\u9700\u8981\u4EBA\u5DE5\u63A5\u7BA1, \u4E13\u5BB6agent\u65E0\u6CD5\u56DE\u7B54"
|
|
1353
|
+
]);
|
|
1354
|
+
var NORMAL_TRANSFER_EVENT_PREFIXES = ["\u9700\u8981\u4EBA\u5DE5\u63A5\u7BA1, \u5B58\u5728\u65E0\u6CD5\u5904\u7406\u7684\u6D88\u606F\u7C7B\u578B\uFF1A"];
|
|
1231
1355
|
function parseSearchTime(value, fieldName) {
|
|
1232
1356
|
const parsed = new Date(value);
|
|
1233
1357
|
if (Number.isNaN(parsed.getTime())) {
|
|
@@ -1256,6 +1380,22 @@ function validateTransferHumanRange(startTime, endTime) {
|
|
|
1256
1380
|
throw new Error("\u67E5\u8BE2\u65F6\u95F4\u8303\u56F4\u4E0D\u80FD\u8D85\u8FC77\u5929");
|
|
1257
1381
|
}
|
|
1258
1382
|
}
|
|
1383
|
+
function shouldKeepTransferHumanConversation(item, onlyAbnormal) {
|
|
1384
|
+
if (!onlyAbnormal) return true;
|
|
1385
|
+
if (!item || typeof item !== "object") return true;
|
|
1386
|
+
const takeoverEvents = item.takeover_event_record;
|
|
1387
|
+
if (!Array.isArray(takeoverEvents) || takeoverEvents.length === 0) return true;
|
|
1388
|
+
const eventNames = takeoverEvents.map((event) => {
|
|
1389
|
+
if (!event || typeof event !== "object") return void 0;
|
|
1390
|
+
const eventName = event.event_name;
|
|
1391
|
+
return typeof eventName === "string" ? eventName : void 0;
|
|
1392
|
+
}).filter((eventName) => typeof eventName === "string");
|
|
1393
|
+
if (eventNames.length === 0) return true;
|
|
1394
|
+
return eventNames.some((eventName) => {
|
|
1395
|
+
if (NORMAL_TRANSFER_EVENTS.has(eventName)) return false;
|
|
1396
|
+
return !NORMAL_TRANSFER_EVENT_PREFIXES.some((prefix) => eventName.startsWith(prefix));
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1259
1399
|
async function contextSearchRecords(opts) {
|
|
1260
1400
|
validateContextSearchRange(opts.startTime, opts.endTime);
|
|
1261
1401
|
const wsId = getWorkspaceId(opts.workspaceId);
|
|
@@ -1320,7 +1460,8 @@ async function listTransferHumanConversations(opts) {
|
|
|
1320
1460
|
}
|
|
1321
1461
|
}
|
|
1322
1462
|
);
|
|
1323
|
-
|
|
1463
|
+
const pageItems = page.items ?? [];
|
|
1464
|
+
items.push(...pageItems.filter((item) => shouldKeepTransferHumanConversation(item, opts.onlyAbnormal ?? false)));
|
|
1324
1465
|
pagination = page.pagination ?? {};
|
|
1325
1466
|
const hasMore = pagination.has_more === true;
|
|
1326
1467
|
const nextCursor = typeof pagination.next_cursor === "string" && pagination.next_cursor ? pagination.next_cursor : void 0;
|
|
@@ -1385,12 +1526,13 @@ function registerConversationCommand(program2) {
|
|
|
1385
1526
|
process.exit(toExitCode(err));
|
|
1386
1527
|
}
|
|
1387
1528
|
});
|
|
1388
|
-
conversation.command("transfer-human").description("\u67E5\u8BE2\u8F6C\u4EBA\u5DE5\u4F1A\u8BDD\u53CA\u5BF9\u5E94\u8F6C\u4EBA\u5DE5\u6D88\u606F\u8BB0\u5F55").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08customer_agent_config_id\uFF09").requiredOption("--start <date>", "\u5F00\u59CB\u65F6\u95F4\uFF08ISO \u683C\u5F0F\uFF0C\u5982 2026-05-20T00:00:00\uFF09").requiredOption("--end <date>", "\u7ED3\u675F\u65F6\u95F4\uFF08ISO \u683C\u5F0F\uFF0C\u5982 2026-05-20T23:59:59\uFF09").action(async (opts) => {
|
|
1529
|
+
conversation.command("transfer-human").description("\u67E5\u8BE2\u8F6C\u4EBA\u5DE5\u4F1A\u8BDD\u53CA\u5BF9\u5E94\u8F6C\u4EBA\u5DE5\u6D88\u606F\u8BB0\u5F55\uFF08\u53EF\u9009\u4EC5\u4FDD\u7559\u5F02\u5E38\u4F1A\u8BDD\uFF09").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08customer_agent_config_id\uFF09").requiredOption("--start <date>", "\u5F00\u59CB\u65F6\u95F4\uFF08ISO \u683C\u5F0F\uFF0C\u5982 2026-05-20T00:00:00\uFF09").requiredOption("--end <date>", "\u7ED3\u675F\u65F6\u95F4\uFF08ISO \u683C\u5F0F\uFF0C\u5982 2026-05-20T23:59:59\uFF09").option("--only-abnormal", "\u4EC5\u4FDD\u7559\u5F02\u5E38\u4F1A\u8BDD\uFF08\u6392\u9664\u6B63\u5E38 SOP \u8F6C\u4EBA\u5DE5\u3001agent \u65E0\u6CD5\u56DE\u7B54\u3001\u8F93\u5165/\u6D88\u606F\u7C7B\u578B\u5F02\u5E38\uFF09", false).action(async (opts) => {
|
|
1389
1530
|
try {
|
|
1390
1531
|
const data = await listTransferHumanConversations({
|
|
1391
1532
|
customerAgentConfigId: opts.agent,
|
|
1392
1533
|
startDate: opts.start,
|
|
1393
|
-
endDate: opts.end
|
|
1534
|
+
endDate: opts.end,
|
|
1535
|
+
onlyAbnormal: opts.onlyAbnormal
|
|
1394
1536
|
});
|
|
1395
1537
|
formatOutput({ success: true, data }, program2.opts().table);
|
|
1396
1538
|
} catch (err) {
|
|
@@ -1575,7 +1717,7 @@ async function writeBinaryToFile(filePath, buffer) {
|
|
|
1575
1717
|
}
|
|
1576
1718
|
|
|
1577
1719
|
// src/commands/dashboard.ts
|
|
1578
|
-
function
|
|
1720
|
+
function collect2(value, previous) {
|
|
1579
1721
|
return previous.concat([value]);
|
|
1580
1722
|
}
|
|
1581
1723
|
function registerDashboardCommand(program2) {
|
|
@@ -1630,7 +1772,7 @@ function registerDashboardCommand(program2) {
|
|
|
1630
1772
|
});
|
|
1631
1773
|
dashboard.command("export").description(
|
|
1632
1774
|
"\u5BFC\u51FA\u5E97\u94FA\u7EF4\u5EA6\u6BCF\u65E5\u660E\u7EC6\uFF08\u63A5\u5F85\u5BA2\u6237\u6570/AI\u72EC\u7ACB\u627F\u63A5/\u8F6C\u4EBA\u5DE5/AI\u56DE\u590D\u6D88\u606F\u6570\uFF09\u3002\u9ED8\u8BA4\u89E3\u6790\u4E3A JSON \u884C\uFF1B--out \u843D\u76D8\u539F\u59CB CSV\u3002\u53EF\u91CD\u590D --config-id \u9650\u5B9A\u5E97\u94FA"
|
|
1633
|
-
).requiredOption("--start <date>", "\u5F00\u59CB\u65E5\u671F (YYYY-MM-DD)\uFF0C\u5FC5\u586B").requiredOption("--end <date>", "\u7ED3\u675F\u65E5\u671F (YYYY-MM-DD)\uFF0C\u5FC5\u586B\uFF0C\u4E0D\u80FD\u665A\u4E8E\u6628\u5929").option("--config-id <id>", "\u5E97\u94FA\u914D\u7F6E ID\uFF08\u53EF\u91CD\u590D\u4F20\uFF1B\u4E0D\u4F20=\u5168\u90E8\u5E97\u94FA\uFF09",
|
|
1775
|
+
).requiredOption("--start <date>", "\u5F00\u59CB\u65E5\u671F (YYYY-MM-DD)\uFF0C\u5FC5\u586B").requiredOption("--end <date>", "\u7ED3\u675F\u65E5\u671F (YYYY-MM-DD)\uFF0C\u5FC5\u586B\uFF0C\u4E0D\u80FD\u665A\u4E8E\u6628\u5929").option("--config-id <id>", "\u5E97\u94FA\u914D\u7F6E ID\uFF08\u53EF\u91CD\u590D\u4F20\uFF1B\u4E0D\u4F20=\u5168\u90E8\u5E97\u94FA\uFF09", collect2, []).option("--channel <channel>", "\u6E20\u9053\u7B5B\u9009: qianniu | jingdong | pinduoduo | douyin").option("--out <path>", "\u843D\u76D8\u539F\u59CB CSV \u8DEF\u5F84\uFF08\u7236\u76EE\u5F55\u81EA\u52A8 mkdir -p\uFF09").action(async (opts) => {
|
|
1634
1776
|
try {
|
|
1635
1777
|
const result = await exportShopData({
|
|
1636
1778
|
startDate: opts.start,
|
|
@@ -7437,6 +7579,7 @@ registerMediaCommand(program);
|
|
|
7437
7579
|
registerKnowledgeCommand(program);
|
|
7438
7580
|
registerActivityCommand(program);
|
|
7439
7581
|
registerIssueCommand(program);
|
|
7582
|
+
registerChannelMetricCommand(program);
|
|
7440
7583
|
registerChatHistoryCommand(program);
|
|
7441
7584
|
registerFaqCommand(program);
|
|
7442
7585
|
registerConversationCommand(program);
|