dsh-tool-folder 0.1.6 → 0.1.7

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 (2) hide show
  1. package/lib/index.js +44 -7
  2. package/package.json +38 -38
package/lib/index.js CHANGED
@@ -163,14 +163,48 @@ function extractQuery(context) {
163
163
  return "";
164
164
  }
165
165
 
166
- function catalogText(tools) {
167
- const lines = tools.map((t) => {
166
+ function serverOf(name) {
167
+ // "mcp__github__get_repo" → "mcp__github"; "openhands_create_conversation" → "openhands";
168
+ // native tools with underscores ("read_file", "search_for_pattern") → "native".
169
+ const m = name.match(/^(mcp__[^_]+(?:_[^_]+)?)/);
170
+ if (m) return m[1];
171
+ if (/^openhands_/.test(name)) return "openhands";
172
+ return "native";
173
+ }
174
+
175
+ function summarizeCaps(tools) {
176
+ // Pull the first few distinct capability keywords from descriptions.
177
+ const seen = new Set();
178
+ const caps = [];
179
+ for (const t of tools) {
168
180
  const d = (t.description || "").replace(/\s+/g, " ").trim();
169
- return `- ${t.name}: ${d.slice(0, 90)}`;
170
- });
181
+ const head = d.split(/[—,;:]/)[0].slice(0, 60);
182
+ if (head && !seen.has(head)) {
183
+ seen.add(head);
184
+ caps.push(head);
185
+ }
186
+ if (caps.length >= 3) break;
187
+ }
188
+ return caps.join(" | ") || "capabilities unknown";
189
+ }
190
+
191
+ function catalogText(tools) {
192
+ // Affordance fix: group folded tools by server and emit a capability
193
+ // summary per server (not a callable-looking name list). The model must
194
+ // expand arguments via tools_schema before calling a folded tool.
195
+ const byServer = new Map();
196
+ for (const t of tools) {
197
+ const s = serverOf(t.name);
198
+ if (!byServer.has(s)) byServer.set(s, []);
199
+ byServer.get(s).push(t);
200
+ }
201
+ const lines = [...byServer.entries()]
202
+ .sort((a, b) => b[1].length - a[1].length)
203
+ .map(([server, ts]) => `- [${server}]: ${ts.length} tools — ${summarizeCaps(ts)}`);
171
204
  return [
172
205
  "Additional tools exist but are not loaded for this request. " +
173
- "You can still call them if needed — name them exactly as listed:",
206
+ "They are grouped by server below. To call one: first expand its " +
207
+ "arguments with tools_schema (exact tool name), then call it by name.",
174
208
  ...lines,
175
209
  ].join("\n");
176
210
  }
@@ -267,11 +301,14 @@ export function apply(ctx, config) {
267
301
  addPerServerTopK(dyn, tools, m.server, `${query} ${m.keywords.join(" ")}`, 3);
268
302
  }
269
303
  } else {
270
- // aliases fallback (existing behavior preserved verbatim)
304
+ // aliases fallback — narrowed to a single representative tool per
305
+ // matching server (topK=1). A whole-server injection cancels the fold
306
+ // budget; the rest of the server stays discoverable via tools_search
307
+ // and the grouped catalog.
271
308
  for (const [prefix, keywords] of Object.entries(cfg.aliases || {})) {
272
309
  const matched = keywords.filter((k) => q.includes(String(k).toLowerCase()));
273
310
  if (matched.length === 0) continue;
274
- addPerServerTopK(dyn, tools, prefix, `${query} ${matched.join(" ")}`, 3);
311
+ addPerServerTopK(dyn, tools, prefix, `${query} ${matched.join(" ")}`, 1);
275
312
  }
276
313
  }
277
314
  // Generic BM25 last as a union (result set unchanged vs. previous order).
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "dsh-tool-folder",
3
- "version": "0.1.6",
4
- "description": "Fold the DSH tool surface per request + ChainGuard firewall (high-risk block + exfil-chain detection). Shrinks schema tokens 80-90% while keeping selection accuracy. v0.1.6 adds a zod Config schema so every toggle renders in the DSH settings UI.",
5
- "keywords": [
6
- "dsh-plugin",
7
- "dsh",
8
- "deepseek-harness",
9
- "cordis",
10
- "tool-selection",
11
- "token-optimization",
12
- "bm25"
13
- ],
14
- "type": "module",
15
- "main": "lib/index.js",
16
- "files": [
17
- "lib",
18
- "cordis.patch.yml",
19
- "README.md"
20
- ],
21
- "dsh": {
22
- "bundle": {
23
- "patch": "./cordis.patch.yml"
24
- }
25
- },
26
- "license": "MIT",
27
- "engines": {
28
- "node": ">=18"
29
- },
30
- "dependencies": {
31
- "zod": "^4.4.3",
32
- "@deepseek-ai/schemastery": "^3.18.1"
33
- },
34
- "peerDependencies": {
35
- "@deepseek-ai/cordis": "^4.0.1",
36
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
37
- }
38
- }
1
+ {
2
+ "name": "dsh-tool-folder",
3
+ "version": "0.1.7",
4
+ "description": "Fold the DSH tool surface per request + ChainGuard firewall (high-risk block + exfil-chain detection). Shrinks schema tokens 80-90% while keeping selection accuracy. v0.1.6 adds a zod Config schema so every toggle renders in the DSH settings UI.",
5
+ "keywords": [
6
+ "dsh-plugin",
7
+ "dsh",
8
+ "deepseek-harness",
9
+ "cordis",
10
+ "tool-selection",
11
+ "token-optimization",
12
+ "bm25"
13
+ ],
14
+ "type": "module",
15
+ "main": "lib/index.js",
16
+ "files": [
17
+ "lib",
18
+ "cordis.patch.yml",
19
+ "README.md"
20
+ ],
21
+ "dsh": {
22
+ "bundle": {
23
+ "patch": "./cordis.patch.yml"
24
+ }
25
+ },
26
+ "license": "MIT",
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "dependencies": {
31
+ "zod": "^4.4.3",
32
+ "@deepseek-ai/schemastery": "^3.18.1"
33
+ },
34
+ "peerDependencies": {
35
+ "@deepseek-ai/cordis": "^4.0.1",
36
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
37
+ }
38
+ }