@numa-tech/numa 1.20.2 → 1.20.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.
Files changed (142) hide show
  1. package/README.md +13 -1
  2. package/dist/application-onboarding/schemas.d.ts +24 -0
  3. package/dist/application-onboarding/schemas.js +4 -0
  4. package/dist/application-onboarding/schemas.js.map +1 -1
  5. package/dist/application-onboarding/tui-model.d.ts +1 -0
  6. package/dist/application-onboarding/tui-model.js +10 -0
  7. package/dist/application-onboarding/tui-model.js.map +1 -1
  8. package/dist/application-onboarding/tui.js +1 -1
  9. package/dist/application-onboarding/tui.js.map +1 -1
  10. package/dist/authorization/application-client.d.ts +46 -5
  11. package/dist/authorization/application-client.js +21 -4
  12. package/dist/authorization/application-client.js.map +1 -1
  13. package/dist/authorization/application-commands.js +10 -3
  14. package/dist/authorization/application-commands.js.map +1 -1
  15. package/dist/authorization/application-schemas.d.ts +52 -6
  16. package/dist/authorization/application-schemas.js +25 -3
  17. package/dist/authorization/application-schemas.js.map +1 -1
  18. package/dist/business-issuer.js +8 -0
  19. package/dist/business-issuer.js.map +1 -1
  20. package/dist/cli.js +49 -31
  21. package/dist/cli.js.map +1 -1
  22. package/dist/command-catalog.js +9 -0
  23. package/dist/command-catalog.js.map +1 -1
  24. package/dist/kb/catalog.d.ts +2 -0
  25. package/dist/kb/catalog.js +14 -0
  26. package/dist/kb/catalog.js.map +1 -0
  27. package/dist/kb/client.d.ts +46 -0
  28. package/dist/kb/client.js +272 -0
  29. package/dist/kb/client.js.map +1 -0
  30. package/dist/kb/commands.d.ts +14 -0
  31. package/dist/kb/commands.js +121 -0
  32. package/dist/kb/commands.js.map +1 -0
  33. package/dist/kb/config.d.ts +15 -0
  34. package/dist/kb/config.js +76 -0
  35. package/dist/kb/config.js.map +1 -0
  36. package/dist/kb/errors.d.ts +9 -0
  37. package/dist/kb/errors.js +31 -0
  38. package/dist/kb/errors.js.map +1 -0
  39. package/dist/kb/transfers.d.ts +67 -0
  40. package/dist/kb/transfers.js +257 -0
  41. package/dist/kb/transfers.js.map +1 -0
  42. package/dist/kb/types.d.ts +81 -0
  43. package/dist/kb/types.js +2 -0
  44. package/dist/kb/types.js.map +1 -0
  45. package/dist/kb/upload-state.d.ts +20 -0
  46. package/dist/kb/upload-state.js +135 -0
  47. package/dist/kb/upload-state.js.map +1 -0
  48. package/dist/login-recovery.js +15 -1
  49. package/dist/login-recovery.js.map +1 -1
  50. package/dist/maintenance/modules.js +1 -1
  51. package/dist/maintenance/modules.js.map +1 -1
  52. package/dist/mcp/catalog.js +6 -1
  53. package/dist/mcp/catalog.js.map +1 -1
  54. package/dist/oss/file-operations.d.ts +8 -0
  55. package/dist/oss/file-operations.js +48 -6
  56. package/dist/oss/file-operations.js.map +1 -1
  57. package/dist/oss/signed-url-transfers.d.ts +41 -0
  58. package/dist/oss/signed-url-transfers.js +207 -0
  59. package/dist/oss/signed-url-transfers.js.map +1 -0
  60. package/dist/oss/transfer-pool.d.ts +2 -0
  61. package/dist/oss/transfer-pool.js +27 -0
  62. package/dist/oss/transfer-pool.js.map +1 -0
  63. package/dist/oss/transfer-worker.js +8 -17
  64. package/dist/oss/transfer-worker.js.map +1 -1
  65. package/dist/oss/web-page.js +48 -8
  66. package/dist/oss/web-page.js.map +1 -1
  67. package/dist/platform-profile.d.ts +1 -1
  68. package/dist/server.d.ts +2 -0
  69. package/dist/server.js +2 -0
  70. package/dist/server.js.map +1 -1
  71. package/dist/tasks/commands.d.ts +9 -0
  72. package/dist/tasks/commands.js +60 -0
  73. package/dist/tasks/commands.js.map +1 -0
  74. package/dist/tasks/oss-query.d.ts +56 -0
  75. package/dist/tasks/oss-query.js +125 -0
  76. package/dist/tasks/oss-query.js.map +1 -0
  77. package/dist/tasks/runtime.d.ts +151 -0
  78. package/dist/tasks/runtime.js +71 -0
  79. package/dist/tasks/runtime.js.map +1 -0
  80. package/dist/tasks/tools.d.ts +3 -0
  81. package/dist/tasks/tools.js +16 -0
  82. package/dist/tasks/tools.js.map +1 -0
  83. package/dist/tasks/types.d.ts +14 -0
  84. package/dist/tasks/types.js +4 -0
  85. package/dist/tasks/types.js.map +1 -0
  86. package/dist/tasks/wecom-notify.d.ts +26 -0
  87. package/dist/tasks/wecom-notify.js +150 -0
  88. package/dist/tasks/wecom-notify.js.map +1 -0
  89. package/docs/agent-tasks.md +97 -0
  90. package/docs/application-default-groups.md +36 -0
  91. package/docs/design/kb-cli.md +94 -0
  92. package/docs/kb-access.md +85 -0
  93. package/package.json +12 -6
  94. package/scripts/export-kb-contract.py +158 -0
  95. package/skills/numa-ai-registry/SKILL.md +2 -2
  96. package/skills/numa-cli/SKILL.md +24 -9
  97. package/skills/numa-cli/agents/openai.yaml +2 -2
  98. package/skills/numa-cli/evals/evals.json +13 -1
  99. package/skills/numa-cli/numa-skill.json +1 -1
  100. package/skills/numa-cli/references/cli-bootstrap.md +8 -8
  101. package/skills/numa-cli/references/cli-mcp.md +28 -20
  102. package/skills/numa-cli/references/pipeline-release.md +9 -9
  103. package/skills/numa-cli/references/skills-command-contract.md +40 -40
  104. package/skills/numa-cli/references/skills-updates.md +13 -13
  105. package/skills/numa-cli/references/skills-workflows.md +4 -4
  106. package/skills/numa-create-application/SKILL.md +1 -1
  107. package/skills/numa-create-application/numa-skill.json +2 -2
  108. package/skills/numa-create-application/references/cli-bootstrap.md +3 -3
  109. package/skills/numa-create-application/references/numa-cli.md +16 -16
  110. package/skills/numa-jenkins-deployment/SKILL.md +8 -8
  111. package/skills/numa-jenkins-deployment/numa-skill.json +2 -2
  112. package/skills/numa-jenkins-deployment/references/cli-bootstrap.md +3 -3
  113. package/skills/numa-jenkins-deployment/references/cli-contract.md +7 -7
  114. package/skills/numa-jenkins-deployment/references/diagnostics.md +2 -2
  115. package/skills/numa-local-flux-deploy/SKILL.md +1 -1
  116. package/skills/numa-local-flux-deploy/numa-skill.json +2 -2
  117. package/skills/numa-local-flux-deploy/references/cli-bootstrap.md +3 -3
  118. package/skills/numa-nacos/SKILL.md +4 -4
  119. package/skills/numa-nacos/numa-skill.json +2 -2
  120. package/skills/numa-nacos/references/cli-bootstrap.md +3 -3
  121. package/skills/numa-nacos/references/command-contract.md +17 -17
  122. package/skills/numa-notion/SKILL.md +4 -4
  123. package/skills/numa-notion/numa-skill.json +2 -2
  124. package/skills/numa-notion/references/agents-automation.md +2 -2
  125. package/skills/numa-notion/references/cli-bootstrap.md +3 -3
  126. package/skills/numa-notion/references/cli.md +17 -17
  127. package/skills/numa-oss-access/SKILL.md +27 -81
  128. package/skills/numa-oss-access/agents/openai.yaml +2 -2
  129. package/skills/numa-oss-access/evals/evals.json +12 -0
  130. package/skills/numa-oss-access/numa-skill.json +2 -2
  131. package/skills/numa-oss-access/references/cli-bootstrap.md +5 -5
  132. package/skills/numa-oss-access/references/object-operations.md +95 -0
  133. package/skills/numa-oss-access/references/search-and-mcp.md +12 -11
  134. package/skills/numa-wecom/SKILL.md +27 -62
  135. package/skills/numa-wecom/agents/openai.yaml +2 -2
  136. package/skills/numa-wecom/evals/evals.json +25 -0
  137. package/skills/numa-wecom/numa-skill.json +2 -2
  138. package/skills/numa-wecom/references/cli-bootstrap.md +5 -5
  139. package/skills/numa-wecom/references/legacy-operations.md +71 -0
  140. package/skills/numa-wecom/references/machine-auth.md +7 -7
  141. package/skills/numa-wecom/references/mcp.md +9 -8
  142. package/src/kb/openapi-contract.json +1432 -0
