dsh-plugin-tool-management 0.12.0 → 0.13.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.
@@ -0,0 +1,101 @@
1
+ // 「模型工具表」开关(2026-09-23)。
2
+ //
3
+ // 为什么要有它:工具表是按**每个请求**付钱的 —— 本插件 20 个工具的 schema 合计 ≈3,100 tok,
4
+ // 每一轮都随请求发出,哪怕这一轮根本用不上(实测口径见 review/后续方向.md)。关掉某几个工具,
5
+ // 它们整份不进请求(不是"把描述写短点"那种省);面板(114 个 op)与注入通道完全不受影响。
6
+ //
7
+ // 本文件只放纯逻辑(normalize / 分域分组 / 体积汇总)。落盘与 TTL 缓存在 index.ts,与
8
+ // 注入设置(`inject-settings.json`)走同一套写法。
9
+ //
10
+ // 谁读这份设置:
11
+ // · index.ts 的 op `tool-table`(读写侧车 + 写后刷新可见性与两个目录);
12
+ // · mcp/manager.ts 的 `pluginHiddenTools` —— 官方 `tools.restrict()` 只允许**每个 agent
13
+ // scope 一层**限制(两处各调一次会互相覆盖),所以 MCP 停用名单与我们的名单必须在那边
14
+ // 并成一次 restrict;
15
+ // · 工具执行门禁(关掉的工具即便被点到也不执行 —— 可见性半边失败时仍有这一半);
16
+ // · 注入通道与两个目录:目录里「用 `skill_manager_list` 查」这类句子在工具关掉后就是假的。
17
+ import { INJECT_DOMAIN_KEYS, domainOfTool } from '../context-inject.js';
18
+ /** 默认一个都不关:装完即用,省钱的开关由用户自己按需打开。 */
19
+ export const DEFAULT_TOOL_TABLE_SETTINGS = { hidden: [] };
20
+ /** 把任意输入夹成合法设置(只收非空字符串;重复的只留一份)。 */
21
+ export function normalizeToolTableSettings(raw) {
22
+ const obj = (raw && typeof raw === 'object' ? raw : {});
23
+ const list = Array.isArray(obj.hidden) ? obj.hidden : [];
24
+ const hidden = [];
25
+ for (const item of list) {
26
+ // 只认字符串:`[7]` 这种手改产物不该被 String() 变成一个看着像工具名的东西。
27
+ if (typeof item !== 'string')
28
+ continue;
29
+ const name = item.trim();
30
+ if (name !== '' && hidden.indexOf(name) < 0)
31
+ hidden.push(name);
32
+ }
33
+ return { hidden };
34
+ }
35
+ /**
36
+ * 宿主与界面共用的字符/词比(`dsh-token-meter` 的 `CHARS_PER_TOKEN`,其
37
+ * `estimateToolsTokens` = `ceil(JSON.stringify(tools).length / 4) + 4`)。
38
+ *
39
+ * 这是**估算**:宿主自己也这么说("Actual usage remains authoritative",真实用量来自
40
+ * API 的 `stream_options.include_usage`)。界面上必须带「≈」。
41
+ */
42
+ export const CHARS_PER_TOKEN = 4;
43
+ export function estimateTok(bytes) {
44
+ const value = Number(bytes);
45
+ if (!Number.isFinite(value) || value <= 0)
46
+ return 0;
47
+ return Math.ceil(value / CHARS_PER_TOKEN);
48
+ }
49
+ /**
50
+ * 纯函数:把注册时量到的体积按域分组,标出哪些被关掉,给出三档合计。
51
+ *
52
+ * 顺序:域按 `INJECT_DOMAIN_KEYS`(界面与注入通道同一顺序),域内按**注册顺序**
53
+ * —— 改顺序等于改显示顺序,不额外定义"重要性",免得出现第二份排序真相。
54
+ */
55
+ export function buildToolTableReport(rows, hidden) {
56
+ const off = new Set(hidden.map((name) => String(name)));
57
+ const buckets = new Map();
58
+ for (const key of INJECT_DOMAIN_KEYS)
59
+ buckets.set(key, []);
60
+ for (const row of rows) {
61
+ const name = String(row && row.name ? row.name : '').trim();
62
+ if (name === '')
63
+ continue;
64
+ // 认不出前缀的工具归到 `other` 而不是丢掉:丢掉 = 它在界面上根本不出现,
65
+ // 于是"没登记的域"就永远关不掉,而且没人看得出来(静默降级)。
66
+ const key = domainOfTool(name) ?? 'other';
67
+ let list = buckets.get(key);
68
+ if (list === undefined) {
69
+ list = [];
70
+ buckets.set(key, list);
71
+ }
72
+ list.push({ name, tok: estimateTok(row.bytes), hidden: off.has(name) });
73
+ }
74
+ const groups = [];
75
+ let visibleTok = 0;
76
+ let hiddenTok = 0;
77
+ let visibleCount = 0;
78
+ let totalCount = 0;
79
+ for (const [key, tools] of buckets) {
80
+ if (!tools.length)
81
+ continue;
82
+ let tok = 0;
83
+ let offTok = 0;
84
+ for (const tool of tools) {
85
+ tok += tool.tok;
86
+ totalCount += 1;
87
+ if (tool.hidden)
88
+ offTok += tool.tok;
89
+ else {
90
+ visibleTok += tool.tok;
91
+ visibleCount += 1;
92
+ }
93
+ }
94
+ hiddenTok += offTok;
95
+ groups.push({ key, tools, tok, hiddenTok: offTok });
96
+ }
97
+ return {
98
+ groups, visibleTok, hiddenTok, totalTok: visibleTok + hiddenTok,
99
+ visibleCount, hiddenCount: totalCount - visibleCount, totalCount,
100
+ };
101
+ }
package/package.json CHANGED
@@ -1,108 +1,108 @@
1
- {
2
- "name": "dsh-plugin-tool-management",
3
- "version": "0.12.0",
4
- "description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagents, AGENTS.md presets and archived sessions — scene memory injects into the system prompt, scene lock freezes all five domains, deleted workspaces re-register with one click. Settings UI + HTTP API + 14 model tools (mcp_manager_*, skill_manager_*, prompt_manager_*, memory_manager_*, subagent_*). Install with one command: dsh plugin --profile web add dsh-plugin-tool-management@latest",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/ouli-1242/dsh-plugin-tool-management"
8
- },
9
- "type": "module",
10
- "main": "lib/index.js",
11
- "exports": {
12
- ".": "./lib/index.js",
13
- "./client": "./lib/client.js",
14
- "./workspace": "./lib/sessions/workspace.js",
15
- "./package.json": "./package.json"
16
- },
17
- "files": [
18
- "lib",
19
- "cordis.patch.yml",
20
- "README.md",
21
- "README_EN.md",
22
- "CHANGELOG.md",
23
- "LICENSE",
24
- "screenshots.json",
25
- "docs"
26
- ],
27
- "engines": {
28
- "node": ">=18"
29
- },
30
- "publishConfig": {
31
- "registry": "https://registry.npmjs.org",
32
- "access": "public"
33
- },
34
- "scripts": {
35
- "build": "tsc -p tsconfig.json && node scripts/sync-client.mjs && node scripts/sync-profile.mjs",
36
- "prepublishOnly": "npm run build && npm run lint && node --test test/client-exports.test.mjs",
37
- "lint": "node --check lib/client.js && node --check lib/index.js",
38
- "typecheck:client": "node scripts/sync-client.mjs && tsc -p tsconfig.client.json",
39
- "check:i18n": "node scripts/check-i18n.mjs lib/client.js",
40
- "check:host": "node scripts/host-deps.mjs && node scripts/doctor.mjs",
41
- "host-deps": "node scripts/host-deps.mjs --fix",
42
- "doctor": "node scripts/doctor.mjs",
43
- "test": "npm run build && npm run check:i18n && node --test test/contracts.test.mjs test/client-exports.test.mjs",
44
- "sync:profile": "node scripts/sync-profile.mjs"
45
- },
46
- "keywords": [
47
- "dsh",
48
- "deepseek-harness",
49
- "skill",
50
- "skills",
51
- "mcp",
52
- "mcp-server",
53
- "plugin",
54
- "cordis"
55
- ],
56
- "dsh": {
57
- "bundle": {
58
- "patch": "./cordis.patch.yml"
59
- },
60
- "client": {
61
- "platform": "web",
62
- "inject": [
63
- "@deepseek-ai/dsh-client-locale"
64
- ]
65
- }
66
- },
67
- "peerDependencies": {
68
- "@deepseek-ai/cordis": "^4.0.2",
69
- "@deepseek-ai/dsh-llm": ">=0.1.5-rc.2",
70
- "@deepseek-ai/dsh-session": ">=0.1.5-rc.2",
71
- "@deepseek-ai/dsh-session-projection-cache": ">=0.1.5-rc.2",
72
- "@deepseek-ai/dsh-spill-local": ">=0.1.5-rc.2",
73
- "@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.2",
74
- "@deepseek-ai/dsh-subagent-fork-in-process": ">=0.1.5-rc.2",
75
- "@deepseek-ai/dsh-subagent-spawn-in-process": ">=0.1.5-rc.2",
76
- "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2",
77
- "@deepseek-ai/dsh-workspace": ">=0.1.5-rc.2",
78
- "react": "^18.2.0"
79
- },
80
- "peerDependenciesMeta": {
81
- "@deepseek-ai/dsh-subagent-fork-in-process": {
82
- "optional": true
83
- },
84
- "@deepseek-ai/dsh-subagent-spawn-in-process": {
85
- "optional": true
86
- }
87
- },
88
- "devDependencies": {
89
- "@deepseek-ai/cordis": "^4.0.1",
90
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
91
- "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
92
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2",
93
- "@deepseek-ai/dsh-spill-local": "^0.1.5-rc.2",
94
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
95
- "@deepseek-ai/dsh-subagent-fork-in-process": "^0.1.5-rc.2",
96
- "@deepseek-ai/dsh-subagent-spawn-in-process": "^0.1.5-rc.2",
97
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
98
- "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2",
99
- "@types/js-yaml": "^4.0.9",
100
- "@types/node": "^24.0.0",
101
- "typescript": "^6.0.0"
102
- },
103
- "license": "MIT",
104
- "dependencies": {
105
- "fflate": "^0.8.3",
106
- "js-yaml": "^4.3.2"
107
- }
108
- }
1
+ {
2
+ "name": "dsh-plugin-tool-management",
3
+ "version": "0.13.0",
4
+ "description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagents, AGENTS.md presets and archived sessions — scene memory injects into the system prompt, scene lock freezes all five domains, deleted workspaces re-register with one click. Settings UI + HTTP API + 20 model tools (mcp_manager_*, skill_manager_*, prompt_manager_*, memory_manager_*, subagent_*). Install with one command: dsh plugin --profile web add dsh-plugin-tool-management@latest",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/ouli-1242/dsh-plugin-tool-management"
8
+ },
9
+ "type": "module",
10
+ "main": "lib/index.js",
11
+ "exports": {
12
+ ".": "./lib/index.js",
13
+ "./client": "./lib/client.js",
14
+ "./workspace": "./lib/sessions/workspace.js",
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "lib",
19
+ "cordis.patch.yml",
20
+ "README.md",
21
+ "README_EN.md",
22
+ "CHANGELOG.md",
23
+ "LICENSE",
24
+ "screenshots.json",
25
+ "docs"
26
+ ],
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "publishConfig": {
31
+ "registry": "https://registry.npmjs.org",
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.json && node scripts/sync-client.mjs && node scripts/sync-profile.mjs",
36
+ "prepublishOnly": "npm run build && npm run lint && npm run typecheck:client && node --test test/client-exports.test.mjs",
37
+ "lint": "node --check lib/client.js && node --check lib/index.js",
38
+ "typecheck:client": "node scripts/sync-client.mjs && tsc -p tsconfig.client.json",
39
+ "check:i18n": "node scripts/check-i18n.mjs lib/client.js",
40
+ "check:host": "node scripts/host-deps.mjs && node scripts/doctor.mjs",
41
+ "host-deps": "node scripts/host-deps.mjs --fix",
42
+ "doctor": "node scripts/doctor.mjs",
43
+ "test": "npm run build && npm run check:i18n && npm run typecheck:client && node --test test/contracts.test.mjs test/client-exports.test.mjs",
44
+ "sync:profile": "node scripts/sync-profile.mjs"
45
+ },
46
+ "keywords": [
47
+ "dsh",
48
+ "deepseek-harness",
49
+ "skill",
50
+ "skills",
51
+ "mcp",
52
+ "mcp-server",
53
+ "plugin",
54
+ "cordis"
55
+ ],
56
+ "dsh": {
57
+ "bundle": {
58
+ "patch": "./cordis.patch.yml"
59
+ },
60
+ "client": {
61
+ "platform": "web",
62
+ "inject": [
63
+ "@deepseek-ai/dsh-client-locale"
64
+ ]
65
+ }
66
+ },
67
+ "peerDependencies": {
68
+ "@deepseek-ai/cordis": "^4.0.2",
69
+ "@deepseek-ai/dsh-llm": ">=0.1.5-rc.2",
70
+ "@deepseek-ai/dsh-session": ">=0.1.5-rc.2",
71
+ "@deepseek-ai/dsh-session-projection-cache": ">=0.1.5-rc.2",
72
+ "@deepseek-ai/dsh-spill-local": ">=0.1.5-rc.2",
73
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.2",
74
+ "@deepseek-ai/dsh-subagent-fork-in-process": ">=0.1.5-rc.2",
75
+ "@deepseek-ai/dsh-subagent-spawn-in-process": ">=0.1.5-rc.2",
76
+ "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2",
77
+ "@deepseek-ai/dsh-workspace": ">=0.1.5-rc.2",
78
+ "react": "^18.2.0"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "@deepseek-ai/dsh-subagent-fork-in-process": {
82
+ "optional": true
83
+ },
84
+ "@deepseek-ai/dsh-subagent-spawn-in-process": {
85
+ "optional": true
86
+ }
87
+ },
88
+ "devDependencies": {
89
+ "@deepseek-ai/cordis": "^4.0.1",
90
+ "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
91
+ "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
92
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2",
93
+ "@deepseek-ai/dsh-spill-local": "^0.1.5-rc.2",
94
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
95
+ "@deepseek-ai/dsh-subagent-fork-in-process": "^0.1.5-rc.2",
96
+ "@deepseek-ai/dsh-subagent-spawn-in-process": "^0.1.5-rc.2",
97
+ "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
98
+ "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2",
99
+ "@types/js-yaml": "^4.0.9",
100
+ "@types/node": "^24.0.0",
101
+ "typescript": "^6.0.0"
102
+ },
103
+ "license": "MIT",
104
+ "dependencies": {
105
+ "fflate": "^0.8.3",
106
+ "js-yaml": "^4.3.2"
107
+ }
108
+ }