@lemoncat7/dsh-knowledge 0.6.0-alpha.6

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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/cordis.patch.yml +12 -0
  4. package/docs/architecture.md +107 -0
  5. package/docs/document-knowledge-design.zh-CN.md +329 -0
  6. package/docs/requirements.md +86 -0
  7. package/lib/api.d.ts +4 -0
  8. package/lib/api.d.ts.map +1 -0
  9. package/lib/api.js +497 -0
  10. package/lib/api.js.map +1 -0
  11. package/lib/client.js +420 -0
  12. package/lib/client.js.map +7 -0
  13. package/lib/config.d.ts +38 -0
  14. package/lib/config.d.ts.map +1 -0
  15. package/lib/config.js +84 -0
  16. package/lib/config.js.map +1 -0
  17. package/lib/connection.d.ts +15 -0
  18. package/lib/connection.d.ts.map +1 -0
  19. package/lib/connection.js +95 -0
  20. package/lib/connection.js.map +1 -0
  21. package/lib/control.d.ts +26 -0
  22. package/lib/control.d.ts.map +1 -0
  23. package/lib/control.js +149 -0
  24. package/lib/control.js.map +1 -0
  25. package/lib/domain.d.ts +207 -0
  26. package/lib/domain.d.ts.map +1 -0
  27. package/lib/domain.js +122 -0
  28. package/lib/domain.js.map +1 -0
  29. package/lib/extraction.d.ts +27 -0
  30. package/lib/extraction.d.ts.map +1 -0
  31. package/lib/extraction.js +367 -0
  32. package/lib/extraction.js.map +1 -0
  33. package/lib/index.d.ts +15 -0
  34. package/lib/index.d.ts.map +1 -0
  35. package/lib/index.js +198 -0
  36. package/lib/index.js.map +1 -0
  37. package/lib/local-provider.d.ts +60 -0
  38. package/lib/local-provider.d.ts.map +1 -0
  39. package/lib/local-provider.js +1096 -0
  40. package/lib/local-provider.js.map +1 -0
  41. package/lib/provider-router.d.ts +19 -0
  42. package/lib/provider-router.d.ts.map +1 -0
  43. package/lib/provider-router.js +83 -0
  44. package/lib/provider-router.js.map +1 -0
  45. package/lib/provider.d.ts +38 -0
  46. package/lib/provider.d.ts.map +1 -0
  47. package/lib/provider.js +2 -0
  48. package/lib/provider.js.map +1 -0
  49. package/lib/recall.d.ts +8 -0
  50. package/lib/recall.d.ts.map +1 -0
  51. package/lib/recall.js +76 -0
  52. package/lib/recall.js.map +1 -0
  53. package/lib/remote-provider.d.ts +51 -0
  54. package/lib/remote-provider.d.ts.map +1 -0
  55. package/lib/remote-provider.js +216 -0
  56. package/lib/remote-provider.js.map +1 -0
  57. package/lib/retrieval.d.ts +35 -0
  58. package/lib/retrieval.d.ts.map +1 -0
  59. package/lib/retrieval.js +206 -0
  60. package/lib/retrieval.js.map +1 -0
  61. package/lib/runtime.d.ts +147 -0
  62. package/lib/runtime.d.ts.map +1 -0
  63. package/lib/runtime.js +26 -0
  64. package/lib/runtime.js.map +1 -0
  65. package/lib/tools.d.ts +6 -0
  66. package/lib/tools.d.ts.map +1 -0
  67. package/lib/tools.js +99 -0
  68. package/lib/tools.js.map +1 -0
  69. package/lib/web.d.ts +3 -0
  70. package/lib/web.d.ts.map +1 -0
  71. package/lib/web.js +71 -0
  72. package/lib/web.js.map +1 -0
  73. package/package.json +79 -0
  74. package/web/app.js +1686 -0
  75. package/web/index.html +19 -0
  76. package/web/styles.css +786 -0
