@bty/customer-service-cli 0.6.0 → 0.6.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 +26 -1
- package/README.md +49 -9
- package/dist/bin.js +1296 -601
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -31,7 +31,24 @@ function formatOutput(response, table) {
|
|
|
31
31
|
if (Array.isArray(data)) {
|
|
32
32
|
renderArrayTable(data);
|
|
33
33
|
} else if (data !== null && typeof data === "object") {
|
|
34
|
-
|
|
34
|
+
const obj = data;
|
|
35
|
+
const innerArray = findInnerArray(obj);
|
|
36
|
+
if (innerArray) {
|
|
37
|
+
renderArrayTable(innerArray);
|
|
38
|
+
const total = obj.total ?? obj.count;
|
|
39
|
+
const pageNo = obj.page_no ?? obj.page;
|
|
40
|
+
const pageSize = obj.page_size;
|
|
41
|
+
if (total !== void 0) {
|
|
42
|
+
const paginationParts = [`total: ${total}`];
|
|
43
|
+
if (pageNo !== void 0) paginationParts.push(`page: ${pageNo}`);
|
|
44
|
+
if (pageSize !== void 0) paginationParts.push(`page_size: ${pageSize}`);
|
|
45
|
+
process.stdout.write(`
|
|
46
|
+
${paginationParts.join(" | ")}
|
|
47
|
+
`);
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
renderObjectTable(obj);
|
|
51
|
+
}
|
|
35
52
|
} else {
|
|
36
53
|
process.stdout.write(JSON.stringify(response, null, 2));
|
|
37
54
|
return;
|
|
@@ -43,6 +60,16 @@ Page ${page} | ${pageSize} per page | ${total} total
|
|
|
43
60
|
`);
|
|
44
61
|
}
|
|
45
62
|
}
|
|
63
|
+
function findInnerArray(obj) {
|
|
64
|
+
const paginationKeys = /* @__PURE__ */ new Set(["total", "count", "page_no", "page", "page_size"]);
|
|
65
|
+
const arrayKey = Object.keys(obj).find(
|
|
66
|
+
(k) => Array.isArray(obj[k]) && !paginationKeys.has(k)
|
|
67
|
+
);
|
|
68
|
+
if (!arrayKey) return null;
|
|
69
|
+
const arr = obj[arrayKey];
|
|
70
|
+
if (arr.length === 0 || typeof arr[0] !== "object" || arr[0] === null) return null;
|
|
71
|
+
return arr;
|
|
72
|
+
}
|
|
46
73
|
function renderArrayTable(data) {
|
|
47
74
|
const first = data[0];
|
|
48
75
|
if (first == null) {
|
|
@@ -52,7 +79,14 @@ function renderArrayTable(data) {
|
|
|
52
79
|
const headers = Object.keys(first);
|
|
53
80
|
const table = new Table({ head: headers });
|
|
54
81
|
for (const row of data) {
|
|
55
|
-
table.push(
|
|
82
|
+
table.push(
|
|
83
|
+
headers.map((h) => {
|
|
84
|
+
const val = row[h];
|
|
85
|
+
if (Array.isArray(val)) return val.length === 0 ? "[]" : `[${val.length} items]`;
|
|
86
|
+
if (val !== null && typeof val === "object") return JSON.stringify(val);
|
|
87
|
+
return String(val ?? "");
|
|
88
|
+
})
|
|
89
|
+
);
|
|
56
90
|
}
|
|
57
91
|
process.stdout.write(`${table.toString()}
|
|
58
92
|
`);
|
|
@@ -60,7 +94,15 @@ function renderArrayTable(data) {
|
|
|
60
94
|
function renderObjectTable(data) {
|
|
61
95
|
const table = new Table();
|
|
62
96
|
for (const [key, value] of Object.entries(data)) {
|
|
63
|
-
|
|
97
|
+
let display;
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
display = value.length === 0 ? "[]" : `[${value.length} items]`;
|
|
100
|
+
} else if (value !== null && typeof value === "object") {
|
|
101
|
+
display = JSON.stringify(value);
|
|
102
|
+
} else {
|
|
103
|
+
display = String(value ?? "");
|
|
104
|
+
}
|
|
105
|
+
table.push({ [key]: display });
|
|
64
106
|
}
|
|
65
107
|
process.stdout.write(`${table.toString()}
|
|
66
108
|
`);
|
|
@@ -436,7 +478,6 @@ function isTokenExpired(expiresAt) {
|
|
|
436
478
|
// src/client/helpers.ts
|
|
437
479
|
var DEFAULT_CS_API_URL = "https://customer-servhub-api.betteryeah.com";
|
|
438
480
|
var DEFAULT_AI_API_URL = "https://ai-api.betteryeah.com";
|
|
439
|
-
var DEFAULT_CUSTOMER_AGENT_API_URL = "https://customer-agent.bantouyan.com";
|
|
440
481
|
var DEFAULT_CS_ADMIN_URL = "https://customer-service-admin.betteryeah.com";
|
|
441
482
|
function getCustomerServiceUrl() {
|
|
442
483
|
const envUrl = process.env.CS_CS_API_URL;
|
|
@@ -450,12 +491,6 @@ function getAiApiUrl() {
|
|
|
450
491
|
const config = readConfig();
|
|
451
492
|
return config?.aiApiUrl ?? DEFAULT_AI_API_URL;
|
|
452
493
|
}
|
|
453
|
-
function getCustomerAgentUrl() {
|
|
454
|
-
const envUrl = process.env.CS_CUSTOMER_AGENT_URL;
|
|
455
|
-
if (envUrl) return envUrl;
|
|
456
|
-
const config = readConfig();
|
|
457
|
-
return config?.customerAgentApiUrl ?? DEFAULT_CUSTOMER_AGENT_API_URL;
|
|
458
|
-
}
|
|
459
494
|
function getCsAdminUrl() {
|
|
460
495
|
const envUrl = process.env.CS_CS_ADMIN_URL;
|
|
461
496
|
if (envUrl) return envUrl;
|
|
@@ -477,15 +512,6 @@ function getWorkspaceId(overrideWorkspaceId) {
|
|
|
477
512
|
if (globalConfig?.defaultWorkspaceId) return globalConfig.defaultWorkspaceId;
|
|
478
513
|
throw new APIError(1, "\u672A\u8BBE\u7F6E\u5DE5\u4F5C\u7A7A\u95F4\uFF0C\u8BF7\u8FD0\u884C: cs-cli config set-workspace <id>");
|
|
479
514
|
}
|
|
480
|
-
function buildCookieHeaders() {
|
|
481
|
-
const creds = readCredentials();
|
|
482
|
-
if (!creds) throw new APIError(2, "\u672A\u767B\u5F55\uFF0C\u8BF7\u8FD0\u884C: cs-cli auth login");
|
|
483
|
-
if (isTokenExpired(creds.expiresAt)) {
|
|
484
|
-
clearCredentials();
|
|
485
|
-
throw new APIError(2, "Token \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C: cs-cli auth login");
|
|
486
|
-
}
|
|
487
|
-
return { Cookie: `auth_token=${creds.accessToken}` };
|
|
488
|
-
}
|
|
489
515
|
|
|
490
516
|
// src/client/activity-api.ts
|
|
491
517
|
var PATH_PREFIX = "/v1/activity";
|
|
@@ -1104,6 +1130,17 @@ async function getDailyDeduction(opts) {
|
|
|
1104
1130
|
}
|
|
1105
1131
|
);
|
|
1106
1132
|
}
|
|
1133
|
+
async function getPointsConsumes(opts) {
|
|
1134
|
+
const request = createRequest();
|
|
1135
|
+
return request(
|
|
1136
|
+
getCustomerServiceUrl(),
|
|
1137
|
+
"/v1/workspace/points_consumes",
|
|
1138
|
+
{
|
|
1139
|
+
method: "POST",
|
|
1140
|
+
body: { page: opts.page, page_size: opts.pageSize, debug: true }
|
|
1141
|
+
}
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1107
1144
|
|
|
1108
1145
|
// src/commands/config.ts
|
|
1109
1146
|
function registerConfigCommand(program2) {
|
|
@@ -1187,6 +1224,7 @@ function registerConfigCommand(program2) {
|
|
|
1187
1224
|
// src/client/conversation-api.ts
|
|
1188
1225
|
var MAX_CONTEXT_SEARCH_RANGE_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
1189
1226
|
var MAX_TRANSFER_HUMAN_RANGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
1227
|
+
var MAX_TRANSFER_HUMAN_CURSOR_PAGES = 500;
|
|
1190
1228
|
function parseSearchTime(value, fieldName) {
|
|
1191
1229
|
const parsed = new Date(value);
|
|
1192
1230
|
if (Number.isNaN(parsed.getTime())) {
|
|
@@ -1259,15 +1297,36 @@ async function listConversations(opts) {
|
|
|
1259
1297
|
async function listTransferHumanConversations(opts) {
|
|
1260
1298
|
validateTransferHumanRange(opts.startDate, opts.endDate);
|
|
1261
1299
|
const request = createRequest();
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1300
|
+
const items = [];
|
|
1301
|
+
let cursor;
|
|
1302
|
+
let fetchedPages = 0;
|
|
1303
|
+
let pagination = {};
|
|
1304
|
+
while (fetchedPages < MAX_TRANSFER_HUMAN_CURSOR_PAGES) {
|
|
1305
|
+
fetchedPages += 1;
|
|
1306
|
+
const page = await request(
|
|
1307
|
+
getCustomerServiceUrl(),
|
|
1308
|
+
"/v1/chat/conversations/transfer-human",
|
|
1309
|
+
{
|
|
1310
|
+
method: "GET",
|
|
1311
|
+
query: {
|
|
1312
|
+
customer_agent_config_id: opts.customerAgentConfigId,
|
|
1313
|
+
start_date: opts.startDate,
|
|
1314
|
+
end_date: opts.endDate,
|
|
1315
|
+
page: 1,
|
|
1316
|
+
cursor
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
);
|
|
1320
|
+
items.push(...page.items ?? []);
|
|
1321
|
+
pagination = page.pagination ?? {};
|
|
1322
|
+
const hasMore = pagination.has_more === true;
|
|
1323
|
+
const nextCursor = typeof pagination.next_cursor === "string" && pagination.next_cursor ? pagination.next_cursor : void 0;
|
|
1324
|
+
if (!hasMore || !nextCursor) {
|
|
1325
|
+
return { ...page, items, pagination: { ...pagination, fetched_pages: fetchedPages } };
|
|
1326
|
+
}
|
|
1327
|
+
cursor = nextCursor;
|
|
1328
|
+
}
|
|
1329
|
+
throw new Error(`\u8F6C\u4EBA\u5DE5\u4F1A\u8BDD\u5206\u9875\u8D85\u8FC7 ${MAX_TRANSFER_HUMAN_CURSOR_PAGES} \u9875\uFF0C\u8BF7\u7F29\u5C0F\u67E5\u8BE2\u65F6\u95F4\u8303\u56F4`);
|
|
1271
1330
|
}
|
|
1272
1331
|
|
|
1273
1332
|
// src/commands/conversation.ts
|
|
@@ -1323,13 +1382,12 @@ function registerConversationCommand(program2) {
|
|
|
1323
1382
|
process.exit(toExitCode(err));
|
|
1324
1383
|
}
|
|
1325
1384
|
});
|
|
1326
|
-
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").
|
|
1385
|
+
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) => {
|
|
1327
1386
|
try {
|
|
1328
1387
|
const data = await listTransferHumanConversations({
|
|
1329
1388
|
customerAgentConfigId: opts.agent,
|
|
1330
1389
|
startDate: opts.start,
|
|
1331
|
-
endDate: opts.end
|
|
1332
|
-
page: Number(opts.page)
|
|
1390
|
+
endDate: opts.end
|
|
1333
1391
|
});
|
|
1334
1392
|
formatOutput({ success: true, data }, program2.opts().table);
|
|
1335
1393
|
} catch (err) {
|
|
@@ -1685,16 +1743,23 @@ async function sendAgentMessage(opts) {
|
|
|
1685
1743
|
];
|
|
1686
1744
|
}
|
|
1687
1745
|
const request = createRequest();
|
|
1746
|
+
const body = {
|
|
1747
|
+
msg_list: msgList,
|
|
1748
|
+
is_stream: false,
|
|
1749
|
+
conversation_id: opts.conversationId
|
|
1750
|
+
};
|
|
1751
|
+
if (opts.mock !== void 0) {
|
|
1752
|
+
body.mock = opts.mock;
|
|
1753
|
+
}
|
|
1754
|
+
if (opts.debugDataOverlay !== void 0) {
|
|
1755
|
+
body.debug_data_overlay = opts.debugDataOverlay;
|
|
1756
|
+
}
|
|
1688
1757
|
return request(
|
|
1689
1758
|
getCustomerServiceUrl(),
|
|
1690
1759
|
"/v1/debug/chat/agent_message",
|
|
1691
1760
|
{
|
|
1692
1761
|
method: "POST",
|
|
1693
|
-
body
|
|
1694
|
-
msg_list: msgList,
|
|
1695
|
-
is_stream: false,
|
|
1696
|
-
conversation_id: opts.conversationId
|
|
1697
|
-
}
|
|
1762
|
+
body
|
|
1698
1763
|
}
|
|
1699
1764
|
);
|
|
1700
1765
|
}
|
|
@@ -1814,218 +1879,677 @@ async function getLangfuseTrace(traceId, env) {
|
|
|
1814
1879
|
);
|
|
1815
1880
|
}
|
|
1816
1881
|
|
|
1817
|
-
// src/
|
|
1818
|
-
function
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
if (!opts.text && !opts.messages) {
|
|
1830
|
-
outputError(1, "\u5FC5\u987B\u6307\u5B9A --text \u6216 --messages \u5176\u4E2D\u4E4B\u4E00");
|
|
1831
|
-
process.exit(1);
|
|
1832
|
-
}
|
|
1833
|
-
const userName = opts.user ?? readCredentials()?.username ?? "cli-user";
|
|
1834
|
-
let conversationId;
|
|
1835
|
-
if (opts.conversation) {
|
|
1836
|
-
conversationId = opts.conversation;
|
|
1837
|
-
} else {
|
|
1838
|
-
const conv = await createDebugConversation({
|
|
1839
|
-
agentConfigId: opts.agent,
|
|
1840
|
-
userName
|
|
1841
|
-
});
|
|
1842
|
-
conversationId = conv.conversation_id;
|
|
1843
|
-
}
|
|
1844
|
-
let msgList;
|
|
1845
|
-
if (opts.messages) {
|
|
1846
|
-
const parsed = parseDataOption(opts.messages);
|
|
1847
|
-
msgList = Array.isArray(parsed) ? parsed : parsed.msg_list;
|
|
1848
|
-
if (!Array.isArray(msgList)) {
|
|
1849
|
-
outputError(1, "--messages \u5FC5\u987B\u662F JSON \u6570\u7EC4\u6216\u5305\u542B msg_list \u5B57\u6BB5\u7684\u5BF9\u8C61");
|
|
1850
|
-
process.exit(1);
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
await sendAgentMessage({
|
|
1854
|
-
conversationId,
|
|
1855
|
-
text: opts.text,
|
|
1856
|
-
imageUrl: opts.url,
|
|
1857
|
-
msgList
|
|
1858
|
-
});
|
|
1859
|
-
const agentRecords = await pollAgentReply(conversationId, {
|
|
1860
|
-
timeout: Number(opts.timeout) * 1e3,
|
|
1861
|
-
pollInterval: Number(opts.pollInterval)
|
|
1862
|
-
});
|
|
1863
|
-
formatOutput(
|
|
1864
|
-
{
|
|
1865
|
-
success: true,
|
|
1866
|
-
data: {
|
|
1867
|
-
conversation_id: conversationId,
|
|
1868
|
-
reply: agentRecords
|
|
1869
|
-
}
|
|
1870
|
-
},
|
|
1871
|
-
program2.opts().table
|
|
1872
|
-
);
|
|
1873
|
-
} catch (err) {
|
|
1874
|
-
reportCaughtError(err);
|
|
1875
|
-
process.exit(toExitCode(err));
|
|
1876
|
-
}
|
|
1877
|
-
});
|
|
1878
|
-
debug.command("record").description("\u83B7\u53D6\u67D0\u6761\u56DE\u590D\u7684\u5185\u90E8\u63A8\u7406\u94FE\u8DEF\uFF08flow_info\uFF09\uFF0C\u7528\u4E8E\u8BCA\u65AD Agent \u4E3A\u4F55\u7ED9\u51FA\u7279\u5B9A\u56DE\u590D").argument("<record_id>", "\u56DE\u590D\u8BB0\u5F55 ID\uFF08\u4ECE debug ask \u8FD4\u56DE\u7684 reply[].record_id \u83B7\u53D6\uFF09").option(
|
|
1879
|
-
"--deep",
|
|
1880
|
-
"\u6DF1\u5EA6\u89E3\u6790\uFF1A\u989D\u5916\u8C03\u7528 ai-api \u7684 flow execute_log \u63A5\u53E3\uFF0C\u62C9\u53D6 flow_info.flow_id + task_id \u5BF9\u5E94\u7684\u5B8C\u6574\u6267\u884C\u65E5\u5FD7\uFF08log_url \u5185\u5BB9\uFF09\uFF0C\u7528\u4E8E\u6392\u67E5\u8282\u70B9\u7EA7\u8F93\u5165\u8F93\u51FA",
|
|
1881
|
-
false
|
|
1882
|
-
).option("--flow-workspace <id>", "flow \u6240\u5728 workspace ID\uFF08--deep \u65F6\u4F7F\u7528\uFF0C\u9ED8\u8BA4\u4F7F\u7528\u5185\u7F6E\u56FA\u5B9A\u503C\uFF09").action(async (recordId, opts) => {
|
|
1883
|
-
try {
|
|
1884
|
-
const data = await getRecordDebugInfo(recordId);
|
|
1885
|
-
let deep;
|
|
1886
|
-
if (opts.deep) {
|
|
1887
|
-
const flowInfo = data.flow_info;
|
|
1888
|
-
const flowId = flowInfo?.flow_id;
|
|
1889
|
-
const taskId = flowInfo?.task_id;
|
|
1890
|
-
if (!flowId || !taskId) {
|
|
1891
|
-
deep = { error: "flow_info \u4E2D\u7F3A\u5C11 flow_id \u6216 task_id\uFF0C\u65E0\u6CD5\u6DF1\u5EA6\u89E3\u6790" };
|
|
1892
|
-
} else {
|
|
1893
|
-
try {
|
|
1894
|
-
deep = await getFlowExecuteLog({
|
|
1895
|
-
flowId,
|
|
1896
|
-
taskId,
|
|
1897
|
-
workspaceId: opts.flowWorkspace
|
|
1898
|
-
});
|
|
1899
|
-
} catch (err) {
|
|
1900
|
-
deep = { error: err.message };
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
formatOutput(
|
|
1905
|
-
{ success: true, data: opts.deep ? { ...data, deep } : data },
|
|
1906
|
-
program2.opts().table
|
|
1907
|
-
);
|
|
1908
|
-
} catch (err) {
|
|
1909
|
-
reportCaughtError(err);
|
|
1910
|
-
process.exit(toExitCode(err));
|
|
1911
|
-
}
|
|
1912
|
-
});
|
|
1913
|
-
debug.command("reproduce").description(
|
|
1914
|
-
"\u6839\u636E record_id \u590D\u73B0\u4E00\u6B21 Agent \u56DE\u590D\u3002\u81EA\u52A8\u83B7\u53D6\u5173\u8054\u4F1A\u8BDD\u3001\u622A\u53D6\u4E0A\u4E0B\u6587\u3001\u7528\u539F\u59CB user_name \u521B\u5EFA debug \u4F1A\u8BDD\u5E76\u91CD\u65B0\u53D1\u9001"
|
|
1915
|
-
).argument("<record_id>", "\u8981\u590D\u73B0\u7684\u56DE\u590D\u8BB0\u5F55 ID").option("--agent <config_id>", "\u4F7F\u7528\u6307\u5B9A Agent \u590D\u73B0\uFF08\u9ED8\u8BA4\u4F7F\u7528\u539F\u59CB Agent\uFF09").option("--timeout <seconds>", "\u6700\u5927\u7B49\u5F85\u56DE\u590D\u65F6\u95F4\uFF08\u79D2\uFF09", "60").option("--poll-interval <ms>", "\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09", "2000").option("--dry-run", "\u4EC5\u8F93\u51FA\u622A\u65AD\u540E\u7684\u4E0A\u4E0B\u6587 msg_list\uFF0C\u4E0D\u53D1\u9001", false).action(async (recordId, opts) => {
|
|
1916
|
-
try {
|
|
1917
|
-
const relations = await getRecordRelations(recordId);
|
|
1918
|
-
const { conversation, agent_config: agentConfig } = relations;
|
|
1919
|
-
const conversationId = conversation.conversation_id;
|
|
1920
|
-
const agentConfigId = opts.agent ?? agentConfig.config_id;
|
|
1921
|
-
const userName = conversation.user_name ?? "cli-user";
|
|
1922
|
-
const records = await getConversationRecords({
|
|
1923
|
-
conversationId,
|
|
1924
|
-
pageSize: 200,
|
|
1925
|
-
direction: "prev"
|
|
1926
|
-
});
|
|
1927
|
-
const truncated = truncateBeforeRecord(records, recordId);
|
|
1928
|
-
const msgList = recordsToMsgList(truncated);
|
|
1929
|
-
if (opts.dryRun) {
|
|
1930
|
-
formatOutput(
|
|
1931
|
-
{
|
|
1932
|
-
success: true,
|
|
1933
|
-
data: {
|
|
1934
|
-
original_record_id: recordId,
|
|
1935
|
-
agent_config_id: agentConfigId,
|
|
1936
|
-
agent_config_name: agentConfig.config_name,
|
|
1937
|
-
user_name: userName,
|
|
1938
|
-
context_messages_count: msgList.length,
|
|
1939
|
-
msg_list: msgList
|
|
1940
|
-
}
|
|
1941
|
-
},
|
|
1942
|
-
program2.opts().table
|
|
1943
|
-
);
|
|
1944
|
-
return;
|
|
1945
|
-
}
|
|
1946
|
-
const conv = await createDebugConversation({
|
|
1947
|
-
agentConfigId,
|
|
1948
|
-
userName
|
|
1949
|
-
});
|
|
1950
|
-
await sendAgentMessage({
|
|
1951
|
-
conversationId: conv.conversation_id,
|
|
1952
|
-
msgList
|
|
1953
|
-
});
|
|
1954
|
-
const agentRecords = await pollAgentReply(conv.conversation_id, {
|
|
1955
|
-
timeout: Number(opts.timeout) * 1e3,
|
|
1956
|
-
pollInterval: Number(opts.pollInterval),
|
|
1957
|
-
category: "agent_response"
|
|
1958
|
-
});
|
|
1959
|
-
let traceId = null;
|
|
1960
|
-
try {
|
|
1961
|
-
const debugInfo = await getRecordDebugInfo(agentRecords[0].record_id);
|
|
1962
|
-
traceId = debugInfo.trace_id ?? null;
|
|
1963
|
-
} catch {
|
|
1964
|
-
}
|
|
1965
|
-
formatOutput(
|
|
1966
|
-
{
|
|
1967
|
-
success: true,
|
|
1968
|
-
data: {
|
|
1969
|
-
original_record_id: recordId,
|
|
1970
|
-
conversation_id: conv.conversation_id,
|
|
1971
|
-
agent_config_id: agentConfigId,
|
|
1972
|
-
agent_config_name: agentConfig.config_name,
|
|
1973
|
-
user_name: userName,
|
|
1974
|
-
context_messages_count: msgList.length,
|
|
1975
|
-
trace_id: traceId,
|
|
1976
|
-
reply: agentRecords
|
|
1977
|
-
}
|
|
1978
|
-
},
|
|
1979
|
-
program2.opts().table
|
|
1980
|
-
);
|
|
1981
|
-
} catch (err) {
|
|
1982
|
-
reportCaughtError(err);
|
|
1983
|
-
process.exit(toExitCode(err));
|
|
1984
|
-
}
|
|
1985
|
-
});
|
|
1986
|
-
debug.command("trace").description(
|
|
1987
|
-
"\u6839\u636E Langfuse Trace ID \u83B7\u53D6\u5B8C\u6574\u7684 Trace \u8BE6\u60C5\uFF08\u4ECE debug record \u8FD4\u56DE\u7684 flow_info \u4E2D\u63D0\u53D6 traceId\uFF09"
|
|
1988
|
-
).argument("<trace_id>", "Langfuse Trace ID\uFF08\u4ECE flow_info \u4E2D\u83B7\u53D6\uFF09").option("--env <env>", "langfuse \u73AF\u5883 dev|prod", "prod").action(async (traceId, opts) => {
|
|
1989
|
-
try {
|
|
1990
|
-
if (opts.env !== "dev" && opts.env !== "prod") {
|
|
1991
|
-
outputError(1, "--env \u4EC5\u652F\u6301 dev \u6216 prod");
|
|
1992
|
-
process.exit(1);
|
|
1993
|
-
}
|
|
1994
|
-
const data = await getLangfuseTrace(traceId, opts.env);
|
|
1995
|
-
formatOutput({ success: true, data }, program2.opts().table);
|
|
1996
|
-
} catch (err) {
|
|
1997
|
-
reportCaughtError(err);
|
|
1998
|
-
process.exit(toExitCode(err));
|
|
1882
|
+
// src/client/product-api.ts
|
|
1883
|
+
async function listProducts(opts) {
|
|
1884
|
+
const request = createRequest();
|
|
1885
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/products", {
|
|
1886
|
+
method: "GET",
|
|
1887
|
+
query: {
|
|
1888
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1889
|
+
search: opts.keyword,
|
|
1890
|
+
status: opts.status?.join(","),
|
|
1891
|
+
tags: opts.tags?.length ? JSON.stringify(opts.tags) : void 0,
|
|
1892
|
+
page: opts.page ?? 1,
|
|
1893
|
+
page_size: opts.pageSize ?? 20
|
|
1999
1894
|
}
|
|
2000
1895
|
});
|
|
2001
1896
|
}
|
|
2002
|
-
|
|
2003
|
-
// src/client/faq-api.ts
|
|
2004
|
-
async function listFaqFiles(opts) {
|
|
1897
|
+
async function getProductDetail(opts) {
|
|
2005
1898
|
const request = createRequest();
|
|
2006
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/
|
|
1899
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/product/detail", {
|
|
2007
1900
|
method: "GET",
|
|
2008
1901
|
query: {
|
|
2009
1902
|
customer_agent_config_id: opts.agentConfigId,
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
suffix_type: "_faq"
|
|
1903
|
+
db_id: opts.dbId,
|
|
1904
|
+
product_id: opts.productId
|
|
2013
1905
|
}
|
|
2014
1906
|
});
|
|
2015
1907
|
}
|
|
2016
|
-
async function
|
|
1908
|
+
async function updateProduct(opts) {
|
|
2017
1909
|
const request = createRequest();
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
}
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
1910
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/product/update", {
|
|
1911
|
+
method: "POST",
|
|
1912
|
+
body: {
|
|
1913
|
+
data_id: opts.dataId,
|
|
1914
|
+
knowledge_id: opts.knowledgeId,
|
|
1915
|
+
db_id: opts.dbId,
|
|
1916
|
+
update_dict: opts.updateDict
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
async function uploadProductByUrl(opts) {
|
|
1921
|
+
const request = createRequest();
|
|
1922
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/products/upload", {
|
|
1923
|
+
method: "POST",
|
|
1924
|
+
body: {
|
|
1925
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1926
|
+
source_type: opts.sourceType ?? "manual",
|
|
1927
|
+
identify: opts.identify ?? true,
|
|
1928
|
+
product_urls: opts.productUrls
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1932
|
+
async function uploadProductData(opts) {
|
|
1933
|
+
const request = createRequest();
|
|
1934
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/products/upload", {
|
|
1935
|
+
method: "POST",
|
|
1936
|
+
body: {
|
|
1937
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1938
|
+
source_type: opts.sourceType ?? "manual",
|
|
1939
|
+
identify: opts.identify ?? true,
|
|
1940
|
+
product_items: opts.productItems
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
async function updateSku(opts) {
|
|
1945
|
+
if (!opts.skuId && !opts.sku) {
|
|
1946
|
+
throw new Error("updateSku \u9700\u8981\u63D0\u4F9B sku \u6216 sku_id \u5176\u4E2D\u4E4B\u4E00");
|
|
1947
|
+
}
|
|
1948
|
+
const identifier = opts.skuId ? { sku_id: opts.skuId } : { sku: opts.sku };
|
|
1949
|
+
const request = createRequest();
|
|
1950
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/sku/update", {
|
|
1951
|
+
method: "POST",
|
|
1952
|
+
body: {
|
|
1953
|
+
...identifier,
|
|
1954
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1955
|
+
update_dict: opts.updateDict
|
|
1956
|
+
}
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
async function syncTaobaoProducts(opts) {
|
|
1960
|
+
const request = createRequest();
|
|
1961
|
+
return request(getCustomerServiceUrl(), "/v1/authorized-shop/sync-taobao-products", {
|
|
1962
|
+
method: "POST",
|
|
1963
|
+
body: {
|
|
1964
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1965
|
+
skip_hash_check: opts.skipHashCheck ?? false,
|
|
1966
|
+
sync_type: opts.syncType ?? "full"
|
|
1967
|
+
}
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
async function syncSingleTaobaoProduct(opts) {
|
|
1971
|
+
const request = createRequest();
|
|
1972
|
+
return request(getCustomerServiceUrl(), "/v1/authorized-shop/sync-single-product", {
|
|
1973
|
+
method: "POST",
|
|
1974
|
+
body: {
|
|
1975
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1976
|
+
product_id: opts.productId
|
|
1977
|
+
}
|
|
1978
|
+
});
|
|
1979
|
+
}
|
|
1980
|
+
async function identifyAllProducts(opts) {
|
|
1981
|
+
const request = createRequest();
|
|
1982
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/products/identify/all", {
|
|
1983
|
+
method: "POST",
|
|
1984
|
+
body: {
|
|
1985
|
+
customer_agent_config_id: opts.agentConfigId
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// src/client/sa-api.ts
|
|
1991
|
+
async function listSituationActions(opts) {
|
|
1992
|
+
const request = createRequest();
|
|
1993
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/list", {
|
|
1994
|
+
method: "GET",
|
|
1995
|
+
query: {
|
|
1996
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
1997
|
+
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
1998
|
+
event_first_label: opts.firstLabel ?? "",
|
|
1999
|
+
event_second_label: opts.secondLabel ?? "",
|
|
2000
|
+
page: opts.page ?? 1,
|
|
2001
|
+
page_size: opts.pageSize ?? 500
|
|
2002
|
+
}
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
async function searchSituationActions(opts) {
|
|
2006
|
+
const request = createRequest();
|
|
2007
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/search", {
|
|
2008
|
+
method: "GET",
|
|
2009
|
+
query: { customer_agent_config_id: opts.agentConfigId, keyword: opts.keyword }
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
async function createSituationAction(opts) {
|
|
2013
|
+
const request = createRequest();
|
|
2014
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/create", {
|
|
2015
|
+
method: "POST",
|
|
2016
|
+
body: {
|
|
2017
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2018
|
+
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
2019
|
+
event_first_label: opts.firstLabel,
|
|
2020
|
+
event_second_label: opts.secondLabel,
|
|
2021
|
+
situation: opts.situation,
|
|
2022
|
+
action: opts.action,
|
|
2023
|
+
transfer_to_human: opts.transferToHuman ?? false
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
2027
|
+
async function updateSituationAction(opts) {
|
|
2028
|
+
const request = createRequest();
|
|
2029
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/update", {
|
|
2030
|
+
method: "POST",
|
|
2031
|
+
body: {
|
|
2032
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2033
|
+
situation_action_id: opts.situationActionId,
|
|
2034
|
+
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
2035
|
+
event_first_label: opts.firstLabel,
|
|
2036
|
+
event_second_label: opts.secondLabel,
|
|
2037
|
+
situation: opts.situation,
|
|
2038
|
+
action: opts.action,
|
|
2039
|
+
transfer_to_human: opts.transferToHuman ?? false
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
async function deleteSituationAction(opts) {
|
|
2044
|
+
const request = createRequest();
|
|
2045
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/delete", {
|
|
2046
|
+
method: "POST",
|
|
2047
|
+
body: {
|
|
2048
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2049
|
+
situation_action_id: opts.situationActionId,
|
|
2050
|
+
event_first_label: opts.firstLabel,
|
|
2051
|
+
event_second_label: opts.secondLabel
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
async function listSituationActionVersions(opts) {
|
|
2056
|
+
const request = createRequest();
|
|
2057
|
+
return request(
|
|
2058
|
+
getCustomerServiceUrl(),
|
|
2059
|
+
"/v1/knowledge/situation-actions/list/versions",
|
|
2060
|
+
{
|
|
2061
|
+
method: "GET",
|
|
2062
|
+
query: {
|
|
2063
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2064
|
+
situation_action_id: opts.situationActionId
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
// src/commands/debug-snapshot.ts
|
|
2071
|
+
var SA_PAGE_SIZE = 500;
|
|
2072
|
+
var ACTIVITY_PAGE_SIZE = 100;
|
|
2073
|
+
var PRODUCT_PAGE_SIZE = 100;
|
|
2074
|
+
var PRODUCT_DETAIL_CONCURRENCY = 4;
|
|
2075
|
+
var PERSONALIZATION_SLOTS = [
|
|
2076
|
+
"intent",
|
|
2077
|
+
"general_qa",
|
|
2078
|
+
"recommend",
|
|
2079
|
+
"takeover_rule",
|
|
2080
|
+
"image_rule",
|
|
2081
|
+
"custom_qa"
|
|
2082
|
+
];
|
|
2083
|
+
var ACTIVITY_FIELDS = [
|
|
2084
|
+
"activity_name",
|
|
2085
|
+
"activity_rule",
|
|
2086
|
+
"participate_condition",
|
|
2087
|
+
"benefit_content",
|
|
2088
|
+
"redeem_desc",
|
|
2089
|
+
"other_info",
|
|
2090
|
+
"qa"
|
|
2091
|
+
];
|
|
2092
|
+
var PRODUCT_FIELDS = [
|
|
2093
|
+
"\u5546\u54C1\u6807\u9898",
|
|
2094
|
+
"\u5546\u54C1\u54C1\u7C7B",
|
|
2095
|
+
"\u53C2\u6570",
|
|
2096
|
+
"\u5356\u70B9",
|
|
2097
|
+
"\u8865\u5145\u77E5\u8BC6",
|
|
2098
|
+
"\u8F6E\u64AD\u56FE\u8BC6\u522B\u7ED3\u679C",
|
|
2099
|
+
"\u5546\u54C1\u8BE6\u60C5\u9875\u8BC6\u522B\u7ED3\u679C",
|
|
2100
|
+
"\u5173\u8054\u77E5\u8BC6\u5E93\u547D\u4E2D"
|
|
2101
|
+
];
|
|
2102
|
+
var SKU_FIELDS = ["\u8865\u5145\u77E5\u8BC6", "sku\u56FE\u8BC6\u522B\u7ED3\u679C"];
|
|
2103
|
+
function asRecord(value) {
|
|
2104
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
2105
|
+
}
|
|
2106
|
+
function asArray(value) {
|
|
2107
|
+
return Array.isArray(value) ? value : [];
|
|
2108
|
+
}
|
|
2109
|
+
function toStringId(value) {
|
|
2110
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
2111
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
2112
|
+
return void 0;
|
|
2113
|
+
}
|
|
2114
|
+
function hasDefined(record, key) {
|
|
2115
|
+
return Object.prototype.hasOwnProperty.call(record, key) && record[key] !== void 0;
|
|
2116
|
+
}
|
|
2117
|
+
function readPageItems(result) {
|
|
2118
|
+
const record = asRecord(result);
|
|
2119
|
+
return {
|
|
2120
|
+
items: asArray(record.items).map(asRecord),
|
|
2121
|
+
total: typeof record.total === "number" ? record.total : void 0
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
function isExhausted(fetchedCount, pageItemsCount, pageSize, total) {
|
|
2125
|
+
if (typeof total === "number") return fetchedCount >= total;
|
|
2126
|
+
return pageItemsCount < pageSize;
|
|
2127
|
+
}
|
|
2128
|
+
async function listAllSituationActions(agentConfigId) {
|
|
2129
|
+
const all = [];
|
|
2130
|
+
for (let page = 1; ; page += 1) {
|
|
2131
|
+
const result = await listSituationActions({
|
|
2132
|
+
agentConfigId,
|
|
2133
|
+
page,
|
|
2134
|
+
pageSize: SA_PAGE_SIZE
|
|
2135
|
+
});
|
|
2136
|
+
const { items, total } = readPageItems(result);
|
|
2137
|
+
all.push(...items);
|
|
2138
|
+
if (isExhausted(all.length, items.length, SA_PAGE_SIZE, total)) return all;
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
async function listAllActivities(agentConfigId) {
|
|
2142
|
+
const all = [];
|
|
2143
|
+
for (let page = 1; ; page += 1) {
|
|
2144
|
+
const result = await listActivities({
|
|
2145
|
+
customerAgentConfigId: agentConfigId,
|
|
2146
|
+
page,
|
|
2147
|
+
pageSize: ACTIVITY_PAGE_SIZE
|
|
2148
|
+
});
|
|
2149
|
+
const { items, total } = readPageItems(result);
|
|
2150
|
+
all.push(...items);
|
|
2151
|
+
if (isExhausted(all.length, items.length, ACTIVITY_PAGE_SIZE, total)) return all;
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
function readProductId(record) {
|
|
2155
|
+
const productInfo = asRecord(record["\u5546\u54C1\u4FE1\u606F"]);
|
|
2156
|
+
return toStringId(record.product_id) ?? toStringId(record["\u5546\u54C1id"]) ?? toStringId(productInfo["\u5546\u54C1id"]) ?? toStringId(record.id);
|
|
2157
|
+
}
|
|
2158
|
+
async function listAllProductIds(agentConfigId) {
|
|
2159
|
+
const productIds = [];
|
|
2160
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2161
|
+
let fetchedCount = 0;
|
|
2162
|
+
for (let page = 1; ; page += 1) {
|
|
2163
|
+
const result = await listProducts({
|
|
2164
|
+
agentConfigId,
|
|
2165
|
+
page,
|
|
2166
|
+
pageSize: PRODUCT_PAGE_SIZE
|
|
2167
|
+
});
|
|
2168
|
+
const { items, total } = readPageItems(result);
|
|
2169
|
+
fetchedCount += items.length;
|
|
2170
|
+
for (const item of items) {
|
|
2171
|
+
const productId = readProductId(item);
|
|
2172
|
+
if (productId && !seen.has(productId)) {
|
|
2173
|
+
seen.add(productId);
|
|
2174
|
+
productIds.push(productId);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
if (isExhausted(fetchedCount, items.length, PRODUCT_PAGE_SIZE, total)) return productIds;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
function buildPersonalization(agent) {
|
|
2181
|
+
const customerConfig = asRecord(agent.customer_config);
|
|
2182
|
+
const personalization = {};
|
|
2183
|
+
for (const slot of PERSONALIZATION_SLOTS) {
|
|
2184
|
+
const source = asRecord(customerConfig[slot]);
|
|
2185
|
+
if (hasDefined(source, "flow_instruction")) {
|
|
2186
|
+
personalization[slot] = { flow_instruction: source.flow_instruction };
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return personalization;
|
|
2190
|
+
}
|
|
2191
|
+
function buildSituationActions(items) {
|
|
2192
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2193
|
+
for (const item of items) {
|
|
2194
|
+
const eventOne = toStringId(item.event_first_label) ?? "";
|
|
2195
|
+
const eventTwo = toStringId(item.event_second_label) ?? "";
|
|
2196
|
+
const key = `${eventOne}__${eventTwo}`;
|
|
2197
|
+
let group = groups.get(key);
|
|
2198
|
+
if (!group) {
|
|
2199
|
+
group = {
|
|
2200
|
+
sa_key: key,
|
|
2201
|
+
event_one: eventOne,
|
|
2202
|
+
event_two: eventTwo,
|
|
2203
|
+
items: []
|
|
2204
|
+
};
|
|
2205
|
+
groups.set(key, group);
|
|
2206
|
+
}
|
|
2207
|
+
const situation = toStringId(item.situation) ?? "";
|
|
2208
|
+
const patchItem = {
|
|
2209
|
+
match: { situation },
|
|
2210
|
+
situation,
|
|
2211
|
+
scene_summary: hasDefined(item, "scene_summary") ? item.scene_summary : situation
|
|
2212
|
+
};
|
|
2213
|
+
if (hasDefined(item, "action")) patchItem.action = item.action;
|
|
2214
|
+
if (hasDefined(item, "transfer_to_human")) {
|
|
2215
|
+
patchItem.transfer_to_human = item.transfer_to_human;
|
|
2216
|
+
}
|
|
2217
|
+
if (hasDefined(item, "react_loop_count")) {
|
|
2218
|
+
patchItem.react_loop_count = item.react_loop_count;
|
|
2219
|
+
}
|
|
2220
|
+
group.items.push(patchItem);
|
|
2221
|
+
}
|
|
2222
|
+
return [...groups.values()];
|
|
2223
|
+
}
|
|
2224
|
+
function buildActivities(items) {
|
|
2225
|
+
return items.flatMap((item) => {
|
|
2226
|
+
const activityId = toStringId(item.activity_id ?? item.id);
|
|
2227
|
+
if (!activityId) return [];
|
|
2228
|
+
const activity = { activity_id: activityId };
|
|
2229
|
+
for (const field of ACTIVITY_FIELDS) {
|
|
2230
|
+
if (hasDefined(item, field)) activity[field] = item[field];
|
|
2231
|
+
}
|
|
2232
|
+
return [activity];
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
function buildSkuItems(detail) {
|
|
2236
|
+
const rawSkuItems = asArray(detail.skus).length > 0 ? asArray(detail.skus) : asArray(detail.sku);
|
|
2237
|
+
return rawSkuItems.flatMap((raw) => {
|
|
2238
|
+
const item = asRecord(raw);
|
|
2239
|
+
const sku = toStringId(item.sku ?? item.sku_id);
|
|
2240
|
+
if (!sku) return [];
|
|
2241
|
+
const skuPatch = {
|
|
2242
|
+
match: { sku },
|
|
2243
|
+
sku
|
|
2244
|
+
};
|
|
2245
|
+
for (const field of SKU_FIELDS) {
|
|
2246
|
+
if (hasDefined(item, field)) skuPatch[field] = item[field];
|
|
2247
|
+
}
|
|
2248
|
+
return [skuPatch];
|
|
2249
|
+
});
|
|
2250
|
+
}
|
|
2251
|
+
function readProductField(detail, productInfo, field) {
|
|
2252
|
+
if (hasDefined(detail, field)) return detail[field];
|
|
2253
|
+
if (hasDefined(productInfo, field)) return productInfo[field];
|
|
2254
|
+
return void 0;
|
|
2255
|
+
}
|
|
2256
|
+
function buildProductKnowledgeItem(detail, fallbackProductId) {
|
|
2257
|
+
const productInfo = asRecord(detail["\u5546\u54C1\u4FE1\u606F"]);
|
|
2258
|
+
const productId = readProductId(detail) ?? fallbackProductId;
|
|
2259
|
+
const product = { product_id: productId };
|
|
2260
|
+
for (const field of PRODUCT_FIELDS) {
|
|
2261
|
+
const value = readProductField(detail, productInfo, field);
|
|
2262
|
+
if (value !== void 0) product[field] = value;
|
|
2263
|
+
}
|
|
2264
|
+
product.sku = buildSkuItems(detail);
|
|
2265
|
+
return product;
|
|
2266
|
+
}
|
|
2267
|
+
async function fetchProductDetails(opts) {
|
|
2268
|
+
const details = [];
|
|
2269
|
+
for (let i = 0; i < opts.productIds.length; i += PRODUCT_DETAIL_CONCURRENCY) {
|
|
2270
|
+
const batch = opts.productIds.slice(i, i + PRODUCT_DETAIL_CONCURRENCY);
|
|
2271
|
+
const batchDetails = await Promise.all(
|
|
2272
|
+
batch.map(async (productId) => {
|
|
2273
|
+
const detail = await getProductDetail({
|
|
2274
|
+
agentConfigId: opts.agentConfigId,
|
|
2275
|
+
dbId: opts.dbId,
|
|
2276
|
+
productId
|
|
2277
|
+
});
|
|
2278
|
+
return buildProductKnowledgeItem(asRecord(detail), productId);
|
|
2279
|
+
})
|
|
2280
|
+
);
|
|
2281
|
+
details.push(...batchDetails);
|
|
2282
|
+
}
|
|
2283
|
+
return details;
|
|
2284
|
+
}
|
|
2285
|
+
async function buildDebugDataOverlaySnapshot(opts) {
|
|
2286
|
+
const agent = asRecord(await getAgent(opts.agentConfigId));
|
|
2287
|
+
const productIds = opts.productIds && opts.productIds.length > 0 ? [...new Set(opts.productIds)] : await listAllProductIds(opts.agentConfigId);
|
|
2288
|
+
const dbId = toStringId(agent.database_id);
|
|
2289
|
+
if (productIds.length > 0 && !dbId) {
|
|
2290
|
+
throw new Error("Agent \u8BE6\u60C5\u4E2D\u672A\u627E\u5230 database_id");
|
|
2291
|
+
}
|
|
2292
|
+
const [saItems, activityItems, productKnowledge] = await Promise.all([
|
|
2293
|
+
listAllSituationActions(opts.agentConfigId),
|
|
2294
|
+
listAllActivities(opts.agentConfigId),
|
|
2295
|
+
dbId ? fetchProductDetails({
|
|
2296
|
+
agentConfigId: opts.agentConfigId,
|
|
2297
|
+
dbId,
|
|
2298
|
+
productIds
|
|
2299
|
+
}) : Promise.resolve([])
|
|
2300
|
+
]);
|
|
2301
|
+
return {
|
|
2302
|
+
version: 1,
|
|
2303
|
+
servhub: {
|
|
2304
|
+
customer_config: buildPersonalization(agent),
|
|
2305
|
+
forbidden_words: asArray(agent.forbidden_words),
|
|
2306
|
+
platform_config: {}
|
|
2307
|
+
},
|
|
2308
|
+
sop: {
|
|
2309
|
+
node_templates: {},
|
|
2310
|
+
sa: buildSituationActions(saItems),
|
|
2311
|
+
activities: buildActivities(activityItems),
|
|
2312
|
+
product_knowledge: productKnowledge
|
|
2313
|
+
}
|
|
2314
|
+
};
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
// src/commands/debug.ts
|
|
2318
|
+
function registerDebugCommand(program2) {
|
|
2319
|
+
const debug = program2.command("debug").description(
|
|
2320
|
+
"Agent \u8C03\u8BD5\u6D4B\u8BD5 \u2014\u2014 \u5411 Agent \u53D1\u9001\u6D4B\u8BD5\u6D88\u606F\u5E76\u83B7\u53D6\u56DE\u590D\uFF0C\u662F\u9A8C\u8BC1 Agent \u56DE\u590D\u8D28\u91CF\u7684\u4E3B\u8981\u624B\u6BB5\u3002\u652F\u6301\u5355\u6761\u6D88\u606F\u548C\u591A\u8F6E\u5BF9\u8BDD\u91CD\u653E"
|
|
2321
|
+
);
|
|
2322
|
+
debug.command("ask").description(
|
|
2323
|
+
"\u5411 Agent \u53D1\u9001\u6D88\u606F\u5E76\u7B49\u5F85\u56DE\u590D\u3002\u8FD4\u56DE { conversation_id, reply: [{ record_id, content, ... }] }\u3002record_id \u53EF\u4F20\u7ED9 debug record \u67E5\u770B\u5185\u90E8\u63A8\u7406\u94FE\u8DEF"
|
|
2324
|
+
).requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08\u4ECE agent list \u83B7\u53D6\uFF09").option("--text <message>", "\u53D1\u9001\u7684\u6D88\u606F\u5185\u5BB9\uFF08\u4E0E --messages \u4E92\u65A5\uFF0C\u4E8C\u9009\u4E00\uFF09").option(
|
|
2325
|
+
"--messages <json>",
|
|
2326
|
+
'\u5B8C\u6574\u6D88\u606F\u5217\u8868 JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF0C\u7528\u4E8E\u91CD\u653E\u591A\u8F6E\u5BF9\u8BDD\uFF08\u4E0E --text \u4E92\u65A5\uFF09\u3002\u63A5\u53D7\u4E24\u79CD\u683C\u5F0F\uFF1A(1) JSON \u6570\u7EC4 [{ match_id, content: { text, image_url? }, timestamp, type: "TEXT", role: "user"|"assistant" }, ...] (2) \u542B msg_list \u5B57\u6BB5\u7684\u5BF9\u8C61 { msg_list: [...] }\uFF08conversation records \u7684\u539F\u59CB\u683C\u5F0F\u53EF\u76F4\u63A5\u4F7F\u7528\uFF09'
|
|
2327
|
+
).option("--user <name>", "\u6A21\u62DF\u7684\u7528\u6237\u540D\uFF08\u9ED8\u8BA4\u4F7F\u7528\u767B\u5F55\u7528\u6237\u540D\uFF09").option("--url <image_url>", "\u9644\u5E26\u7684\u56FE\u7247 URL\uFF08\u4EC5 --text \u6A21\u5F0F\u6709\u6548\uFF09").option("--conversation <id>", "\u590D\u7528\u5DF2\u6709\u4F1A\u8BDD ID\uFF0C\u7528\u4E8E\u5728\u540C\u4E00\u4E0A\u4E0B\u6587\u4E2D\u7EE7\u7EED\u5BF9\u8BDD").option("--mock <json>", "\u5DE5\u5177\u7ED3\u679C mock JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF0C\u5F62\u5982 [{ tool_name, result }]").option("--data-overlay <json>", "debug_data_overlay JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF0C\u7528\u4E8E\u672C\u8F6E debug \u6570\u636E\u8986\u76D6").option("--timeout <seconds>", "\u6700\u5927\u7B49\u5F85\u56DE\u590D\u65F6\u95F4\uFF08\u79D2\uFF09\uFF0C\u590D\u6742 Agent \u5EFA\u8BAE\u8C03\u9AD8", "30").option("--poll-interval <ms>", "\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09", "2000").action(async (opts) => {
|
|
2328
|
+
try {
|
|
2329
|
+
if (!opts.text && !opts.messages) {
|
|
2330
|
+
outputError(1, "\u5FC5\u987B\u6307\u5B9A --text \u6216 --messages \u5176\u4E2D\u4E4B\u4E00");
|
|
2331
|
+
process.exit(1);
|
|
2332
|
+
}
|
|
2333
|
+
const userName = opts.user ?? readCredentials()?.username ?? "cli-user";
|
|
2334
|
+
let conversationId;
|
|
2335
|
+
if (opts.conversation) {
|
|
2336
|
+
conversationId = opts.conversation;
|
|
2337
|
+
} else {
|
|
2338
|
+
const conv = await createDebugConversation({
|
|
2339
|
+
agentConfigId: opts.agent,
|
|
2340
|
+
userName
|
|
2341
|
+
});
|
|
2342
|
+
conversationId = conv.conversation_id;
|
|
2343
|
+
}
|
|
2344
|
+
let msgList;
|
|
2345
|
+
if (opts.messages) {
|
|
2346
|
+
const parsed = parseDataOption(opts.messages);
|
|
2347
|
+
msgList = Array.isArray(parsed) ? parsed : parsed.msg_list;
|
|
2348
|
+
if (!Array.isArray(msgList)) {
|
|
2349
|
+
outputError(1, "--messages \u5FC5\u987B\u662F JSON \u6570\u7EC4\u6216\u5305\u542B msg_list \u5B57\u6BB5\u7684\u5BF9\u8C61");
|
|
2350
|
+
process.exit(1);
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
const mock = opts.mock ? parseDataOption(opts.mock) : void 0;
|
|
2354
|
+
const debugDataOverlay = opts.dataOverlay ? parseDataOption(opts.dataOverlay) : void 0;
|
|
2355
|
+
await sendAgentMessage({
|
|
2356
|
+
conversationId,
|
|
2357
|
+
text: opts.text,
|
|
2358
|
+
imageUrl: opts.url,
|
|
2359
|
+
msgList,
|
|
2360
|
+
mock,
|
|
2361
|
+
debugDataOverlay
|
|
2362
|
+
});
|
|
2363
|
+
const agentRecords = await pollAgentReply(conversationId, {
|
|
2364
|
+
timeout: Number(opts.timeout) * 1e3,
|
|
2365
|
+
pollInterval: Number(opts.pollInterval)
|
|
2366
|
+
});
|
|
2367
|
+
formatOutput(
|
|
2368
|
+
{
|
|
2369
|
+
success: true,
|
|
2370
|
+
data: {
|
|
2371
|
+
conversation_id: conversationId,
|
|
2372
|
+
reply: agentRecords
|
|
2373
|
+
}
|
|
2374
|
+
},
|
|
2375
|
+
program2.opts().table
|
|
2376
|
+
);
|
|
2377
|
+
} catch (err) {
|
|
2378
|
+
reportCaughtError(err);
|
|
2379
|
+
process.exit(toExitCode(err));
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
debug.command("record").description("\u83B7\u53D6\u67D0\u6761\u56DE\u590D\u7684\u5185\u90E8\u63A8\u7406\u94FE\u8DEF\uFF08flow_info\uFF09\uFF0C\u7528\u4E8E\u8BCA\u65AD Agent \u4E3A\u4F55\u7ED9\u51FA\u7279\u5B9A\u56DE\u590D").argument("<record_id>", "\u56DE\u590D\u8BB0\u5F55 ID\uFF08\u4ECE debug ask \u8FD4\u56DE\u7684 reply[].record_id \u83B7\u53D6\uFF09").option(
|
|
2383
|
+
"--deep",
|
|
2384
|
+
"\u6DF1\u5EA6\u89E3\u6790\uFF1A\u989D\u5916\u8C03\u7528 ai-api \u7684 flow execute_log \u63A5\u53E3\uFF0C\u62C9\u53D6 flow_info.flow_id + task_id \u5BF9\u5E94\u7684\u5B8C\u6574\u6267\u884C\u65E5\u5FD7\uFF08log_url \u5185\u5BB9\uFF09\uFF0C\u7528\u4E8E\u6392\u67E5\u8282\u70B9\u7EA7\u8F93\u5165\u8F93\u51FA",
|
|
2385
|
+
false
|
|
2386
|
+
).option("--flow-workspace <id>", "flow \u6240\u5728 workspace ID\uFF08--deep \u65F6\u4F7F\u7528\uFF0C\u9ED8\u8BA4\u4F7F\u7528\u5185\u7F6E\u56FA\u5B9A\u503C\uFF09").action(async (recordId, opts) => {
|
|
2387
|
+
try {
|
|
2388
|
+
const data2 = await getRecordDebugInfo(recordId);
|
|
2389
|
+
let deep;
|
|
2390
|
+
if (opts.deep) {
|
|
2391
|
+
const flowInfo = data2.flow_info;
|
|
2392
|
+
const flowId = flowInfo?.flow_id;
|
|
2393
|
+
const taskId = flowInfo?.task_id;
|
|
2394
|
+
if (!flowId || !taskId) {
|
|
2395
|
+
deep = { error: "flow_info \u4E2D\u7F3A\u5C11 flow_id \u6216 task_id\uFF0C\u65E0\u6CD5\u6DF1\u5EA6\u89E3\u6790" };
|
|
2396
|
+
} else {
|
|
2397
|
+
try {
|
|
2398
|
+
deep = await getFlowExecuteLog({
|
|
2399
|
+
flowId,
|
|
2400
|
+
taskId,
|
|
2401
|
+
workspaceId: opts.flowWorkspace
|
|
2402
|
+
});
|
|
2403
|
+
} catch (err) {
|
|
2404
|
+
deep = { error: err.message };
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
formatOutput(
|
|
2409
|
+
{ success: true, data: opts.deep ? { ...data2, deep } : data2 },
|
|
2410
|
+
program2.opts().table
|
|
2411
|
+
);
|
|
2412
|
+
} catch (err) {
|
|
2413
|
+
reportCaughtError(err);
|
|
2414
|
+
process.exit(toExitCode(err));
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
debug.command("reproduce").description(
|
|
2418
|
+
"\u6839\u636E record_id \u590D\u73B0\u4E00\u6B21 Agent \u56DE\u590D\u3002\u81EA\u52A8\u83B7\u53D6\u5173\u8054\u4F1A\u8BDD\u3001\u622A\u53D6\u4E0A\u4E0B\u6587\u3001\u7528\u539F\u59CB user_name \u521B\u5EFA debug \u4F1A\u8BDD\u5E76\u91CD\u65B0\u53D1\u9001"
|
|
2419
|
+
).argument("<record_id>", "\u8981\u590D\u73B0\u7684\u56DE\u590D\u8BB0\u5F55 ID").option("--agent <config_id>", "\u4F7F\u7528\u6307\u5B9A Agent \u590D\u73B0\uFF08\u9ED8\u8BA4\u4F7F\u7528\u539F\u59CB Agent\uFF09").option("--timeout <seconds>", "\u6700\u5927\u7B49\u5F85\u56DE\u590D\u65F6\u95F4\uFF08\u79D2\uFF09", "60").option("--poll-interval <ms>", "\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09", "2000").option("--mock <json>", "\u5DE5\u5177\u7ED3\u679C mock JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF0C\u5F62\u5982 [{ tool_name, result }]").option("--data-overlay <json>", "debug_data_overlay JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF0C\u7528\u4E8E\u672C\u8F6E debug \u6570\u636E\u8986\u76D6").option("--dry-run", "\u4EC5\u8F93\u51FA\u622A\u65AD\u540E\u7684\u4E0A\u4E0B\u6587 msg_list\uFF0C\u4E0D\u53D1\u9001", false).action(async (recordId, opts) => {
|
|
2420
|
+
try {
|
|
2421
|
+
const relations = await getRecordRelations(recordId);
|
|
2422
|
+
const { conversation, agent_config: agentConfig } = relations;
|
|
2423
|
+
const conversationId = conversation.conversation_id;
|
|
2424
|
+
const agentConfigId = opts.agent ?? agentConfig.config_id;
|
|
2425
|
+
const userName = conversation.user_name ?? "cli-user";
|
|
2426
|
+
const records = await getConversationRecords({
|
|
2427
|
+
conversationId,
|
|
2428
|
+
pageSize: 200,
|
|
2429
|
+
direction: "prev"
|
|
2430
|
+
});
|
|
2431
|
+
const truncated = truncateBeforeRecord(records, recordId);
|
|
2432
|
+
const msgList = recordsToMsgList(truncated);
|
|
2433
|
+
const mock = opts.mock ? parseDataOption(opts.mock) : void 0;
|
|
2434
|
+
const debugDataOverlay = opts.dataOverlay ? parseDataOption(opts.dataOverlay) : void 0;
|
|
2435
|
+
if (opts.dryRun) {
|
|
2436
|
+
formatOutput(
|
|
2437
|
+
{
|
|
2438
|
+
success: true,
|
|
2439
|
+
data: {
|
|
2440
|
+
original_record_id: recordId,
|
|
2441
|
+
agent_config_id: agentConfigId,
|
|
2442
|
+
agent_config_name: agentConfig.config_name,
|
|
2443
|
+
user_name: userName,
|
|
2444
|
+
context_messages_count: msgList.length,
|
|
2445
|
+
msg_list: msgList,
|
|
2446
|
+
mock,
|
|
2447
|
+
debug_data_overlay: debugDataOverlay
|
|
2448
|
+
}
|
|
2449
|
+
},
|
|
2450
|
+
program2.opts().table
|
|
2451
|
+
);
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
const conv = await createDebugConversation({
|
|
2455
|
+
agentConfigId,
|
|
2456
|
+
userName
|
|
2457
|
+
});
|
|
2458
|
+
await sendAgentMessage({
|
|
2459
|
+
conversationId: conv.conversation_id,
|
|
2460
|
+
msgList,
|
|
2461
|
+
mock,
|
|
2462
|
+
debugDataOverlay
|
|
2463
|
+
});
|
|
2464
|
+
const agentRecords = await pollAgentReply(conv.conversation_id, {
|
|
2465
|
+
timeout: Number(opts.timeout) * 1e3,
|
|
2466
|
+
pollInterval: Number(opts.pollInterval),
|
|
2467
|
+
category: "agent_response"
|
|
2468
|
+
});
|
|
2469
|
+
let traceId = null;
|
|
2470
|
+
try {
|
|
2471
|
+
const debugInfo = await getRecordDebugInfo(agentRecords[0].record_id);
|
|
2472
|
+
traceId = debugInfo.trace_id ?? null;
|
|
2473
|
+
} catch {
|
|
2474
|
+
}
|
|
2475
|
+
formatOutput(
|
|
2476
|
+
{
|
|
2477
|
+
success: true,
|
|
2478
|
+
data: {
|
|
2479
|
+
original_record_id: recordId,
|
|
2480
|
+
conversation_id: conv.conversation_id,
|
|
2481
|
+
agent_config_id: agentConfigId,
|
|
2482
|
+
agent_config_name: agentConfig.config_name,
|
|
2483
|
+
user_name: userName,
|
|
2484
|
+
context_messages_count: msgList.length,
|
|
2485
|
+
trace_id: traceId,
|
|
2486
|
+
reply: agentRecords
|
|
2487
|
+
}
|
|
2488
|
+
},
|
|
2489
|
+
program2.opts().table
|
|
2490
|
+
);
|
|
2491
|
+
} catch (err) {
|
|
2492
|
+
reportCaughtError(err);
|
|
2493
|
+
process.exit(toExitCode(err));
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2496
|
+
const data = debug.command("data").description("debug \u6570\u636E\u5DE5\u5177");
|
|
2497
|
+
data.command("snapshot").description("\u751F\u6210\u53EF\u76F4\u63A5\u4F20\u7ED9 --data-overlay @file \u7684 debug_data_overlay v1 JSON").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID\uFF08\u4ECE agent list \u83B7\u53D6\uFF09").option("--product-id <id...>", "\u53EA\u5BFC\u51FA\u6307\u5B9A\u5546\u54C1 ID\uFF1B\u4E0D\u4F20\u5219\u5206\u9875\u5BFC\u51FA\u5168\u91CF\u5546\u54C1").action(async (opts) => {
|
|
2498
|
+
try {
|
|
2499
|
+
const snapshot = await buildDebugDataOverlaySnapshot({
|
|
2500
|
+
agentConfigId: opts.agent,
|
|
2501
|
+
productIds: opts.productId
|
|
2502
|
+
});
|
|
2503
|
+
process.stdout.write(`${JSON.stringify(snapshot, null, 2)}
|
|
2504
|
+
`);
|
|
2505
|
+
} catch (err) {
|
|
2506
|
+
reportCaughtError(err);
|
|
2507
|
+
process.exit(toExitCode(err));
|
|
2508
|
+
}
|
|
2509
|
+
});
|
|
2510
|
+
debug.command("trace").description(
|
|
2511
|
+
"\u6839\u636E Langfuse Trace ID \u83B7\u53D6\u5B8C\u6574\u7684 Trace \u8BE6\u60C5\uFF08\u4ECE debug record \u8FD4\u56DE\u7684 flow_info \u4E2D\u63D0\u53D6 traceId\uFF09"
|
|
2512
|
+
).argument("<trace_id>", "Langfuse Trace ID\uFF08\u4ECE flow_info \u4E2D\u83B7\u53D6\uFF09").option("--env <env>", "langfuse \u73AF\u5883 dev|prod", "prod").action(async (traceId, opts) => {
|
|
2513
|
+
try {
|
|
2514
|
+
if (opts.env !== "dev" && opts.env !== "prod") {
|
|
2515
|
+
outputError(1, "--env \u4EC5\u652F\u6301 dev \u6216 prod");
|
|
2516
|
+
process.exit(1);
|
|
2517
|
+
}
|
|
2518
|
+
const data2 = await getLangfuseTrace(traceId, opts.env);
|
|
2519
|
+
formatOutput({ success: true, data: data2 }, program2.opts().table);
|
|
2520
|
+
} catch (err) {
|
|
2521
|
+
reportCaughtError(err);
|
|
2522
|
+
process.exit(toExitCode(err));
|
|
2523
|
+
}
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
// src/client/faq-api.ts
|
|
2528
|
+
async function listFaqFiles(opts) {
|
|
2529
|
+
const request = createRequest();
|
|
2530
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/external", {
|
|
2531
|
+
method: "GET",
|
|
2532
|
+
query: {
|
|
2533
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2534
|
+
page: opts.page ?? 1,
|
|
2535
|
+
page_size: opts.pageSize ?? 20,
|
|
2536
|
+
suffix_type: "_faq"
|
|
2537
|
+
}
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
async function saveFaqContent(opts) {
|
|
2541
|
+
const request = createRequest();
|
|
2542
|
+
const body = {
|
|
2543
|
+
chunks_to_delete: opts.chunksToDelete ?? [],
|
|
2544
|
+
contents: opts.contents.map((c) => ({
|
|
2545
|
+
content: c.content,
|
|
2546
|
+
keywords: c.keywords ?? [],
|
|
2547
|
+
enable: c.enable ?? true,
|
|
2548
|
+
...c.chunkId !== void 0 ? { chunk_id: c.chunkId } : {}
|
|
2549
|
+
})),
|
|
2550
|
+
answers: opts.answers
|
|
2551
|
+
};
|
|
2552
|
+
if (opts.answerGroupId !== void 0) {
|
|
2029
2553
|
body.answer_group_id = opts.answerGroupId;
|
|
2030
2554
|
}
|
|
2031
2555
|
return request(
|
|
@@ -2035,33 +2559,469 @@ async function saveFaqContent(opts) {
|
|
|
2035
2559
|
method: "POST",
|
|
2036
2560
|
body
|
|
2037
2561
|
}
|
|
2038
|
-
);
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2564
|
+
async function listFaqContents(opts) {
|
|
2565
|
+
const request = createRequest();
|
|
2566
|
+
return request(
|
|
2567
|
+
getAiApiUrl(),
|
|
2568
|
+
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/faq_contents`,
|
|
2569
|
+
{
|
|
2570
|
+
method: "GET",
|
|
2571
|
+
query: {
|
|
2572
|
+
page_size: opts.pageSize ?? 20,
|
|
2573
|
+
search_words: opts.searchWords,
|
|
2574
|
+
next_group_id: opts.nextGroupId,
|
|
2575
|
+
need_total: opts.needTotal ?? true
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
);
|
|
2579
|
+
}
|
|
2580
|
+
async function deleteFaqGroup(opts) {
|
|
2581
|
+
const request = createRequest();
|
|
2582
|
+
return request(
|
|
2583
|
+
getAiApiUrl(),
|
|
2584
|
+
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/faq_contents/${opts.answerGroupId}`,
|
|
2585
|
+
{
|
|
2586
|
+
method: "DELETE"
|
|
2587
|
+
}
|
|
2588
|
+
);
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
// src/client/knowledge-api.ts
|
|
2592
|
+
async function listExternalKnowledge(opts) {
|
|
2593
|
+
const request = createRequest();
|
|
2594
|
+
return request(getCustomerServiceUrl(), "/v1/knowledge/external", {
|
|
2595
|
+
method: "GET",
|
|
2596
|
+
query: {
|
|
2597
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2598
|
+
page: opts.page ?? 1,
|
|
2599
|
+
page_size: opts.pageSize ?? 20,
|
|
2600
|
+
suffix_type: "_common"
|
|
2601
|
+
}
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
async function listKnowledgeContents(opts) {
|
|
2605
|
+
const request = createRequest();
|
|
2606
|
+
return request(getAiApiUrl(), `/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents`, {
|
|
2607
|
+
method: "GET",
|
|
2608
|
+
query: {
|
|
2609
|
+
page_size: opts.pageSize ?? 20,
|
|
2610
|
+
need_total: opts.needTotal ?? true,
|
|
2611
|
+
direction: opts.direction ?? "down"
|
|
2612
|
+
}
|
|
2613
|
+
});
|
|
2614
|
+
}
|
|
2615
|
+
async function addKnowledgeContent(opts) {
|
|
2616
|
+
const request = createRequest();
|
|
2617
|
+
const ts = (opts.now ?? Date.now)();
|
|
2618
|
+
const identifier = `temp_${ts}`;
|
|
2619
|
+
const body = {
|
|
2620
|
+
operations: [
|
|
2621
|
+
{
|
|
2622
|
+
action: "add",
|
|
2623
|
+
original_identifier: opts.afterChunkId ?? "0",
|
|
2624
|
+
identifier
|
|
2625
|
+
}
|
|
2626
|
+
],
|
|
2627
|
+
content_updates: { [identifier]: opts.content },
|
|
2628
|
+
keywords_updates: { [identifier]: opts.keywords ?? [] },
|
|
2629
|
+
extra_info_updates: { [identifier]: { chunk_status: "done" } }
|
|
2630
|
+
};
|
|
2631
|
+
return request(
|
|
2632
|
+
getAiApiUrl(),
|
|
2633
|
+
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents/perform-operations`,
|
|
2634
|
+
{
|
|
2635
|
+
method: "POST",
|
|
2636
|
+
body
|
|
2637
|
+
}
|
|
2638
|
+
);
|
|
2639
|
+
}
|
|
2640
|
+
async function updateKnowledgeContent(opts) {
|
|
2641
|
+
const request = createRequest();
|
|
2642
|
+
const operation = {
|
|
2643
|
+
action: "update",
|
|
2644
|
+
identifier: opts.chunkId,
|
|
2645
|
+
enable: opts.enable
|
|
2646
|
+
};
|
|
2647
|
+
const contentUpdates = opts.content !== void 0 ? { [opts.chunkId]: opts.content } : {};
|
|
2648
|
+
const keywordsUpdates = opts.keywords !== void 0 ? { [opts.chunkId]: opts.keywords } : {};
|
|
2649
|
+
const extraInfoUpdates = opts.content !== void 0 || opts.keywords !== void 0 ? { [opts.chunkId]: { chunk_status: "done" } } : {};
|
|
2650
|
+
const body = {
|
|
2651
|
+
operations: [operation],
|
|
2652
|
+
content_updates: contentUpdates,
|
|
2653
|
+
keywords_updates: keywordsUpdates,
|
|
2654
|
+
extra_info_updates: extraInfoUpdates
|
|
2655
|
+
};
|
|
2656
|
+
return request(
|
|
2657
|
+
getAiApiUrl(),
|
|
2658
|
+
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents/perform-operations`,
|
|
2659
|
+
{
|
|
2660
|
+
method: "POST",
|
|
2661
|
+
body
|
|
2662
|
+
}
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
async function findKnowledgeChunk(opts) {
|
|
2666
|
+
const result = await listKnowledgeContents({
|
|
2667
|
+
knowledgeId: opts.knowledgeId,
|
|
2668
|
+
pageSize: opts.pageSize ?? 500,
|
|
2669
|
+
needTotal: true,
|
|
2670
|
+
direction: "down"
|
|
2671
|
+
});
|
|
2672
|
+
return result.contents?.find((c) => c.chunk_id === opts.chunkId);
|
|
2673
|
+
}
|
|
2674
|
+
async function deleteKnowledgeContent(opts) {
|
|
2675
|
+
const request = createRequest();
|
|
2676
|
+
const body = {
|
|
2677
|
+
operations: [{ action: "delete", identifier: opts.chunkId }],
|
|
2678
|
+
content_updates: {},
|
|
2679
|
+
keywords_updates: {},
|
|
2680
|
+
extra_info_updates: {}
|
|
2681
|
+
};
|
|
2682
|
+
return request(
|
|
2683
|
+
getAiApiUrl(),
|
|
2684
|
+
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents/perform-operations`,
|
|
2685
|
+
{
|
|
2686
|
+
method: "POST",
|
|
2687
|
+
body
|
|
2688
|
+
}
|
|
2689
|
+
);
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
// src/client/product-knowledge-binding-api.ts
|
|
2693
|
+
var PATH_PREFIX2 = "/v1/knowledge/product-bindings";
|
|
2694
|
+
async function listProductKnowledgeBindings(opts) {
|
|
2695
|
+
const request = createRequest();
|
|
2696
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX2, {
|
|
2697
|
+
method: "GET",
|
|
2698
|
+
query: {
|
|
2699
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2700
|
+
product_id: opts.productId,
|
|
2701
|
+
knowledge_type: opts.knowledgeType,
|
|
2702
|
+
file_id: opts.fileId
|
|
2703
|
+
}
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2706
|
+
async function replaceProductKnowledgeBindingsByProduct(opts) {
|
|
2707
|
+
const request = createRequest();
|
|
2708
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX2}/by-product`, {
|
|
2709
|
+
method: "PUT",
|
|
2710
|
+
body: {
|
|
2711
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2712
|
+
product_id: opts.productId,
|
|
2713
|
+
bindings: opts.bindings
|
|
2714
|
+
}
|
|
2715
|
+
});
|
|
2039
2716
|
}
|
|
2040
|
-
async function
|
|
2717
|
+
async function replaceProductKnowledgeBindingsByFile(opts) {
|
|
2041
2718
|
const request = createRequest();
|
|
2042
|
-
return request(
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
}
|
|
2719
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX2}/by-file`, {
|
|
2720
|
+
method: "PUT",
|
|
2721
|
+
body: {
|
|
2722
|
+
customer_agent_config_id: opts.agentConfigId,
|
|
2723
|
+
knowledge_type: opts.knowledgeType,
|
|
2724
|
+
file_id: opts.fileId,
|
|
2725
|
+
file_name: opts.fileName,
|
|
2726
|
+
partition_id: opts.partitionId,
|
|
2727
|
+
partition_name: opts.partitionName,
|
|
2728
|
+
products: opts.productIds.map((product_id) => ({ product_id }))
|
|
2053
2729
|
}
|
|
2054
|
-
);
|
|
2730
|
+
});
|
|
2055
2731
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
{
|
|
2062
|
-
|
|
2732
|
+
|
|
2733
|
+
// src/commands/product-knowledge-binding.ts
|
|
2734
|
+
function parsePositiveInt(value, fieldName) {
|
|
2735
|
+
const n = Number(value);
|
|
2736
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
2737
|
+
throw new Error(`${fieldName} \u5FC5\u987B\u4E3A\u6B63\u6574\u6570`);
|
|
2738
|
+
}
|
|
2739
|
+
return n;
|
|
2740
|
+
}
|
|
2741
|
+
function parseKnowledgeType(value) {
|
|
2742
|
+
if (value === "qa" || value === "common") return value;
|
|
2743
|
+
throw new Error("--type \u4EC5\u63A5\u53D7 qa | common");
|
|
2744
|
+
}
|
|
2745
|
+
function dedupeStrings(values) {
|
|
2746
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2747
|
+
const result = [];
|
|
2748
|
+
for (const value of values) {
|
|
2749
|
+
const trimmed = String(value || "").trim();
|
|
2750
|
+
if (!trimmed || seen.has(trimmed)) continue;
|
|
2751
|
+
seen.add(trimmed);
|
|
2752
|
+
result.push(trimmed);
|
|
2753
|
+
}
|
|
2754
|
+
return result;
|
|
2755
|
+
}
|
|
2756
|
+
function bindingKey(item) {
|
|
2757
|
+
return `${item.knowledge_type}:${item.file_id}`;
|
|
2758
|
+
}
|
|
2759
|
+
function toBindingInput(item) {
|
|
2760
|
+
return {
|
|
2761
|
+
knowledge_type: item.knowledge_type,
|
|
2762
|
+
file_id: parsePositiveInt(item.file_id, "file_id"),
|
|
2763
|
+
file_name: item.file_name ?? null,
|
|
2764
|
+
partition_id: parsePositiveInt(item.partition_id, "partition_id"),
|
|
2765
|
+
partition_name: item.partition_name ?? null
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
function normalizeBindingInput(value) {
|
|
2769
|
+
if (!value || typeof value !== "object") {
|
|
2770
|
+
throw new Error("bindings \u6BCF\u9879\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
2771
|
+
}
|
|
2772
|
+
const item = value;
|
|
2773
|
+
return {
|
|
2774
|
+
knowledge_type: parseKnowledgeType(String(item.knowledge_type ?? "")),
|
|
2775
|
+
file_id: parsePositiveInt(item.file_id, "file_id"),
|
|
2776
|
+
file_name: item.file_name ?? null,
|
|
2777
|
+
partition_id: parsePositiveInt(item.partition_id, "partition_id"),
|
|
2778
|
+
partition_name: item.partition_name ?? null
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2781
|
+
function parseBindingsOption(raw) {
|
|
2782
|
+
const parsed = parseDataOption(raw);
|
|
2783
|
+
if (!Array.isArray(parsed)) {
|
|
2784
|
+
throw new Error("--bindings \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
2785
|
+
}
|
|
2786
|
+
return parsed.map(normalizeBindingInput);
|
|
2787
|
+
}
|
|
2788
|
+
function fileIdOf(item) {
|
|
2789
|
+
return parsePositiveInt(item.knowledge_id ?? item.file_id, "file_id");
|
|
2790
|
+
}
|
|
2791
|
+
function partitionIdOf(item) {
|
|
2792
|
+
return parsePositiveInt(item.partition_id, "partition_id");
|
|
2793
|
+
}
|
|
2794
|
+
function failWithMessage(message) {
|
|
2795
|
+
outputError(1, message);
|
|
2796
|
+
process.exit(1);
|
|
2797
|
+
}
|
|
2798
|
+
async function listFilesByType(knowledgeType, agentConfigId) {
|
|
2799
|
+
const result = knowledgeType === "qa" ? await listFaqFiles({ agentConfigId, page: 1, pageSize: 100 }) : await listExternalKnowledge({ agentConfigId, page: 1, pageSize: 100 });
|
|
2800
|
+
return result.items ?? [];
|
|
2801
|
+
}
|
|
2802
|
+
async function resolveFile(opts) {
|
|
2803
|
+
if (opts.file && (opts.fileId || opts.partitionId)) {
|
|
2804
|
+
throw new Error("--file \u4E0E --file-id/--partition-id \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
2805
|
+
}
|
|
2806
|
+
if (opts.file) {
|
|
2807
|
+
const files = await listFilesByType(opts.knowledgeType, opts.agentConfigId);
|
|
2808
|
+
const matched = files.filter((item2) => item2.file_name === opts.file);
|
|
2809
|
+
if (matched.length === 0) {
|
|
2810
|
+
failWithMessage(`\u672A\u627E\u5230\u77E5\u8BC6\u5E93\u6587\u4EF6: ${opts.file}`);
|
|
2063
2811
|
}
|
|
2064
|
-
|
|
2812
|
+
if (matched.length > 1) {
|
|
2813
|
+
failWithMessage(`\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\u4E0D\u552F\u4E00: ${opts.file}\uFF0C\u8BF7\u6539\u7528 --file-id/--partition-id`);
|
|
2814
|
+
}
|
|
2815
|
+
const item = matched[0];
|
|
2816
|
+
return {
|
|
2817
|
+
fileId: fileIdOf(item),
|
|
2818
|
+
fileName: item.file_name ?? opts.file,
|
|
2819
|
+
partitionId: partitionIdOf(item),
|
|
2820
|
+
partitionName: item.partition_name ?? null
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
if (!opts.fileId || !opts.partitionId) {
|
|
2824
|
+
throw new Error("\u8BF7\u63D0\u4F9B --file \u6216\u540C\u65F6\u63D0\u4F9B --file-id \u4E0E --partition-id");
|
|
2825
|
+
}
|
|
2826
|
+
return {
|
|
2827
|
+
fileId: parsePositiveInt(opts.fileId, "file_id"),
|
|
2828
|
+
fileName: opts.fileName,
|
|
2829
|
+
partitionId: parsePositiveInt(opts.partitionId, "partition_id"),
|
|
2830
|
+
partitionName: opts.partitionName
|
|
2831
|
+
};
|
|
2832
|
+
}
|
|
2833
|
+
async function replaceProductBindings(opts) {
|
|
2834
|
+
return replaceProductKnowledgeBindingsByProduct({
|
|
2835
|
+
agentConfigId: opts.agentConfigId,
|
|
2836
|
+
productId: opts.productId,
|
|
2837
|
+
bindings: opts.bindings
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
async function getProductBindingInputs(opts) {
|
|
2841
|
+
const current = await listProductKnowledgeBindings({
|
|
2842
|
+
agentConfigId: opts.agentConfigId,
|
|
2843
|
+
productId: opts.productId
|
|
2844
|
+
});
|
|
2845
|
+
return (current.items ?? []).map(toBindingInput);
|
|
2846
|
+
}
|
|
2847
|
+
async function replaceFileBindings(opts) {
|
|
2848
|
+
return replaceProductKnowledgeBindingsByFile({
|
|
2849
|
+
agentConfigId: opts.agentConfigId,
|
|
2850
|
+
knowledgeType: opts.knowledgeType,
|
|
2851
|
+
fileId: opts.file.fileId,
|
|
2852
|
+
fileName: opts.file.fileName,
|
|
2853
|
+
partitionId: opts.file.partitionId,
|
|
2854
|
+
partitionName: opts.file.partitionName,
|
|
2855
|
+
productIds: opts.productIds
|
|
2856
|
+
});
|
|
2857
|
+
}
|
|
2858
|
+
async function getFileProductIds(opts) {
|
|
2859
|
+
const current = await listProductKnowledgeBindings({
|
|
2860
|
+
agentConfigId: opts.agentConfigId,
|
|
2861
|
+
knowledgeType: opts.knowledgeType,
|
|
2862
|
+
fileId: opts.fileId
|
|
2863
|
+
});
|
|
2864
|
+
return dedupeStrings((current.items ?? []).map((item) => item.product_id));
|
|
2865
|
+
}
|
|
2866
|
+
function handleError(err) {
|
|
2867
|
+
reportCaughtError(err);
|
|
2868
|
+
process.exit(toExitCode(err));
|
|
2869
|
+
}
|
|
2870
|
+
function registerProductRelatedKnowledgeCommand(product, program2) {
|
|
2871
|
+
const related = product.command("related-knowledge").description("\u5546\u54C1\u8BE6\u60C5\u5173\u8054\u77E5\u8BC6\u5E93\u6587\u4EF6\u7BA1\u7406\uFF1Alist / add / remove / set");
|
|
2872
|
+
related.command("list").description("\u5217\u51FA\u6307\u5B9A\u5546\u54C1\u7ED1\u5B9A\u7684 QA / \u6269\u5C55\u77E5\u8BC6\u5E93\u6587\u4EF6").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").requiredOption("--product-id <product_id>", "\u5546\u54C1 ID").action(async (opts) => {
|
|
2873
|
+
try {
|
|
2874
|
+
const data = await listProductKnowledgeBindings({
|
|
2875
|
+
agentConfigId: opts.agent,
|
|
2876
|
+
productId: opts.productId
|
|
2877
|
+
});
|
|
2878
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2879
|
+
} catch (err) {
|
|
2880
|
+
handleError(err);
|
|
2881
|
+
}
|
|
2882
|
+
});
|
|
2883
|
+
related.command("add").description(
|
|
2884
|
+
"\u7ED9\u5546\u54C1\u8FFD\u52A0\u4E00\u4E2A\u5173\u8054\u77E5\u8BC6\u5E93\u6587\u4EF6\u3002\u652F\u6301 --file \u7CBE\u786E\u5339\u914D\uFF0C\u6216\u663E\u5F0F\u4F20 --file-id + --partition-id"
|
|
2885
|
+
).requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").requiredOption("--product-id <product_id>", "\u5546\u54C1 ID").requiredOption("--type <qa|common>", "\u77E5\u8BC6\u5E93\u7C7B\u578B\uFF1Aqa \u6216 common").option("--file <exact_name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\uFF0C\u7CBE\u786E\u5339\u914D").option("--file-id <id>", "\u77E5\u8BC6\u5E93\u6587\u4EF6 ID").option("--file-name <name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\u5FEB\u7167").option("--partition-id <id>", "\u77E5\u8BC6\u5E93\u5206\u533A ID").option("--partition-name <name>", "\u77E5\u8BC6\u5E93\u5206\u533A\u540D\u5FEB\u7167").action(async (opts) => {
|
|
2886
|
+
try {
|
|
2887
|
+
const knowledgeType = parseKnowledgeType(opts.type);
|
|
2888
|
+
const file = await resolveFile({ ...opts, agentConfigId: opts.agent, knowledgeType });
|
|
2889
|
+
const current = await getProductBindingInputs({
|
|
2890
|
+
agentConfigId: opts.agent,
|
|
2891
|
+
productId: opts.productId
|
|
2892
|
+
});
|
|
2893
|
+
const byKey = new Map(current.map((item) => [bindingKey(item), item]));
|
|
2894
|
+
byKey.set(bindingKey({ knowledge_type: knowledgeType, file_id: file.fileId }), {
|
|
2895
|
+
knowledge_type: knowledgeType,
|
|
2896
|
+
file_id: file.fileId,
|
|
2897
|
+
file_name: file.fileName ?? null,
|
|
2898
|
+
partition_id: file.partitionId,
|
|
2899
|
+
partition_name: file.partitionName ?? null
|
|
2900
|
+
});
|
|
2901
|
+
const data = await replaceProductBindings({
|
|
2902
|
+
agentConfigId: opts.agent,
|
|
2903
|
+
productId: opts.productId,
|
|
2904
|
+
bindings: Array.from(byKey.values())
|
|
2905
|
+
});
|
|
2906
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2907
|
+
} catch (err) {
|
|
2908
|
+
handleError(err);
|
|
2909
|
+
}
|
|
2910
|
+
});
|
|
2911
|
+
related.command("remove").description("\u79FB\u9664\u5546\u54C1\u7ED1\u5B9A\u7684\u4E00\u4E2A\u77E5\u8BC6\u5E93\u6587\u4EF6\uFF1B\u76EE\u6807\u4E0D\u5B58\u5728\u65F6\u4FDD\u6301\u5E42\u7B49\u6210\u529F").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").requiredOption("--product-id <product_id>", "\u5546\u54C1 ID").requiredOption("--type <qa|common>", "\u77E5\u8BC6\u5E93\u7C7B\u578B\uFF1Aqa \u6216 common").requiredOption("--file-id <id>", "\u77E5\u8BC6\u5E93\u6587\u4EF6 ID").action(async (opts) => {
|
|
2912
|
+
try {
|
|
2913
|
+
const knowledgeType = parseKnowledgeType(opts.type);
|
|
2914
|
+
const fileId = parsePositiveInt(opts.fileId, "file_id");
|
|
2915
|
+
const current = await getProductBindingInputs({
|
|
2916
|
+
agentConfigId: opts.agent,
|
|
2917
|
+
productId: opts.productId
|
|
2918
|
+
});
|
|
2919
|
+
const next = current.filter(
|
|
2920
|
+
(item) => !(item.knowledge_type === knowledgeType && item.file_id === fileId)
|
|
2921
|
+
);
|
|
2922
|
+
const data = await replaceProductBindings({
|
|
2923
|
+
agentConfigId: opts.agent,
|
|
2924
|
+
productId: opts.productId,
|
|
2925
|
+
bindings: next
|
|
2926
|
+
});
|
|
2927
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2928
|
+
} catch (err) {
|
|
2929
|
+
handleError(err);
|
|
2930
|
+
}
|
|
2931
|
+
});
|
|
2932
|
+
related.command("set").description("\u8986\u76D6\u6307\u5B9A\u5546\u54C1\u7684\u5168\u90E8\u5173\u8054\u77E5\u8BC6\u5E93\u6587\u4EF6\u3002--bindings \u652F\u6301 JSON \u6216 @file").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").requiredOption("--product-id <product_id>", "\u5546\u54C1 ID").requiredOption("--bindings <json>", "\u7ED1\u5B9A\u6570\u7EC4 JSON \u6216 @\u6587\u4EF6\u8DEF\u5F84").action(async (opts) => {
|
|
2933
|
+
try {
|
|
2934
|
+
const bindings = parseBindingsOption(opts.bindings);
|
|
2935
|
+
const data = await replaceProductBindings({
|
|
2936
|
+
agentConfigId: opts.agent,
|
|
2937
|
+
productId: opts.productId,
|
|
2938
|
+
bindings
|
|
2939
|
+
});
|
|
2940
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2941
|
+
} catch (err) {
|
|
2942
|
+
handleError(err);
|
|
2943
|
+
}
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
function registerKnowledgeFileBindProductsCommand(parent, program2, kind) {
|
|
2947
|
+
const knowledgeType = kind === "faq" ? "qa" : "common";
|
|
2948
|
+
const bind = parent.command("bind-products").description("\u77E5\u8BC6\u5E93\u6587\u4EF6\u7ED1\u5B9A\u5546\u54C1\u7BA1\u7406\uFF1Alist / add / remove / set");
|
|
2949
|
+
function addFileOptions(command) {
|
|
2950
|
+
return command.requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").option("--file <exact_name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\uFF0C\u7CBE\u786E\u5339\u914D").option("--file-id <id>", "\u77E5\u8BC6\u5E93\u6587\u4EF6 ID").option("--file-name <name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\u5FEB\u7167").option("--partition-id <id>", "\u77E5\u8BC6\u5E93\u5206\u533A ID").option("--partition-name <name>", "\u77E5\u8BC6\u5E93\u5206\u533A\u540D\u5FEB\u7167");
|
|
2951
|
+
}
|
|
2952
|
+
bind.command("list").description("\u5217\u51FA\u6307\u5B9A\u77E5\u8BC6\u5E93\u6587\u4EF6\u7ED1\u5B9A\u7684\u5546\u54C1").requiredOption("--agent <config_id>", "Agent \u914D\u7F6E ID").option("--file <exact_name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\uFF0C\u7CBE\u786E\u5339\u914D").option("--file-id <id>", "\u77E5\u8BC6\u5E93\u6587\u4EF6 ID").option("--file-name <name>", "\u77E5\u8BC6\u5E93\u6587\u4EF6\u540D\u5FEB\u7167").option("--partition-id <id>", "\u77E5\u8BC6\u5E93\u5206\u533A ID").option("--partition-name <name>", "\u77E5\u8BC6\u5E93\u5206\u533A\u540D\u5FEB\u7167").action(async (opts) => {
|
|
2953
|
+
try {
|
|
2954
|
+
const file = await resolveFile({ ...opts, agentConfigId: opts.agent, knowledgeType });
|
|
2955
|
+
const data = await listProductKnowledgeBindings({
|
|
2956
|
+
agentConfigId: opts.agent,
|
|
2957
|
+
knowledgeType,
|
|
2958
|
+
fileId: file.fileId
|
|
2959
|
+
});
|
|
2960
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2961
|
+
} catch (err) {
|
|
2962
|
+
handleError(err);
|
|
2963
|
+
}
|
|
2964
|
+
});
|
|
2965
|
+
addFileOptions(
|
|
2966
|
+
bind.command("add").description("\u7ED9\u77E5\u8BC6\u5E93\u6587\u4EF6\u8FFD\u52A0\u7ED1\u5B9A\u5546\u54C1\uFF1B\u5DF2\u7ED1\u5B9A\u5546\u54C1\u4F1A\u81EA\u52A8\u53BB\u91CD").requiredOption("--product-id <id...>", "\u5546\u54C1 ID\uFF0C\u53EF\u4F20\u591A\u4E2A")
|
|
2967
|
+
).action(async (opts) => {
|
|
2968
|
+
try {
|
|
2969
|
+
const file = await resolveFile({ ...opts, agentConfigId: opts.agent, knowledgeType });
|
|
2970
|
+
const currentIds = await getFileProductIds({
|
|
2971
|
+
agentConfigId: opts.agent,
|
|
2972
|
+
knowledgeType,
|
|
2973
|
+
fileId: file.fileId
|
|
2974
|
+
});
|
|
2975
|
+
const productIds = dedupeStrings([...currentIds, ...opts.productId ?? []]);
|
|
2976
|
+
const data = await replaceFileBindings({
|
|
2977
|
+
agentConfigId: opts.agent,
|
|
2978
|
+
knowledgeType,
|
|
2979
|
+
file,
|
|
2980
|
+
productIds
|
|
2981
|
+
});
|
|
2982
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
2983
|
+
} catch (err) {
|
|
2984
|
+
handleError(err);
|
|
2985
|
+
}
|
|
2986
|
+
});
|
|
2987
|
+
addFileOptions(
|
|
2988
|
+
bind.command("remove").description("\u4ECE\u77E5\u8BC6\u5E93\u6587\u4EF6\u79FB\u9664\u7ED1\u5B9A\u5546\u54C1\uFF1B\u76EE\u6807\u4E0D\u5B58\u5728\u65F6\u4FDD\u6301\u5E42\u7B49\u6210\u529F").requiredOption("--product-id <id...>", "\u5546\u54C1 ID\uFF0C\u53EF\u4F20\u591A\u4E2A")
|
|
2989
|
+
).action(async (opts) => {
|
|
2990
|
+
try {
|
|
2991
|
+
const file = await resolveFile({ ...opts, agentConfigId: opts.agent, knowledgeType });
|
|
2992
|
+
const removing = new Set(dedupeStrings(opts.productId ?? []));
|
|
2993
|
+
const currentIds = await getFileProductIds({
|
|
2994
|
+
agentConfigId: opts.agent,
|
|
2995
|
+
knowledgeType,
|
|
2996
|
+
fileId: file.fileId
|
|
2997
|
+
});
|
|
2998
|
+
const data = await replaceFileBindings({
|
|
2999
|
+
agentConfigId: opts.agent,
|
|
3000
|
+
knowledgeType,
|
|
3001
|
+
file,
|
|
3002
|
+
productIds: currentIds.filter((productId) => !removing.has(productId))
|
|
3003
|
+
});
|
|
3004
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
3005
|
+
} catch (err) {
|
|
3006
|
+
handleError(err);
|
|
3007
|
+
}
|
|
3008
|
+
});
|
|
3009
|
+
addFileOptions(
|
|
3010
|
+
bind.command("set").description("\u8986\u76D6\u77E5\u8BC6\u5E93\u6587\u4EF6\u7ED1\u5B9A\u7684\u5168\u90E8\u5546\u54C1").requiredOption("--product-id <id...>", "\u5546\u54C1 ID\uFF0C\u53EF\u4F20\u591A\u4E2A")
|
|
3011
|
+
).action(async (opts) => {
|
|
3012
|
+
try {
|
|
3013
|
+
const file = await resolveFile({ ...opts, agentConfigId: opts.agent, knowledgeType });
|
|
3014
|
+
const data = await replaceFileBindings({
|
|
3015
|
+
agentConfigId: opts.agent,
|
|
3016
|
+
knowledgeType,
|
|
3017
|
+
file,
|
|
3018
|
+
productIds: dedupeStrings(opts.productId ?? [])
|
|
3019
|
+
});
|
|
3020
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
3021
|
+
} catch (err) {
|
|
3022
|
+
handleError(err);
|
|
3023
|
+
}
|
|
3024
|
+
});
|
|
2065
3025
|
}
|
|
2066
3026
|
|
|
2067
3027
|
// src/commands/faq.ts
|
|
@@ -2196,6 +3156,7 @@ function registerFaqCommand(program2) {
|
|
|
2196
3156
|
process.exit(toExitCode(err));
|
|
2197
3157
|
}
|
|
2198
3158
|
});
|
|
3159
|
+
registerKnowledgeFileBindProductsCommand(faq, program2, "faq");
|
|
2199
3160
|
}
|
|
2200
3161
|
|
|
2201
3162
|
// src/client/issue-api.ts
|
|
@@ -2261,11 +3222,9 @@ async function getIssueStats(opts) {
|
|
|
2261
3222
|
const query = {};
|
|
2262
3223
|
if (opts.dateStart) query.date_start = opts.dateStart;
|
|
2263
3224
|
if (opts.dateEnd) query.date_end = opts.dateEnd;
|
|
2264
|
-
const result = await request(
|
|
3225
|
+
const result = await request(getCsAdminUrl(), "/api/issues/stats", {
|
|
2265
3226
|
method: "GET",
|
|
2266
|
-
query
|
|
2267
|
-
headers: buildCookieHeaders(),
|
|
2268
|
-
skipAuth: true
|
|
3227
|
+
query
|
|
2269
3228
|
});
|
|
2270
3229
|
return result.data ?? result;
|
|
2271
3230
|
}
|
|
@@ -2926,148 +3885,45 @@ function registerIssueCommand(program2) {
|
|
|
2926
3885
|
try {
|
|
2927
3886
|
const data = await listIssueComments(issueId);
|
|
2928
3887
|
formatOutput({ success: true, data }, program2.opts().table);
|
|
2929
|
-
} catch (err) {
|
|
2930
|
-
reportCaughtError(err);
|
|
2931
|
-
process.exit(toExitCode(err));
|
|
2932
|
-
}
|
|
2933
|
-
});
|
|
2934
|
-
comment.command("add").description("\u6DFB\u52A0\u8BC4\u8BBA").argument("<issue_id>", "\u5DE5\u5355 ID").requiredOption("--content <text>", "\u8BC4\u8BBA\u5185\u5BB9").action(async (issueId, opts) => {
|
|
2935
|
-
try {
|
|
2936
|
-
const data = await addIssueComment(issueId, opts.content);
|
|
2937
|
-
formatOutput({ success: true, data }, program2.opts().table);
|
|
2938
|
-
} catch (err) {
|
|
2939
|
-
reportCaughtError(err);
|
|
2940
|
-
process.exit(toExitCode(err));
|
|
2941
|
-
}
|
|
2942
|
-
});
|
|
2943
|
-
}
|
|
2944
|
-
async function resolveSessionsForIssues(issues, workspaceId) {
|
|
2945
|
-
const out = [];
|
|
2946
|
-
for (let i = 0; i < issues.length; i++) {
|
|
2947
|
-
const it = issues[i];
|
|
2948
|
-
let conversationId;
|
|
2949
|
-
if (it.conversation_id) {
|
|
2950
|
-
conversationId = it.conversation_id;
|
|
2951
|
-
} else if (it.user_name) {
|
|
2952
|
-
try {
|
|
2953
|
-
conversationId = await resolveSession({ userName: it.user_name, workspaceId });
|
|
2954
|
-
} catch (err) {
|
|
2955
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2956
|
-
throw new Error(`issues[${i}] \u53CD\u67E5\u4F1A\u8BDD\u5931\u8D25\uFF1A${msg}`);
|
|
2957
|
-
}
|
|
2958
|
-
} else {
|
|
2959
|
-
throw new Error(`issues[${i}] \u65E2\u65E0 conversation_id \u4E5F\u65E0 user_name`);
|
|
2960
|
-
}
|
|
2961
|
-
out.push({ issue: it, conversationId });
|
|
2962
|
-
}
|
|
2963
|
-
return out;
|
|
2964
|
-
}
|
|
2965
|
-
|
|
2966
|
-
// src/commands/knowledge.ts
|
|
2967
|
-
import fs8 from "fs";
|
|
2968
|
-
|
|
2969
|
-
// src/client/knowledge-api.ts
|
|
2970
|
-
async function listExternalKnowledge(opts) {
|
|
2971
|
-
const request = createRequest();
|
|
2972
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/external", {
|
|
2973
|
-
method: "GET",
|
|
2974
|
-
query: {
|
|
2975
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
2976
|
-
page: opts.page ?? 1,
|
|
2977
|
-
page_size: opts.pageSize ?? 20,
|
|
2978
|
-
suffix_type: "_common"
|
|
2979
|
-
}
|
|
2980
|
-
});
|
|
2981
|
-
}
|
|
2982
|
-
async function listKnowledgeContents(opts) {
|
|
2983
|
-
const request = createRequest();
|
|
2984
|
-
return request(getAiApiUrl(), `/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents`, {
|
|
2985
|
-
method: "GET",
|
|
2986
|
-
query: {
|
|
2987
|
-
page_size: opts.pageSize ?? 20,
|
|
2988
|
-
need_total: opts.needTotal ?? true,
|
|
2989
|
-
direction: opts.direction ?? "down"
|
|
2990
|
-
}
|
|
2991
|
-
});
|
|
2992
|
-
}
|
|
2993
|
-
async function addKnowledgeContent(opts) {
|
|
2994
|
-
const request = createRequest();
|
|
2995
|
-
const ts = (opts.now ?? Date.now)();
|
|
2996
|
-
const identifier = `temp_${ts}`;
|
|
2997
|
-
const body = {
|
|
2998
|
-
operations: [
|
|
2999
|
-
{
|
|
3000
|
-
action: "add",
|
|
3001
|
-
original_identifier: opts.afterChunkId ?? "0",
|
|
3002
|
-
identifier
|
|
3003
|
-
}
|
|
3004
|
-
],
|
|
3005
|
-
content_updates: { [identifier]: opts.content },
|
|
3006
|
-
keywords_updates: { [identifier]: opts.keywords ?? [] },
|
|
3007
|
-
extra_info_updates: { [identifier]: { chunk_status: "done" } }
|
|
3008
|
-
};
|
|
3009
|
-
return request(
|
|
3010
|
-
getAiApiUrl(),
|
|
3011
|
-
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents/perform-operations`,
|
|
3012
|
-
{
|
|
3013
|
-
method: "POST",
|
|
3014
|
-
body
|
|
3015
|
-
}
|
|
3016
|
-
);
|
|
3017
|
-
}
|
|
3018
|
-
async function updateKnowledgeContent(opts) {
|
|
3019
|
-
const request = createRequest();
|
|
3020
|
-
const operation = {
|
|
3021
|
-
action: "update",
|
|
3022
|
-
identifier: opts.chunkId,
|
|
3023
|
-
enable: opts.enable
|
|
3024
|
-
};
|
|
3025
|
-
const contentUpdates = opts.content !== void 0 ? { [opts.chunkId]: opts.content } : {};
|
|
3026
|
-
const keywordsUpdates = opts.keywords !== void 0 ? { [opts.chunkId]: opts.keywords } : {};
|
|
3027
|
-
const extraInfoUpdates = opts.content !== void 0 || opts.keywords !== void 0 ? { [opts.chunkId]: { chunk_status: "done" } } : {};
|
|
3028
|
-
const body = {
|
|
3029
|
-
operations: [operation],
|
|
3030
|
-
content_updates: contentUpdates,
|
|
3031
|
-
keywords_updates: keywordsUpdates,
|
|
3032
|
-
extra_info_updates: extraInfoUpdates
|
|
3033
|
-
};
|
|
3034
|
-
return request(
|
|
3035
|
-
getAiApiUrl(),
|
|
3036
|
-
`/mebsuta/api/v1/dataset/${opts.knowledgeId}/contents/perform-operations`,
|
|
3037
|
-
{
|
|
3038
|
-
method: "POST",
|
|
3039
|
-
body
|
|
3888
|
+
} catch (err) {
|
|
3889
|
+
reportCaughtError(err);
|
|
3890
|
+
process.exit(toExitCode(err));
|
|
3891
|
+
}
|
|
3892
|
+
});
|
|
3893
|
+
comment.command("add").description("\u6DFB\u52A0\u8BC4\u8BBA").argument("<issue_id>", "\u5DE5\u5355 ID").requiredOption("--content <text>", "\u8BC4\u8BBA\u5185\u5BB9").action(async (issueId, opts) => {
|
|
3894
|
+
try {
|
|
3895
|
+
const data = await addIssueComment(issueId, opts.content);
|
|
3896
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
3897
|
+
} catch (err) {
|
|
3898
|
+
reportCaughtError(err);
|
|
3899
|
+
process.exit(toExitCode(err));
|
|
3040
3900
|
}
|
|
3041
|
-
);
|
|
3042
|
-
}
|
|
3043
|
-
async function findKnowledgeChunk(opts) {
|
|
3044
|
-
const result = await listKnowledgeContents({
|
|
3045
|
-
knowledgeId: opts.knowledgeId,
|
|
3046
|
-
pageSize: opts.pageSize ?? 500,
|
|
3047
|
-
needTotal: true,
|
|
3048
|
-
direction: "down"
|
|
3049
3901
|
});
|
|
3050
|
-
return result.contents?.find((c) => c.chunk_id === opts.chunkId);
|
|
3051
3902
|
}
|
|
3052
|
-
async function
|
|
3053
|
-
const
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3903
|
+
async function resolveSessionsForIssues(issues, workspaceId) {
|
|
3904
|
+
const out = [];
|
|
3905
|
+
for (let i = 0; i < issues.length; i++) {
|
|
3906
|
+
const it = issues[i];
|
|
3907
|
+
let conversationId;
|
|
3908
|
+
if (it.conversation_id) {
|
|
3909
|
+
conversationId = it.conversation_id;
|
|
3910
|
+
} else if (it.user_name) {
|
|
3911
|
+
try {
|
|
3912
|
+
conversationId = await resolveSession({ userName: it.user_name, workspaceId });
|
|
3913
|
+
} catch (err) {
|
|
3914
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3915
|
+
throw new Error(`issues[${i}] \u53CD\u67E5\u4F1A\u8BDD\u5931\u8D25\uFF1A${msg}`);
|
|
3916
|
+
}
|
|
3917
|
+
} else {
|
|
3918
|
+
throw new Error(`issues[${i}] \u65E2\u65E0 conversation_id \u4E5F\u65E0 user_name`);
|
|
3066
3919
|
}
|
|
3067
|
-
|
|
3920
|
+
out.push({ issue: it, conversationId });
|
|
3921
|
+
}
|
|
3922
|
+
return out;
|
|
3068
3923
|
}
|
|
3069
3924
|
|
|
3070
3925
|
// src/commands/knowledge.ts
|
|
3926
|
+
import fs8 from "fs";
|
|
3071
3927
|
function readContentArg(value) {
|
|
3072
3928
|
if (value.startsWith("@")) {
|
|
3073
3929
|
return fs8.readFileSync(value.slice(1), "utf-8");
|
|
@@ -3203,6 +4059,7 @@ function registerKnowledgeCommand(program2) {
|
|
|
3203
4059
|
process.exit(toExitCode(err));
|
|
3204
4060
|
}
|
|
3205
4061
|
});
|
|
4062
|
+
registerKnowledgeFileBindProductsCommand(knowledge, program2, "common");
|
|
3206
4063
|
}
|
|
3207
4064
|
|
|
3208
4065
|
// src/client/monitor-api.ts
|
|
@@ -4136,7 +4993,7 @@ function registerOpsAgentCommand(program2) {
|
|
|
4136
4993
|
}
|
|
4137
4994
|
|
|
4138
4995
|
// src/client/operations-record-api.ts
|
|
4139
|
-
var
|
|
4996
|
+
var PATH_PREFIX3 = "/v1/agent_operations_records";
|
|
4140
4997
|
async function listOperationsRecords(opts) {
|
|
4141
4998
|
const request = createRequest();
|
|
4142
4999
|
const query = {};
|
|
@@ -4144,34 +5001,34 @@ async function listOperationsRecords(opts) {
|
|
|
4144
5001
|
if (opts.agentId) query.agent_id = opts.agentId;
|
|
4145
5002
|
if (opts.page) query.page = opts.page;
|
|
4146
5003
|
if (opts.pageSize) query.page_size = opts.pageSize;
|
|
4147
|
-
return request(getCustomerServiceUrl(),
|
|
5004
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX3, {
|
|
4148
5005
|
method: "GET",
|
|
4149
5006
|
query
|
|
4150
5007
|
});
|
|
4151
5008
|
}
|
|
4152
5009
|
async function getOperationsRecord(recordId) {
|
|
4153
5010
|
const request = createRequest();
|
|
4154
|
-
return request(getCustomerServiceUrl(), `${
|
|
5011
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX3}/${recordId}`, {
|
|
4155
5012
|
method: "GET"
|
|
4156
5013
|
});
|
|
4157
5014
|
}
|
|
4158
5015
|
async function createOperationsRecord(data) {
|
|
4159
5016
|
const request = createRequest();
|
|
4160
|
-
return request(getCustomerServiceUrl(),
|
|
5017
|
+
return request(getCustomerServiceUrl(), PATH_PREFIX3, {
|
|
4161
5018
|
method: "POST",
|
|
4162
5019
|
body: data
|
|
4163
5020
|
});
|
|
4164
5021
|
}
|
|
4165
5022
|
async function updateOperationsRecord(recordId, data) {
|
|
4166
5023
|
const request = createRequest();
|
|
4167
|
-
return request(getCustomerServiceUrl(), `${
|
|
5024
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX3}/${recordId}`, {
|
|
4168
5025
|
method: "PUT",
|
|
4169
5026
|
body: data
|
|
4170
5027
|
});
|
|
4171
5028
|
}
|
|
4172
5029
|
async function deleteOperationsRecord(recordId) {
|
|
4173
5030
|
const request = createRequest();
|
|
4174
|
-
return request(getCustomerServiceUrl(), `${
|
|
5031
|
+
return request(getCustomerServiceUrl(), `${PATH_PREFIX3}/${recordId}`, {
|
|
4175
5032
|
method: "DELETE"
|
|
4176
5033
|
});
|
|
4177
5034
|
}
|
|
@@ -4249,114 +5106,6 @@ function registerOperationsRecordCommand(program2) {
|
|
|
4249
5106
|
});
|
|
4250
5107
|
}
|
|
4251
5108
|
|
|
4252
|
-
// src/client/product-api.ts
|
|
4253
|
-
async function listProducts(opts) {
|
|
4254
|
-
const request = createRequest();
|
|
4255
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/products", {
|
|
4256
|
-
method: "GET",
|
|
4257
|
-
query: {
|
|
4258
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4259
|
-
search: opts.keyword,
|
|
4260
|
-
status: opts.status?.join(","),
|
|
4261
|
-
tags: opts.tags?.length ? JSON.stringify(opts.tags) : void 0,
|
|
4262
|
-
page: opts.page ?? 1,
|
|
4263
|
-
page_size: opts.pageSize ?? 20
|
|
4264
|
-
}
|
|
4265
|
-
});
|
|
4266
|
-
}
|
|
4267
|
-
async function getProductDetail(opts) {
|
|
4268
|
-
const request = createRequest();
|
|
4269
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/product/detail", {
|
|
4270
|
-
method: "GET",
|
|
4271
|
-
query: {
|
|
4272
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4273
|
-
db_id: opts.dbId,
|
|
4274
|
-
product_id: opts.productId
|
|
4275
|
-
}
|
|
4276
|
-
});
|
|
4277
|
-
}
|
|
4278
|
-
async function updateProduct(opts) {
|
|
4279
|
-
const request = createRequest();
|
|
4280
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/product/update", {
|
|
4281
|
-
method: "POST",
|
|
4282
|
-
body: {
|
|
4283
|
-
data_id: opts.dataId,
|
|
4284
|
-
knowledge_id: opts.knowledgeId,
|
|
4285
|
-
db_id: opts.dbId,
|
|
4286
|
-
update_dict: opts.updateDict
|
|
4287
|
-
}
|
|
4288
|
-
});
|
|
4289
|
-
}
|
|
4290
|
-
async function uploadProductByUrl(opts) {
|
|
4291
|
-
const request = createRequest();
|
|
4292
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/products/upload", {
|
|
4293
|
-
method: "POST",
|
|
4294
|
-
body: {
|
|
4295
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4296
|
-
source_type: opts.sourceType ?? "manual",
|
|
4297
|
-
identify: opts.identify ?? true,
|
|
4298
|
-
product_urls: opts.productUrls
|
|
4299
|
-
}
|
|
4300
|
-
});
|
|
4301
|
-
}
|
|
4302
|
-
async function uploadProductData(opts) {
|
|
4303
|
-
const request = createRequest();
|
|
4304
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/products/upload", {
|
|
4305
|
-
method: "POST",
|
|
4306
|
-
body: {
|
|
4307
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4308
|
-
source_type: opts.sourceType ?? "manual",
|
|
4309
|
-
identify: opts.identify ?? true,
|
|
4310
|
-
product_items: opts.productItems
|
|
4311
|
-
}
|
|
4312
|
-
});
|
|
4313
|
-
}
|
|
4314
|
-
async function updateSku(opts) {
|
|
4315
|
-
if (!opts.skuId && !opts.sku) {
|
|
4316
|
-
throw new Error("updateSku \u9700\u8981\u63D0\u4F9B sku \u6216 sku_id \u5176\u4E2D\u4E4B\u4E00");
|
|
4317
|
-
}
|
|
4318
|
-
const identifier = opts.skuId ? { sku_id: opts.skuId } : { sku: opts.sku };
|
|
4319
|
-
const request = createRequest();
|
|
4320
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/sku/update", {
|
|
4321
|
-
method: "POST",
|
|
4322
|
-
body: {
|
|
4323
|
-
...identifier,
|
|
4324
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4325
|
-
update_dict: opts.updateDict
|
|
4326
|
-
}
|
|
4327
|
-
});
|
|
4328
|
-
}
|
|
4329
|
-
async function syncTaobaoProducts(opts) {
|
|
4330
|
-
const request = createRequest();
|
|
4331
|
-
return request(getCustomerServiceUrl(), "/v1/authorized-shop/sync-taobao-products", {
|
|
4332
|
-
method: "POST",
|
|
4333
|
-
body: {
|
|
4334
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4335
|
-
skip_hash_check: opts.skipHashCheck ?? false,
|
|
4336
|
-
sync_type: opts.syncType ?? "full"
|
|
4337
|
-
}
|
|
4338
|
-
});
|
|
4339
|
-
}
|
|
4340
|
-
async function syncSingleTaobaoProduct(opts) {
|
|
4341
|
-
const request = createRequest();
|
|
4342
|
-
return request(getCustomerServiceUrl(), "/v1/authorized-shop/sync-single-product", {
|
|
4343
|
-
method: "POST",
|
|
4344
|
-
body: {
|
|
4345
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4346
|
-
product_id: opts.productId
|
|
4347
|
-
}
|
|
4348
|
-
});
|
|
4349
|
-
}
|
|
4350
|
-
async function identifyAllProducts(opts) {
|
|
4351
|
-
const request = createRequest();
|
|
4352
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/products/identify/all", {
|
|
4353
|
-
method: "POST",
|
|
4354
|
-
body: {
|
|
4355
|
-
customer_agent_config_id: opts.agentConfigId
|
|
4356
|
-
}
|
|
4357
|
-
});
|
|
4358
|
-
}
|
|
4359
|
-
|
|
4360
5109
|
// src/commands/product.ts
|
|
4361
5110
|
async function getDbId(agentConfigId) {
|
|
4362
5111
|
const agent = await getAgent(agentConfigId);
|
|
@@ -4366,12 +5115,20 @@ async function getDbId(agentConfigId) {
|
|
|
4366
5115
|
return agent.database_id;
|
|
4367
5116
|
}
|
|
4368
5117
|
async function findProduct(agentConfigId, productId) {
|
|
4369
|
-
const
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
5118
|
+
const pageSize = 100;
|
|
5119
|
+
for (let page = 1; ; page += 1) {
|
|
5120
|
+
const result = await listProducts({ agentConfigId, page, pageSize });
|
|
5121
|
+
const items = result.items ?? [];
|
|
5122
|
+
const matched = items.find((p) => p.product_id === productId);
|
|
5123
|
+
if (matched) {
|
|
5124
|
+
return matched;
|
|
5125
|
+
}
|
|
5126
|
+
const fetched = page * pageSize;
|
|
5127
|
+
const exhausted = items.length < pageSize || typeof result.total === "number" && fetched >= result.total;
|
|
5128
|
+
if (exhausted) {
|
|
5129
|
+
throw new Error(`\u672A\u627E\u5230\u5546\u54C1 product_id=${productId}`);
|
|
5130
|
+
}
|
|
4373
5131
|
}
|
|
4374
|
-
return matched;
|
|
4375
5132
|
}
|
|
4376
5133
|
function registerProductCommand(program2) {
|
|
4377
5134
|
const product = program2.command("product").description(
|
|
@@ -4558,10 +5315,11 @@ function registerProductCommand(program2) {
|
|
|
4558
5315
|
process.exit(toExitCode(err));
|
|
4559
5316
|
}
|
|
4560
5317
|
});
|
|
5318
|
+
registerProductRelatedKnowledgeCommand(product, program2);
|
|
4561
5319
|
}
|
|
4562
5320
|
|
|
4563
5321
|
// src/client/repair-record-api.ts
|
|
4564
|
-
var
|
|
5322
|
+
var PATH_PREFIX4 = "/api/repair-records";
|
|
4565
5323
|
async function listRepairRecords(opts) {
|
|
4566
5324
|
const request = createRequest();
|
|
4567
5325
|
const query = {};
|
|
@@ -4570,21 +5328,21 @@ async function listRepairRecords(opts) {
|
|
|
4570
5328
|
if (opts.workspaceId) query.workspace_id = opts.workspaceId;
|
|
4571
5329
|
if (opts.page) query.page = opts.page;
|
|
4572
5330
|
if (opts.pageSize) query.page_size = opts.pageSize;
|
|
4573
|
-
return request(getCsAdminUrl(),
|
|
5331
|
+
return request(getCsAdminUrl(), PATH_PREFIX4, {
|
|
4574
5332
|
method: "GET",
|
|
4575
5333
|
query
|
|
4576
5334
|
});
|
|
4577
5335
|
}
|
|
4578
5336
|
async function createRepairRecord(data) {
|
|
4579
5337
|
const request = createRequest();
|
|
4580
|
-
return request(getCsAdminUrl(),
|
|
5338
|
+
return request(getCsAdminUrl(), PATH_PREFIX4, {
|
|
4581
5339
|
method: "POST",
|
|
4582
5340
|
body: data
|
|
4583
5341
|
});
|
|
4584
5342
|
}
|
|
4585
5343
|
async function updateRepairRecord(recordId, data) {
|
|
4586
5344
|
const request = createRequest();
|
|
4587
|
-
return request(getCsAdminUrl(), `${
|
|
5345
|
+
return request(getCsAdminUrl(), `${PATH_PREFIX4}/${recordId}`, {
|
|
4588
5346
|
method: "PUT",
|
|
4589
5347
|
body: data
|
|
4590
5348
|
});
|
|
@@ -4660,86 +5418,6 @@ function registerRepairRecordCommand(program2) {
|
|
|
4660
5418
|
});
|
|
4661
5419
|
}
|
|
4662
5420
|
|
|
4663
|
-
// src/client/sa-api.ts
|
|
4664
|
-
async function listSituationActions(opts) {
|
|
4665
|
-
const request = createRequest();
|
|
4666
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/list", {
|
|
4667
|
-
method: "GET",
|
|
4668
|
-
query: {
|
|
4669
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4670
|
-
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
4671
|
-
event_first_label: opts.firstLabel ?? "",
|
|
4672
|
-
event_second_label: opts.secondLabel ?? "",
|
|
4673
|
-
page: opts.page ?? 1,
|
|
4674
|
-
page_size: opts.pageSize ?? 500
|
|
4675
|
-
}
|
|
4676
|
-
});
|
|
4677
|
-
}
|
|
4678
|
-
async function searchSituationActions(opts) {
|
|
4679
|
-
const request = createRequest();
|
|
4680
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/search", {
|
|
4681
|
-
method: "GET",
|
|
4682
|
-
query: { customer_agent_config_id: opts.agentConfigId, keyword: opts.keyword }
|
|
4683
|
-
});
|
|
4684
|
-
}
|
|
4685
|
-
async function createSituationAction(opts) {
|
|
4686
|
-
const request = createRequest();
|
|
4687
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/create", {
|
|
4688
|
-
method: "POST",
|
|
4689
|
-
body: {
|
|
4690
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4691
|
-
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
4692
|
-
event_first_label: opts.firstLabel,
|
|
4693
|
-
event_second_label: opts.secondLabel,
|
|
4694
|
-
situation: opts.situation,
|
|
4695
|
-
action: opts.action,
|
|
4696
|
-
transfer_to_human: opts.transferToHuman ?? false
|
|
4697
|
-
}
|
|
4698
|
-
});
|
|
4699
|
-
}
|
|
4700
|
-
async function updateSituationAction(opts) {
|
|
4701
|
-
const request = createRequest();
|
|
4702
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/update", {
|
|
4703
|
-
method: "POST",
|
|
4704
|
-
body: {
|
|
4705
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4706
|
-
situation_action_id: opts.situationActionId,
|
|
4707
|
-
sub_agent_intent: opts.subAgentIntent ?? "GENERAL_QA",
|
|
4708
|
-
event_first_label: opts.firstLabel,
|
|
4709
|
-
event_second_label: opts.secondLabel,
|
|
4710
|
-
situation: opts.situation,
|
|
4711
|
-
action: opts.action,
|
|
4712
|
-
transfer_to_human: opts.transferToHuman ?? false
|
|
4713
|
-
}
|
|
4714
|
-
});
|
|
4715
|
-
}
|
|
4716
|
-
async function deleteSituationAction(opts) {
|
|
4717
|
-
const request = createRequest();
|
|
4718
|
-
return request(getCustomerServiceUrl(), "/v1/knowledge/situation-actions/delete", {
|
|
4719
|
-
method: "POST",
|
|
4720
|
-
body: {
|
|
4721
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4722
|
-
situation_action_id: opts.situationActionId,
|
|
4723
|
-
event_first_label: opts.firstLabel,
|
|
4724
|
-
event_second_label: opts.secondLabel
|
|
4725
|
-
}
|
|
4726
|
-
});
|
|
4727
|
-
}
|
|
4728
|
-
async function listSituationActionVersions(opts) {
|
|
4729
|
-
const request = createRequest();
|
|
4730
|
-
return request(
|
|
4731
|
-
getCustomerServiceUrl(),
|
|
4732
|
-
"/v1/knowledge/situation-actions/list/versions",
|
|
4733
|
-
{
|
|
4734
|
-
method: "GET",
|
|
4735
|
-
query: {
|
|
4736
|
-
customer_agent_config_id: opts.agentConfigId,
|
|
4737
|
-
situation_action_id: opts.situationActionId
|
|
4738
|
-
}
|
|
4739
|
-
}
|
|
4740
|
-
);
|
|
4741
|
-
}
|
|
4742
|
-
|
|
4743
5421
|
// src/commands/sa.ts
|
|
4744
5422
|
function registerSACommand(program2) {
|
|
4745
5423
|
const sa = program2.command("sa").description(
|
|
@@ -5661,6 +6339,23 @@ function registerWorkspaceCommand(program2) {
|
|
|
5661
6339
|
process.exit(toExitCode(err));
|
|
5662
6340
|
}
|
|
5663
6341
|
});
|
|
6342
|
+
workspace.command("points-consumes").description("\u5206\u9875\u67E5\u8BE2\u5F53\u524D\u5DE5\u4F5C\u7A7A\u95F4\u7684\u79EF\u5206\u8D26\u6237\u6D88\u8017\u6D41\u6C34\uFF0C\u56FA\u5B9A\u8FD4\u56DE extra \u8C03\u8BD5\u5B57\u6BB5").option("--page <number>", "\u9875\u7801\uFF0C\u9ED8\u8BA4 1", "1").option("--page-size <number>", "\u6BCF\u9875\u6570\u91CF\uFF0C\u9ED8\u8BA4 20", "20").action(async (opts) => {
|
|
6343
|
+
try {
|
|
6344
|
+
const page = Number(opts.page);
|
|
6345
|
+
const pageSize = Number(opts.pageSize);
|
|
6346
|
+
if (!Number.isInteger(page) || page <= 0) {
|
|
6347
|
+
throw new Error("--page \u5FC5\u987B\u4E3A\u6B63\u6574\u6570");
|
|
6348
|
+
}
|
|
6349
|
+
if (!Number.isInteger(pageSize) || pageSize <= 0) {
|
|
6350
|
+
throw new Error("--page-size \u5FC5\u987B\u4E3A\u6B63\u6574\u6570");
|
|
6351
|
+
}
|
|
6352
|
+
const data = await getPointsConsumes({ page, pageSize });
|
|
6353
|
+
formatOutput({ success: true, data }, program2.opts().table);
|
|
6354
|
+
} catch (err) {
|
|
6355
|
+
reportCaughtError(err);
|
|
6356
|
+
process.exit(toExitCode(err));
|
|
6357
|
+
}
|
|
6358
|
+
});
|
|
5664
6359
|
workspace.command("points-consumes-daily").description(
|
|
5665
6360
|
"\u6309\u5929\u67E5\u8BE2\u5F53\u524D\u5DE5\u4F5C\u7A7A\u95F4\u7684\u79EF\u5206\u6D88\u8017\u3002\u9ED8\u8BA4\u6700\u8FD1 30 \u5929\uFF08end=\u4ECA\u5929\uFF0Cstart=\u4ECA\u5929-29d\uFF09\uFF0C\u8FD4\u56DE consume_date / total_consume_points \u5217\u8868"
|
|
5666
6361
|
).option("--start <YYYY-MM-DD>", "\u8D77\u59CB\u65E5\u671F\uFF08\u542B\uFF09\uFF0C\u9ED8\u8BA4\u4ECA\u5929-29d").option("--end <YYYY-MM-DD>", "\u7ED3\u675F\u65E5\u671F\uFF08\u542B\uFF09\uFF0C\u9ED8\u8BA4\u4ECA\u5929").action(async (opts) => {
|