@thinkingai/ae-cli 6.1.18 → 6.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -38
- package/README.zh.md +101 -38
- package/dist/{auth-ROB2EDYV.js → auth-FUM37MHF.js} +241 -126
- package/dist/{capability-DKMYUTLC.js → capability-AXFQW5WM.js} +49 -35
- package/dist/{chunk-JHENBQ5B.js → chunk-4P355ZWB.js} +70 -1
- package/dist/chunk-6ZIQV5GW.js +26 -0
- package/dist/{chunk-TUKQZTMI.js → chunk-7K24F7T2.js} +2 -0
- package/dist/{chunk-OO6XR6LK.js → chunk-AMBFK2K3.js} +2 -0
- package/dist/chunk-ATSM5XAW.js +623 -0
- package/dist/{chunk-4XXOWOTA.js → chunk-BBEFP4SB.js} +31 -38
- package/dist/{chunk-BYYS3ANB.js → chunk-CZU3V3DQ.js} +5 -15
- package/dist/{chunk-VTWMIC5L.js → chunk-E2JKXMVO.js} +2 -0
- package/dist/chunk-ECBLHAZO.js +15 -0
- package/dist/{sync-HKIOZXQE.js → chunk-I4WQAEYB.js} +31 -540
- package/dist/{chunk-DWO43OIB.js → chunk-JQ3ENZZH.js} +2 -0
- package/dist/chunk-LNZBEQXW.js +25216 -0
- package/dist/{chunk-ZQ47LWTI.js → chunk-QJQZH5GQ.js} +49 -79
- package/dist/{chunk-QZ3AS4KK.js → chunk-RSG4ONOI.js} +9 -8
- package/dist/{chunk-4NN5IWVN.js → chunk-T6OSFQZD.js} +2 -0
- package/dist/{chunk-Y3LOALAV.js → chunk-TAL6CZH6.js} +8 -7
- package/dist/{chunk-3KWQYGYI.js → chunk-TKHSULJT.js} +2 -0
- package/dist/chunk-VXNMYUXU.js +202 -0
- package/dist/{chunk-3FY3RJ26.js → chunk-WZ6YVQSF.js} +15 -14
- package/dist/{chunk-6EIJSNBD.js → chunk-Y74WTIKJ.js} +2 -0
- package/dist/{community-report-client-C7WDGET3.js → community-report-client-XXWGSBSD.js} +3 -4
- package/dist/{config-BMYZX2UE.js → config-EXUGQN5T.js} +10 -10
- package/dist/{data-integration-QEKDWQDY.js → data-integration-4NZ53OMT.js} +920 -97
- package/dist/index.js +56 -81
- package/dist/{local-data-upload-client-4YYHSYD6.js → local-data-upload-client-KYOKVYZV.js} +3 -4
- package/dist/{memory-I2WXDTV2.js → memory-ATNKZNW5.js} +6 -7
- package/dist/{metadata-I4C2EWUN.js → metadata-VZVC7YMH.js} +10 -11
- package/dist/{model-HLHIEFMU.js → model-E4JMQ4V2.js} +8 -9
- package/dist/{personal-semantic-preference-LIPACBDX.js → personal-semantic-preference-7S2SQ3UV.js} +9 -10
- package/dist/{project-semantic-RT3R2VQD.js → project-semantic-2SZP2OPO.js} +13 -14
- package/dist/sync-YV3E66IF.js +520 -0
- package/dist/{te-agent-BR6VDBNX.js → te-agent-JB5T3PO7.js} +396 -92
- package/dist/{te-analysis-7VUNUYWZ.js → te-analysis-3YJAAT2D.js} +196 -43
- package/dist/{te-community-5DMNKJWY.js → te-community-UDBI672N.js} +12 -34
- package/dist/{te-dataops-6P5IKWNJ.js → te-dataops-ZLYOCXZ4.js} +480 -81
- package/dist/{te-engage-KZPR5R22.js → te-engage-4XG6OJML.js} +88 -16
- package/dist/{te-experiment-6BITX4RD.js → te-experiment-VXUWPINJ.js} +83 -12
- package/dist/te-kb-WYQWHFSC.js +1732 -0
- package/dist/{te-system-FXITO2JG.js → te-system-7G6F2LJA.js} +569 -35
- package/dist/{te-team-ADOC2ROP.js → te-team-E7FBBXMQ.js} +8 -7
- package/dist/{update-YCYCKJOO.js → update-D47BUG25.js} +8 -8
- package/package.json +22 -10
- package/skills/ae-agent/SKILL.md +30 -13
- package/skills/ae-agent/references/agent-distribution.md +94 -0
- package/skills/ae-agent/references/approval-request.md +4 -0
- package/skills/ae-agent/references/command_index.md +9 -2
- package/skills/ae-agent/references/create-automation.md +20 -2
- package/skills/ae-agent/references/get-agent-context.md +70 -0
- package/skills/ae-agent/references/list-automations.md +18 -3
- package/skills/ae-agent/references/list-mcp-credentials.md +1 -1
- package/skills/ae-agent/references/mcp-token.md +3 -3
- package/skills/ae-agent/references/set-mcp-credential.md +0 -1
- package/skills/ae-agent/references/update-automation.md +18 -0
- package/skills/ae-analysis/SKILL.md +11 -2
- package/skills/ae-analysis/references/adhoc_run.md +2 -0
- package/skills/ae-analysis/references/ai_models.md +23 -3
- package/skills/ae-analysis/references/analysis_gateway_assets.md +3 -3
- package/skills/ae-analysis/references/audience_models.md +18 -0
- package/skills/ae-analysis/references/command_index.md +9 -9
- package/skills/ae-analysis/references/cross_source_config.md +84 -0
- package/skills/ae-analysis/references/dashboard_update.md +1 -1
- package/skills/ae-analysis/references/project_timezone_update.md +13 -4
- package/skills/ae-analysis/references/property_create.md +2 -0
- package/skills/ae-analysis/references/super_metadata_batch_create.md +2 -0
- package/skills/ae-analysis/references/user_cluster_models.md +2 -0
- package/skills/ae-analysis/references/user_cluster_update.md +8 -4
- package/skills/ae-analysis/references/user_tag_create.md +30 -2
- package/skills/ae-analysis/references/user_tag_models.md +17 -3
- package/skills/ae-analysis/references/user_tag_update.md +14 -2
- package/skills/ae-data-integration/SKILL.md +3 -1
- package/skills/ae-data-integration/references/dimension-routing.md +36 -0
- package/skills/ae-data-integration/references/error-handling.md +54 -1
- package/skills/ae-data-integration/references/local-analysis.md +2 -0
- package/skills/ae-data-integration/references/source-inspect.md +18 -2
- package/skills/ae-data-integration/references/tracking-plan.md +1 -1
- package/skills/ae-data-integration/references/transform.md +4 -2
- package/skills/ae-data-integration/references/ue-mapping.md +5 -2
- package/skills/ae-data-integration/references/ue-routing.md +40 -1
- package/skills/ae-dataops/SKILL.md +11 -1
- package/skills/ae-dataops/references/dataops-backfill.md +135 -0
- package/skills/ae-engage/SKILL.md +5 -0
- package/skills/ae-engage/references/build-task-save-guide.md +5 -1
- package/skills/ae-engage/references/save-flow.md +37 -1
- package/skills/ae-engage/references/save-task.md +6 -0
- package/skills/ae-experiment/SKILL.md +6 -2
- package/skills/ae-experiment/references/save_metric.md +20 -8
- package/skills/ae-generate-tracking-plan/SKILL.md +25 -13
- package/skills/ae-generate-tracking-plan/references/business-dimension-mapping.md +1 -1
- package/skills/ae-kb/SKILL.md +218 -36
- package/skills/ae-kb/references/query-workflow.md +59 -29
- package/skills/ae-kb/references/versions.md +46 -0
- package/skills/ae-system/SKILL.md +29 -31
- package/skills/ae-system/references/channel-management.md +303 -0
- package/skills/ae-use-agent/SKILL.md +42 -0
- package/skills/ae-use-agent/references/local-agent.md +114 -0
- package/dist/auth-GBMV6TEJ.js +0 -14
- package/dist/capability-HYVVPG25.js +0 -352
- package/dist/chunk-EFH4XWYC.js +0 -556
- package/dist/chunk-J2DEBMRF.js +0 -313
- package/dist/chunk-JRJY5DMJ.js +0 -71
- package/dist/chunk-OMPRXM3V.js +0 -349
- package/dist/chunk-QNOLN2LJ.js +0 -509
- package/dist/chunk-RJDU7NYP.js +0 -1198
- package/dist/chunk-RNAALWJK.js +0 -98
- package/dist/chunk-SERWF6G5.js +0 -13
- package/dist/chunk-UW5UN47B.js +0 -70
- package/dist/chunk-ZQKDZXDO.js +0 -317
- package/dist/client-L2YDMHQ6.js +0 -203
- package/dist/memory-3ORCR7JH.js +0 -893
- package/dist/metadata-VUOQJE26.js +0 -339
- package/dist/model-UGRDX4MW.js +0 -139
- package/dist/personal-semantic-preference-OEISBRHM.js +0 -239
- package/dist/project-semantic-FFPWFPIW.js +0 -1114
- package/dist/sync-TFHU2UTG.js +0 -10261
- package/dist/te-agent-VLYOV7S4.js +0 -3894
- package/dist/te-analysis-4YGQL5RC.js +0 -9357
- package/dist/te-community-ISDQWJU7.js +0 -1859
- package/dist/te-dataops-CVULXNVB.js +0 -2209
- package/dist/te-engage-N5WI32H6.js +0 -4898
- package/dist/te-experiment-UVR4HLND.js +0 -988
- package/dist/te-kb-RCLSSH2Q.js +0 -935
- package/dist/te-system-K2GYMCTB.js +0 -2213
- package/skills/ae-agent/references/auto-provision-mcp-credentials.md +0 -57
package/dist/te-kb-RCLSSH2Q.js
DELETED
|
@@ -1,935 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
kbApi,
|
|
3
|
-
kbUpload
|
|
4
|
-
} from "./chunk-RNAALWJK.js";
|
|
5
|
-
import {
|
|
6
|
-
printError
|
|
7
|
-
} from "./chunk-BYYS3ANB.js";
|
|
8
|
-
import "./chunk-J2DEBMRF.js";
|
|
9
|
-
import "./chunk-ZQKDZXDO.js";
|
|
10
|
-
import "./chunk-3FY3RJ26.js";
|
|
11
|
-
import {
|
|
12
|
-
PermissionError
|
|
13
|
-
} from "./chunk-UW5UN47B.js";
|
|
14
|
-
import "./chunk-JHENBQ5B.js";
|
|
15
|
-
|
|
16
|
-
// src/commands/te-kb/add.ts
|
|
17
|
-
import { promises as fs } from "fs";
|
|
18
|
-
import * as path from "path";
|
|
19
|
-
import TurndownService from "turndown";
|
|
20
|
-
var API_PATH = "/agent/api/external/knowledge-bases/sources/upload";
|
|
21
|
-
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
22
|
-
".md",
|
|
23
|
-
".markdown",
|
|
24
|
-
".txt",
|
|
25
|
-
".csv",
|
|
26
|
-
".pdf",
|
|
27
|
-
".doc",
|
|
28
|
-
".docx",
|
|
29
|
-
".xls",
|
|
30
|
-
".xlsx",
|
|
31
|
-
".ppt",
|
|
32
|
-
".pptx",
|
|
33
|
-
".jpg",
|
|
34
|
-
".jpeg",
|
|
35
|
-
".png",
|
|
36
|
-
".gif",
|
|
37
|
-
".webp",
|
|
38
|
-
".bmp",
|
|
39
|
-
".svg"
|
|
40
|
-
]);
|
|
41
|
-
function normalizeFilesInput(raw) {
|
|
42
|
-
if (!Array.isArray(raw)) {
|
|
43
|
-
throw new Error(`--files must be a JSON array of strings, e.g. '["./a.md","./docs","https://example.com/page"]'`);
|
|
44
|
-
}
|
|
45
|
-
const items = [];
|
|
46
|
-
for (const v of raw) {
|
|
47
|
-
if (typeof v !== "string") {
|
|
48
|
-
throw new Error(`--files entries must be strings (got: ${JSON.stringify(v)})`);
|
|
49
|
-
}
|
|
50
|
-
const trimmed = v.trim();
|
|
51
|
-
if (trimmed) items.push(trimmed);
|
|
52
|
-
}
|
|
53
|
-
return items;
|
|
54
|
-
}
|
|
55
|
-
function isUrl(s) {
|
|
56
|
-
return /^https?:\/\//i.test(s);
|
|
57
|
-
}
|
|
58
|
-
function classifyInput(item) {
|
|
59
|
-
return isUrl(item) ? "url" : "path";
|
|
60
|
-
}
|
|
61
|
-
function sanitizeFilename(name) {
|
|
62
|
-
const cleaned = name.replace(/[\\/:*?"<>|\s]+/g, "-").replace(/^-+|-+$/g, "");
|
|
63
|
-
return cleaned || "document";
|
|
64
|
-
}
|
|
65
|
-
function getMimeType(filename) {
|
|
66
|
-
const ext = path.extname(filename).toLowerCase();
|
|
67
|
-
switch (ext) {
|
|
68
|
-
case ".md":
|
|
69
|
-
case ".markdown":
|
|
70
|
-
return "text/markdown";
|
|
71
|
-
case ".txt":
|
|
72
|
-
return "text/plain";
|
|
73
|
-
case ".csv":
|
|
74
|
-
return "text/csv";
|
|
75
|
-
case ".pdf":
|
|
76
|
-
return "application/pdf";
|
|
77
|
-
case ".doc":
|
|
78
|
-
return "application/msword";
|
|
79
|
-
case ".docx":
|
|
80
|
-
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
|
81
|
-
case ".xls":
|
|
82
|
-
return "application/vnd.ms-excel";
|
|
83
|
-
case ".xlsx":
|
|
84
|
-
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
85
|
-
case ".ppt":
|
|
86
|
-
return "application/vnd.ms-powerpoint";
|
|
87
|
-
case ".pptx":
|
|
88
|
-
return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
89
|
-
case ".jpg":
|
|
90
|
-
case ".jpeg":
|
|
91
|
-
return "image/jpeg";
|
|
92
|
-
case ".png":
|
|
93
|
-
return "image/png";
|
|
94
|
-
case ".gif":
|
|
95
|
-
return "image/gif";
|
|
96
|
-
case ".webp":
|
|
97
|
-
return "image/webp";
|
|
98
|
-
case ".bmp":
|
|
99
|
-
return "image/bmp";
|
|
100
|
-
case ".svg":
|
|
101
|
-
return "image/svg+xml";
|
|
102
|
-
default:
|
|
103
|
-
return "application/octet-stream";
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
async function readLocalFile(filePath) {
|
|
107
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
108
|
-
if (!SUPPORTED_EXTENSIONS.has(ext)) {
|
|
109
|
-
throw new Error(`Unsupported file extension (${ext || "none"}): ${filePath}`);
|
|
110
|
-
}
|
|
111
|
-
const content = await fs.readFile(filePath);
|
|
112
|
-
const filename = path.basename(filePath);
|
|
113
|
-
return { filename, content, mimeType: getMimeType(filename), origin: "file", source: filePath };
|
|
114
|
-
}
|
|
115
|
-
async function readDirectory(dir) {
|
|
116
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
117
|
-
const files = [];
|
|
118
|
-
for (const entry of entries) {
|
|
119
|
-
if (!entry.isFile()) continue;
|
|
120
|
-
const ext = path.extname(entry.name).toLowerCase();
|
|
121
|
-
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
122
|
-
const full = path.join(dir, entry.name);
|
|
123
|
-
const content = await fs.readFile(full);
|
|
124
|
-
files.push({ filename: entry.name, content, mimeType: getMimeType(entry.name), origin: "dir", source: full });
|
|
125
|
-
}
|
|
126
|
-
if (files.length === 0) {
|
|
127
|
-
throw new Error(`No supported files found in directory: ${dir}`);
|
|
128
|
-
}
|
|
129
|
-
return files;
|
|
130
|
-
}
|
|
131
|
-
function deriveFilenameFromUrl(rawUrl) {
|
|
132
|
-
try {
|
|
133
|
-
const u = new URL(rawUrl);
|
|
134
|
-
const lastSeg = u.pathname.split("/").filter(Boolean).pop();
|
|
135
|
-
const base = lastSeg ? lastSeg.replace(/\.[^.]+$/, "") : u.hostname;
|
|
136
|
-
return `${sanitizeFilename(base)}.md`;
|
|
137
|
-
} catch {
|
|
138
|
-
return `${sanitizeFilename(rawUrl)}.md`;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
async function fetchAsMarkdown(rawUrl) {
|
|
142
|
-
const resp = await fetch(rawUrl);
|
|
143
|
-
if (!resp.ok) {
|
|
144
|
-
throw new Error(`Failed to fetch ${rawUrl}: HTTP ${resp.status}`);
|
|
145
|
-
}
|
|
146
|
-
const html = await resp.text();
|
|
147
|
-
const turndown = new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced" });
|
|
148
|
-
const markdown = turndown.turndown(html);
|
|
149
|
-
return {
|
|
150
|
-
filename: deriveFilenameFromUrl(rawUrl),
|
|
151
|
-
content: markdown,
|
|
152
|
-
mimeType: "text/markdown",
|
|
153
|
-
origin: "url",
|
|
154
|
-
source: rawUrl
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
async function resolveLocalPath(p) {
|
|
158
|
-
const abs = path.resolve(p);
|
|
159
|
-
let stat;
|
|
160
|
-
try {
|
|
161
|
-
stat = await fs.stat(abs);
|
|
162
|
-
} catch {
|
|
163
|
-
throw new Error(`Path not found: ${p}`);
|
|
164
|
-
}
|
|
165
|
-
if (stat.isDirectory()) {
|
|
166
|
-
return readDirectory(abs);
|
|
167
|
-
}
|
|
168
|
-
if (stat.isFile()) {
|
|
169
|
-
return [await readLocalFile(abs)];
|
|
170
|
-
}
|
|
171
|
-
throw new Error(`Unsupported path (not file or directory): ${p}`);
|
|
172
|
-
}
|
|
173
|
-
async function collectFiles(ctx) {
|
|
174
|
-
const items = normalizeFilesInput(ctx.json("files"));
|
|
175
|
-
if (items.length === 0) {
|
|
176
|
-
throw new Error("--files must contain at least one entry");
|
|
177
|
-
}
|
|
178
|
-
const collected = [];
|
|
179
|
-
for (const item of items) {
|
|
180
|
-
if (classifyInput(item) === "url") {
|
|
181
|
-
collected.push(await fetchAsMarkdown(item));
|
|
182
|
-
} else {
|
|
183
|
-
collected.push(...await resolveLocalPath(item));
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
if (collected.length === 0) {
|
|
187
|
-
throw new Error("No supported files collected from the given inputs");
|
|
188
|
-
}
|
|
189
|
-
return dedupeByFilename(collected);
|
|
190
|
-
}
|
|
191
|
-
function dedupeByFilename(files) {
|
|
192
|
-
const used = /* @__PURE__ */ new Map();
|
|
193
|
-
return files.map((f) => {
|
|
194
|
-
const count = used.get(f.filename) ?? 0;
|
|
195
|
-
used.set(f.filename, count + 1);
|
|
196
|
-
if (count === 0) return f;
|
|
197
|
-
const ext = path.extname(f.filename);
|
|
198
|
-
const stem = f.filename.slice(0, f.filename.length - ext.length);
|
|
199
|
-
return { ...f, filename: `${stem}-${count}${ext}` };
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
function buildForm(name, files) {
|
|
203
|
-
const form = new FormData();
|
|
204
|
-
form.append("name", name);
|
|
205
|
-
for (const f of files) {
|
|
206
|
-
form.append("files", new Blob([f.content], { type: f.mimeType }), f.filename);
|
|
207
|
-
}
|
|
208
|
-
return form;
|
|
209
|
-
}
|
|
210
|
-
var add = {
|
|
211
|
-
service: "kb",
|
|
212
|
-
command: "+add",
|
|
213
|
-
description: "Upload sources to a knowledge. --files accepts a JSON array; each entry can be a supported file path, a directory path (supported files inside, non-recursive), or an http(s) URL (HTML auto-converted to markdown).",
|
|
214
|
-
flags: [
|
|
215
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name" },
|
|
216
|
-
{
|
|
217
|
-
name: "files",
|
|
218
|
-
type: "json",
|
|
219
|
-
required: true,
|
|
220
|
-
desc: `JSON array of strings. Each entry can be a supported file path, a directory path, or an http(s) URL. Example: '["./a.md","./docs","https://example.com/page"]'`
|
|
221
|
-
}
|
|
222
|
-
],
|
|
223
|
-
risk: "write",
|
|
224
|
-
validate: (ctx) => {
|
|
225
|
-
normalizeFilesInput(ctx.json("files"));
|
|
226
|
-
},
|
|
227
|
-
dryRun: (ctx) => {
|
|
228
|
-
const items = normalizeFilesInput(ctx.json("files"));
|
|
229
|
-
return {
|
|
230
|
-
method: "POST",
|
|
231
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH}`,
|
|
232
|
-
body: {
|
|
233
|
-
name: ctx.str("name"),
|
|
234
|
-
files: items.map((item) => ({ value: item, type: classifyInput(item) })),
|
|
235
|
-
contentType: "multipart/form-data"
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
},
|
|
239
|
-
execute: async (ctx) => {
|
|
240
|
-
const name = ctx.str("name");
|
|
241
|
-
const files = await collectFiles(ctx);
|
|
242
|
-
const form = buildForm(name, files);
|
|
243
|
-
const result = await kbUpload(ctx, API_PATH, form);
|
|
244
|
-
return {
|
|
245
|
-
uploaded: files.map((f) => ({ filename: f.filename, origin: f.origin, source: f.source })),
|
|
246
|
-
result
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
// src/commands/te-kb/compile.ts
|
|
252
|
-
var API_PATH2 = "/agent/api/external/knowledge-bases/compile";
|
|
253
|
-
var VALID_MODES = /* @__PURE__ */ new Set(["incremental", "full"]);
|
|
254
|
-
function getMode(ctx) {
|
|
255
|
-
const mode = ctx.str("mode") || "incremental";
|
|
256
|
-
if (!VALID_MODES.has(mode)) {
|
|
257
|
-
throw new Error(`Invalid --mode: ${mode}. Must be one of: incremental | full`);
|
|
258
|
-
}
|
|
259
|
-
return mode;
|
|
260
|
-
}
|
|
261
|
-
function buildBody(ctx) {
|
|
262
|
-
return {
|
|
263
|
-
name: ctx.str("name"),
|
|
264
|
-
mode: getMode(ctx)
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
var compile = {
|
|
268
|
-
service: "kb",
|
|
269
|
-
command: "+compile",
|
|
270
|
-
description: "Compile a knowledge.",
|
|
271
|
-
flags: [
|
|
272
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name" },
|
|
273
|
-
{ name: "mode", type: "string", required: false, default: "incremental", desc: "Compile mode: incremental | full (default: incremental)" }
|
|
274
|
-
],
|
|
275
|
-
risk: "write",
|
|
276
|
-
validate: (ctx) => {
|
|
277
|
-
getMode(ctx);
|
|
278
|
-
},
|
|
279
|
-
dryRun: (ctx) => ({
|
|
280
|
-
method: "POST",
|
|
281
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH2}`,
|
|
282
|
-
body: buildBody(ctx)
|
|
283
|
-
}),
|
|
284
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH2, {}, buildBody(ctx))
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
// src/commands/te-kb/remove.ts
|
|
288
|
-
var API_PATH3 = "/agent/api/external/knowledge-bases";
|
|
289
|
-
function buildBody2(ctx) {
|
|
290
|
-
return { name: ctx.str("name") };
|
|
291
|
-
}
|
|
292
|
-
var remove = {
|
|
293
|
-
service: "kb",
|
|
294
|
-
command: "+remove",
|
|
295
|
-
description: "Delete an entire knowledge.",
|
|
296
|
-
flags: [
|
|
297
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name to delete" }
|
|
298
|
-
],
|
|
299
|
-
risk: "high-risk-write",
|
|
300
|
-
dryRun: (ctx) => ({
|
|
301
|
-
method: "DELETE",
|
|
302
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH3}`,
|
|
303
|
-
body: buildBody2(ctx)
|
|
304
|
-
}),
|
|
305
|
-
execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH3, {}, buildBody2(ctx))
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
// src/commands/te-kb/create.ts
|
|
309
|
-
var API_PATH4 = "/agent/api/external/knowledge-bases/create";
|
|
310
|
-
var VALID_SCOPES = /* @__PURE__ */ new Set(["personal", "company"]);
|
|
311
|
-
function getScope(ctx) {
|
|
312
|
-
const scope = ctx.str("scope") || "company";
|
|
313
|
-
validateScope(scope);
|
|
314
|
-
return scope;
|
|
315
|
-
}
|
|
316
|
-
function validateScope(scope) {
|
|
317
|
-
if (!VALID_SCOPES.has(scope)) {
|
|
318
|
-
throw new Error(`Invalid --scope: ${scope}. Must be one of: personal | company`);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
function normalizeTags(raw) {
|
|
322
|
-
if (raw === void 0 || raw === null) return void 0;
|
|
323
|
-
if (!Array.isArray(raw)) {
|
|
324
|
-
throw new Error(`--tags must be a JSON array of strings, e.g. '["t1","t2"]'`);
|
|
325
|
-
}
|
|
326
|
-
const tags = [];
|
|
327
|
-
for (const v of raw) {
|
|
328
|
-
if (typeof v !== "string") {
|
|
329
|
-
throw new Error(`--tags entries must be strings (got: ${JSON.stringify(v)})`);
|
|
330
|
-
}
|
|
331
|
-
const t = v.trim();
|
|
332
|
-
if (t) tags.push(t);
|
|
333
|
-
}
|
|
334
|
-
return tags;
|
|
335
|
-
}
|
|
336
|
-
function buildBody3(ctx) {
|
|
337
|
-
const body = {
|
|
338
|
-
scope: getScope(ctx),
|
|
339
|
-
name: ctx.str("name")
|
|
340
|
-
};
|
|
341
|
-
const description = ctx.str("description");
|
|
342
|
-
if (description) body.description = description;
|
|
343
|
-
const tags = normalizeTags(ctx.json("tags"));
|
|
344
|
-
if (tags && tags.length > 0) body.tags = tags;
|
|
345
|
-
const projectId = ctx.str("project-id");
|
|
346
|
-
if (projectId) body.projectId = projectId;
|
|
347
|
-
const projectName = ctx.str("project-name");
|
|
348
|
-
if (projectName) body.projectName = projectName;
|
|
349
|
-
return body;
|
|
350
|
-
}
|
|
351
|
-
var create = {
|
|
352
|
-
service: "kb",
|
|
353
|
-
command: "+new",
|
|
354
|
-
description: "Create a new knowledge.",
|
|
355
|
-
flags: [
|
|
356
|
-
{ name: "scope", type: "string", required: false, default: "company", desc: "Knowledge base scope: personal | company (default: company)" },
|
|
357
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name (\u226430 chars, unique per scope)" },
|
|
358
|
-
{ name: "description", type: "string", required: false, desc: "Optional description (\u2264200 chars)" },
|
|
359
|
-
{ name: "tags", type: "json", required: false, desc: `Optional JSON array of tags (max 2, each \u226415 chars). Example: '["t1","t2"]'` },
|
|
360
|
-
{ name: "project-id", type: "string", required: false, desc: "Optional project ID to bind" },
|
|
361
|
-
{ name: "project-name", type: "string", required: false, desc: "Optional project display name" }
|
|
362
|
-
],
|
|
363
|
-
risk: "write",
|
|
364
|
-
validate: (ctx) => {
|
|
365
|
-
getScope(ctx);
|
|
366
|
-
normalizeTags(ctx.json("tags"));
|
|
367
|
-
},
|
|
368
|
-
dryRun: (ctx) => ({
|
|
369
|
-
method: "POST",
|
|
370
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
|
|
371
|
-
body: buildBody3(ctx)
|
|
372
|
-
}),
|
|
373
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH4, {}, buildBody3(ctx))
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
// src/commands/te-kb/rm-source.ts
|
|
377
|
-
var API_PATH5 = "/agent/api/external/knowledge-bases/sources";
|
|
378
|
-
function buildBody4(ctx) {
|
|
379
|
-
return {
|
|
380
|
-
name: ctx.str("name"),
|
|
381
|
-
displayName: ctx.str("display-name")
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
var rmSource = {
|
|
385
|
-
service: "kb",
|
|
386
|
-
command: "+rm-source",
|
|
387
|
-
description: "Delete a single source file inside a knowledge.",
|
|
388
|
-
flags: [
|
|
389
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name (looked up personal \u2192 company)" },
|
|
390
|
-
{ name: "display-name", type: "string", required: true, desc: "Source file display name as uploaded (e.g. kb-1780046712-foo.md)" }
|
|
391
|
-
],
|
|
392
|
-
risk: "write",
|
|
393
|
-
dryRun: (ctx) => ({
|
|
394
|
-
method: "DELETE",
|
|
395
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
|
|
396
|
-
body: buildBody4(ctx)
|
|
397
|
-
}),
|
|
398
|
-
execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH5, {}, buildBody4(ctx))
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
// src/commands/te-kb/schema.ts
|
|
402
|
-
var API_PATH6 = "/agent/api/external/knowledge-bases/schema";
|
|
403
|
-
function buildBody5(ctx) {
|
|
404
|
-
const body = {
|
|
405
|
-
name: ctx.str("name")
|
|
406
|
-
};
|
|
407
|
-
if (ctx.bool("force")) body.force = true;
|
|
408
|
-
const model = ctx.str("model");
|
|
409
|
-
if (model) body.model = model;
|
|
410
|
-
return body;
|
|
411
|
-
}
|
|
412
|
-
var schema = {
|
|
413
|
-
service: "kb",
|
|
414
|
-
command: "+schema",
|
|
415
|
-
description: "Generate the compile schema for a knowledge base via POST /agent/api/external/knowledge-bases/schema.",
|
|
416
|
-
flags: [
|
|
417
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name (looked up personal \u2192 company)" },
|
|
418
|
-
{ name: "force", type: "boolean", required: false, desc: "Preempt generation even when status is `generating` (use only for stuck recovery)" },
|
|
419
|
-
{ name: "model", type: "string", required: false, desc: "Optional model displayName to use for schema generation" }
|
|
420
|
-
],
|
|
421
|
-
risk: "write",
|
|
422
|
-
dryRun: (ctx) => ({
|
|
423
|
-
method: "POST",
|
|
424
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
|
|
425
|
-
body: buildBody5(ctx)
|
|
426
|
-
}),
|
|
427
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH6, {}, buildBody5(ctx))
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
// src/commands/te-kb/status.ts
|
|
431
|
-
var API_PATH7 = "/agent/api/external/knowledge-bases/status";
|
|
432
|
-
function buildBody6(ctx) {
|
|
433
|
-
return {
|
|
434
|
-
name: ctx.str("name")
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
var status = {
|
|
438
|
-
service: "kb",
|
|
439
|
-
command: "+status",
|
|
440
|
-
description: "Query knowledge base status.",
|
|
441
|
-
flags: [
|
|
442
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name" }
|
|
443
|
-
],
|
|
444
|
-
risk: "read",
|
|
445
|
-
dryRun: (ctx) => ({
|
|
446
|
-
method: "POST",
|
|
447
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
|
|
448
|
-
body: buildBody6(ctx)
|
|
449
|
-
}),
|
|
450
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH7, {}, buildBody6(ctx))
|
|
451
|
-
};
|
|
452
|
-
|
|
453
|
-
// src/commands/te-kb/kb-index.ts
|
|
454
|
-
var API_PATH8 = "/agent/api/external/knowledge-bases/index";
|
|
455
|
-
function buildBody7(ctx) {
|
|
456
|
-
const body = {};
|
|
457
|
-
const sources = ctx.json("sources");
|
|
458
|
-
if (sources) body.sources = sources;
|
|
459
|
-
const locale = ctx.str("locale");
|
|
460
|
-
if (locale) body.locale = locale;
|
|
461
|
-
return body;
|
|
462
|
-
}
|
|
463
|
-
var kbIndex = {
|
|
464
|
-
service: "kb",
|
|
465
|
-
command: "+index",
|
|
466
|
-
description: "List accessible knowledge bases and their index.md navigation maps via POST /agent/api/external/knowledge-bases/index. Call this first to see the layout, then use +grep to locate and +read to open pages.",
|
|
467
|
-
flags: [
|
|
468
|
-
{
|
|
469
|
-
name: "sources",
|
|
470
|
-
type: "json",
|
|
471
|
-
required: false,
|
|
472
|
-
desc: 'Optional JSON array of knowledge base refs to scope the index, e.g. [{"scope":"company","name":"engineering-handbook"}]. Omit to list all accessible knowledge bases.'
|
|
473
|
-
},
|
|
474
|
-
{ name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
|
|
475
|
-
],
|
|
476
|
-
risk: "read",
|
|
477
|
-
dryRun: (ctx) => ({
|
|
478
|
-
method: "POST",
|
|
479
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH8}`,
|
|
480
|
-
body: buildBody7(ctx)
|
|
481
|
-
}),
|
|
482
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH8, {}, buildBody7(ctx))
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
// src/commands/te-kb/kb-list.ts
|
|
486
|
-
var API_PATH9 = "/agent/api/external/knowledge-bases/list";
|
|
487
|
-
var DEFAULT_BUILD_STATUS = "compiled";
|
|
488
|
-
var VALID_BUILD_STATUSES = ["idle", "pending", "compiling", "compiled", "failed"];
|
|
489
|
-
function getBuildStatus(ctx) {
|
|
490
|
-
return ctx.str("build-status") || DEFAULT_BUILD_STATUS;
|
|
491
|
-
}
|
|
492
|
-
function validateBuildStatus(ctx) {
|
|
493
|
-
const value = ctx.str("build-status");
|
|
494
|
-
if (value && !VALID_BUILD_STATUSES.includes(value)) {
|
|
495
|
-
printError(
|
|
496
|
-
"validation",
|
|
497
|
-
`Invalid --build-status: ${value}. Valid values: ${VALID_BUILD_STATUSES.join(" | ")} (omit to default to ${DEFAULT_BUILD_STATUS}).`
|
|
498
|
-
);
|
|
499
|
-
process.exit(1);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
function buildBody8(ctx) {
|
|
503
|
-
const body = {
|
|
504
|
-
buildStatus: getBuildStatus(ctx)
|
|
505
|
-
};
|
|
506
|
-
const locale = ctx.str("locale");
|
|
507
|
-
if (locale) body.locale = locale;
|
|
508
|
-
return body;
|
|
509
|
-
}
|
|
510
|
-
var kbList = {
|
|
511
|
-
service: "kb",
|
|
512
|
-
command: "+list",
|
|
513
|
-
description: "List accessible knowledge bases via POST /agent/api/external/knowledge-bases/list. Filters by buildStatus (default: compiled). Returns KB metadata including buildStatus, without index.md navigation maps.",
|
|
514
|
-
flags: [
|
|
515
|
-
{
|
|
516
|
-
name: "build-status",
|
|
517
|
-
type: "string",
|
|
518
|
-
required: false,
|
|
519
|
-
default: DEFAULT_BUILD_STATUS,
|
|
520
|
-
desc: `Filter by knowledge base build status: ${VALID_BUILD_STATUSES.join(" | ")} (default: ${DEFAULT_BUILD_STATUS} when omitted)`
|
|
521
|
-
},
|
|
522
|
-
{ name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
|
|
523
|
-
],
|
|
524
|
-
risk: "read",
|
|
525
|
-
validate: (ctx) => {
|
|
526
|
-
validateBuildStatus(ctx);
|
|
527
|
-
},
|
|
528
|
-
dryRun: (ctx) => ({
|
|
529
|
-
method: "POST",
|
|
530
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
|
|
531
|
-
body: buildBody8(ctx)
|
|
532
|
-
}),
|
|
533
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody8(ctx))
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
// src/commands/te-kb/kb-grep.ts
|
|
537
|
-
var API_PATH10 = "/agent/api/external/knowledge-bases/grep";
|
|
538
|
-
function buildBody9(ctx) {
|
|
539
|
-
const body = {
|
|
540
|
-
query: ctx.str("query"),
|
|
541
|
-
sources: ctx.json("sources"),
|
|
542
|
-
paths: ctx.json("paths")
|
|
543
|
-
};
|
|
544
|
-
const topK = ctx.num("top-k");
|
|
545
|
-
if (topK) body.topK = topK;
|
|
546
|
-
const locale = ctx.str("locale");
|
|
547
|
-
if (locale) body.locale = locale;
|
|
548
|
-
return body;
|
|
549
|
-
}
|
|
550
|
-
var kbGrep = {
|
|
551
|
-
service: "kb",
|
|
552
|
-
command: "+grep",
|
|
553
|
-
description: "Keyword-search knowledge base pages via POST /agent/api/external/knowledge-bases/grep. Returns matched lines with path, line number, breadcrumb, context snippet, and the section line range (sectionStartLine/sectionEndLine) of each hit. Copy --paths from +index (wiki pages or subdirectories). Use +read with the hit range to open the section.",
|
|
554
|
-
flags: [
|
|
555
|
-
{
|
|
556
|
-
name: "query",
|
|
557
|
-
type: "string",
|
|
558
|
-
required: true,
|
|
559
|
-
alias: "q",
|
|
560
|
-
desc: "Keywords to search across the knowledge bases"
|
|
561
|
-
},
|
|
562
|
-
{
|
|
563
|
-
name: "sources",
|
|
564
|
-
type: "json",
|
|
565
|
-
required: true,
|
|
566
|
-
desc: 'JSON array of knowledge base refs, e.g. [{"scope":"company","name":"engineering-handbook"}]'
|
|
567
|
-
},
|
|
568
|
-
{
|
|
569
|
-
name: "paths",
|
|
570
|
-
type: "json",
|
|
571
|
-
required: true,
|
|
572
|
-
desc: 'JSON array of wiki pages or subdirectories copied from +index, e.g. ["wiki/sandbox.md"] or ["wiki/guides"]'
|
|
573
|
-
},
|
|
574
|
-
{ name: "top-k", type: "number", required: false, desc: "Max number of hits to return (1-50, default 10)" },
|
|
575
|
-
{ name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
|
|
576
|
-
],
|
|
577
|
-
risk: "read",
|
|
578
|
-
dryRun: (ctx) => ({
|
|
579
|
-
method: "POST",
|
|
580
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
|
|
581
|
-
body: buildBody9(ctx)
|
|
582
|
-
}),
|
|
583
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody9(ctx))
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
// src/commands/te-kb/kb-read.ts
|
|
587
|
-
var API_PATH11 = "/agent/api/external/knowledge-bases/read";
|
|
588
|
-
function buildBody10(ctx) {
|
|
589
|
-
const body = {
|
|
590
|
-
source: ctx.json("source"),
|
|
591
|
-
path: ctx.str("path")
|
|
592
|
-
};
|
|
593
|
-
const offset = ctx.num("offset");
|
|
594
|
-
if (offset) body.offset = offset;
|
|
595
|
-
const limit = ctx.num("limit");
|
|
596
|
-
if (limit) body.limit = limit;
|
|
597
|
-
if (ctx.bool("outline")) body.outline = true;
|
|
598
|
-
const locale = ctx.str("locale");
|
|
599
|
-
if (locale) body.locale = locale;
|
|
600
|
-
return body;
|
|
601
|
-
}
|
|
602
|
-
var kbRead = {
|
|
603
|
-
service: "kb",
|
|
604
|
-
command: "+read",
|
|
605
|
-
description: "Read a full knowledge base page (or a line window) via POST /agent/api/external/knowledge-bases/read. Use after +index / +grep locate a candidate page. Pass --outline to get only the page heading tree (no content) and pick a section to read.",
|
|
606
|
-
flags: [
|
|
607
|
-
{
|
|
608
|
-
name: "source",
|
|
609
|
-
type: "json",
|
|
610
|
-
required: true,
|
|
611
|
-
desc: 'Knowledge base ref pointing to exactly one base, e.g. {"scope":"company","name":"engineering-handbook"}'
|
|
612
|
-
},
|
|
613
|
-
{
|
|
614
|
-
name: "path",
|
|
615
|
-
type: "string",
|
|
616
|
-
required: true,
|
|
617
|
-
desc: "Page path relative to the knowledge base root, e.g. wiki/concepts/data-model.md or index.md"
|
|
618
|
-
},
|
|
619
|
-
{ name: "offset", type: "number", required: false, desc: "Start line (1-based). Omit to read from the beginning." },
|
|
620
|
-
{ name: "limit", type: "number", required: false, desc: "Max number of lines to return (1-10000)." },
|
|
621
|
-
{
|
|
622
|
-
name: "outline",
|
|
623
|
-
type: "boolean",
|
|
624
|
-
required: false,
|
|
625
|
-
desc: "Return only the page outline (headings with line numbers), no content. Use it to decide which section to read on long pages."
|
|
626
|
-
},
|
|
627
|
-
{ name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
|
|
628
|
-
],
|
|
629
|
-
risk: "read",
|
|
630
|
-
dryRun: (ctx) => ({
|
|
631
|
-
method: "POST",
|
|
632
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH11}`,
|
|
633
|
-
body: buildBody10(ctx)
|
|
634
|
-
}),
|
|
635
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH11, {}, buildBody10(ctx))
|
|
636
|
-
};
|
|
637
|
-
|
|
638
|
-
// src/commands/te-kb/ask-shared.ts
|
|
639
|
-
var ASK_API_PATH = "/agent/api/external/knowledge-bases/ask";
|
|
640
|
-
var ASK_POLL_INTERVAL_MS = 5e3;
|
|
641
|
-
var ASK_POLL_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
642
|
-
var ASK_MAX_TRANSIENT_POLL_FAILURES = 3;
|
|
643
|
-
function isTransientAskPollError(error) {
|
|
644
|
-
if (error instanceof PermissionError) return false;
|
|
645
|
-
if (error instanceof TypeError) return true;
|
|
646
|
-
if (!(error instanceof Error)) return false;
|
|
647
|
-
if (/KB MCP token auth failed|unauthorized|Invalid access token/i.test(error.message)) {
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
return /fetch|network|socket|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|timeout/i.test(
|
|
651
|
-
error.message
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
async function pollUntilSettled(getStatus, executionId, options = {}) {
|
|
655
|
-
const intervalMs = options.intervalMs ?? ASK_POLL_INTERVAL_MS;
|
|
656
|
-
const timeoutMs = options.timeoutMs ?? ASK_POLL_TIMEOUT_MS;
|
|
657
|
-
const maxTransientFailures = options.maxTransientFailures ?? ASK_MAX_TRANSIENT_POLL_FAILURES;
|
|
658
|
-
const now = options.now ?? Date.now;
|
|
659
|
-
const sleep = options.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
|
|
660
|
-
const startTime = now();
|
|
661
|
-
let transientFailures = 0;
|
|
662
|
-
while (true) {
|
|
663
|
-
const elapsed = now() - startTime;
|
|
664
|
-
if (elapsed > timeoutMs) {
|
|
665
|
-
throw new Error(
|
|
666
|
-
`Ask execution timeout after ${Math.floor(elapsed / 1e3)} seconds (executionId: ${executionId})`
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
let response;
|
|
670
|
-
try {
|
|
671
|
-
response = await getStatus(executionId);
|
|
672
|
-
transientFailures = 0;
|
|
673
|
-
} catch (err) {
|
|
674
|
-
if (!isTransientAskPollError(err) || ++transientFailures >= maxTransientFailures) {
|
|
675
|
-
throw err;
|
|
676
|
-
}
|
|
677
|
-
await sleep(intervalMs);
|
|
678
|
-
continue;
|
|
679
|
-
}
|
|
680
|
-
if (response.status !== "running") {
|
|
681
|
-
return response;
|
|
682
|
-
}
|
|
683
|
-
await sleep(intervalMs);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
function transformCompletedResponse(response) {
|
|
687
|
-
const result = {
|
|
688
|
-
executionId: response.executionId,
|
|
689
|
-
answer: response.answer ?? "",
|
|
690
|
-
sources: response.sources ?? []
|
|
691
|
-
};
|
|
692
|
-
if (response.modelId !== void 0) result.modelId = response.modelId;
|
|
693
|
-
if (response.modelUsage !== void 0) result.modelUsage = response.modelUsage;
|
|
694
|
-
if (response.toolCallCount !== void 0) result.toolCallCount = response.toolCallCount;
|
|
695
|
-
if (response.maxTurns !== void 0) result.maxTurns = response.maxTurns;
|
|
696
|
-
return result;
|
|
697
|
-
}
|
|
698
|
-
function buildFailedMessage(response) {
|
|
699
|
-
const type = response.error?.type || "unknown";
|
|
700
|
-
const message = response.error?.message || "Ask execution failed";
|
|
701
|
-
return `[${type}] ${message} (executionId: ${response.executionId})`;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
// src/commands/te-kb/ask.ts
|
|
705
|
-
var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
|
|
706
|
-
var MIN_QUESTION_LEN = 1;
|
|
707
|
-
var MAX_QUESTION_LEN = 2e3;
|
|
708
|
-
var MIN_MAX_TURNS = 1;
|
|
709
|
-
var MAX_MAX_TURNS = 100;
|
|
710
|
-
function validateQuestion(question) {
|
|
711
|
-
const len = question.length;
|
|
712
|
-
if (len < MIN_QUESTION_LEN || len > MAX_QUESTION_LEN) {
|
|
713
|
-
throw new Error(
|
|
714
|
-
`Invalid --question length: ${len}. Must be between ${MIN_QUESTION_LEN} and ${MAX_QUESTION_LEN} characters.`
|
|
715
|
-
);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
function validateLocale(locale) {
|
|
719
|
-
if (locale && !VALID_LOCALES.has(locale)) {
|
|
720
|
-
throw new Error(`Invalid --locale: ${locale}. Must be one of: zh | en | ja | ko`);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
function validateMaxTurns(maxTurns) {
|
|
724
|
-
if (maxTurns !== 0 && (maxTurns < MIN_MAX_TURNS || maxTurns > MAX_MAX_TURNS)) {
|
|
725
|
-
throw new Error(
|
|
726
|
-
`Invalid --max-turns: ${maxTurns}. Must be between ${MIN_MAX_TURNS} and ${MAX_MAX_TURNS}.`
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
function buildBody11(ctx) {
|
|
731
|
-
const body = {
|
|
732
|
-
question: ctx.str("question")
|
|
733
|
-
};
|
|
734
|
-
const sources = ctx.json("sources");
|
|
735
|
-
if (sources) body.sources = sources;
|
|
736
|
-
const modelId = ctx.str("model-id");
|
|
737
|
-
if (modelId) body.modelId = modelId;
|
|
738
|
-
const maxTurns = ctx.num("max-turns");
|
|
739
|
-
if (maxTurns) body.maxTurns = maxTurns;
|
|
740
|
-
const locale = ctx.str("locale");
|
|
741
|
-
if (locale) body.locale = locale;
|
|
742
|
-
return body;
|
|
743
|
-
}
|
|
744
|
-
var ask = {
|
|
745
|
-
service: "kb",
|
|
746
|
-
command: "+ask",
|
|
747
|
-
description: "Ask knowledge bases via LLM-powered retrieval (POST /agent/api/external/knowledge-bases/ask). Consumes platform tokens. Prefer +index -> +grep -> +read for deterministic, token-free lookup. By default, polls for completion; use --no-wait to return immediately with executionId.",
|
|
748
|
-
flags: [
|
|
749
|
-
{
|
|
750
|
-
name: "question",
|
|
751
|
-
type: "string",
|
|
752
|
-
required: true,
|
|
753
|
-
alias: "q",
|
|
754
|
-
desc: "Natural-language question (1-2000 characters). Required."
|
|
755
|
-
},
|
|
756
|
-
{
|
|
757
|
-
name: "sources",
|
|
758
|
-
type: "json",
|
|
759
|
-
required: false,
|
|
760
|
-
desc: 'Optional JSON array of knowledge base refs to scope the search, e.g. [{"scope":"company","name":"engineering-handbook"}]. Omit to search all accessible knowledge bases.'
|
|
761
|
-
},
|
|
762
|
-
{
|
|
763
|
-
name: "model-id",
|
|
764
|
-
type: "string",
|
|
765
|
-
required: false,
|
|
766
|
-
desc: "Optional LLM model ID (e.g. claude-sonnet-4-6). Omit to use the platform default model."
|
|
767
|
-
},
|
|
768
|
-
{
|
|
769
|
-
name: "max-turns",
|
|
770
|
-
type: "number",
|
|
771
|
-
required: false,
|
|
772
|
-
desc: "Optional agent turn limit (1-100, default 50 on server when omitted)."
|
|
773
|
-
},
|
|
774
|
-
{ name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" },
|
|
775
|
-
{
|
|
776
|
-
name: "no-wait",
|
|
777
|
-
type: "boolean",
|
|
778
|
-
required: false,
|
|
779
|
-
desc: "Return immediately after submission with executionId, without polling for completion."
|
|
780
|
-
}
|
|
781
|
-
],
|
|
782
|
-
risk: "read",
|
|
783
|
-
validate: (ctx) => {
|
|
784
|
-
validateQuestion(ctx.str("question"));
|
|
785
|
-
validateLocale(ctx.str("locale"));
|
|
786
|
-
validateMaxTurns(ctx.num("max-turns"));
|
|
787
|
-
},
|
|
788
|
-
dryRun: (ctx) => ({
|
|
789
|
-
method: "POST",
|
|
790
|
-
url: `${ctx.host().replace(/\/$/, "")}${ASK_API_PATH}`,
|
|
791
|
-
body: buildBody11(ctx)
|
|
792
|
-
}),
|
|
793
|
-
execute: async (ctx) => {
|
|
794
|
-
const noWait = ctx.bool("no-wait");
|
|
795
|
-
const submitResponse = await kbApi(ctx, "POST", ASK_API_PATH, {}, buildBody11(ctx));
|
|
796
|
-
if (!submitResponse.executionId) {
|
|
797
|
-
throw new Error("Invalid submit response: missing executionId");
|
|
798
|
-
}
|
|
799
|
-
const executionId = submitResponse.executionId;
|
|
800
|
-
if (noWait) {
|
|
801
|
-
return {
|
|
802
|
-
executionId,
|
|
803
|
-
status: submitResponse.status
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
const finalResponse = await pollUntilSettled(
|
|
807
|
-
(id) => kbApi(ctx, "GET", ASK_API_PATH, { executionId: id }),
|
|
808
|
-
executionId
|
|
809
|
-
);
|
|
810
|
-
if (finalResponse.status === "completed") {
|
|
811
|
-
return transformCompletedResponse(finalResponse);
|
|
812
|
-
}
|
|
813
|
-
if (finalResponse.status === "failed") {
|
|
814
|
-
throw new Error(buildFailedMessage(finalResponse));
|
|
815
|
-
}
|
|
816
|
-
throw new Error(`Unexpected execution status: ${finalResponse.status}`);
|
|
817
|
-
}
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
// src/commands/te-kb/ask-status.ts
|
|
821
|
-
var MAX_EXECUTION_ID_LEN = 64;
|
|
822
|
-
function executionIdFrom(ctx) {
|
|
823
|
-
return ctx.str("execution-id").trim();
|
|
824
|
-
}
|
|
825
|
-
var askStatus = {
|
|
826
|
-
service: "kb",
|
|
827
|
-
command: "+ask-status",
|
|
828
|
-
description: "Query the status of an in-progress or completed knowledge base ask execution (GET /agent/api/external/knowledge-bases/ask?executionId=<id>). Does not poll; returns the current state.",
|
|
829
|
-
flags: [
|
|
830
|
-
{
|
|
831
|
-
name: "execution-id",
|
|
832
|
-
type: "string",
|
|
833
|
-
required: true,
|
|
834
|
-
minLength: 1,
|
|
835
|
-
maxLength: MAX_EXECUTION_ID_LEN,
|
|
836
|
-
desc: "The execution ID returned by kb +ask submission."
|
|
837
|
-
}
|
|
838
|
-
],
|
|
839
|
-
risk: "read",
|
|
840
|
-
validate: (ctx) => {
|
|
841
|
-
const executionId = executionIdFrom(ctx);
|
|
842
|
-
if (!executionId) {
|
|
843
|
-
throw new Error("Invalid --execution-id: must be non-empty.");
|
|
844
|
-
}
|
|
845
|
-
if (executionId.length > MAX_EXECUTION_ID_LEN) {
|
|
846
|
-
throw new Error(
|
|
847
|
-
`Invalid --execution-id length: ${executionId.length}. Must be at most ${MAX_EXECUTION_ID_LEN} characters.`
|
|
848
|
-
);
|
|
849
|
-
}
|
|
850
|
-
},
|
|
851
|
-
dryRun: (ctx) => ({
|
|
852
|
-
method: "GET",
|
|
853
|
-
url: `${ctx.host().replace(/\/$/, "")}${ASK_API_PATH}?executionId=${encodeURIComponent(executionIdFrom(ctx))}`
|
|
854
|
-
}),
|
|
855
|
-
execute: async (ctx) => {
|
|
856
|
-
const executionId = executionIdFrom(ctx);
|
|
857
|
-
return await kbApi(ctx, "GET", ASK_API_PATH, { executionId });
|
|
858
|
-
}
|
|
859
|
-
};
|
|
860
|
-
|
|
861
|
-
// src/commands/te-kb/url.ts
|
|
862
|
-
var API_PATH12 = "/agent/api/external/knowledge-bases/sources/url";
|
|
863
|
-
function validateUrl(url2) {
|
|
864
|
-
if (!/^https?:\/\//i.test(url2)) {
|
|
865
|
-
throw new Error(`Invalid --url: ${url2}. Must be an http(s) URL`);
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
function buildBody12(ctx) {
|
|
869
|
-
const body = {
|
|
870
|
-
name: ctx.str("name"),
|
|
871
|
-
url: ctx.str("url")
|
|
872
|
-
};
|
|
873
|
-
const displayName = ctx.str("display-name");
|
|
874
|
-
if (displayName) body.displayName = displayName;
|
|
875
|
-
const parseInstruction = ctx.str("parse-instruction");
|
|
876
|
-
if (parseInstruction) body.parseInstruction = parseInstruction;
|
|
877
|
-
return body;
|
|
878
|
-
}
|
|
879
|
-
var url = {
|
|
880
|
-
service: "kb",
|
|
881
|
-
command: "+url",
|
|
882
|
-
description: "Upload a URL source to a knowledge base.",
|
|
883
|
-
flags: [
|
|
884
|
-
{ name: "name", type: "string", required: true, desc: "Knowledge base name" },
|
|
885
|
-
{ name: "url", type: "string", required: true, desc: "Source URL to upload" },
|
|
886
|
-
{ name: "display-name", type: "string", required: false, desc: "Optional display name for the URL source" },
|
|
887
|
-
{ name: "parse-instruction", type: "string", required: false, desc: "Optional parsing instruction for the URL source; ignored for Lark/Feishu doc URLs (the server applies its own Feishu parsing)" }
|
|
888
|
-
],
|
|
889
|
-
risk: "write",
|
|
890
|
-
validate: (ctx) => {
|
|
891
|
-
validateUrl(ctx.str("url"));
|
|
892
|
-
},
|
|
893
|
-
dryRun: (ctx) => ({
|
|
894
|
-
method: "POST",
|
|
895
|
-
url: `${ctx.host().replace(/\/$/, "")}${API_PATH12}`,
|
|
896
|
-
body: buildBody12(ctx)
|
|
897
|
-
}),
|
|
898
|
-
execute: async (ctx) => kbApi(ctx, "POST", API_PATH12, {}, buildBody12(ctx))
|
|
899
|
-
};
|
|
900
|
-
|
|
901
|
-
// src/commands/te-kb/index.ts
|
|
902
|
-
var commands = [
|
|
903
|
-
ask,
|
|
904
|
-
askStatus,
|
|
905
|
-
add,
|
|
906
|
-
url,
|
|
907
|
-
compile,
|
|
908
|
-
remove,
|
|
909
|
-
create,
|
|
910
|
-
rmSource,
|
|
911
|
-
schema,
|
|
912
|
-
status,
|
|
913
|
-
kbList,
|
|
914
|
-
kbIndex,
|
|
915
|
-
kbGrep,
|
|
916
|
-
kbRead
|
|
917
|
-
];
|
|
918
|
-
var te_kb_default = commands;
|
|
919
|
-
export {
|
|
920
|
-
add,
|
|
921
|
-
ask,
|
|
922
|
-
askStatus,
|
|
923
|
-
compile,
|
|
924
|
-
create,
|
|
925
|
-
te_kb_default as default,
|
|
926
|
-
kbGrep,
|
|
927
|
-
kbIndex,
|
|
928
|
-
kbList,
|
|
929
|
-
kbRead,
|
|
930
|
-
remove,
|
|
931
|
-
rmSource,
|
|
932
|
-
schema,
|
|
933
|
-
status,
|
|
934
|
-
url
|
|
935
|
-
};
|