@numa-tech/numa 1.24.0 → 1.26.0
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 +4 -0
- package/dist/business-issuer.js +5 -5
- package/dist/business-issuer.js.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/kb/catalog.js +33 -2
- package/dist/kb/catalog.js.map +1 -1
- package/dist/kb/chat-stream.d.ts +5 -0
- package/dist/kb/chat-stream.js +61 -0
- package/dist/kb/chat-stream.js.map +1 -0
- package/dist/kb/client.d.ts +75 -6
- package/dist/kb/client.js +114 -12
- package/dist/kb/client.js.map +1 -1
- package/dist/kb/commands.js +93 -8
- package/dist/kb/commands.js.map +1 -1
- package/dist/kb/config.d.ts +15 -3
- package/dist/kb/config.js +40 -21
- package/dist/kb/config.js.map +1 -1
- package/dist/kb/management-commands.d.ts +7 -0
- package/dist/kb/management-commands.js +86 -0
- package/dist/kb/management-commands.js.map +1 -0
- package/dist/kb/management-schemas.d.ts +106 -0
- package/dist/kb/management-schemas.js +33 -0
- package/dist/kb/management-schemas.js.map +1 -0
- package/dist/kb/transfers.d.ts +4 -0
- package/dist/kb/transfers.js +11 -4
- package/dist/kb/transfers.js.map +1 -1
- package/dist/kb/upload-decisions.d.ts +28 -0
- package/dist/kb/upload-decisions.js +23 -0
- package/dist/kb/upload-decisions.js.map +1 -0
- package/dist/kb/upload-state.d.ts +1 -0
- package/dist/kb/upload-state.js +1 -0
- package/dist/kb/upload-state.js.map +1 -1
- package/dist/kb/web-login.d.ts +10 -0
- package/dist/kb/web-login.js +25 -0
- package/dist/kb/web-login.js.map +1 -0
- package/dist/kb/web-page.d.ts +3 -0
- package/dist/kb/web-page.js +114 -0
- package/dist/kb/web-page.js.map +1 -0
- package/dist/kb/web-queue.d.ts +61 -0
- package/dist/kb/web-queue.js +101 -0
- package/dist/kb/web-queue.js.map +1 -0
- package/dist/kb/web.d.ts +26 -0
- package/dist/kb/web.js +234 -0
- package/dist/kb/web.js.map +1 -0
- package/dist/local-web/context-menu.d.ts +2 -0
- package/dist/local-web/context-menu.js +53 -0
- package/dist/local-web/context-menu.js.map +1 -0
- package/dist/local-web/file-workspace-style.d.ts +2 -0
- package/dist/local-web/file-workspace-style.js +58 -0
- package/dist/local-web/file-workspace-style.js.map +1 -0
- package/dist/local-web/file-workspace.d.ts +2 -0
- package/dist/local-web/file-workspace.js +39 -0
- package/dist/local-web/file-workspace.js.map +1 -0
- package/dist/local-web/security.d.ts +6 -0
- package/dist/local-web/security.js +51 -0
- package/dist/local-web/security.js.map +1 -0
- package/dist/login-recovery.js +8 -3
- package/dist/login-recovery.js.map +1 -1
- package/dist/mcp-gateway/profile.d.ts +4 -0
- package/dist/mcp-gateway/profile.js +6 -3
- package/dist/mcp-gateway/profile.js.map +1 -1
- package/dist/mcp-gateway/runtime.js +14 -0
- package/dist/mcp-gateway/runtime.js.map +1 -1
- package/dist/oss/transfer-queue.d.ts +7 -51
- package/dist/oss/transfer-queue.js +15 -308
- package/dist/oss/transfer-queue.js.map +1 -1
- package/dist/oss/web-page.js +21 -103
- package/dist/oss/web-page.js.map +1 -1
- package/dist/oss/web.js +4 -45
- package/dist/oss/web.js.map +1 -1
- package/dist/platform-profile.d.ts +25 -1
- package/dist/platform-profile.js +44 -1
- package/dist/platform-profile.js.map +1 -1
- package/dist/transfers/persistent-queue.d.ts +65 -0
- package/dist/transfers/persistent-queue.js +312 -0
- package/dist/transfers/persistent-queue.js.map +1 -0
- package/docs/design/kb-capability-upgrade.md +36 -0
- package/docs/design/kb-cli.md +4 -4
- package/docs/design/kb-web-workspace.md +97 -0
- package/docs/kb-access.md +86 -7
- package/examples/jev/README.md +65 -0
- package/examples/jev/platform-client.test.ts +136 -0
- package/examples/jev/platform-client.ts +122 -0
- package/package.json +9 -7
- package/scripts/export-kb-contract.py +25 -6
- package/skills/numa-jev/LICENSE +21 -0
- package/skills/numa-jev/SKILL.md +54 -0
- package/skills/numa-jev/assets/decision.json +37 -0
- package/skills/numa-jev/numa-skill.json +8 -0
- package/skills/numa-jev/references/application-integration.md +36 -0
- package/skills/numa-jev/references/mcp-usage.md +53 -0
- package/skills/numa-jev/references/upstream.md +13 -0
- package/src/kb/openapi-contract.json +2297 -566
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { checked, resourceId } from './management-schemas.js';
|
|
3
|
+
import { KbError } from './errors.js';
|
|
4
|
+
const decision = z.object({
|
|
5
|
+
filename: z.string().min(1).max(255), sha256: z.string().regex(/^[0-9a-f]{64}$/),
|
|
6
|
+
duplicate_action: z.enum(['upload', 'new_version']), existing_document_id: resourceId.optional(),
|
|
7
|
+
version_reason: z.string().trim().min(1).max(500).optional(), version_confirmation: z.literal('SWITCH_CURRENT_VERSION').optional(),
|
|
8
|
+
}).strict().superRefine((v, ctx) => {
|
|
9
|
+
if (v.duplicate_action === 'new_version' && (!v.existing_document_id || !v.version_reason || !v.version_confirmation))
|
|
10
|
+
ctx.addIssue({ code: 'custom', message: 'A version replacement requires target, reason and confirmation' });
|
|
11
|
+
if (v.duplicate_action === 'upload' && (v.existing_document_id || v.version_reason || v.version_confirmation))
|
|
12
|
+
ctx.addIssue({ code: 'custom', message: 'Independent upload cannot carry version replacement fields' });
|
|
13
|
+
});
|
|
14
|
+
export const uploadDecisionsSchema = z.array(decision).max(10000).refine(v => new Set(v.map(x => x.filename)).size === v.length);
|
|
15
|
+
export function uploadDecisions(value) { return checked(uploadDecisionsSchema, value).sort((a, b) => a.filename.localeCompare(b.filename)); }
|
|
16
|
+
export function verifyDecisions(decisions, files) {
|
|
17
|
+
for (const item of decisions) {
|
|
18
|
+
const file = files.find(f => f.filename === item.filename);
|
|
19
|
+
if (!file || file.sha256 !== item.sha256)
|
|
20
|
+
throw new KbError('上传决策与当前文件不匹配,请重新预检。', 'kb_source_changed');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=upload-decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-decisions.js","sourceRoot":"","sources":["../../src/kb/upload-decisions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,QAAQ,GAAC,CAAC,CAAC,MAAM,CAAC;IACvB,QAAQ,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAC,MAAM,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC7E,gBAAgB,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAC,aAAa,CAAC,CAAC,EAAC,oBAAoB,EAAC,UAAU,CAAC,QAAQ,EAAE;IAC5F,cAAc,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAC,oBAAoB,EAAC,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,QAAQ,EAAE;CAC/H,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAC,GAAG,EAAC,EAAE;IAChC,IAAG,CAAC,CAAC,gBAAgB,KAAG,aAAa,IAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,IAAE,CAAC,CAAC,CAAC,cAAc,IAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAAC,GAAG,CAAC,QAAQ,CAAC,EAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,gEAAgE,EAAC,CAAC,CAAC;IACpN,IAAG,CAAC,CAAC,gBAAgB,KAAG,QAAQ,IAAE,CAAC,CAAC,CAAC,oBAAoB,IAAE,CAAC,CAAC,cAAc,IAAE,CAAC,CAAC,oBAAoB,CAAC;QAAC,GAAG,CAAC,QAAQ,CAAC,EAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,4DAA4D,EAAC,CAAC,CAAC;AACzM,CAAC,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA,EAAE,CAAA,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzH,MAAM,UAAU,eAAe,CAAC,KAAa,IAAmB,OAAO,OAAO,CAAC,qBAAqB,EAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAC,EAAE,CAAA,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA,CAAC;AAC/J,MAAM,UAAU,eAAe,CAAC,SAA0B,EAAC,KAAkB;IAC5E,KAAI,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,QAAQ,KAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAG,CAAC,IAAI,IAAE,IAAI,CAAC,MAAM,KAAG,IAAI,CAAC,MAAM;YAAC,MAAM,IAAI,OAAO,CAAC,qBAAqB,EAAC,mBAAmB,CAAC,CAAC;IAClG,CAAC;AACF,CAAC"}
|
package/dist/kb/upload-state.js
CHANGED
|
@@ -109,6 +109,7 @@ export async function writeUploadState(path, state) {
|
|
|
109
109
|
try {
|
|
110
110
|
// Explicit allowlist keeps remote capabilities and credentials out of the manifest.
|
|
111
111
|
const safe = { version: 1, binding: state.binding, collectionId: state.collectionId, sourcePath: state.sourcePath,
|
|
112
|
+
...(state.decisions ? { decisions: state.decisions.map(({ filename, sha256, duplicate_action, existing_document_id, version_reason, version_confirmation }) => ({ filename, sha256, duplicate_action, existing_document_id, version_reason, version_confirmation })) } : {}),
|
|
112
113
|
files: state.files.map(({ path, filename, size_bytes, sha256, content_md5, content_type }) => ({ path, filename, size_bytes, sha256, content_md5, content_type })),
|
|
113
114
|
batches: state.batches.map(({ requestId, fileIndexes, sessionId, batchId, transport, submitted }) => ({ requestId, fileIndexes, sessionId, batchId, transport, submitted })) };
|
|
114
115
|
await file.writeFile(`${JSON.stringify(safe, null, 2)}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../src/kb/upload-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAmB,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../src/kb/upload-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthConfig } from '../config.js';
|
|
2
|
+
import { startBrowserLogin, completeBrowserLogin } from '../oauth.js';
|
|
3
|
+
/** Reuse the shared PKCE callback/token-cache flow, with workspace shutdown cancellation. */
|
|
4
|
+
export declare function loginKbWorkspace(config: AuthConfig, returnUrl: string, signal: AbortSignal, dependencies?: {
|
|
5
|
+
start?: typeof startBrowserLogin;
|
|
6
|
+
complete?: typeof completeBrowserLogin;
|
|
7
|
+
pollMs?: number;
|
|
8
|
+
write?: (message: string) => void;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
export declare function needsKbLogin(error: unknown): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
+
import { startBrowserLogin, completeBrowserLogin } from '../oauth.js';
|
|
3
|
+
import { KbError } from './errors.js';
|
|
4
|
+
/** Reuse the shared PKCE callback/token-cache flow, with workspace shutdown cancellation. */
|
|
5
|
+
export async function loginKbWorkspace(config, returnUrl, signal, dependencies = {}) {
|
|
6
|
+
if (config.authenticationMode === 'client_credentials')
|
|
7
|
+
throw new KbError('Browser login unavailable.', 'kb_interactive_login_disabled', 400);
|
|
8
|
+
signal.throwIfAborted();
|
|
9
|
+
const options = { successRedirectUrl: returnUrl, failureRedirectUrl: returnUrl, loadUserinfo: false };
|
|
10
|
+
const session = await (dependencies.start ?? startBrowserLogin)({ ...config, openBrowser: true }, options);
|
|
11
|
+
try {
|
|
12
|
+
(dependencies.write ?? (message => process.stderr.write(message)))(`请在浏览器完成 KB 登录。若未自动打开,可访问:\n${session.authorizationUrl}\n`);
|
|
13
|
+
while (!session.code && !session.error && session.expiresAt > Math.floor(Date.now() / 1000))
|
|
14
|
+
await delay(dependencies.pollMs ?? 500, undefined, { signal });
|
|
15
|
+
signal.throwIfAborted();
|
|
16
|
+
await (dependencies.complete ?? completeBrowserLogin)(config, session, options);
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await session.close().catch(() => undefined);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function needsKbLogin(error) {
|
|
23
|
+
return error instanceof KbError && (error.code === 'kb_auth_required' || error.code === 'kb_auth_failed' && error.status === 401);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=web-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-login.js","sourceRoot":"","sources":["../../src/kb/web-login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAAgB,EAAE,MAAkB,EAC5F,YAAY,GAAsH,EAAE;IACpI,IAAG,MAAM,CAAC,kBAAkB,KAAG,oBAAoB;QAAC,MAAM,IAAI,OAAO,CAAC,4BAA4B,EAAC,+BAA+B,EAAC,GAAG,CAAC,CAAC;IACxI,MAAM,CAAC,cAAc,EAAE,CAAC;IACxB,MAAM,OAAO,GAAC,EAAC,kBAAkB,EAAC,SAAS,EAAC,kBAAkB,EAAC,SAAS,EAAC,YAAY,EAAC,KAAK,EAAC,CAAC;IAC7F,MAAM,OAAO,GAAC,MAAK,CAAC,YAAY,CAAC,KAAK,IAAE,iBAAiB,CAAC,CAAC,EAAC,GAAG,MAAM,EAAC,WAAW,EAAC,IAAI,EAAC,EAAC,OAAO,CAAC,CAAC;IACjG,IAAI,CAAC;QACH,CAAC,YAAY,CAAC,KAAK,IAAE,CAAC,OAAO,CAAA,EAAE,CAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,8BAA8B,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC3H,OAAM,CAAC,OAAO,CAAC,IAAI,IAAE,CAAC,OAAO,CAAC,KAAK,IAAE,OAAO,CAAC,SAAS,GAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAC,IAAI,CAAC;YAAC,MAAM,KAAK,CAAC,YAAY,CAAC,MAAM,IAAE,GAAG,EAAC,SAAS,EAAC,EAAC,MAAM,EAAC,CAAC,CAAC;QAC5I,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAK,CAAC,YAAY,CAAC,QAAQ,IAAE,oBAAoB,CAAC,CAAC,MAAM,EAAC,OAAO,EAAC,OAAO,CAAC,CAAC;IAC7E,CAAC;YAAS,CAAC;QAAA,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAE,EAAE,CAAA,SAAS,CAAC,CAAC;IAAA,CAAC;AACzD,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,YAAY,OAAO,IAAE,CAAC,KAAK,CAAC,IAAI,KAAG,kBAAkB,IAAE,KAAK,CAAC,IAAI,KAAG,gBAAgB,IAAE,KAAK,CAAC,MAAM,KAAG,GAAG,CAAC,CAAC;AACxH,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { LOCAL_CONTEXT_MENU_JS } from '../local-web/context-menu.js';
|
|
2
|
+
import { FILE_WORKSPACE_CSS } from '../local-web/file-workspace-style.js';
|
|
3
|
+
import { FILE_WORKSPACE_JS } from '../local-web/file-workspace.js';
|
|
4
|
+
import { OSS_REFRESH_ICON } from '../oss/web-icons.js';
|
|
5
|
+
export const KB_WEB_CSS = FILE_WORKSPACE_CSS + String.raw `
|
|
6
|
+
.kb-collections{display:flex;flex-direction:column;gap:6px;margin-top:18px}.kb-collections button{text-align:left;white-space:normal;overflow-wrap:anywhere}.kb-collections button[aria-current=true]{background:#e1ebe2;border-color:#9fbba1}.kb-status{display:inline-block;padding:3px 7px;border-radius:4px;background:#edf5ee;color:#24573d}.kb-actions{display:flex;gap:7px;flex-wrap:wrap}.kb-detail{white-space:pre-wrap;overflow-wrap:anywhere;font-size:12px;line-height:1.8}.task-ingestion{font-size:12px;margin-top:8px;line-height:1.7;color:#24573d}.tenant-label{white-space:nowrap}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid #227b54;outline-offset:3px}@media(max-width:820px){.sidebar{display:flex;max-height:210px;flex-shrink:0}.kb-collections{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:10px}.workspace{overflow:auto}}
|
|
7
|
+
`;
|
|
8
|
+
export const KB_WEB_HTML = String.raw `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Numa · 知识库文档</title><link rel="icon" href="data:,"><link rel="stylesheet" href="/app.css"><script src="/app.js" defer></script></head><body>
|
|
9
|
+
<header class="topbar"><strong>Numa · 知识库文档</strong><span class="topnote">管理文档与上传任务</span><button id="tasks-toggle">传输与入库 <span id="tasks-count">0</span></button><button id="service-stop">停止本地服务</button></header>
|
|
10
|
+
<section class="authorization"><label for="environment">Namespace</label><select id="environment" aria-label="Namespace"></select><button id="environment-login" hidden>登录当前环境</button><label class="tenant-label" for="tenant">租户</label><select id="tenant" aria-label="租户"></select><button id="refresh" aria-label="刷新文档">${OSS_REFRESH_ICON}</button></section>
|
|
11
|
+
<p id="notice" class="notice" role="status" hidden></p>
|
|
12
|
+
<main class="workspace"><aside class="sidebar"><h2>知识库</h2><div id="collections" class="kb-collections"></div></aside>
|
|
13
|
+
<section class="files"><div class="page-heading"><div><h1 id="heading">选择知识库</h1><p id="collection-info" class="scope"></p></div><div class="upload-actions"><button id="upload-file" class="primary" disabled>上传文件</button><button id="upload-folder" disabled>上传目录</button></div></div>
|
|
14
|
+
<form id="search-form" class="toolbar"><input id="search" type="search" placeholder="搜索文档名称" aria-label="文档名称"><button type="submit">搜索</button></form>
|
|
15
|
+
<div class="table-wrap"><table><thead><tr><th>文档</th><th class="size-cell">大小</th><th class="date-cell">处理状态</th></tr></thead><tbody id="documents"></tbody></table><p id="empty" class="empty">请先选择知识库。</p></div>
|
|
16
|
+
<footer class="list-footer"><span id="page-info"></span><div><button id="previous" disabled>上一页</button><button id="next" disabled>下一页</button></div></footer></section>
|
|
17
|
+
<aside class="preview-panel"><div class="preview-heading"><h2>文档详情</h2></div><div id="detail" class="preview-body"><p>选择文档,查看状态和版本。</p></div><div class="preview-actions"><button id="download" disabled>下载原件</button><button id="delete" class="danger" disabled>删除文档</button></div></aside></main>
|
|
18
|
+
<section id="tasks-panel" class="tasks-panel" aria-label="传输与入库任务" hidden><div class="tasks-heading"><h2>传输与入库</h2><button id="tasks-close" aria-label="关闭任务面板">关闭</button></div><p class="tasks-note">关闭页面不影响上传;停止本地服务会暂停传输。已提交的入库任务继续在服务端处理。恢复上传会跳过已完成文件,未完成文件重新传输。</p><p id="tasks-connection" role="status"></p><div id="tasks" class="tasks-list"></div></section>
|
|
19
|
+
<dialog id="delete-dialog"><h2>删除文档</h2><p id="delete-message"></p><p>将通过知识库服务删除文档,并清理相关文件与索引。</p><div class="dialog-actions"><button id="delete-cancel">取消</button><button id="delete-confirm" class="destructive">确认删除</button></div></dialog>
|
|
20
|
+
<div id="file-menu" class="file-menu" role="menu" aria-label="文档操作" hidden></div>
|
|
21
|
+
</body></html>`;
|
|
22
|
+
export const KB_WEB_JS = String.raw `'use strict';
|
|
23
|
+
${LOCAL_CONTEXT_MENU_JS}
|
|
24
|
+
${FILE_WORKSPACE_JS}
|
|
25
|
+
const $=id=>document.getElementById(id);
|
|
26
|
+
const entryFragment=new URLSearchParams(location.hash.slice(1));
|
|
27
|
+
let token=entryFragment.get('token')||sessionStorage.getItem('numa-kb-web-token')||'';
|
|
28
|
+
if(token)sessionStorage.setItem('numa-kb-web-token',token);history.replaceState(null,'',location.pathname);
|
|
29
|
+
let autoLogin=true,loginReturn=entryFragment.get('login')==='return',environment='',environmentChoices=[],tenant='',collection='',collections=[],documents=[],selected=null,offset=0,epoch=0,taskBusy=false,stopped=false,deleting=null;
|
|
30
|
+
const bytes=n=>n>=1048576?(n/1048576).toFixed(1)+' MiB':n>=1024?(n/1024).toFixed(1)+' KiB':String(n||0)+' B';
|
|
31
|
+
const status=s=>({queued:'等待上传',running:'传输中',paused:'已暂停',pausing:'暂停中',cancelling:'停止中',cancelled:'已停止',completed:'已完成',failed:'失败',submitted:'已提交入库',processing:'处理中',indexed:'已索引',pending:'待处理',archived:'已入库',needs_resolution:'需要处理冲突',partial_failed:'部分失败',reused:'已复用',skipped:'已跳过'})[s]||String(s||'未知');
|
|
32
|
+
const node=(tag,text,cls)=>{const e=document.createElement(tag);if(text!==undefined)e.textContent=String(text);if(cls)e.className=cls;return e;};
|
|
33
|
+
function notice(message){$('notice').hidden=!message;$('notice').textContent=message||'';}
|
|
34
|
+
async function api(path,body,targetEnvironment=environment){const route=path+(path.includes('?')?'&':'?')+new URLSearchParams({environment:targetEnvironment});const r=await fetch(route,{method:body===undefined?'GET':'POST',headers:{Authorization:'Bearer '+token,...(body===undefined?{}:{'Content-Type':'application/json'})},...(body===undefined?{}:{body:JSON.stringify(body)})});const d=await r.json();if(!r.ok||!d.ok){const error=new Error((d.error?.message||'请求未完成,请刷新后重试。')+' ['+(d.error?.code||'kb_web_error')+']');error.code=d.error?.code;error.status=r.status;throw error;}return d.data;}
|
|
35
|
+
function run(work){Promise.resolve().then(work).catch(e=>notice(e.message));}
|
|
36
|
+
const documentMenu=createLocalContextMenu($('file-menu'));
|
|
37
|
+
function clearDocument(){documentMenu.close();selected=null;$('download').disabled=true;$('delete').disabled=true;$('detail').replaceChildren(node('p','选择文档,查看状态和版本。'));}
|
|
38
|
+
function selectDocument(d){selected=d;$('download').disabled=false;$('delete').disabled=d.can_manage_versions!==true;const box=$('detail');box.replaceChildren(node('h3',d.filename||d.document_id));const dl=node('dl');for(const [k,v] of [['状态',status(d.status)],['版本',d.version_number??d.version??'—'],['大小',bytes(d.file_size_bytes??d.size_bytes)],['更新时间',d.updated_at||'—']]){dl.append(node('dt',k),node('dd',v));}box.append(dl);if(d.summary)box.append(node('p',d.summary));}
|
|
39
|
+
function openDocumentMenu(event,d,anchor){
|
|
40
|
+
documentMenu.begin(event,anchor);selectDocument(d);
|
|
41
|
+
documentMenu.item('查看详情',()=>selectDocument(d));
|
|
42
|
+
documentMenu.item('下载原件…',()=>$('download').onclick());
|
|
43
|
+
documentMenu.item('删除文档…',()=>$('delete').onclick(),{danger:true,disabled:d.can_manage_versions!==true,onDisabled:()=>notice('当前身份没有此文档的管理权限。')});
|
|
44
|
+
documentMenu.show(event,anchor);
|
|
45
|
+
}
|
|
46
|
+
async function loadDocuments(){const version=++epoch;clearDocument();$('documents').replaceChildren();$('empty').hidden=false;$('empty').textContent=collection?'正在加载文档…':'请先选择知识库。';$('previous').disabled=true;$('next').disabled=true;if(!collection)return;
|
|
47
|
+
const rows=await api('/api/documents?'+new URLSearchParams({tenant,collection,offset:String(offset),q:$('search').value}));if(version!==epoch)return;documents=rows;$('empty').hidden=rows.length>0;$('empty').textContent='此知识库暂无匹配文档。';
|
|
48
|
+
for(const d of rows)$('documents').append(workspaceFileRow({name:d.filename||d.document_id,title:d.filename||d.document_id,onOpen:()=>selectDocument(d),onMenu:(e,anchor)=>openDocumentMenu(e,d,anchor),cells:[[bytes(d.file_size_bytes??d.size_bytes),'size-cell'],[status(d.status),'date-cell']]}));
|
|
49
|
+
$('page-info').textContent=rows.length?'第 '+(offset+1)+'–'+(offset+rows.length)+' 条':'暂无文档';$('previous').disabled=offset===0;$('next').disabled=rows.length<100;
|
|
50
|
+
}
|
|
51
|
+
async function selectCollection(c){collection=String(c.collection_id);offset=0;$('heading').textContent=c.name||collection;$('collection-info').textContent=c.description||'';$('upload-file').disabled=c.can_upload!==true;$('upload-folder').disabled=c.can_upload!==true;for(const b of $('collections').children)b.setAttribute('aria-current',String(b.dataset.id===collection));await loadDocuments();}
|
|
52
|
+
async function loadCollections(){const version=++epoch;collection='';collections=[];clearDocument();$('documents').replaceChildren();$('collections').replaceChildren();$('heading').textContent='选择知识库';$('collection-info').textContent='';$('upload-file').disabled=true;$('upload-folder').disabled=true;
|
|
53
|
+
const result=await api('/api/collections?'+new URLSearchParams({tenant}));if(version!==epoch)return;collections=result.collections;
|
|
54
|
+
for(const c of collections){const b=node('button',c.name||c.collection_id);b.dataset.id=c.collection_id;b.onclick=()=>run(()=>selectCollection(c));$('collections').append(b);}if(collections.length)await selectCollection(collections[0]);else{$('empty').hidden=false;$('empty').textContent='当前租户下没有可访问的知识库。';}
|
|
55
|
+
}
|
|
56
|
+
const transferCards=new Map(),transferBusy=new Set();
|
|
57
|
+
async function transferAction(id,action,targetEnvironment){
|
|
58
|
+
const key=targetEnvironment+'\0'+id;if(transferBusy.has(key))return;transferBusy.add(key);
|
|
59
|
+
const card=transferCards.get(key);if(card)for(const button of card.actions.values())button.disabled=true;
|
|
60
|
+
try{await api('/api/transfers/'+id+'/'+action,{},targetEnvironment);}catch(e){notice(e.message);}finally{transferBusy.delete(key);await refreshTasks();}
|
|
61
|
+
}
|
|
62
|
+
async function refreshTasks(){
|
|
63
|
+
if(taskBusy||stopped)return;taskBusy=true;const targetEnvironment=environment;
|
|
64
|
+
try{
|
|
65
|
+
const rows=await api('/api/transfers',undefined,targetEnvironment);if(targetEnvironment!==environment)return;
|
|
66
|
+
$('tasks-count').textContent=String(rows.filter(x=>!['completed','cancelled'].includes(x.status)).length);$('tasks-connection').textContent='';
|
|
67
|
+
const present=new Set(rows.map(t=>targetEnvironment+'\0'+t.id));
|
|
68
|
+
for(const [key,card] of transferCards)if(!present.has(key)){card.root.remove();transferCards.delete(key);}
|
|
69
|
+
for(const t of rows){
|
|
70
|
+
const key=targetEnvironment+'\0'+t.id;let card=transferCards.get(key);
|
|
71
|
+
if(!card){card=createWorkspaceTransferCard(t.id,(id,action)=>transferAction(id,action,targetEnvironment),{pause:'暂停',resume:'恢复',cancel:'停止传输'});transferCards.set(key,card);$('tasks').append(card.root);}
|
|
72
|
+
updateWorkspaceTransferCard(card,t,{title:t.label,meta:(t.direction==='upload'?'上传':'下载')+' · '+status(t.status)+' · 租户 '+t.tenant+' · 知识库 '+t.collection,progress:bytes(t.transferred)+' / '+bytes(t.size),stats:bytes(t.transferred)+' / '+bytes(t.size)},transferBusy.has(key));
|
|
73
|
+
if(t.batches?.length&&!$('tasks-panel').hidden&&!card.ingestionBusy){
|
|
74
|
+
card.ingestionBusy=true;const detail=card.extra;
|
|
75
|
+
if(!detail.textContent)detail.textContent='已提交 '+t.batches.length+' 个入库批次';
|
|
76
|
+
api('/api/ingestion/'+encodeURIComponent(t.id),undefined,targetEnvironment).then(tasks=>{detail.textContent=tasks.map(x=>'入库:'+status(x.task_status||x.status)+' · 完成 '+(x.completed_count||0)+' / '+(x.total_count||0)).join(';');}).catch(()=>{detail.textContent='入库状态暂不可用,可稍后刷新。';}).finally(()=>{card.ingestionBusy=false;});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}catch(e){if(targetEnvironment===environment)$('tasks-connection').textContent=e.message;}finally{taskBusy=false;}
|
|
80
|
+
}
|
|
81
|
+
const loginWaits=new Map();
|
|
82
|
+
function loginEnvironment(id,explicit=false,resume=false){
|
|
83
|
+
if(loginWaits.has(id))return loginWaits.get(id);
|
|
84
|
+
const pending=(async()=>{
|
|
85
|
+
let state=await api('/api/login',undefined,id);
|
|
86
|
+
if(state.status==='idle'||state.status==='succeeded'&&!resume||explicit&&state.status!=='pending')state=await api('/api/login',{},id);
|
|
87
|
+
if(environment===id)notice('正在登录当前环境,请在浏览器完成认证,完成后自动返回知识库。');
|
|
88
|
+
while(state.status==='pending'&&!stopped){await new Promise(resolve=>setTimeout(resolve,500));state=await api('/api/login',undefined,id);}
|
|
89
|
+
if(stopped)return;
|
|
90
|
+
if(state.status!=='succeeded')throw new Error(state.code==='kb_identity_changed'?'登录账号已改变,请重启工作台。':state.code==='kb_auth_failed'?'登录已完成,但当前账号没有 KB 访问权限。':'登录未完成,请点击“登录当前环境”重试。');
|
|
91
|
+
if(environment===id)await selectEnvironment(id,false);
|
|
92
|
+
})().catch(error=>{if(environment===id)notice(error.message);}).finally(()=>{loginWaits.delete(id);});
|
|
93
|
+
loginWaits.set(id,pending);return pending;
|
|
94
|
+
}
|
|
95
|
+
$('environment-login').onclick=()=>run(()=>loginEnvironment(environment,true));
|
|
96
|
+
async function selectEnvironment(id,allowLogin=true){
|
|
97
|
+
environment=id;tenant='';epoch++;collection='';collections=[];clearDocument();$('documents').replaceChildren();$('collections').replaceChildren();$('tenant').replaceChildren();$('tasks').replaceChildren();transferCards.clear();$('tasks-count').textContent='0';$('heading').textContent='选择知识库';$('upload-file').disabled=true;$('upload-folder').disabled=true;
|
|
98
|
+
const chosen=environmentChoices.find(e=>e.id===id);$('environment-login').hidden=!chosen?.loginAvailable;notice('');
|
|
99
|
+
const version=epoch;let result;try{result=await api('/api/tenants',undefined,id);}catch(e){if(version!==epoch)return;const required=e.code==='kb_auth_required'||e.code==='kb_auth_failed'&&e.status===401;if(required&&chosen?.loginAvailable&&allowLogin&&autoLogin){await loginEnvironment(id);return;}notice(e.message);return;}if(version!==epoch)return;
|
|
100
|
+
for(const t of result.items){const option=node('option',t.name);option.value=t.tenant_id;$('tenant').append(option);}
|
|
101
|
+
tenant=result.items.some(t=>t.tenant_id===result.current_tenant_id)?result.current_tenant_id:result.items[0]?.tenant_id||'';$('tenant').value=tenant;
|
|
102
|
+
if(tenant)await loadCollections();else notice('当前身份没有可访问的租户。');await refreshTasks();
|
|
103
|
+
}
|
|
104
|
+
$('environment').onchange=()=>run(()=>selectEnvironment($('environment').value));
|
|
105
|
+
$('tenant').onchange=()=>run(async()=>{tenant=$('tenant').value;await loadCollections();});
|
|
106
|
+
$('refresh').onclick=()=>run(loadDocuments);$('search-form').onsubmit=e=>{e.preventDefault();offset=0;run(loadDocuments);};$('previous').onclick=()=>{offset=Math.max(0,offset-100);run(loadDocuments);};$('next').onclick=()=>{offset+=100;run(loadDocuments);};
|
|
107
|
+
for(const [id,folder] of [['upload-file',false],['upload-folder',true]])$(id).onclick=()=>run(async()=>{const targetEnvironment=environment,selection={tenant,collection,folder};$('upload-file').disabled=true;$('upload-folder').disabled=true;try{await api('/api/upload',selection,targetEnvironment);$('tasks-panel').hidden=false;await refreshTasks();}finally{const c=collections.find(c=>c.collection_id===collection);$('upload-file').disabled=c?.can_upload!==true;$('upload-folder').disabled=c?.can_upload!==true;}});
|
|
108
|
+
$('download').onclick=()=>run(async()=>{if(!selected)return;const targetEnvironment=environment,choice={tenant,collection,document:selected.document_id};await api('/api/download',choice,targetEnvironment);$('tasks-panel').hidden=false;await refreshTasks();});
|
|
109
|
+
$('delete').onclick=()=>{if(!selected)return;deleting={environment,tenant,document:selected.document_id};$('delete-message').textContent='删除“'+(selected.filename||selected.document_id)+'”? 环境:'+(environmentChoices.find(e=>e.id===environment)?.name||'当前默认配置')+';租户:'+tenant+'。';$('delete-dialog').showModal();};$('delete-cancel').onclick=()=>$('delete-dialog').close();$('delete-confirm').onclick=()=>run(async()=>{$('delete-confirm').disabled=true;try{await api('/api/delete',{tenant:deleting.tenant,document:deleting.document,confirmation:'DELETE_DOCUMENT'},deleting.environment);$('delete-dialog').close();await loadDocuments();}finally{$('delete-confirm').disabled=false;}});
|
|
110
|
+
$('tasks-toggle').onclick=()=>{$('tasks-panel').hidden=!$('tasks-panel').hidden;void refreshTasks();};$('tasks-close').onclick=()=>{$('tasks-panel').hidden=true;};
|
|
111
|
+
$('service-stop').onclick=()=>run(async()=>{if(!confirm('停止本地服务并暂停尚未完成的传输?已提交的入库任务将继续。'))return;await api('/api/shutdown',{confirmation:'STOP_SERVICE'});stopped=true;notice('本地服务已停止,可重新运行 numa kb web 继续管理文档。');});
|
|
112
|
+
run(async()=>{if(!token)throw new Error('请使用 CLI 打开的完整本地链接进入。');const result=await api('/api/environments');environmentChoices=result.items;autoLogin=result.autoLogin!==false;for(const e of result.items){const option=node('option',e.namespace||e.name);option.value=e.id;$('environment').append(option);}const initial=result.items.some(e=>e.id===entryFragment.get('environment'))?entryFragment.get('environment'):result.defaultEnvironment;$('environment').value=initial;if(loginReturn){environment=initial;await loginEnvironment(initial,false,true);}else await selectEnvironment(initial);});setInterval(()=>{void refreshTasks();},3000);
|
|
113
|
+
`;
|
|
114
|
+
//# sourceMappingURL=web-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-page.js","sourceRoot":"","sources":["../../src/kb/web-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,MAAM,CAAC,MAAM,UAAU,GAAC,kBAAkB,GAAC,MAAM,CAAC,GAAG,CAAA;;CAEpD,CAAC;AACF,MAAM,CAAC,MAAM,WAAW,GAAC,MAAM,CAAC,GAAG,CAAA;;gUAE6R,gBAAgB;;;;;;;;;;;eAWjU,CAAC;AAChB,MAAM,CAAC,MAAM,SAAS,GAAC,MAAM,CAAC,GAAG,CAAA;EAC/B,qBAAqB;EACrB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFlB,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { PersistentTransferQueue, type BaseContext } from '../transfers/persistent-queue.js';
|
|
3
|
+
import { KbClient } from './client.js';
|
|
4
|
+
import { uploadToKb, downloadFromKb } from './transfers.js';
|
|
5
|
+
declare const jobSchema: z.ZodObject<{
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
direction: z.ZodEnum<{
|
|
8
|
+
download: "download";
|
|
9
|
+
upload: "upload";
|
|
10
|
+
}>;
|
|
11
|
+
tenant: z.ZodString;
|
|
12
|
+
collection: z.ZodString;
|
|
13
|
+
document: z.ZodString;
|
|
14
|
+
label: z.ZodString;
|
|
15
|
+
localPath: z.ZodString;
|
|
16
|
+
binding: z.ZodString;
|
|
17
|
+
size: z.ZodNumber;
|
|
18
|
+
transferred: z.ZodNumber;
|
|
19
|
+
status: z.ZodEnum<{
|
|
20
|
+
cancelled: "cancelled";
|
|
21
|
+
cancelling: "cancelling";
|
|
22
|
+
completed: "completed";
|
|
23
|
+
failed: "failed";
|
|
24
|
+
paused: "paused";
|
|
25
|
+
pausing: "pausing";
|
|
26
|
+
queued: "queued";
|
|
27
|
+
running: "running";
|
|
28
|
+
}>;
|
|
29
|
+
createdAt: z.ZodString;
|
|
30
|
+
updatedAt: z.ZodString;
|
|
31
|
+
error: z.ZodOptional<z.ZodString>;
|
|
32
|
+
phase: z.ZodString;
|
|
33
|
+
batches: z.ZodArray<z.ZodObject<{
|
|
34
|
+
batch_id: z.ZodString;
|
|
35
|
+
kind: z.ZodEnum<{
|
|
36
|
+
archive: "archive";
|
|
37
|
+
batch: "batch";
|
|
38
|
+
}>;
|
|
39
|
+
status: z.ZodString;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
type KbJob = z.infer<typeof jobSchema>;
|
|
43
|
+
interface Options {
|
|
44
|
+
directory: string;
|
|
45
|
+
client(tenant: string): Promise<KbClient>;
|
|
46
|
+
upload?: typeof uploadToKb;
|
|
47
|
+
download?: typeof downloadFromKb;
|
|
48
|
+
}
|
|
49
|
+
export declare class KbWebQueue extends PersistentTransferQueue<KbJob, BaseContext> {
|
|
50
|
+
private readonly kb;
|
|
51
|
+
constructor(kb: Options);
|
|
52
|
+
uploads(tenant: string, collection: string, paths: string[], signal?: AbortSignal): Promise<(import("../transfers/persistent-queue.js").PersistentJob & Record<string, unknown> & {
|
|
53
|
+
bytesPerSecond: number;
|
|
54
|
+
})[]>;
|
|
55
|
+
download(tenant: string, collection: string, document: string, folder: string): Promise<(import("../transfers/persistent-queue.js").PersistentJob & Record<string, unknown> & {
|
|
56
|
+
bytesPerSecond: number;
|
|
57
|
+
})[]>;
|
|
58
|
+
ingestion(id: string): Promise<import("./types.js").KbTask[]>;
|
|
59
|
+
private job;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstat } from 'node:fs/promises';
|
|
3
|
+
import { basename, isAbsolute, join } from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { PersistentTransferQueue } from '../transfers/persistent-queue.js';
|
|
6
|
+
import { KbError } from './errors.js';
|
|
7
|
+
import { scanUploadFiles, uploadToKb, downloadFromKb } from './transfers.js';
|
|
8
|
+
import { readUploadState } from './upload-state.js';
|
|
9
|
+
const jobSchema = z.object({ id: z.string().uuid(), direction: z.enum(['upload', 'download']), tenant: z.string().min(1).max(128), collection: z.string().max(256), document: z.string().max(256), label: z.string().max(8192), localPath: z.string().max(8192), binding: z.string().regex(/^[a-f0-9]{64}$/), size: z.number().nonnegative().safe(), transferred: z.number().nonnegative(), status: z.enum(['queued', 'running', 'pausing', 'paused', 'cancelling', 'cancelled', 'completed', 'failed']), createdAt: z.string().datetime(), updatedAt: z.string().datetime(), error: z.string().max(2048).optional(), phase: z.string().max(40), batches: z.array(z.object({ batch_id: z.string(), kind: z.enum(['archive', 'batch']), status: z.string() })).max(10000) }).strict();
|
|
10
|
+
export class KbWebQueue extends PersistentTransferQueue {
|
|
11
|
+
kb;
|
|
12
|
+
constructor(kb) {
|
|
13
|
+
const statePath = (j) => join(kb.directory, `${j.id}.upload.json`);
|
|
14
|
+
const client = async (j) => { const c = await kb.client(j.tenant); if (c.binding !== j.binding)
|
|
15
|
+
throw new KbError('Target changed.', 'kb_state_binding_mismatch'); return c; };
|
|
16
|
+
super({ directory: kb.directory, maxConcurrent: 3, stateSchema: z.object({ version: z.literal(1), jobs: z.array(jobSchema).max(10000) }).strict(),
|
|
17
|
+
validate: j => { jobSchema.parse(j); if (!isAbsolute(j.localPath))
|
|
18
|
+
throw new Error('invalid local path'); },
|
|
19
|
+
context: (_j, base) => base,
|
|
20
|
+
conflicts: (a, b) => a.direction === b.direction && a.tenant === b.tenant && a.collection === b.collection && a.localPath === b.localPath,
|
|
21
|
+
view: j => { const { binding: _binding, ...view } = j; return view; },
|
|
22
|
+
safeError: e => e instanceof KbError && /^kb_[a-z_]+$/.test(e.code) ? e.code : 'kb_transfer_failed',
|
|
23
|
+
worker: { run: async (j, ctx) => {
|
|
24
|
+
const c = await client(j);
|
|
25
|
+
if (j.direction === 'download') {
|
|
26
|
+
const result = await (kb.download ?? downloadFromKb)(c, { documentId: j.document, output: j.localPath, signal: ctx.signal, onProgress: p => { j.phase = p.phase; ctx.progress(p.transferred ?? 0); } });
|
|
27
|
+
if (typeof result.size_bytes === 'number')
|
|
28
|
+
j.size = result.size_bytes;
|
|
29
|
+
j.phase = 'downloaded';
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const state = statePath(j);
|
|
33
|
+
const exists = await lstat(state).then(() => true, e => { if (e.code === 'ENOENT')
|
|
34
|
+
return false; throw e; });
|
|
35
|
+
const progress = new Map();
|
|
36
|
+
const result = await (kb.upload ?? uploadToKb)(c, { path: j.localPath, collectionId: j.collection, stateFile: state, resume: exists, signal: ctx.signal, concurrency: 3, onProgress: p => {
|
|
37
|
+
j.phase = p.phase;
|
|
38
|
+
if (p.filename && p.transferred !== undefined) {
|
|
39
|
+
progress.set(p.filename, p.transferred);
|
|
40
|
+
ctx.progress([...progress.values()].reduce((a, b) => a + b, 0));
|
|
41
|
+
}
|
|
42
|
+
} });
|
|
43
|
+
j.batches = result.batches;
|
|
44
|
+
j.phase = 'submitted';
|
|
45
|
+
await ctx.save();
|
|
46
|
+
}, cancel: async (j) => {
|
|
47
|
+
if (j.direction === 'download')
|
|
48
|
+
return;
|
|
49
|
+
const c = await client(j);
|
|
50
|
+
const path = statePath(j);
|
|
51
|
+
if (!await lstat(path).then(() => true, e => { if (e.code === 'ENOENT')
|
|
52
|
+
return false; throw e; }))
|
|
53
|
+
return;
|
|
54
|
+
const state = await readUploadState(path);
|
|
55
|
+
// Cancelling local transfers must never cancel or delete an already submitted ingestion job.
|
|
56
|
+
for (const batch of state.batches)
|
|
57
|
+
if (batch.sessionId) {
|
|
58
|
+
const session = await c.getUpload(batch.sessionId);
|
|
59
|
+
if (session.status === 'uploading')
|
|
60
|
+
await c.cancelUpload(batch.sessionId);
|
|
61
|
+
if (session.status === 'submitted')
|
|
62
|
+
j.batches.push({ batch_id: session.batch_id, kind: 'archive', status: 'submitted' });
|
|
63
|
+
}
|
|
64
|
+
j.phase = j.batches.length ? 'partially_submitted' : 'cancelled';
|
|
65
|
+
} }
|
|
66
|
+
});
|
|
67
|
+
this.kb = kb;
|
|
68
|
+
}
|
|
69
|
+
async uploads(tenant, collection, paths, signal) {
|
|
70
|
+
const c = await this.kb.client(tenant);
|
|
71
|
+
const jobs = [];
|
|
72
|
+
// Plan before enqueue: a bad selection never leaves half a queue behind.
|
|
73
|
+
for (const path of paths) {
|
|
74
|
+
const files = await scanUploadFiles(path, signal);
|
|
75
|
+
for (const file of files)
|
|
76
|
+
jobs.push(this.job(c, tenant, collection, '', file.path, file.size_bytes, 'upload'));
|
|
77
|
+
}
|
|
78
|
+
signal?.throwIfAborted();
|
|
79
|
+
return this.enqueue(jobs);
|
|
80
|
+
}
|
|
81
|
+
async download(tenant, collection, document, folder) {
|
|
82
|
+
const c = await this.kb.client(tenant), ticket = await c.downloadTicket(document);
|
|
83
|
+
if (!ticket.filename || basename(ticket.filename) !== ticket.filename || /[\\/\u0000-\u001f]/u.test(ticket.filename) || ['.', '..'].includes(ticket.filename))
|
|
84
|
+
throw new KbError('Invalid filename.', 'kb_input_invalid', 400);
|
|
85
|
+
return this.enqueue([this.job(c, tenant, collection, document, join(folder, ticket.filename), ticket.size_bytes ?? 0, 'download')]);
|
|
86
|
+
}
|
|
87
|
+
async ingestion(id) {
|
|
88
|
+
const job = this.jobs.find(j => j.id === id);
|
|
89
|
+
if (!job)
|
|
90
|
+
throw new KbError('Task not found.', 'kb_input_invalid', 404);
|
|
91
|
+
const c = await this.kb.client(job.tenant);
|
|
92
|
+
if (c.binding !== job.binding)
|
|
93
|
+
throw new KbError('Target changed.', 'kb_state_binding_mismatch');
|
|
94
|
+
return Promise.all(job.batches.map(b => c.getTask(b.batch_id, b.kind)));
|
|
95
|
+
}
|
|
96
|
+
job(c, tenant, collection, document, localPath, size, direction) {
|
|
97
|
+
const date = new Date().toISOString();
|
|
98
|
+
return { id: randomUUID(), tenant, collection, document, localPath, label: basename(localPath), binding: c.binding, size, transferred: 0, status: 'queued', createdAt: date, updatedAt: date, phase: 'queued', direction, batches: [] };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=web-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-queue.js","sourceRoot":"","sources":["../../src/kb/web-queue.ts"],"names":[],"mappings":"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"}
|
package/dist/kb/web.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type LocalPicker } from '../oss/local-picker.js';
|
|
2
|
+
import { KbClient } from './client.js';
|
|
3
|
+
export interface KbWebEnvironment {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
namespace?: string;
|
|
7
|
+
endpoint: string;
|
|
8
|
+
client(): Promise<KbClient>;
|
|
9
|
+
login?: (returnUrl: string, signal: AbortSignal) => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export interface KbWebOptions {
|
|
12
|
+
client: KbClient;
|
|
13
|
+
environments?: KbWebEnvironment[];
|
|
14
|
+
defaultEnvironment?: string;
|
|
15
|
+
directory?: string;
|
|
16
|
+
picker?: LocalPicker;
|
|
17
|
+
port?: number;
|
|
18
|
+
openBrowser?: boolean;
|
|
19
|
+
browserOpen?: (url: string) => Promise<unknown>;
|
|
20
|
+
}
|
|
21
|
+
export declare function startKbWeb(options: KbWebOptions): Promise<{
|
|
22
|
+
url: string;
|
|
23
|
+
browserOpened: boolean;
|
|
24
|
+
close: () => Promise<void>;
|
|
25
|
+
waitUntilClosed: () => Promise<void>;
|
|
26
|
+
}>;
|