package/lib/runtime.js ADDED
@@ -0,0 +1,26 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ export function messageText(message) {
3
+ return message.content
4
+ .filter(block => block.type === 'text' && typeof block.text === 'string')
5
+ .map(block => block.text ?? '')
6
+ .join('\n')
7
+ .trim();
8
+ }
9
+ export function createRecallMessage(text) {
10
+ return {
11
+ id: randomUUID(),
12
+ role: 'user',
13
+ content: [{ type: 'text', text }],
14
+ source: { kind: 'plugin', plugin: 'dsh-knowledge', form: 'recall' },
15
+ };
16
+ }
17
+ export function createWritebackMessage(summary) {
18
+ const bounded = summary.trim().slice(0, 120);
19
+ return {
20
+ id: randomUUID(),
21
+ role: 'user',
22
+ content: [{ type: 'text', text: bounded }],
23
+ source: { kind: 'plugin', plugin: 'dsh-knowledge', form: 'notice', summary: bounded },
24
+ };
25
+ }
26
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAqIxC,MAAM,UAAU,WAAW,CAAC,OAAoB;IAC9C,OAAO,OAAO,CAAC,OAAO;SACnB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;SACxE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;SAC9B,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE;KACpE,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC5C,OAAO;QACL,EAAE,EAAE,UAAU,EAAE;QAChB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE;KACtF,CAAA;AACH,CAAC"}
package/lib/tools.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { KnowledgeProvider } from './provider.js';
2
+ import { KnowledgeHandleCodec } from './retrieval.js';
3
+ import type { RuntimeContextLike } from './runtime.js';
4
+ /** Register read-only retrieval tools. Their effective base scope is resolved from the calling Agent. */
5
+ export declare function registerKnowledgeTools(ctx: RuntimeContextLike, provider: KnowledgeProvider, codec: KnowledgeHandleCodec): void;
6
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAGL,oBAAoB,EAKrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAa,kBAAkB,EAA0C,MAAM,cAAc,CAAA;AAOzG,yGAAyG;AACzG,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,oBAAoB,GAC1B,IAAI,CAGN"}
package/lib/tools.js ADDED
@@ -0,0 +1,99 @@
1
+ import { formatKnowledgeEntry, formatSearchResults, readMountedKnowledge, resolveRecallMounts, searchMountedKnowledge, selectMounts, } from './retrieval.js';
2
+ const textOutput = {
3
+ schema: { type: 'string' },
4
+ render: (_args, value) => [{ type: 'text', text: String(value) }],
5
+ };
6
+ /** Register read-only retrieval tools. Their effective base scope is resolved from the calling Agent. */
7
+ export function registerKnowledgeTools(ctx, provider, codec) {
8
+ ctx.tools.register(searchTool(provider, codec));
9
+ ctx.tools.register(readTool(provider, codec));
10
+ }
11
+ function searchTool(provider, codec) {
12
+ return {
13
+ name: 'knowledge_search',
14
+ description: 'Search only the knowledge bases mounted for recall in THIS session. Use this before answering from memory when the mounted-base catalog may cover the user\'s topic. Returns ranked snippets and signed opaque handles; call knowledge_read with an exact handle to open a result. Natural-language queries are supported. Never invent a handle.',
15
+ parameters: {
16
+ type: 'object',
17
+ additionalProperties: false,
18
+ properties: {
19
+ query: { type: 'string', description: 'What to find. Prefer focused words from the current user request.' },
20
+ base: { type: 'string', description: 'Optional exact mounted knowledge-base name or id. Omit to search all mounted bases.' },
21
+ limit: { type: 'integer', description: 'Maximum ranked results, default 8 and maximum 20.' },
22
+ },
23
+ required: ['query'],
24
+ },
25
+ output: textOutput,
26
+ isConcurrencySafe: () => true,
27
+ async execute(raw, exec) {
28
+ const agent = requireAgent(exec);
29
+ const args = asRecord(raw);
30
+ const query = requireNonEmptyString(args.query, 'query', 6000);
31
+ const base = optionalString(args.base, 'base', 200);
32
+ const limit = optionalInteger(args.limit, 'limit', 1, 20) ?? 8;
33
+ const mounts = selectMounts(await resolveRecallMounts(provider, agent, exec.signal), base);
34
+ if (mounts.length === 0)
35
+ return 'No knowledge bases are mounted for recall in this session.';
36
+ const hits = await searchMountedKnowledge(provider, agent, mounts, query, limit, codec, exec.signal);
37
+ return formatSearchResults(query, hits);
38
+ },
39
+ };
40
+ }
41
+ function readTool(provider, codec) {
42
+ return {
43
+ name: 'knowledge_read',
44
+ description: 'Read one approved knowledge section using the exact signed handle returned by knowledge_search or proactive retrieval. Handles are session-bound. Long sections are paginated; when a result says it was truncated, call again with the reported offset.',
45
+ parameters: {
46
+ type: 'object',
47
+ additionalProperties: false,
48
+ properties: {
49
+ handle: { type: 'string', description: 'Exact opaque handle returned by knowledge_search. Do not reconstruct it.' },
50
+ offset: { type: 'integer', description: 'Character offset for continuing a long section; default 0.' },
51
+ maxChars: { type: 'integer', description: 'Characters to return, default 12000 and maximum 20000.' },
52
+ },
53
+ required: ['handle'],
54
+ },
55
+ output: textOutput,
56
+ isConcurrencySafe: () => true,
57
+ async execute(raw, exec) {
58
+ const agent = requireAgent(exec);
59
+ const args = asRecord(raw);
60
+ const handle = requireNonEmptyString(args.handle, 'handle', 4096);
61
+ const offset = optionalInteger(args.offset, 'offset', 0, 1_000_000) ?? 0;
62
+ const maxChars = optionalInteger(args.maxChars, 'maxChars', 500, 20_000) ?? 12_000;
63
+ const { entry, mount } = await readMountedKnowledge(provider, agent, handle, codec, exec.signal);
64
+ return formatKnowledgeEntry(entry, mount, offset, maxChars);
65
+ },
66
+ };
67
+ }
68
+ function requireAgent(exec) {
69
+ if (exec.agent === undefined)
70
+ throw new Error('knowledge tools require a calling DSH agent');
71
+ return exec.agent;
72
+ }
73
+ function asRecord(value) {
74
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
75
+ throw new Error('tool arguments must be an object');
76
+ return value;
77
+ }
78
+ function requireNonEmptyString(value, name, maxLength) {
79
+ if (typeof value !== 'string' || value.trim().length === 0)
80
+ throw new Error(`${name} must be a non-empty string`);
81
+ const result = value.trim();
82
+ if (result.length > maxLength)
83
+ throw new Error(`${name} must contain at most ${maxLength} characters`);
84
+ return result;
85
+ }
86
+ function optionalString(value, name, maxLength) {
87
+ if (value === undefined)
88
+ return undefined;
89
+ return requireNonEmptyString(value, name, maxLength);
90
+ }
91
+ function optionalInteger(value, name, min, max) {
92
+ if (value === undefined)
93
+ return undefined;
94
+ if (!Number.isInteger(value) || Number(value) < min || Number(value) > max) {
95
+ throw new Error(`${name} must be an integer between ${min} and ${max}`);
96
+ }
97
+ return Number(value);
98
+ }
99
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/lib/web.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { RuntimeContextLike } from './runtime.js';
2
+ export declare function registerKnowledgeWeb(ctx: RuntimeContextLike, webPath: string, apiPrefix: string): () => void;
3
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAiBtD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,MAAM,IAAI,CAYZ"}
package/lib/web.js ADDED
@@ -0,0 +1,71 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { createHash } from 'node:crypto';
3
+ const STATIC_ASSETS = new Map([
4
+ ['app.js', loadAsset('../web/app.js', 'text/javascript; charset=utf-8')],
5
+ ['styles.css', loadAsset('../web/styles.css', 'text/css; charset=utf-8')],
6
+ ]);
7
+ const ASSET_VERSION = createHash('sha256')
8
+ .update([...STATIC_ASSETS.values()].map(asset => asset.body).join(''))
9
+ .digest('hex')
10
+ .slice(0, 12);
11
+ const INDEX_TEMPLATE = readFileSync(new URL('../web/index.html', import.meta.url), 'utf8');
12
+ export function registerKnowledgeWeb(ctx, webPath, apiPrefix) {
13
+ const webServer = ctx.webServer ?? ctx.get('webServer');
14
+ if (webServer === undefined)
15
+ throw new Error('exposeWeb requires the DSH webServer service');
16
+ const index = Buffer.from(INDEX_TEMPLATE
17
+ .replaceAll('__DSH_KNOWLEDGE_API_PREFIX__', escapeHtmlAttribute(apiPrefix))
18
+ .replaceAll('__DSH_KNOWLEDGE_WEB_PATH__', escapeHtmlAttribute(webPath))
19
+ .replaceAll('__DSH_KNOWLEDGE_ASSET_VERSION__', ASSET_VERSION));
20
+ return webServer.register({
21
+ kind: 'prefix',
22
+ path: webPath,
23
+ handler: (req, res) => serveWeb(req, res, webPath, index),
24
+ });
25
+ }
26
+ function serveWeb(req, res, webPath, index) {
27
+ const method = req.method ?? 'GET';
28
+ if (method !== 'GET' && method !== 'HEAD') {
29
+ res.writeHead(405, { allow: 'GET, HEAD', ...securityHeaders() });
30
+ res.end();
31
+ return;
32
+ }
33
+ const pathname = new URL(req.url ?? '/', 'http://knowledge.local').pathname;
34
+ const relative = pathname.slice(webPath.length).replace(/^\/+|\/+$/g, '');
35
+ if (relative.length === 0) {
36
+ sendAsset(res, method, { body: index, contentType: 'text/html; charset=utf-8' });
37
+ return;
38
+ }
39
+ const asset = STATIC_ASSETS.get(relative);
40
+ if (asset === undefined) {
41
+ res.writeHead(404, securityHeaders());
42
+ res.end();
43
+ return;
44
+ }
45
+ sendAsset(res, method, asset);
46
+ }
47
+ function sendAsset(res, method, asset) {
48
+ res.writeHead(200, {
49
+ ...securityHeaders(),
50
+ 'content-type': asset.contentType,
51
+ 'content-length': asset.body.byteLength,
52
+ 'cache-control': asset.contentType.startsWith('text/html') ? 'no-store' : 'public, max-age=31536000, immutable',
53
+ });
54
+ res.end(method === 'HEAD' ? undefined : asset.body);
55
+ }
56
+ function securityHeaders() {
57
+ return {
58
+ 'content-security-policy': "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'; font-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'self'; form-action 'self'",
59
+ 'referrer-policy': 'no-referrer',
60
+ 'x-content-type-options': 'nosniff',
61
+ 'x-frame-options': 'SAMEORIGIN',
62
+ 'cross-origin-opener-policy': 'same-origin',
63
+ };
64
+ }
65
+ function loadAsset(path, contentType) {
66
+ return { body: readFileSync(new URL(path, import.meta.url)), contentType };
67
+ }
68
+ function escapeHtmlAttribute(value) {
69
+ return value.replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
70
+ }
71
+ //# sourceMappingURL=web.js.map
package/lib/web.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@lemoncat7/dsh-knowledge",
3
+ "version": "0.6.0-alpha.6",
4
+ "description": "Installable DeepSeek Harness knowledge base plugin",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./lib/index.js",
8
+ "types": "./lib/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./lib/index.d.ts",
12
+ "default": "./lib/index.js"
13
+ },
14
+ "./client": {
15
+ "default": "./lib/client.js"
16
+ },
17
+ "./cordis.patch.yml": "./cordis.patch.yml",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "lib/**/*.js",
22
+ "lib/**/*.d.ts",
23
+ "lib/**/*.map",
24
+ "lib/client.js",
25
+ "lib/client.js.map",
26
+ "cordis.patch.yml",
27
+ "web/**/*",
28
+ "docs/**/*.md",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "dsh": {
33
+ "bundle": {
34
+ "patch": "./cordis.patch.yml"
35
+ },
36
+ "client": {
37
+ "platform": "web",
38
+ "inject": [
39
+ "@deepseek-ai/dsh-client-runtime",
40
+ "@deepseek-ai/dsh-client-ui-sidebar",
41
+ "@deepseek-ai/dsh-client-ui-settings",
42
+ "@deepseek-ai/dsh-client-ui-settings-plugins"
43
+ ]
44
+ }
45
+ },
46
+ "engines": {
47
+ "node": "^22.19.0 || >=24.0.0"
48
+ },
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.json && node scripts/build-client.mjs",
51
+ "clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
52
+ "prepare": "npm run clean && npm run build",
53
+ "test": "npm run build && node --test test/*.test.mjs",
54
+ "pack:check": "npm pack --dry-run"
55
+ },
56
+ "dependencies": {
57
+ "@deepseek-ai/schemastery": "^3.18.1"
58
+ },
59
+ "peerDependencies": {
60
+ "@deepseek-ai/cordis": "^4.0.1"
61
+ },
62
+ "devDependencies": {
63
+ "@deepseek-ai/cordis": "^4.0.1",
64
+ "@types/node": "^24.0.0",
65
+ "esbuild": "^0.25.0",
66
+ "typescript": "^5.9.3"
67
+ },
68
+ "publishConfig": {
69
+ "access": "public"
70
+ },
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "git+https://github.com/lemoncat7/dsh-knowledge.git"
74
+ },
75
+ "bugs": {
76
+ "url": "https://github.com/lemoncat7/dsh-knowledge/issues"
77
+ },
78
+ "homepage": "https://github.com/lemoncat7/dsh-knowledge#readme"
79
+ }