@dsh-libing/knowledge-base 0.1.0 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +12 -2
- package/lib/agent-access.d.ts +23 -0
- package/lib/agent-access.js +28 -0
- package/lib/chunks.js +27 -5
- package/lib/client-types/client/JobDetails.d.ts +16 -0
- package/lib/client-types/client/JobsPanel.d.ts +6 -1
- package/lib/client-types/client/QualityReport.d.ts +3 -2
- package/lib/client-types/client/api.d.ts +83 -52
- package/lib/client-types/client/locales.d.ts +2 -0
- package/lib/client-types/client/useKnowledge.d.ts +30 -15
- package/lib/client-types/contract.d.ts +83 -52
- package/lib/client-types/data.d.ts +11 -0
- package/lib/client-types/settings.d.ts +4 -0
- package/lib/client-types/shared.d.ts +17 -0
- package/lib/client.js +40 -40
- package/lib/config.js +9 -1
- package/lib/contract.d.ts +33 -2
- package/lib/contract.js +2 -1
- package/lib/data.d.ts +11 -0
- package/lib/data.js +2 -0
- package/lib/document/convert.js +52 -16
- package/lib/document/pdf-layout.js +45 -10
- package/lib/document/pdf-session.js +10 -4
- package/lib/document/pdf-vision.js +8 -3
- package/lib/document/pdf-worker.js +76 -21
- package/lib/document/pdf.js +39 -9
- package/lib/document/zip.js +14 -6
- package/lib/figures/image-client.d.ts +5 -0
- package/lib/figures/image-client.js +63 -0
- package/lib/figures/image-gate.d.ts +12 -0
- package/lib/figures/image-gate.js +39 -0
- package/lib/figures/image-protocol.d.ts +19 -0
- package/lib/figures/image-protocol.js +9 -0
- package/lib/figures/image-worker.d.ts +1 -0
- package/lib/figures/image-worker.js +69 -0
- package/lib/figures/process.d.ts +1 -1
- package/lib/figures/process.js +19 -38
- package/lib/index.js +6 -2
- package/lib/indexes.js +17 -6
- package/lib/job-storage.d.ts +264 -0
- package/lib/job-storage.js +118 -0
- package/lib/jobs.d.ts +782 -1489
- package/lib/jobs.js +64 -31
- package/lib/models.d.ts +1 -1
- package/lib/models.js +15 -9
- package/lib/retrieval.js +44 -13
- package/lib/revision-cache.d.ts +24 -0
- package/lib/revision-cache.js +100 -0
- package/lib/routes.js +66 -20
- package/lib/runtime.d.ts +4 -0
- package/lib/runtime.js +15 -4
- package/lib/settings.d.ts +4 -0
- package/lib/settings.js +5 -2
- package/lib/shared.d.ts +17 -0
- package/lib/shared.js +3 -0
- package/lib/skills.js +6 -3
- package/lib/store.d.ts +101 -5
- package/lib/store.js +78 -29
- package/lib/tools.js +12 -4
- package/lib/util.js +2 -1
- package/package.json +1 -1
package/lib/routes.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { API, browserBuildSchema, jobActionSchema, catalogQuerySchema, readQuerySchema, searchSchema, assetQuerySchema, revisionQuerySchema } from "./shared.js";
|
|
4
|
+
import { API, jobListQuerySchema, jobDetailsQuerySchema, jobUsageQuerySchema, browserBuildSchema, jobActionSchema, catalogQuerySchema, readQuerySchema, searchSchema, assetQuerySchema, revisionQuerySchema } from "./shared.js";
|
|
5
5
|
import { figureDataSchema, overlaySchema } from "./data.js";
|
|
6
6
|
import { inspectPdf } from "./document/pdf-session.js";
|
|
7
7
|
import { hash, safePath, message, required, fileBytes, checkAbort } from "./util.js";
|
|
8
8
|
const HOST_VERSION = z.object({ version: z.string() }).parse(JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))).version;
|
|
9
|
-
const id = z.string().regex(/^[a-z0-9][a-z0-9-]{0,95}$/u)
|
|
10
|
-
const
|
|
9
|
+
const id = z.string().regex(/^[a-z0-9][a-z0-9-]{0,95}$/u);
|
|
10
|
+
const name = z.string().trim().min(1).max(120);
|
|
11
|
+
const digest = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
12
|
+
const libraryArgs = z.strictObject({ kbId: id });
|
|
13
|
+
const managementArgs = libraryArgs.extend({ confirmName: name });
|
|
11
14
|
const reviewSchema = z.strictObject({ kbId: id, revision: id, docId: id, occurrenceId: id, expectedHash: digest, action: z.enum(['reidentify', 'restore']).optional(), figure: z.union([figureDataSchema.strict(), z.strictObject({ ignore: z.literal(true) }), z.strictObject({ skip: z.literal(true) })]).optional(), visionProvider: z.string().optional(), visionModel: z.string().optional() }).refine(value => Boolean(value.action) !== Boolean(value.figure), '指定一个复核操作或内容');
|
|
12
|
-
const draftQuery = z.strictObject({ jobId: id })
|
|
15
|
+
const draftQuery = z.strictObject({ jobId: id });
|
|
16
|
+
const sourceQuery = revisionQuerySchema.extend({ docId: id });
|
|
17
|
+
const draftAssetQuery = draftQuery.extend({ docId: id, assetId: id });
|
|
13
18
|
const draftReadQuery = draftQuery.extend(readQuerySchema.omit({ kbId: true, revision: true }).shape);
|
|
14
19
|
const headers = { 'cache-control': 'no-store', 'x-content-type-options': 'nosniff', 'referrer-policy': 'no-referrer' };
|
|
15
20
|
function query(request) {
|
|
@@ -69,16 +74,19 @@ export function routes(runtime, ctx) {
|
|
|
69
74
|
throw new Error('PDF 原件不存在于所选版本中');
|
|
70
75
|
return binary((await store.rawSource(snapshot.kbId, doc)).data, 'application/pdf');
|
|
71
76
|
};
|
|
72
|
-
const image = async (asset, file) => {
|
|
77
|
+
const image = async (asset, file, verified) => {
|
|
73
78
|
if (!['image/png', 'image/jpeg', 'image/webp', 'image/gif', 'image/bmp', 'image/tiff'].includes(asset.mime))
|
|
74
79
|
throw new Error('不支持浏览此图片格式,请提供 PNG/JPEG 预览');
|
|
75
|
-
const data = await fileBytes(file, config.maxUncompressedBytes);
|
|
76
|
-
if (`a-${hash(data).slice(0, 20)}` !== asset.assetId)
|
|
80
|
+
const data = verified ?? await fileBytes(file, config.maxUncompressedBytes);
|
|
81
|
+
if (!verified && `a-${hash(data).slice(0, 20)}` !== asset.assetId)
|
|
77
82
|
throw new Error('图片内容与清单不一致');
|
|
78
83
|
return binary(data, asset.mime);
|
|
79
84
|
};
|
|
80
85
|
const tree = (snapshot, kbId) => ({ kbId, revision: snapshot.revision, coverageIncomplete: snapshot.manifest.coverageIncomplete, report: snapshot.manifest.report, documents: snapshot.manifest.documents.map(doc => ({ ...doc, chunks: doc.chunks.map(({ segments: _segments, anchors: _anchors, ...chunk }) => chunk) })) });
|
|
81
|
-
add('list', 'GET', async (request) => {
|
|
86
|
+
add('list', 'GET', async (request) => { const args = jobListQuerySchema.parse(query(request)); if (args.jobsKbId)
|
|
87
|
+
await store.kb(args.jobsKbId); return ({ hostVersion: HOST_VERSION, ...await store.overview(), ...jobs.list(args.jobsKbId, args.jobOffset, args.jobLimit), dataRoot: store.root, config: { chunkTargetChars: config.chunkTargetChars, visionProvider: config.visionProvider, visionModel: config.visionModel, maxInputBytes: config.maxInputBytes } }); });
|
|
88
|
+
add('job-details', 'GET', async (request) => { const args = jobDetailsQuerySchema.parse(query(request)); return jobs.details(args.jobId, args.section === 'report'); });
|
|
89
|
+
add('job-usage', 'GET', async (request) => { const args = jobUsageQuerySchema.parse(query(request)); return jobs.usage(args.jobId, args.offset, args.limit, request.signal); });
|
|
82
90
|
add('create', 'POST', async (request) => store.create((await body(request, z.strictObject({ name }))).name));
|
|
83
91
|
add('delete', 'POST', async (request) => { const args = await body(request, managementArgs); return jobs.trash(args.kbId, args.confirmName); });
|
|
84
92
|
add('restore', 'POST', async (request) => jobs.restore((await body(request, libraryArgs)).kbId));
|
|
@@ -90,32 +98,52 @@ export function routes(runtime, ctx) {
|
|
|
90
98
|
return store.upload(await bytes(request, config.maxInputBytes), args.filename);
|
|
91
99
|
});
|
|
92
100
|
add('inspect-document', 'POST', async (request) => {
|
|
93
|
-
const { receiptId } = await body(request, z.strictObject({ receiptId: id }))
|
|
101
|
+
const { receiptId } = await body(request, z.strictObject({ receiptId: id }));
|
|
102
|
+
const uploaded = await store.uploaded(receiptId);
|
|
94
103
|
if (!/\.pdf$/iu.test(uploaded.filename))
|
|
95
104
|
throw new Error('文档预检只支持 PDF');
|
|
96
105
|
return inspectPdf(await safePath(store.root, join('uploads', receiptId + '.bin')), config, request.signal);
|
|
97
106
|
});
|
|
98
|
-
add('source', 'GET', async (request) => { const args = sourceQuery.parse(query(request))
|
|
107
|
+
add('source', 'GET', async (request) => { const args = sourceQuery.parse(query(request)); const kb = await store.kb(args.kbId); return original({ ...await store.revision(kb.kbId, args.revision), kbId: kb.kbId }, args.docId); });
|
|
99
108
|
add('draft-source', 'GET', async (request) => { const args = draftQuery.extend({ docId: id }).parse(query(request)); return original(await jobs.preview(args.jobId), args.docId); });
|
|
100
109
|
add('build', 'POST', async (request) => jobs.submit(await body(request, browserBuildSchema)));
|
|
101
110
|
add('job', 'POST', async (request) => { const args = await body(request, jobActionSchema); return jobs.action(args.jobId, args.action, args); });
|
|
102
111
|
add('draft', 'GET', async (request) => { const snapshot = await jobs.preview(draftQuery.parse(query(request)).jobId); return { ...tree(snapshot, snapshot.kbId), previewJobId: snapshot.jobId, coverageIncomplete: true }; });
|
|
103
112
|
add('draft-read', 'GET', async (request) => {
|
|
104
|
-
const { jobId, ...args } = draftReadQuery.parse(query(request))
|
|
113
|
+
const { jobId, ...args } = draftReadQuery.parse(query(request));
|
|
114
|
+
const snapshot = await jobs.preview(jobId);
|
|
115
|
+
const chunk = required(snapshot.manifest.documents.flatMap(d => d.chunks).find(c => c.chunkId === args.chunkId), '草稿片段');
|
|
105
116
|
const value = retrieval.readSnapshot(snapshot.kbId, { ...snapshot, chunk, content: await store.chunkContent(snapshot, chunk) }, { ...args, kbId: snapshot.kbId });
|
|
106
117
|
return { ...value, previewJobId: jobId, warnings: ['待发布预览:未向 Agent 检索开放', ...value.warnings] };
|
|
107
118
|
});
|
|
108
|
-
add('draft-asset', 'GET', async (request) => { const args = draftAssetQuery.parse(query(request))
|
|
119
|
+
add('draft-asset', 'GET', async (request) => { const args = draftAssetQuery.parse(query(request)); const snapshot = await jobs.preview(args.jobId); const doc = required(snapshot.manifest.documents.find(d => d.docId === args.docId), '草稿文档'); const asset = required(doc.assets.find(a => a.assetId === args.assetId), '草稿图片'); return image(asset, await safePath(snapshot.root, join('sources', doc.docId, asset.path))); });
|
|
109
120
|
add('catalog', 'GET', async (request) => retrieval.catalog(catalogQuerySchema.parse(query(request))));
|
|
110
|
-
add('tree', 'GET', async (request) => { const args = revisionQuerySchema.parse(query(request))
|
|
121
|
+
add('tree', 'GET', async (request) => { const args = revisionQuerySchema.parse(query(request)); const { kb, snapshot } = await store.open(args.kbId, args.revision); const overlays = await store.overlays(kb.kbId); const value = tree(snapshot, kb.kbId); return { ...value, location: await store.snapshotLocation(kb.kbId, snapshot), documents: value.documents.map(doc => ({ ...doc, figures: doc.figures.map(figure => ({ ...figure, expectedHash: hash(overlays[figure.overlayKey] || null) })) })) }; });
|
|
111
122
|
add('read', 'GET', async (request) => retrieval.read(readQuerySchema.parse(query(request))));
|
|
112
123
|
add('search', 'POST', async (request) => retrieval.search(await body(request, searchSchema)));
|
|
113
|
-
add('asset', 'GET', async (request) => { const args = assetQuerySchema.parse(query(request))
|
|
114
|
-
add('schema', 'GET', async (request) => { const kb = await store.kb(libraryArgs.parse(query(request)).kbId)
|
|
115
|
-
add('schema', 'POST', async (request) => { const args = await body(request, libraryArgs.extend({ content: z.string().max(20000), expectedHash: digest }))
|
|
124
|
+
add('asset', 'GET', async (request) => { const args = assetQuerySchema.parse(query(request)); const kb = await store.kb(args.kbId); const asset = await store.asset(kb.kbId, args.revision, args.docId, args.assetId); return image(asset.asset, asset.file, asset.data); });
|
|
125
|
+
add('schema', 'GET', async (request) => { const kb = await store.kb(libraryArgs.parse(query(request)).kbId); const content = await store.schema(kb.kbId); return { content, hash: hash(content) }; });
|
|
126
|
+
add('schema', 'POST', async (request) => { const args = await body(request, libraryArgs.extend({ content: z.string().max(20000), expectedHash: digest })); const kb = await store.kb(args.kbId); return store.setSchema(kb.kbId, args.content, args.expectedHash); });
|
|
116
127
|
add('review', 'POST', async (request) => {
|
|
117
|
-
const args = await body(request, reviewSchema)
|
|
118
|
-
const
|
|
128
|
+
const args = await body(request, reviewSchema);
|
|
129
|
+
const kb = await store.kb(args.kbId);
|
|
130
|
+
let figure;
|
|
131
|
+
if (args.action) {
|
|
132
|
+
figure = null;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (args.figure && 'ignore' in args.figure) {
|
|
136
|
+
figure = { ignore: true };
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (args.figure && 'skip' in args.figure) {
|
|
140
|
+
figure = { skip: true, types: ['decoration'], description: '人工确认装饰图', visibleLabels: [], relations: [], uncertainties: [], needsReview: false };
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
figure = args.figure;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
119
147
|
if (figure && JSON.stringify(figure).length > config.figureMaxChars * 3)
|
|
120
148
|
throw new Error('图片复核内容超过预算');
|
|
121
149
|
return jobs.review(kb.kbId, args.revision, args.docId, args.occurrenceId, figure === null ? null : overlaySchema.parse(figure), args.expectedHash, { restore: args.action === 'restore', visionProvider: args.visionProvider, visionModel: args.visionModel });
|
|
@@ -139,11 +167,29 @@ export function routes(runtime, ctx) {
|
|
|
139
167
|
try {
|
|
140
168
|
await runtime.ready;
|
|
141
169
|
checkAbort(request.signal);
|
|
142
|
-
const handler = required(methods.get(z.enum(['GET', 'POST', 'HEAD']).parse(request.method)), '请求方法')
|
|
170
|
+
const handler = required(methods.get(z.enum(['GET', 'POST', 'HEAD']).parse(request.method)), '请求方法');
|
|
171
|
+
const value = await runtime.run(signal => handler(new Request(request, { signal })), request.signal);
|
|
143
172
|
return value instanceof Response ? value : json(value);
|
|
144
173
|
}
|
|
145
174
|
catch (error) {
|
|
146
|
-
const detail = message(error)
|
|
175
|
+
const detail = message(error);
|
|
176
|
+
let status;
|
|
177
|
+
if (error instanceof z.ZodError || error instanceof SyntaxError) {
|
|
178
|
+
status = 400;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
if (/变化|冲突|已存在|未退出|正在关闭/u.test(detail)) {
|
|
182
|
+
status = 409;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
if (/无效|必须|不支持|不能|只能|不在回收站|超过|过大|缺少|缺失|尚无|不存在|提供|请选择|待复核|重复/u.test(detail)) {
|
|
186
|
+
status = 400;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
status = 500;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
147
193
|
if (status === 500)
|
|
148
194
|
ctx.logger.warn(`knowledge-base: ${detail}`);
|
|
149
195
|
return json({ error: detail }, status);
|
package/lib/runtime.d.ts
CHANGED
|
@@ -18,8 +18,12 @@ export declare function createRuntime(ctx: Context, raw?: Config): {
|
|
|
18
18
|
modelTimeoutMs: number;
|
|
19
19
|
modelAttempts: number;
|
|
20
20
|
visionConcurrency: number;
|
|
21
|
+
maxModelCallsLimit: number;
|
|
22
|
+
maxModelTokensLimit: number;
|
|
23
|
+
uploadRetentionDays: number;
|
|
21
24
|
maxModelCalls: number;
|
|
22
25
|
maxModelTokens: number;
|
|
26
|
+
imageTimeoutMs: number;
|
|
23
27
|
visionMaxEdge: number;
|
|
24
28
|
visionTileSize: number;
|
|
25
29
|
visionMaxTiles: number;
|
package/lib/runtime.js
CHANGED
|
@@ -7,10 +7,16 @@ import { Jobs } from "./jobs.js";
|
|
|
7
7
|
import { Retrieval } from "./retrieval.js";
|
|
8
8
|
/** One root owner; admitted tasks are durable and the close promise drains them once. */
|
|
9
9
|
export function createRuntime(ctx, raw = {}) {
|
|
10
|
-
const config = resolveConfig(raw)
|
|
10
|
+
const config = resolveConfig(raw);
|
|
11
|
+
const store = new Store(config);
|
|
12
|
+
const models = new Models(ctx, config);
|
|
13
|
+
const jobs = new Jobs(store, models, config);
|
|
14
|
+
const retrieval = new Retrieval(store, config);
|
|
11
15
|
const ready = mkdir(store.root, { recursive: true }).then(() => jobs.init());
|
|
12
|
-
let closing
|
|
13
|
-
|
|
16
|
+
let closing;
|
|
17
|
+
let stopped = false;
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
const pending = new Set();
|
|
14
20
|
const run = (operation, signal) => {
|
|
15
21
|
if (stopped)
|
|
16
22
|
return Promise.reject(new Error('任务服务正在关闭'));
|
|
@@ -32,7 +38,12 @@ export function createRuntime(ctx, raw = {}) {
|
|
|
32
38
|
}
|
|
33
39
|
finally {
|
|
34
40
|
await Promise.allSettled(pending);
|
|
35
|
-
|
|
41
|
+
try {
|
|
42
|
+
await jobs.close();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
store.revisionCache.clear();
|
|
46
|
+
}
|
|
36
47
|
}
|
|
37
48
|
})();
|
|
38
49
|
return closing;
|
package/lib/settings.d.ts
CHANGED
|
@@ -11,8 +11,12 @@ export declare const settingsSchema: z.ZodObject<{
|
|
|
11
11
|
modelTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
12
12
|
modelAttempts: z.ZodDefault<z.ZodNumber>;
|
|
13
13
|
visionConcurrency: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
maxModelCallsLimit: z.ZodDefault<z.ZodNumber>;
|
|
15
|
+
maxModelTokensLimit: z.ZodDefault<z.ZodNumber>;
|
|
16
|
+
uploadRetentionDays: z.ZodDefault<z.ZodNumber>;
|
|
14
17
|
maxModelCalls: z.ZodDefault<z.ZodNumber>;
|
|
15
18
|
maxModelTokens: z.ZodDefault<z.ZodNumber>;
|
|
19
|
+
imageTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
16
20
|
visionMaxEdge: z.ZodDefault<z.ZodNumber>;
|
|
17
21
|
visionTileSize: z.ZodDefault<z.ZodNumber>;
|
|
18
22
|
visionMaxTiles: z.ZodDefault<z.ZodNumber>;
|
package/lib/settings.js
CHANGED
|
@@ -6,13 +6,16 @@ export const settingsSchema = z.strictObject({
|
|
|
6
6
|
catalogMaxChars: positive.min(512).default(6000), candidateLimit: positive.max(30).default(6),
|
|
7
7
|
maxInputBytes: positive.default(64 * 1024 * 1024), maxUncompressedBytes: positive.default(256 * 1024 * 1024), maxArchiveEntries: positive.default(10000),
|
|
8
8
|
modelTimeoutMs: positive.default(90000), modelAttempts: positive.default(3), visionConcurrency: positive.max(8).default(2),
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
maxModelCallsLimit: positive.max(100000).default(10000), maxModelTokensLimit: positive.max(1000000000).default(20000000), uploadRetentionDays: positive.max(365).default(7),
|
|
10
|
+
maxModelCalls: positive.max(100000).default(1000), maxModelTokens: positive.max(1000000000).default(2000000), imageTimeoutMs: positive.max(120000).default(60000), visionMaxEdge: positive.max(4096).default(2048),
|
|
11
|
+
visionTileSize: positive.max(4096).default(1536), visionMaxTiles: positive.max(64).default(12), modelMaxOutputTokens: positive.default(4096),
|
|
11
12
|
summaryMaxChars: positive.default(160), figureMaxChars: positive.default(6000), pdfMaxPages: positive.default(2000),
|
|
12
13
|
pdfMaxPagePixels: positive.default(12000000), pdfPageTimeoutMs: positive.default(60000),
|
|
13
14
|
libreOfficePath: z.string().default(''), visionProvider: z.string().default(''), visionModel: z.string().default(''),
|
|
14
15
|
summaryProvider: z.string().default(''), summaryModel: z.string().default(''), skipImages: z.boolean().default(false), acceptPartial: z.boolean().default(false),
|
|
15
16
|
}).superRefine((value, context) => {
|
|
17
|
+
if (value.maxModelCalls > value.maxModelCallsLimit || value.maxModelTokens > value.maxModelTokensLimit)
|
|
18
|
+
context.addIssue({ code: 'custom', message: '默认任务预算不能超过宿主预算上限' });
|
|
16
19
|
for (const kind of ['vision', 'summary'])
|
|
17
20
|
if (Boolean(value[`${kind}Provider`]) !== Boolean(value[`${kind}Model`]))
|
|
18
21
|
context.addIssue({ code: 'custom', message: `${kind}Provider / ${kind}Model 必须成对配置` });
|
package/lib/shared.d.ts
CHANGED
|
@@ -93,3 +93,20 @@ export declare const revisionQuerySchema: z.ZodObject<{
|
|
|
93
93
|
kbId: z.ZodString;
|
|
94
94
|
revision: z.ZodOptional<z.ZodString>;
|
|
95
95
|
}, z.core.$strict>;
|
|
96
|
+
export declare const jobListQuerySchema: z.ZodObject<{
|
|
97
|
+
jobsKbId: z.ZodOptional<z.ZodString>;
|
|
98
|
+
jobOffset: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
99
|
+
jobLimit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
100
|
+
}, z.core.$strict>;
|
|
101
|
+
export declare const jobDetailsQuerySchema: z.ZodObject<{
|
|
102
|
+
jobId: z.ZodString;
|
|
103
|
+
section: z.ZodDefault<z.ZodEnum<{
|
|
104
|
+
report: "report";
|
|
105
|
+
details: "details";
|
|
106
|
+
}>>;
|
|
107
|
+
}, z.core.$strict>;
|
|
108
|
+
export declare const jobUsageQuerySchema: z.ZodObject<{
|
|
109
|
+
jobId: z.ZodString;
|
|
110
|
+
offset: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
111
|
+
limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
112
|
+
}, z.core.$strict>;
|
package/lib/shared.js
CHANGED
|
@@ -15,3 +15,6 @@ export const searchSchema = z.strictObject({ kbId: selector, revision: id.option
|
|
|
15
15
|
export const readQuerySchema = z.strictObject({ kbId: selector, revision: id.optional(), chunkId: id, query: z.string().max(2000).optional(), keywords: keywordsSchema.optional(), segmentIndex: z.coerce.number().int().nonnegative().optional(), offset: z.coerce.number().int().nonnegative().optional() });
|
|
16
16
|
export const assetQuerySchema = z.strictObject({ kbId: selector, revision: id.optional(), docId: id, assetId: id });
|
|
17
17
|
export const revisionQuerySchema = z.strictObject({ kbId: selector, revision: id.optional() });
|
|
18
|
+
export const jobListQuerySchema = z.strictObject({ jobsKbId: id.optional(), jobOffset: z.coerce.number().int().nonnegative().max(1000000).default(0), jobLimit: z.coerce.number().int().min(1).max(50).default(20) });
|
|
19
|
+
export const jobDetailsQuerySchema = z.strictObject({ jobId: id, section: z.enum(['details', 'report']).default('details') });
|
|
20
|
+
export const jobUsageQuerySchema = jobDetailsQuerySchema.omit({ section: true }).extend({ offset: z.coerce.number().int().nonnegative().max(1000000).default(0), limit: z.coerce.number().int().min(1).max(50).default(20) });
|
package/lib/skills.js
CHANGED
|
@@ -3,10 +3,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
3
3
|
import { checkAbort, required } from "./util.js";
|
|
4
4
|
/** Packaged, invocation-neutral skills; no copies in the operator's user directory. */
|
|
5
5
|
export function skillProvider() {
|
|
6
|
-
const provider = 'libing-knowledge-base'
|
|
6
|
+
const provider = 'libing-knowledge-base';
|
|
7
|
+
const names = ['libing-knowledge-base', 'libing-kb-build', 'libing-kb-search'];
|
|
7
8
|
const candidates = names.map(name => {
|
|
8
|
-
const directory = fileURLToPath(new URL(`../skills/${name}/`, import.meta.url))
|
|
9
|
-
const
|
|
9
|
+
const directory = fileURLToPath(new URL(`../skills/${name}/`, import.meta.url));
|
|
10
|
+
const path = fileURLToPath(new URL(`../skills/${name}/SKILL.md`, import.meta.url));
|
|
11
|
+
const raw = readFileSync(path, 'utf8');
|
|
12
|
+
const header = required(/^---\n([\s\S]*?)\n---\n/u.exec(raw), `skill frontmatter: ${name}`);
|
|
10
13
|
const description = required(/^description:\s*(.+)$/mu.exec(required(header[1]))?.[1], `skill description: ${name}`);
|
|
11
14
|
return { name, description, source: 'bundled', provider, rank: 600, path, resourceBase: { kind: 'directory', path: directory }, invocation: { modelInvocable: true, userInvocable: true }, locator: path };
|
|
12
15
|
});
|
package/lib/store.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { RevisionCache } from './revision-cache.ts';
|
|
1
2
|
import type { Settings } from './config.ts';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { registrySchema } from './data.ts';
|
|
4
5
|
import type { Library, Manifest, Snapshot, Chunk, PublishedDocument, BuildDocument, Overlay } from './data.ts';
|
|
5
6
|
export declare const DEFAULT_SCHEMA = "# \u77E5\u8BC6\u5E93\u6CBB\u7406\u7EA6\u5B9A\n\n\u4FDD\u7559\u539F\u6587\u4E2D\u7684\u578B\u53F7\u3001\u7BA1\u811A\u3001\u5355\u4F4D\u3001\u6570\u503C\u3001\u6781\u6027\u548C\u9002\u7528\u6761\u4EF6\u3002\u56FE\u7247\u63CF\u8FF0\u4E0E\u539F\u6587\u5206\u522B\u6807\u6CE8\uFF1B\u4E0D\u786E\u5B9A\u7684\u4FE1\u606F\u4FDD\u7559\u5F85\u590D\u6838\u3002\u6458\u8981\u7528\u4E8E\u5BFC\u822A\uFF0C\u56DE\u7B54\u4F9D\u636E\u539F\u6587\u548C\u53EF\u6838\u9A8C\u56FE\u50CF\u3002\u5F15\u7528\u5305\u542B\u6587\u6863\u7248\u672C\u3001\u7AE0\u8282\u3001\u7247\u6BB5\u548C\u56FE\u8868\u7F16\u53F7\u3002\n";
|
|
6
7
|
export declare class Store {
|
|
8
|
+
readonly revisionCache: RevisionCache;
|
|
7
9
|
readonly config: Settings;
|
|
8
10
|
readonly root: string;
|
|
9
11
|
private registryTail;
|
|
@@ -103,16 +105,88 @@ export declare class Store {
|
|
|
103
105
|
coverageIncomplete: boolean;
|
|
104
106
|
};
|
|
105
107
|
}>;
|
|
106
|
-
|
|
108
|
+
private inspectKnown;
|
|
109
|
+
overview(): Promise<{
|
|
110
|
+
kbs: ({
|
|
111
|
+
location: {
|
|
112
|
+
kbPath: string;
|
|
113
|
+
revision: null;
|
|
114
|
+
wikiPath: null;
|
|
115
|
+
indexPath: null;
|
|
116
|
+
};
|
|
117
|
+
summary: {
|
|
118
|
+
revision: null;
|
|
119
|
+
documentCount: number;
|
|
120
|
+
chunkCount: number;
|
|
121
|
+
coverageIncomplete: boolean;
|
|
122
|
+
};
|
|
123
|
+
kbId: string;
|
|
124
|
+
name: string;
|
|
125
|
+
createdAt: string;
|
|
126
|
+
deletedAt?: string | undefined;
|
|
127
|
+
purge?: {
|
|
128
|
+
startedAt: string;
|
|
129
|
+
jobIds: string[];
|
|
130
|
+
error?: string | undefined;
|
|
131
|
+
} | undefined;
|
|
132
|
+
} | {
|
|
133
|
+
location: {
|
|
134
|
+
kbPath: string;
|
|
135
|
+
revision: string;
|
|
136
|
+
wikiPath: string;
|
|
137
|
+
indexPath: string;
|
|
138
|
+
};
|
|
139
|
+
summary: {
|
|
140
|
+
revision: string;
|
|
141
|
+
documentCount: number;
|
|
142
|
+
chunkCount: number;
|
|
143
|
+
coverageIncomplete: boolean;
|
|
144
|
+
};
|
|
145
|
+
kbId: string;
|
|
146
|
+
name: string;
|
|
147
|
+
createdAt: string;
|
|
148
|
+
deletedAt?: string | undefined;
|
|
149
|
+
purge?: {
|
|
150
|
+
startedAt: string;
|
|
151
|
+
jobIds: string[];
|
|
152
|
+
error?: string | undefined;
|
|
153
|
+
} | undefined;
|
|
154
|
+
})[];
|
|
155
|
+
deletedKbs: {
|
|
156
|
+
kbId: string;
|
|
157
|
+
name: string;
|
|
158
|
+
createdAt: string;
|
|
159
|
+
deletedAt?: string | undefined;
|
|
160
|
+
purge?: {
|
|
161
|
+
startedAt: string;
|
|
162
|
+
jobIds: string[];
|
|
163
|
+
error?: string | undefined;
|
|
164
|
+
} | undefined;
|
|
165
|
+
}[];
|
|
166
|
+
activities: {
|
|
167
|
+
eventId: string;
|
|
168
|
+
at: string;
|
|
169
|
+
action: "purge" | "create" | "trash" | "restore";
|
|
170
|
+
kbId: string;
|
|
171
|
+
name: string;
|
|
172
|
+
}[];
|
|
173
|
+
}>;
|
|
174
|
+
snapshotLocation(kbId: string, snapshot: Snapshot): Promise<{
|
|
107
175
|
kbPath: string;
|
|
108
|
-
revision:
|
|
109
|
-
wikiPath:
|
|
110
|
-
indexPath:
|
|
111
|
-
}
|
|
176
|
+
revision: string;
|
|
177
|
+
wikiPath: string;
|
|
178
|
+
indexPath: string;
|
|
179
|
+
}>;
|
|
180
|
+
location(kbId: string, revision?: string): Promise<{
|
|
112
181
|
kbPath: string;
|
|
113
182
|
revision: string;
|
|
114
183
|
wikiPath: string;
|
|
115
184
|
indexPath: string;
|
|
185
|
+
} | {
|
|
186
|
+
kbPath: string;
|
|
187
|
+
revision: null;
|
|
188
|
+
wikiPath: null;
|
|
189
|
+
indexPath: null;
|
|
116
190
|
}>;
|
|
117
191
|
schema(kbId: string): Promise<string>;
|
|
118
192
|
setSchema(kbId: string, content: string, expectedHash: string): Promise<{
|
|
@@ -138,7 +212,22 @@ export declare class Store {
|
|
|
138
212
|
buildKey: string;
|
|
139
213
|
coverageIncomplete: boolean;
|
|
140
214
|
} | null>;
|
|
215
|
+
open(selector: string, requested?: string): Promise<{
|
|
216
|
+
kb: {
|
|
217
|
+
kbId: string;
|
|
218
|
+
name: string;
|
|
219
|
+
createdAt: string;
|
|
220
|
+
deletedAt?: string | undefined;
|
|
221
|
+
purge?: {
|
|
222
|
+
startedAt: string;
|
|
223
|
+
jobIds: string[];
|
|
224
|
+
error?: string | undefined;
|
|
225
|
+
} | undefined;
|
|
226
|
+
};
|
|
227
|
+
snapshot: Snapshot;
|
|
228
|
+
}>;
|
|
141
229
|
revision(kbId: string, requested?: string): Promise<Snapshot>;
|
|
230
|
+
private revisionKnown;
|
|
142
231
|
readChunk(kbId: string, revision: string | undefined, chunkId: string): Promise<{
|
|
143
232
|
chunk: {
|
|
144
233
|
chunkId: string;
|
|
@@ -187,6 +276,10 @@ export declare class Store {
|
|
|
187
276
|
manifest: Manifest;
|
|
188
277
|
}>;
|
|
189
278
|
chunkContent(snapshot: Snapshot, chunk: Chunk): Promise<string>;
|
|
279
|
+
chunkView(snapshot: Snapshot, chunk: Chunk, fresh?: boolean): Promise<{
|
|
280
|
+
content: string;
|
|
281
|
+
lower: string;
|
|
282
|
+
}>;
|
|
190
283
|
asset(kbId: string, revision: string | undefined, docId: string, assetId: string): Promise<{
|
|
191
284
|
asset: {
|
|
192
285
|
assetId: string;
|
|
@@ -197,6 +290,7 @@ export declare class Store {
|
|
|
197
290
|
source?: import("./data.ts").Source | undefined;
|
|
198
291
|
};
|
|
199
292
|
file: string;
|
|
293
|
+
data: Buffer<ArrayBufferLike>;
|
|
200
294
|
doc: {
|
|
201
295
|
docId: string;
|
|
202
296
|
title: string;
|
|
@@ -404,6 +498,8 @@ export declare class Store {
|
|
|
404
498
|
}): Promise<string>;
|
|
405
499
|
overlays(kbId: string): Promise<Record<string, Overlay>>;
|
|
406
500
|
setOverlay(kbId: string, key: string, value: Overlay | null, expectedHash: string): Promise<Overlay | undefined>;
|
|
501
|
+
/** Cleanup runs with the sole owner before accepting uploads or starting jobs. Inputs are independent copies. */
|
|
502
|
+
cleanUploads(at?: number): Promise<void>;
|
|
407
503
|
jobDirectories(): Promise<string[]>;
|
|
408
504
|
acquireOwner(): Promise<() => Promise<void>>;
|
|
409
505
|
}
|