@@ -0,0 +1,272 @@
1
+ import { createHash } from "node:crypto";
2
+ import { openAsBlob } from "node:fs";
3
+ import { z } from "zod";
4
+ import { ensureAccessToken } from "../oauth.js";
5
+ import { validateKbBaseUrl } from "./config.js";
6
+ import { KbError, sanitizeKbOutput } from "./errors.js";
7
+ const AGENT = "/api/v1/external/agent";
8
+ const EXTERNAL = "/api/v1/external";
9
+ const text = z.string().min(1);
10
+ const headersSchema = z.record(z.string(), z.string());
11
+ const taskSchema = z.object({ batch_id: text, status: text, archive_id: text.optional(),
12
+ task_status: text.optional(), collection_id: text.optional(),
13
+ total_count: z.number().int().nonnegative().optional(), completed_count: z.number().int().nonnegative().optional(),
14
+ failed_count: z.number().int().nonnegative().optional(), reused_count: z.number().int().nonnegative().optional(),
15
+ skipped_count: z.number().int().nonnegative().optional(), needs_resolution_count: z.number().int().nonnegative().optional(),
16
+ pending_count: z.number().int().nonnegative().optional(), processing_count: z.number().int().nonnegative().optional(),
17
+ files: z.array(z.record(z.string(), z.unknown())).optional() }).passthrough();
18
+ const uploadSchema = z.object({ method: z.literal("PUT"), url: text, headers: headersSchema, expires_at: text });
19
+ const sessionSchema = z.discriminatedUnion("transport", [
20
+ z.object({ transport: z.literal("proxy") }),
21
+ z.object({ transport: z.literal("direct"), session_id: text, batch_id: text, collection_id: text, request_id: text,
22
+ status: z.enum(["uploading", "submitted", "cancelled", "expired"]), expires_at: text,
23
+ files: z.array(z.object({ file_id: text, filename: text, size_bytes: z.number().int().positive(),
24
+ sha256: z.string().regex(/^[0-9a-f]{64}$/u), content_md5: text, content_type: text,
25
+ object_uploaded: z.boolean().optional(), upload: uploadSchema.nullable().optional() })).min(1),
26
+ batch: taskSchema.optional() })
27
+ ]);
28
+ const directSessionSchema = sessionSchema.options[1];
29
+ const downloadSchema = z.object({ transport: z.enum(["oss", "proxy"]), method: z.literal("GET"), url: text,
30
+ headers: headersSchema, expires_at: text.nullable(), filename: text,
31
+ size_bytes: z.number().int().nonnegative().nullable(), sha256: text.nullable(), content_type: text,
32
+ requires_api_key: z.boolean().optional() });
33
+ const objectSchema = z.record(z.string(), z.unknown());
34
+ async function boundedJson(response, limit) {
35
+ if (!response.body)
36
+ throw new Error("Empty body");
37
+ const reader = response.body.getReader();
38
+ const chunks = [];
39
+ let length = 0;
40
+ try {
41
+ while (true) {
42
+ const { value, done } = await reader.read();
43
+ if (done)
44
+ break;
45
+ length += value.byteLength;
46
+ if (length > limit)
47
+ throw new Error("Response too large");
48
+ chunks.push(value);
49
+ }
50
+ return JSON.parse(Buffer.concat(chunks, length).toString("utf8"));
51
+ }
52
+ catch (error) {
53
+ await reader.cancel().catch(() => { });
54
+ throw error;
55
+ }
56
+ finally {
57
+ reader.releaseLock();
58
+ }
59
+ }
60
+ function machineDetails(body, secrets) {
61
+ const allowed = new Set(["code", "error_code", "retryable", "suggested_action", "detail", "details", "conflicts", "files",
62
+ "filename", "document_id", "existing_document_id", "collection_id", "request_id", "session_id", "batch_id", "conflict_action", "reason_code",
63
+ "file_index", "file_id", "candidates", "requires_confirmation", "conflict_type", "can_manage_versions", "retry_after_seconds"]);
64
+ const project = (item, depth = 0) => {
65
+ if (depth > 5)
66
+ return undefined;
67
+ if (Array.isArray(item))
68
+ return item.slice(0, 100).map(value => project(value, depth + 1));
69
+ if (item && typeof item === "object")
70
+ return Object.fromEntries(Object.entries(item)
71
+ .filter(([key, value]) => allowed.has(key) && (!["detail", "details"].includes(key) || (value !== null && typeof value === "object")))
72
+ .map(([key, value]) => [key, project(value, depth + 1)]));
73
+ if (typeof item === "string") {
74
+ let value = item.slice(0, 500);
75
+ for (const secret of secrets)
76
+ if (secret)
77
+ value = value.replaceAll(secret, "[redacted]");
78
+ return value;
79
+ }
80
+ return typeof item === "boolean" || typeof item === "number" ? item : undefined;
81
+ };
82
+ const result = sanitizeKbOutput(project(body));
83
+ return result && typeof result === "object" && !Array.isArray(result) && Object.keys(result).length ? result : undefined;
84
+ }
85
+ function identifier(value) {
86
+ if (!value || value === "." || value === ".." || /[\u0000-\u001f\u007f]/u.test(value)) {
87
+ throw new KbError("A valid KB resource ID is required.", "kb_input_invalid");
88
+ }
89
+ return encodeURIComponent(value);
90
+ }
91
+ export class KbClient {
92
+ config;
93
+ baseUrl;
94
+ binding;
95
+ fetchImpl;
96
+ tokenProvider;
97
+ timeoutMs;
98
+ constructor(config, dependencies = {}) {
99
+ this.config = config;
100
+ this.baseUrl = validateKbBaseUrl(config.baseUrl);
101
+ if (!config.apiKey || /[\u0000-\u0020\u007f]/u.test(config.apiKey))
102
+ throw new KbError("A valid KB API key is required.", "kb_config_missing");
103
+ if (config.authMode !== "api-key" && (config.authMode !== "keycloak" || !config.auth))
104
+ throw new KbError("Keycloak configuration is required.", "kb_config_invalid");
105
+ if (config.tenantHeader && (!/^x-[a-z0-9-]+$/iu.test(config.tenantHeader.name) || /api.?key/iu.test(config.tenantHeader.name)
106
+ || /[\r\n]/u.test(config.tenantHeader.value)))
107
+ throw new KbError("Invalid KB tenant header.", "kb_config_invalid");
108
+ this.fetchImpl = dependencies.fetch ?? fetch;
109
+ this.tokenProvider = dependencies.tokenProvider ?? ensureAccessToken;
110
+ this.timeoutMs = dependencies.timeoutMs ?? 30_000;
111
+ this.binding = createHash("sha256").update(JSON.stringify({ baseUrl: this.baseUrl, mode: config.authMode,
112
+ keyFingerprint: createHash("sha256").update(config.apiKey).digest("hex"), tenant: config.tenantHeader,
113
+ issuer: config.auth?.issuerUrl ?? config.auth?.discoveryUrl, client: config.auth?.clientId,
114
+ audience: config.auth?.resourceAudience })).digest("hex");
115
+ }
116
+ async authenticatedFetch(url, init, write, timeout = this.timeoutMs) {
117
+ const headers = new Headers(init.headers);
118
+ headers.set("Accept", "application/json");
119
+ headers.set("X-Api-Key", this.config.apiKey);
120
+ if (this.config.tenantHeader)
121
+ headers.set(this.config.tenantHeader.name, this.config.tenantHeader.value);
122
+ const secrets = [this.config.apiKey];
123
+ if (this.config.authMode === "keycloak") {
124
+ let token;
125
+ try {
126
+ token = await this.tokenProvider(this.config.auth);
127
+ }
128
+ catch {
129
+ throw new KbError("KB Keycloak authentication is unavailable; run numa login --service kb with the configured identity.", "kb_auth_required");
130
+ }
131
+ if (!token || /[\r\n]/u.test(token))
132
+ throw new KbError("KB Keycloak token is invalid.", "kb_auth_required");
133
+ headers.set("Authorization", `Bearer ${token}`);
134
+ secrets.push(token);
135
+ }
136
+ const signal = init.signal ? AbortSignal.any([init.signal, AbortSignal.timeout(timeout)]) : AbortSignal.timeout(timeout);
137
+ let response;
138
+ try {
139
+ response = await this.fetchImpl(url, { ...init, headers, signal, redirect: "manual" });
140
+ }
141
+ catch {
142
+ throw new KbError(write ? "KB write result is unknown. Read the affected resource before retrying; uploads can resume with the original request ID." : "KB request failed or timed out.", write ? "kb_write_result_unknown" : "kb_network_error");
143
+ }
144
+ if (response.status >= 300 && response.status < 400) {
145
+ await response.body?.cancel();
146
+ throw new KbError("KB redirects are not followed. Check the configured service URL.", "kb_redirect_rejected", response.status);
147
+ }
148
+ if (!response.ok) {
149
+ let details;
150
+ try {
151
+ details = machineDetails(await boundedJson(response, 1024 * 1024), secrets);
152
+ }
153
+ catch { /* Remote errors are optional, bounded metadata. */ }
154
+ const auth = response.status === 401 || response.status === 403;
155
+ const unknown = write && response.status >= 500;
156
+ throw new KbError(auth ? "KB authorization failed; verify the API key and selected Keycloak identity."
157
+ : unknown ? "KB write result is unknown. Read the affected resource before retrying; uploads can resume with the original request ID."
158
+ : `KB API returned HTTP ${response.status}.`, auth ? "kb_auth_failed" : unknown ? "kb_write_result_unknown" : "kb_api_error", response.status, details);
159
+ }
160
+ return response;
161
+ }
162
+ async json(path, schema, init = {}, write = false) {
163
+ const headers = new Headers(init.headers);
164
+ if (typeof init.body === "string")
165
+ headers.set("Content-Type", "application/json");
166
+ const response = await this.authenticatedFetch(`${this.baseUrl}${path}`, { ...init, headers }, write, init.body instanceof FormData ? 10 * 60_000 : this.timeoutMs);
167
+ let body;
168
+ try {
169
+ body = await boundedJson(response, 8 * 1024 * 1024);
170
+ }
171
+ catch {
172
+ throw new KbError(write ? "KB write response was unreadable. Read the affected resource before retrying; uploads can resume with the original request ID." : "KB returned an unreadable JSON response.", write ? "kb_write_result_unknown" : "kb_invalid_response", response.status);
173
+ }
174
+ // Agent search can return a semantic error with HTTP 200.
175
+ if (body && typeof body === "object" && "error" in body)
176
+ throw new KbError("KB operation failed.", "kb_api_error", response.status);
177
+ const result = schema.safeParse(body);
178
+ if (!result.success)
179
+ throw new KbError(write ? "KB write returned an invalid response. Read the affected resource before retrying; uploads can resume with the original request ID." : "KB returned an invalid response.", write ? "kb_write_result_unknown" : "kb_invalid_response", response.status);
180
+ return result.data;
181
+ }
182
+ listCollections() {
183
+ return this.json(`${AGENT}/collections`, z.object({ collections: z.array(objectSchema), total: z.number().int().nonnegative() }).passthrough());
184
+ }
185
+ createCollection(input) {
186
+ if (!input.name.trim())
187
+ throw new KbError("Collection name is required.", "kb_input_invalid");
188
+ return this.json(`${AGENT}/task-collections`, z.object({ collection_id: text }).passthrough(), {
189
+ method: "POST", body: JSON.stringify({ task_name: input.name, collection_name: input.name, description: input.description, visibility: "private" })
190
+ }, true);
191
+ }
192
+ search(input) {
193
+ if (!input.query.trim() || !input.collection_id || (input.top_k !== undefined && (!Number.isInteger(input.top_k) || input.top_k < 1 || input.top_k > 10))
194
+ || (input.min_score !== undefined && (!Number.isFinite(input.min_score) || input.min_score < 0 || input.min_score > 1))) {
195
+ throw new KbError("Search requires a query, collection ID, top-k 1–10 and min-score 0–1.", "kb_input_invalid");
196
+ }
197
+ return this.json(`${AGENT}/search`, objectSchema, { method: "POST", body: JSON.stringify(input) });
198
+ }
199
+ beginUpload(input) {
200
+ return this.json(`${AGENT}/upload-sessions`, sessionSchema, { method: "POST", body: JSON.stringify(input) }, true);
201
+ }
202
+ getUpload(sessionId, renew = false) {
203
+ return this.json(`${AGENT}/upload-sessions/${identifier(sessionId)}?renew=${renew}`, directSessionSchema);
204
+ }
205
+ completeUpload(sessionId) {
206
+ return this.json(`${AGENT}/upload-sessions/${identifier(sessionId)}/complete`, directSessionSchema, { method: "POST" }, true);
207
+ }
208
+ cancelUpload(sessionId) {
209
+ return this.json(`${AGENT}/upload-sessions/${identifier(sessionId)}`, directSessionSchema, { method: "DELETE" }, true);
210
+ }
211
+ downloadTicket(documentId) {
212
+ return this.json(`${AGENT}/documents/${identifier(documentId)}/download-ticket`, downloadSchema);
213
+ }
214
+ getTask(taskId, kind = "archive") {
215
+ return this.json(`${kind === "batch" ? `${EXTERNAL}/batches` : `${AGENT}/archives`}/${identifier(taskId)}`, taskSchema);
216
+ }
217
+ retryTask(taskId, kind = "archive") {
218
+ return this.json(`${kind === "batch" ? `${EXTERNAL}/batches` : `${AGENT}/archives`}/${identifier(taskId)}/retry`, taskSchema, { method: "POST" }, true);
219
+ }
220
+ async proxyUpload(input) {
221
+ const form = new FormData();
222
+ form.set("collection_id", input.collectionId);
223
+ form.set("request_id", input.requestId);
224
+ form.set("conflict_policy", "reject");
225
+ for (const file of input.files) {
226
+ let blob;
227
+ try {
228
+ blob = await openAsBlob(file.path);
229
+ }
230
+ catch {
231
+ throw new KbError("Cannot read a proxy upload source file.", "kb_input_invalid");
232
+ }
233
+ form.append("files", blob, file.filename);
234
+ }
235
+ return this.json(`${EXTERNAL}/documents/batch-upload`, taskSchema, { method: "POST", body: form, signal: input.signal }, true);
236
+ }
237
+ async downloadProxy(ticket, signal) {
238
+ if (ticket.transport !== "proxy" || ticket.method !== "GET")
239
+ throw new KbError("Invalid proxy download ticket.", "kb_invalid_response");
240
+ const base = new URL(this.baseUrl);
241
+ let url;
242
+ try {
243
+ // The backend's relative ticket path omits a gateway service prefix.
244
+ url = ticket.url.startsWith("/api/v1/external/") ? new URL(`${this.baseUrl}${ticket.url}`) : new URL(ticket.url, `${this.baseUrl}/`);
245
+ }
246
+ catch {
247
+ throw new KbError("Invalid proxy download URL.", "kb_invalid_response");
248
+ }
249
+ const prefix = `${base.pathname.replace(/\/+$/u, "")}${EXTERNAL}/`;
250
+ let decoded = url.pathname;
251
+ try {
252
+ for (let i = 0; i < 3; i++)
253
+ decoded = decodeURIComponent(decoded);
254
+ }
255
+ catch {
256
+ throw new KbError("Invalid proxy download URL.", "kb_invalid_response");
257
+ }
258
+ if (url.origin !== base.origin || url.username || url.password || url.hash || !url.pathname.startsWith(prefix)
259
+ || decoded.includes("\\") || decoded.split("/").some(part => part === "." || part === "..")) {
260
+ throw new KbError("Proxy downloads must stay within the configured KB service.", "kb_download_origin_rejected");
261
+ }
262
+ // Never accept authentication headers from a remote ticket.
263
+ const headers = new Headers();
264
+ for (const [key, value] of Object.entries(ticket.headers)) {
265
+ if (!["accept", "range", "if-match", "if-none-match"].includes(key.toLowerCase()))
266
+ throw new KbError("Unsafe proxy ticket header.", "kb_invalid_response");
267
+ headers.set(key, value);
268
+ }
269
+ return this.authenticatedFetch(url.toString(), { method: "GET", headers, signal }, false, 10 * 60_000);
270
+ }
271
+ }
272
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/kb/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Command } from "commander";
2
+ import { KbClient } from "./client.js";
3
+ import { uploadToKb, downloadFromKb, waitForTask } from "./transfers.js";
4
+ import { KB_COMMAND_CATALOG } from "./catalog.js";
5
+ export { KB_COMMAND_CATALOG };
6
+ export interface KbCommandDependencies {
7
+ clientFactory?: () => KbClient | Promise<KbClient>;
8
+ write?: (text: string) => void;
9
+ writeProgress?: (text: string) => void;
10
+ upload?: typeof uploadToKb;
11
+ download?: typeof downloadFromKb;
12
+ wait?: typeof waitForTask;
13
+ }
14
+ export declare function registerKbCommands(program: Command, dependencies?: KbCommandDependencies): void;
@@ -0,0 +1,121 @@
1
+ import process from "node:process";
2
+ import { KbClient } from "./client.js";
3
+ import { loadKbConfig } from "./config.js";
4
+ import { KbError, sanitizeKbOutput } from "./errors.js";
5
+ import { uploadToKb, downloadFromKb, waitForTask } from "./transfers.js";
6
+ import { KB_COMMAND_CATALOG } from "./catalog.js";
7
+ export { KB_COMMAND_CATALOG };
8
+ function integer(value, name, max) {
9
+ if (!/^\d+$/u.test(value) || Number(value) < 1 || Number(value) > max) {
10
+ throw new KbError(`${name} 必须是 1-${max} 的整数。`, "kb_input_invalid");
11
+ }
12
+ return Number(value);
13
+ }
14
+ function taskKind(id, kind) {
15
+ if (kind !== undefined && kind !== "archive" && kind !== "batch") {
16
+ throw new KbError("--kind 必须是 archive 或 batch。", "kb_input_invalid");
17
+ }
18
+ return kind ?? (id.startsWith("ext_") ? "batch" : "archive");
19
+ }
20
+ async function interruptible(work) {
21
+ const controller = new AbortController();
22
+ const abort = () => controller.abort();
23
+ process.once("SIGINT", abort);
24
+ process.once("SIGTERM", abort);
25
+ try {
26
+ return await work(controller.signal);
27
+ }
28
+ finally {
29
+ process.removeListener("SIGINT", abort);
30
+ process.removeListener("SIGTERM", abort);
31
+ }
32
+ }
33
+ export function registerKbCommands(program, dependencies = {}) {
34
+ const client = async () => dependencies.clientFactory?.() ?? new KbClient(await loadKbConfig());
35
+ const output = (value) => (dependencies.write ?? ((text) => process.stdout.write(text)))(`${JSON.stringify({ ok: true, data: sanitizeKbOutput(value) }, null, 2)}\n`);
36
+ // Only explicit progress fields are rendered; tickets and response payloads never reach stderr.
37
+ const progress = (value) => {
38
+ if (!value || typeof value !== "object")
39
+ return;
40
+ const item = value;
41
+ const parts = [];
42
+ if (typeof item.phase === "string" && /^[a-z_-]{1,40}$/u.test(item.phase))
43
+ parts.push(item.phase);
44
+ if (typeof item.transferred === "number" && Number.isFinite(item.transferred))
45
+ parts.push(`${item.transferred} bytes`);
46
+ if (parts.length)
47
+ (dependencies.writeProgress ?? ((text) => process.stderr.write(text)))(`${parts.join(" ")}\n`);
48
+ };
49
+ const kb = program.command("kb").description("知识库检索、原件传输和入库任务;通过 KB REST API 复用 OSS 传输")
50
+ .addHelpText("after", "\n配置:Profile services.kb 或 NUMA_KB_BASE_URL;NUMA_KB_API_KEY / NUMA_KB_API_KEY_FILE。\n默认使用 Numa Keycloak 登录,NUMA_KB_AUTH_MODE=api-key 可显式选择仅 API Key 的部署。\n");
51
+ const collections = kb.command("collections").description("当前身份可见的知识库");
52
+ collections.command("list").description("列出知识库").action(async () => output(await (await client()).listCollections()));
53
+ collections.command("create").description("创建私有任务知识库")
54
+ .requiredOption("--name <name>", "知识库名称")
55
+ .option("--description <text>", "知识库说明")
56
+ .action(async (options) => {
57
+ if (!options.name.trim() || options.name.length > 50)
58
+ throw new KbError("名称须为 1-50 个字符。", "kb_input_invalid");
59
+ output(await (await client()).createCollection({ name: options.name, description: options.description }));
60
+ });
61
+ kb.command("search <query>").description("检索文档内容与来源")
62
+ .requiredOption("--collection-id <id>", "目标知识库 ID")
63
+ .option("--top-k <number>", "返回片段数 1-10", "5")
64
+ .option("--min-score <number>", "最低相关度 0-1", "0")
65
+ .action(async (query, options) => {
66
+ const top = integer(options.topK, "--top-k", 10);
67
+ const score = Number(options.minScore);
68
+ if (!query.trim() || !options.minScore.trim() || !Number.isFinite(score) || score < 0 || score > 1) {
69
+ throw new KbError("查询不能为空,--min-score 须为 0-1。", "kb_input_invalid");
70
+ }
71
+ output(await (await client()).search({ query, collection_id: options.collectionId, top_k: top, min_score: score }));
72
+ });
73
+ kb.command("upload <path>").description("上传普通文件或递归目录,并提交入库;支持文件级恢复")
74
+ .requiredOption("--collection-id <id>", "目标知识库 ID")
75
+ .option("--state-file <path>", "本地私有恢复记录,自动生成时在结果中返回")
76
+ .option("--resume", "使用既有恢复记录继续;须同时指定 --state-file")
77
+ .option("--batch-size <number>", "每批文件数 1-50", "50")
78
+ .option("--concurrency <number>", "同时传输文件数 1-10", "3")
79
+ .option("--wait", "等待解析入库完成")
80
+ .option("--timeout <seconds>", "等待入库的最长秒数", "600")
81
+ .action(async (path, options) => {
82
+ const batchSize = integer(options.batchSize, "--batch-size", 50);
83
+ const concurrency = integer(options.concurrency, "--concurrency", 10);
84
+ const timeoutMs = integer(options.timeout, "--timeout", 86_400) * 1000;
85
+ if (options.resume && !options.stateFile)
86
+ throw new KbError("--resume 必须同时指定 --state-file。", "kb_input_invalid");
87
+ const api = await client();
88
+ output(await interruptible(signal => (dependencies.upload ?? uploadToKb)(api, {
89
+ path, collectionId: options.collectionId, stateFile: options.stateFile, resume: options.resume,
90
+ batchSize, concurrency, wait: options.wait, timeoutMs, signal, onProgress: progress,
91
+ })));
92
+ });
93
+ kb.command("download <document-id>").description("下载已授权原件,校验后保存;不覆盖现有文件")
94
+ .requiredOption("--output <path>", "保存到指定文件路径")
95
+ .action(async (documentId, options) => {
96
+ const api = await client();
97
+ output(await interruptible(signal => (dependencies.download ?? downloadFromKb)(api, {
98
+ documentId, output: options.output, signal, onProgress: progress,
99
+ })));
100
+ });
101
+ const tasks = kb.command("tasks").description("查看和重试解析入库任务");
102
+ tasks.command("status <task-id>").description("查询任务及逐文件结果")
103
+ .option("--kind <kind>", "archive 或 batch;ext_ 前缀默认 batch")
104
+ .option("--wait", "等待终态;失败、部分失败或需要处理冲突时返回非零退出码")
105
+ .option("--timeout <seconds>", "最长等待秒数", "600")
106
+ .action(async (id, options) => {
107
+ const kind = taskKind(id, options.kind);
108
+ const timeoutMs = integer(options.timeout, "--timeout", 86_400) * 1000;
109
+ const api = await client();
110
+ output(options.wait
111
+ ? await interruptible(signal => (dependencies.wait ?? waitForTask)(api, id, { kind, timeoutMs, signal }))
112
+ : await api.getTask(id, kind));
113
+ });
114
+ tasks.command("retry <task-id>").description("显式重试可恢复的失败入库项")
115
+ .option("--kind <kind>", "archive 或 batch;ext_ 前缀默认 batch")
116
+ .action(async (id, options) => {
117
+ const kind = taskKind(id, options.kind);
118
+ output(await (await client()).retryTask(id, kind));
119
+ });
120
+ }
121
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/kb/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { type AuthConfig } from "../config.js";
2
+ export interface KbConfig {
3
+ baseUrl: string;
4
+ apiKey: string;
5
+ authMode: "keycloak" | "api-key";
6
+ auth?: AuthConfig;
7
+ tenantHeader?: {
8
+ name: string;
9
+ value: string;
10
+ };
11
+ }
12
+ export declare function validateKbBaseUrl(value: string): string;
13
+ export declare function loadKbConfig(): Promise<KbConfig>;
14
+ /** Uses the same governed authority and token cache as KB requests, without requiring a KB API key. */
15
+ export declare function loadKbAuthConfig(): AuthConfig;
@@ -0,0 +1,76 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { appConfigDirectory } from "../app-config.js";
5
+ import { loadConfig } from "../config.js";
6
+ import { requireProfileService } from "../platform-profile.js";
7
+ import { KbError } from "./errors.js";
8
+ export function validateKbBaseUrl(value) {
9
+ let url;
10
+ try {
11
+ url = new URL(value);
12
+ }
13
+ catch {
14
+ throw new KbError("KB base URL is invalid.", "kb_config_invalid");
15
+ }
16
+ const local = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
17
+ if ((url.protocol !== "https:" && !(url.protocol === "http:" && local)) || url.username || url.password || url.search || url.hash) {
18
+ throw new KbError("KB base URL must use HTTPS without credentials, query or fragment (loopback HTTP allowed).", "kb_config_invalid");
19
+ }
20
+ return url.toString().replace(/\/+$/u, "");
21
+ }
22
+ export async function loadKbConfig() {
23
+ const selected = requireProfileService("kb");
24
+ const explicit = process.env.NUMA_KB_BASE_URL?.trim();
25
+ const base = selected?.service.baseUrl ?? explicit;
26
+ if (!base)
27
+ throw new KbError("Configure services.kb in the platform profile or NUMA_KB_BASE_URL.", "kb_config_missing");
28
+ const baseUrl = validateKbBaseUrl(base);
29
+ if (selected && explicit && validateKbBaseUrl(explicit) !== baseUrl) {
30
+ throw new KbError("NUMA_KB_BASE_URL cannot override the profile KB service.", "kb_config_invalid");
31
+ }
32
+ const mode = process.env.NUMA_KB_AUTH_MODE?.trim() || "keycloak";
33
+ if (mode !== "keycloak" && mode !== "api-key")
34
+ throw new KbError("NUMA_KB_AUTH_MODE must be keycloak or api-key.", "kb_config_invalid");
35
+ const keyEnv = process.env.NUMA_KB_API_KEY;
36
+ const keyFile = process.env.NUMA_KB_API_KEY_FILE;
37
+ if (keyEnv !== undefined && keyFile !== undefined)
38
+ throw new KbError("Set only one of NUMA_KB_API_KEY and NUMA_KB_API_KEY_FILE.", "kb_config_invalid");
39
+ let apiKey = keyEnv?.trim();
40
+ if (keyFile) {
41
+ try {
42
+ apiKey = (await readFile(keyFile, "utf8")).trim();
43
+ }
44
+ catch {
45
+ throw new KbError("Cannot read NUMA_KB_API_KEY_FILE.", "kb_config_invalid");
46
+ }
47
+ }
48
+ if (!apiKey || /[\u0000-\u0020\u007f]/u.test(apiKey))
49
+ throw new KbError("A valid KB API key is required.", "kb_config_missing");
50
+ const auth = mode === "keycloak" ? loadKbAuthConfig() : undefined;
51
+ return { baseUrl, apiKey, authMode: mode, auth,
52
+ ...(selected ? { tenantHeader: { name: selected.profile.tenant.headerName, value: selected.profile.tenant.id } } : {}) };
53
+ }
54
+ /** Uses the same governed authority and token cache as KB requests, without requiring a KB API key. */
55
+ export function loadKbAuthConfig() {
56
+ const selected = requireProfileService("kb");
57
+ const explicit = process.env.NUMA_KB_BASE_URL?.trim();
58
+ const base = selected?.service.baseUrl ?? explicit;
59
+ if (!base)
60
+ throw new KbError("Configure services.kb or NUMA_KB_BASE_URL.", "kb_config_missing");
61
+ const baseUrl = validateKbBaseUrl(base);
62
+ if (selected && explicit && validateKbBaseUrl(explicit) !== baseUrl)
63
+ throw new KbError("NUMA_KB_BASE_URL cannot override the profile KB service.", "kb_config_invalid");
64
+ let auth = loadConfig("kb");
65
+ if (selected) {
66
+ // Older profiles allow global overrides in loadConfig; KB always honors its declared authority.
67
+ const clientId = auth.authenticationMode === "client_credentials" ? auth.clientId : selected.authority.clientId;
68
+ const tokenKey = createHash("sha256").update(`${selected.authority.issuer}\0${clientId}\0${selected.profile.tenant.id}\0${selected.service.audience}`).digest("hex").slice(0, 24);
69
+ auth = { ...auth, discoveryUrl: selected.authority.discoveryUrl, issuerUrl: selected.authority.issuer,
70
+ clientId, resourceAudience: selected.service.audience, profileTenantId: selected.profile.tenant.id,
71
+ tokenFile: join(appConfigDirectory(), `keycloak-token-${tokenKey}.json`),
72
+ scope: auth.authenticationMode === "client_credentials" ? auth.scope : selected.authority.scopes.join(" ") };
73
+ }
74
+ return { ...auth, backendBaseUrl: baseUrl };
75
+ }
76
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/kb/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Only locally generated messages belong here; never interpolate remote response bodies. */
2
+ export declare class KbError extends Error {
3
+ readonly code: string;
4
+ readonly status?: number | undefined;
5
+ readonly details?: Record<string, unknown> | undefined;
6
+ constructor(message: string, code: string, status?: number | undefined, details?: Record<string, unknown> | undefined);
7
+ }
8
+ /** Output-only projection. Transport code must keep using the original ticket. */
9
+ export declare function sanitizeKbOutput(value: unknown): unknown;
@@ -0,0 +1,31 @@
1
+ /** Only locally generated messages belong here; never interpolate remote response bodies. */
2
+ export class KbError extends Error {
3
+ code;
4
+ status;
5
+ details;
6
+ constructor(message, code, status, details) {
7
+ super(message);
8
+ this.code = code;
9
+ this.status = status;
10
+ this.details = details;
11
+ this.name = "KbError";
12
+ }
13
+ }
14
+ const secretKey = /(?:authorization|api.?key|access.?token|refresh.?token|id.?token|secret|password|cookie|credential|signature|ticket|^token$|^upload$|^headers$)/iu;
15
+ const urlKey = /(?:url|uri)$/iu;
16
+ /** Output-only projection. Transport code must keep using the original ticket. */
17
+ export function sanitizeKbOutput(value) {
18
+ if (Array.isArray(value))
19
+ return value.map(sanitizeKbOutput);
20
+ if (value && typeof value === "object") {
21
+ return Object.fromEntries(Object.entries(value).filter(([key]) => !secretKey.test(key) && !urlKey.test(key))
22
+ .map(([key, item]) => [key, sanitizeKbOutput(item)]));
23
+ }
24
+ if (typeof value === "string") {
25
+ return value.replace(/https?:\/\/[^\s<>"']+/giu, "[redacted URL]")
26
+ .replace(/\bBearer\s+[^\s,;]+/giu, "Bearer [redacted]")
27
+ .replace(/((?:api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|password|secret)\s*[:=]\s*)[^\s,;]+/giu, "$1[redacted]");
28
+ }
29
+ return value;
30
+ }
31
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/kb/errors.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,MAAM,OAAO,OAAQ,SAAQ,KAAK;IACM,IAAI;IAAmB,MAAM;IAAoB,OAAO;IAA9F,YAAY,OAAe,EAAW,IAAY,EAAW,MAAe,EAAW,OAAiC;QACtH,KAAK,CAAC,OAAO,CAAC,CAAC;oBADqB,IAAI;sBAAmB,MAAM;uBAAoB,OAAO;QAE5F,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,CAAC;CACF;AAED,MAAM,SAAS,GAAG,mJAAmJ,CAAC;AACtK,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAEhC,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACzG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,0BAA0B,EAAE,gBAAgB,CAAC;aAC/D,OAAO,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;aACtD,OAAO,CAAC,8FAA8F,EAAE,cAAc,CAAC,CAAC;IAC7H,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}