@oh-my-pi/pi-coding-agent 14.7.1 → 14.7.3
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 +15 -0
- package/package.json +7 -7
- package/src/config/model-equivalence.ts +1 -0
- package/src/config/model-registry.ts +108 -22
- package/src/config/settings-schema.ts +36 -1
- package/src/discovery/helpers.ts +4 -3
- package/src/edit/index.ts +1 -0
- package/src/eval/py/gateway-coordinator.ts +2 -3
- package/src/eval/py/runtime.ts +1 -0
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/lsp/index.ts +2 -0
- package/src/mcp/discoverable-tool-metadata.ts +24 -202
- package/src/modes/components/extensions/extension-dashboard.ts +26 -2
- package/src/modes/components/extensions/state-manager.ts +41 -0
- package/src/modes/components/tool-execution.ts +3 -29
- package/src/modes/controllers/selector-controller.ts +3 -0
- package/src/modes/interactive-mode.ts +26 -1
- package/src/prompts/tools/search-tool-bm25.md +14 -14
- package/src/prompts/tools/todo-write.md +3 -2
- package/src/sdk.ts +69 -8
- package/src/session/agent-session.ts +177 -1
- package/src/slash-commands/builtin-registry.ts +11 -0
- package/src/task/index.ts +2 -0
- package/src/tool-discovery/tool-index.ts +377 -0
- package/src/tools/ask.ts +2 -0
- package/src/tools/ast-edit.ts +2 -0
- package/src/tools/ast-grep.ts +2 -0
- package/src/tools/bash.ts +1 -0
- package/src/tools/browser.ts +2 -0
- package/src/tools/calculator.ts +2 -0
- package/src/tools/checkpoint.ts +4 -0
- package/src/tools/debug.ts +2 -0
- package/src/tools/eval.ts +2 -0
- package/src/tools/find.ts +2 -0
- package/src/tools/gh.ts +2 -0
- package/src/tools/hindsight-recall.ts +2 -0
- package/src/tools/hindsight-reflect.ts +2 -0
- package/src/tools/hindsight-retain.ts +2 -0
- package/src/tools/index.ts +74 -14
- package/src/tools/inspect-image.ts +2 -0
- package/src/tools/irc.ts +2 -1
- package/src/tools/job.ts +2 -1
- package/src/tools/notebook.ts +2 -0
- package/src/tools/read.ts +1 -0
- package/src/tools/recipe/index.ts +2 -0
- package/src/tools/render-mermaid.ts +2 -0
- package/src/tools/search-tool-bm25.ts +128 -42
- package/src/tools/search.ts +2 -0
- package/src/tools/ssh.ts +2 -0
- package/src/tools/todo-write.ts +2 -1
- package/src/tools/write.ts +2 -0
- package/src/web/search/index.ts +2 -0
- package/src/web/search/providers/searxng.ts +8 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
|
|
3
|
+
// ─── Generic Tool Discovery Types ────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export type DiscoverableToolSource = "builtin" | "mcp" | "extension" | "custom";
|
|
6
|
+
|
|
7
|
+
export interface DiscoverableTool {
|
|
8
|
+
name: string;
|
|
9
|
+
label: string;
|
|
10
|
+
/** Short BM25 corpus entry; falls back to description first 200 chars */
|
|
11
|
+
summary: string;
|
|
12
|
+
source: DiscoverableToolSource;
|
|
13
|
+
/** MCP only */
|
|
14
|
+
serverName?: string;
|
|
15
|
+
/** MCP only */
|
|
16
|
+
mcpToolName?: string;
|
|
17
|
+
schemaKeys: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DiscoverableToolServerSummary {
|
|
21
|
+
name: string;
|
|
22
|
+
toolCount: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface DiscoverableToolSummary {
|
|
26
|
+
servers: DiscoverableToolServerSummary[];
|
|
27
|
+
toolCount: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DiscoverableToolSearchDocument {
|
|
31
|
+
tool: DiscoverableTool;
|
|
32
|
+
termFrequencies: Map<string, number>;
|
|
33
|
+
length: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface DiscoverableToolSearchIndex {
|
|
37
|
+
documents: DiscoverableToolSearchDocument[];
|
|
38
|
+
averageLength: number;
|
|
39
|
+
documentFrequencies: Map<string, number>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface DiscoverableToolSearchResult {
|
|
43
|
+
tool: DiscoverableTool;
|
|
44
|
+
score: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ─── Legacy MCP-typed aliases (back-compat) ──────────────────────────────────
|
|
48
|
+
|
|
49
|
+
/** @deprecated Use DiscoverableTool with source === "mcp" */
|
|
50
|
+
export type DiscoverableMCPTool = Pick<
|
|
51
|
+
DiscoverableTool,
|
|
52
|
+
"name" | "label" | "schemaKeys" | "serverName" | "mcpToolName"
|
|
53
|
+
> & { description: string };
|
|
54
|
+
|
|
55
|
+
/** @deprecated Use DiscoverableToolServerSummary */
|
|
56
|
+
export type DiscoverableMCPToolServerSummary = DiscoverableToolServerSummary;
|
|
57
|
+
|
|
58
|
+
/** @deprecated Use DiscoverableToolSummary */
|
|
59
|
+
export type DiscoverableMCPToolSummary = DiscoverableToolSummary;
|
|
60
|
+
|
|
61
|
+
/** Tool object stored on legacy MCP index documents. Carries both legacy `description` and the
|
|
62
|
+
* generic `summary`/`source` so the legacy index is structurally assignable to
|
|
63
|
+
* DiscoverableToolSearchIndex (search functions read termFrequencies, not the tool fields). */
|
|
64
|
+
export type DiscoverableMCPSearchTool = DiscoverableTool & { description: string };
|
|
65
|
+
|
|
66
|
+
/** @deprecated Use DiscoverableToolSearchDocument */
|
|
67
|
+
export interface DiscoverableMCPSearchDocument {
|
|
68
|
+
tool: DiscoverableMCPSearchTool;
|
|
69
|
+
termFrequencies: Map<string, number>;
|
|
70
|
+
length: number;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** @deprecated Use DiscoverableToolSearchIndex.
|
|
74
|
+
* Documents on this index expose `tool.description` (legacy MCP shape) while still being
|
|
75
|
+
* searchable via `searchDiscoverableTools`. */
|
|
76
|
+
export interface DiscoverableMCPSearchIndex {
|
|
77
|
+
documents: DiscoverableMCPSearchDocument[];
|
|
78
|
+
averageLength: number;
|
|
79
|
+
documentFrequencies: Map<string, number>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** @deprecated Use DiscoverableToolSearchResult */
|
|
83
|
+
export interface DiscoverableMCPSearchResult {
|
|
84
|
+
tool: DiscoverableMCPSearchTool;
|
|
85
|
+
score: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ─── BM25 Constants ───────────────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
const BM25_K1 = 1.2;
|
|
91
|
+
const BM25_B = 0.75;
|
|
92
|
+
const FIELD_WEIGHTS = {
|
|
93
|
+
name: 6,
|
|
94
|
+
label: 4,
|
|
95
|
+
serverName: 2,
|
|
96
|
+
mcpToolName: 4,
|
|
97
|
+
summary: 2,
|
|
98
|
+
schemaKey: 1,
|
|
99
|
+
} as const;
|
|
100
|
+
|
|
101
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
export function isMCPToolName(name: string): boolean {
|
|
104
|
+
return name.startsWith("mcp__");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getSchemaPropertyKeys(parameters: unknown): string[] {
|
|
108
|
+
if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) return [];
|
|
109
|
+
const properties = (parameters as { properties?: unknown }).properties;
|
|
110
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) return [];
|
|
111
|
+
return Object.keys(properties as Record<string, unknown>).sort();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function tokenize(value: string): string[] {
|
|
115
|
+
return value
|
|
116
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
117
|
+
.replace(/[^a-zA-Z0-9]+/g, " ")
|
|
118
|
+
.toLowerCase()
|
|
119
|
+
.trim()
|
|
120
|
+
.split(/\s+/)
|
|
121
|
+
.filter(token => token.length > 0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function addWeightedTokens(termFrequencies: Map<string, number>, value: string | undefined, weight: number): void {
|
|
125
|
+
if (!value) return;
|
|
126
|
+
for (const token of tokenize(value)) {
|
|
127
|
+
termFrequencies.set(token, (termFrequencies.get(token) ?? 0) + weight);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function buildSearchDocument(tool: DiscoverableTool): DiscoverableToolSearchDocument {
|
|
132
|
+
const termFrequencies = new Map<string, number>();
|
|
133
|
+
addWeightedTokens(termFrequencies, tool.name, FIELD_WEIGHTS.name);
|
|
134
|
+
addWeightedTokens(termFrequencies, tool.label, FIELD_WEIGHTS.label);
|
|
135
|
+
addWeightedTokens(termFrequencies, tool.serverName, FIELD_WEIGHTS.serverName);
|
|
136
|
+
addWeightedTokens(termFrequencies, tool.mcpToolName, FIELD_WEIGHTS.mcpToolName);
|
|
137
|
+
addWeightedTokens(termFrequencies, tool.summary, FIELD_WEIGHTS.summary);
|
|
138
|
+
for (const schemaKey of tool.schemaKeys) {
|
|
139
|
+
addWeightedTokens(termFrequencies, schemaKey, FIELD_WEIGHTS.schemaKey);
|
|
140
|
+
}
|
|
141
|
+
const length = Array.from(termFrequencies.values()).reduce((sum, value) => sum + value, 0);
|
|
142
|
+
return { tool, termFrequencies, length };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ─── Generic Tool Discovery Functions ────────────────────────────────────────
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Convert a raw AgentTool into a DiscoverableTool generic descriptor.
|
|
149
|
+
* source: "mcp" if name starts with "mcp__", else "builtin" (caller may override).
|
|
150
|
+
*/
|
|
151
|
+
export function getDiscoverableTool(
|
|
152
|
+
tool: AgentTool,
|
|
153
|
+
overrides?: { source?: DiscoverableToolSource; summary?: string },
|
|
154
|
+
): DiscoverableTool | null {
|
|
155
|
+
const toolRecord = tool as AgentTool & {
|
|
156
|
+
label?: string;
|
|
157
|
+
description?: string;
|
|
158
|
+
mcpServerName?: string;
|
|
159
|
+
summary?: string;
|
|
160
|
+
mcpToolName?: string;
|
|
161
|
+
parameters?: unknown;
|
|
162
|
+
};
|
|
163
|
+
const source: DiscoverableToolSource = overrides?.source ?? (isMCPToolName(tool.name) ? "mcp" : "builtin");
|
|
164
|
+
const rawSummary =
|
|
165
|
+
typeof overrides?.summary === "string"
|
|
166
|
+
? overrides.summary
|
|
167
|
+
: typeof toolRecord.summary === "string"
|
|
168
|
+
? toolRecord.summary
|
|
169
|
+
: undefined;
|
|
170
|
+
const rawDescription = typeof toolRecord.description === "string" ? toolRecord.description : "";
|
|
171
|
+
const summary = rawSummary ?? rawDescription.slice(0, 200);
|
|
172
|
+
return {
|
|
173
|
+
name: tool.name,
|
|
174
|
+
label: typeof toolRecord.label === "string" ? toolRecord.label : tool.name,
|
|
175
|
+
summary,
|
|
176
|
+
source,
|
|
177
|
+
serverName: typeof toolRecord.mcpServerName === "string" ? toolRecord.mcpServerName : undefined,
|
|
178
|
+
mcpToolName: typeof toolRecord.mcpToolName === "string" ? toolRecord.mcpToolName : undefined,
|
|
179
|
+
schemaKeys: getSchemaPropertyKeys(toolRecord.parameters),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Collect all DiscoverableTools from a tool iterable. Skips tools that return null. */
|
|
184
|
+
export function collectDiscoverableTools(
|
|
185
|
+
tools: Iterable<AgentTool>,
|
|
186
|
+
options?: { source?: DiscoverableToolSource; summaryMap?: Map<string, string> },
|
|
187
|
+
): DiscoverableTool[] {
|
|
188
|
+
const discoverable: DiscoverableTool[] = [];
|
|
189
|
+
for (const tool of tools) {
|
|
190
|
+
const summary = options?.summaryMap?.get(tool.name);
|
|
191
|
+
const meta = getDiscoverableTool(tool, { source: options?.source, summary });
|
|
192
|
+
if (meta) {
|
|
193
|
+
discoverable.push(meta);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return discoverable;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Filter discoverable tools by source */
|
|
200
|
+
export function filterBySource(tools: DiscoverableTool[], source: DiscoverableToolSource): DiscoverableTool[] {
|
|
201
|
+
return tools.filter(t => t.source === source);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function formatDiscoverableToolServerSummary(server: DiscoverableToolServerSummary): string {
|
|
205
|
+
const toolLabel = server.toolCount === 1 ? "tool" : "tools";
|
|
206
|
+
return `${server.name} (${server.toolCount} ${toolLabel})`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function selectDiscoverableToolNamesByServer(
|
|
210
|
+
tools: Iterable<DiscoverableTool>,
|
|
211
|
+
serverNames: ReadonlySet<string>,
|
|
212
|
+
): string[] {
|
|
213
|
+
if (serverNames.size === 0) return [];
|
|
214
|
+
return Array.from(tools)
|
|
215
|
+
.filter(tool => tool.serverName !== undefined && serverNames.has(tool.serverName))
|
|
216
|
+
.map(tool => tool.name);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function summarizeDiscoverableTools(tools: DiscoverableTool[]): DiscoverableToolSummary {
|
|
220
|
+
const serverToolCounts = new Map<string, number>();
|
|
221
|
+
for (const tool of tools) {
|
|
222
|
+
if (!tool.serverName) continue;
|
|
223
|
+
serverToolCounts.set(tool.serverName, (serverToolCounts.get(tool.serverName) ?? 0) + 1);
|
|
224
|
+
}
|
|
225
|
+
const servers = Array.from(serverToolCounts.entries())
|
|
226
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
227
|
+
.map(([name, toolCount]) => ({ name, toolCount }));
|
|
228
|
+
return {
|
|
229
|
+
servers,
|
|
230
|
+
toolCount: tools.length,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function buildDiscoverableToolSearchIndex(tools: Iterable<DiscoverableTool>): DiscoverableToolSearchIndex {
|
|
235
|
+
const documents = Array.from(tools, buildSearchDocument);
|
|
236
|
+
const averageLength = documents.reduce((sum, document) => sum + document.length, 0) / documents.length || 1;
|
|
237
|
+
const documentFrequencies = new Map<string, number>();
|
|
238
|
+
for (const document of documents) {
|
|
239
|
+
for (const token of new Set(document.termFrequencies.keys())) {
|
|
240
|
+
documentFrequencies.set(token, (documentFrequencies.get(token) ?? 0) + 1);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
documents,
|
|
245
|
+
averageLength,
|
|
246
|
+
documentFrequencies,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function searchDiscoverableTools(
|
|
251
|
+
index: DiscoverableToolSearchIndex,
|
|
252
|
+
query: string,
|
|
253
|
+
limit: number,
|
|
254
|
+
): DiscoverableToolSearchResult[] {
|
|
255
|
+
const queryTokens = tokenize(query);
|
|
256
|
+
if (queryTokens.length === 0) {
|
|
257
|
+
throw new Error("Query must contain at least one letter or number.");
|
|
258
|
+
}
|
|
259
|
+
if (index.documents.length === 0) {
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const queryTermCounts = new Map<string, number>();
|
|
264
|
+
for (const token of queryTokens) {
|
|
265
|
+
queryTermCounts.set(token, (queryTermCounts.get(token) ?? 0) + 1);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return index.documents
|
|
269
|
+
.map(document => {
|
|
270
|
+
let score = 0;
|
|
271
|
+
for (const [token, queryTermCount] of queryTermCounts) {
|
|
272
|
+
const termFrequency = document.termFrequencies.get(token) ?? 0;
|
|
273
|
+
if (termFrequency === 0) continue;
|
|
274
|
+
const documentFrequency = index.documentFrequencies.get(token) ?? 0;
|
|
275
|
+
const idf = Math.log(1 + (index.documents.length - documentFrequency + 0.5) / (documentFrequency + 0.5));
|
|
276
|
+
const normalization = BM25_K1 * (1 - BM25_B + BM25_B * (document.length / index.averageLength));
|
|
277
|
+
score += queryTermCount * idf * ((termFrequency * (BM25_K1 + 1)) / (termFrequency + normalization));
|
|
278
|
+
}
|
|
279
|
+
return { tool: document.tool, score };
|
|
280
|
+
})
|
|
281
|
+
.filter(result => result.score > 0)
|
|
282
|
+
.sort((left, right) => right.score - left.score || left.tool.name.localeCompare(right.tool.name))
|
|
283
|
+
.slice(0, limit);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ─── Legacy MCP-specific shims (back-compat wrappers) ────────────────────────
|
|
287
|
+
|
|
288
|
+
/** @deprecated Use getDiscoverableTool */
|
|
289
|
+
export function getDiscoverableMCPTool(tool: AgentTool): DiscoverableMCPTool | null {
|
|
290
|
+
if (!isMCPToolName(tool.name)) return null;
|
|
291
|
+
const toolRecord = tool as AgentTool & {
|
|
292
|
+
label?: string;
|
|
293
|
+
description?: string;
|
|
294
|
+
mcpServerName?: string;
|
|
295
|
+
mcpToolName?: string;
|
|
296
|
+
parameters?: unknown;
|
|
297
|
+
};
|
|
298
|
+
return {
|
|
299
|
+
name: tool.name,
|
|
300
|
+
label: typeof toolRecord.label === "string" ? toolRecord.label : tool.name,
|
|
301
|
+
description: typeof toolRecord.description === "string" ? toolRecord.description : "",
|
|
302
|
+
serverName: typeof toolRecord.mcpServerName === "string" ? toolRecord.mcpServerName : undefined,
|
|
303
|
+
mcpToolName: typeof toolRecord.mcpToolName === "string" ? toolRecord.mcpToolName : undefined,
|
|
304
|
+
schemaKeys: getSchemaPropertyKeys(toolRecord.parameters),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** @deprecated Use collectDiscoverableTools with source filter */
|
|
309
|
+
export function collectDiscoverableMCPTools(tools: Iterable<AgentTool>): DiscoverableMCPTool[] {
|
|
310
|
+
const discoverable: DiscoverableMCPTool[] = [];
|
|
311
|
+
for (const tool of tools) {
|
|
312
|
+
const metadata = getDiscoverableMCPTool(tool);
|
|
313
|
+
if (metadata) {
|
|
314
|
+
discoverable.push(metadata);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return discoverable;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** @deprecated Use selectDiscoverableToolNamesByServer */
|
|
321
|
+
export function selectDiscoverableMCPToolNamesByServer(
|
|
322
|
+
tools: Iterable<DiscoverableMCPTool>,
|
|
323
|
+
serverNames: ReadonlySet<string>,
|
|
324
|
+
): string[] {
|
|
325
|
+
if (serverNames.size === 0) return [];
|
|
326
|
+
return Array.from(tools)
|
|
327
|
+
.filter(tool => tool.serverName !== undefined && serverNames.has(tool.serverName))
|
|
328
|
+
.map(tool => tool.name);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** @deprecated Use summarizeDiscoverableTools */
|
|
332
|
+
export function summarizeDiscoverableMCPTools(tools: DiscoverableMCPTool[]): DiscoverableMCPToolSummary {
|
|
333
|
+
const serverToolCounts = new Map<string, number>();
|
|
334
|
+
for (const tool of tools) {
|
|
335
|
+
if (!tool.serverName) continue;
|
|
336
|
+
serverToolCounts.set(tool.serverName, (serverToolCounts.get(tool.serverName) ?? 0) + 1);
|
|
337
|
+
}
|
|
338
|
+
const servers = Array.from(serverToolCounts.entries())
|
|
339
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
340
|
+
.map(([name, toolCount]) => ({ name, toolCount }));
|
|
341
|
+
return {
|
|
342
|
+
servers,
|
|
343
|
+
toolCount: tools.length,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** @deprecated Use buildDiscoverableToolSearchIndex.
|
|
348
|
+
* Builds an index whose documents preserve the legacy `description` field on each tool while
|
|
349
|
+
* also carrying the generic `summary` (set from `description`) so the index remains usable
|
|
350
|
+
* with `searchDiscoverableTools`. */
|
|
351
|
+
export function buildDiscoverableMCPSearchIndex(tools: Iterable<DiscoverableMCPTool>): DiscoverableMCPSearchIndex {
|
|
352
|
+
const adapted: DiscoverableMCPSearchTool[] = Array.from(tools).map(t => ({
|
|
353
|
+
name: t.name,
|
|
354
|
+
label: t.label,
|
|
355
|
+
description: t.description,
|
|
356
|
+
summary: t.description,
|
|
357
|
+
source: "mcp" as DiscoverableToolSource,
|
|
358
|
+
serverName: t.serverName,
|
|
359
|
+
mcpToolName: t.mcpToolName,
|
|
360
|
+
schemaKeys: t.schemaKeys,
|
|
361
|
+
}));
|
|
362
|
+
const generic = buildDiscoverableToolSearchIndex(adapted);
|
|
363
|
+
// Documents reference `adapted` tools (with `description`), so the cast is sound.
|
|
364
|
+
return generic as unknown as DiscoverableMCPSearchIndex;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** @deprecated Use searchDiscoverableTools */
|
|
368
|
+
export function searchDiscoverableMCPTools(
|
|
369
|
+
index: DiscoverableMCPSearchIndex | DiscoverableToolSearchIndex,
|
|
370
|
+
query: string,
|
|
371
|
+
limit: number,
|
|
372
|
+
): DiscoverableMCPSearchResult[] {
|
|
373
|
+
return searchDiscoverableTools(index as DiscoverableToolSearchIndex, query, limit) as DiscoverableMCPSearchResult[];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** @deprecated Use formatDiscoverableToolServerSummary */
|
|
377
|
+
export const formatDiscoverableMCPToolServerSummary = formatDiscoverableToolServerSummary;
|
package/src/tools/ask.ts
CHANGED
|
@@ -379,9 +379,11 @@ type AskParams = AskToolInput;
|
|
|
379
379
|
export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
380
380
|
readonly name = "ask";
|
|
381
381
|
readonly label = "Ask";
|
|
382
|
+
readonly summary = "Ask the user a clarifying question";
|
|
382
383
|
readonly description: string;
|
|
383
384
|
readonly parameters = askSchema;
|
|
384
385
|
readonly strict = true;
|
|
386
|
+
readonly loadMode = "discoverable";
|
|
385
387
|
|
|
386
388
|
constructor(private readonly session: ToolSession) {
|
|
387
389
|
this.description = prompt.render(askDescription);
|
package/src/tools/ast-edit.ts
CHANGED
|
@@ -167,10 +167,12 @@ export interface AstEditToolDetails {
|
|
|
167
167
|
export class AstEditTool implements AgentTool<typeof astEditSchema, AstEditToolDetails> {
|
|
168
168
|
readonly name = "ast_edit";
|
|
169
169
|
readonly label = "AST Edit";
|
|
170
|
+
readonly summary = "Perform AST-aware code edits (structural refactoring)";
|
|
170
171
|
readonly description: string;
|
|
171
172
|
readonly parameters = astEditSchema;
|
|
172
173
|
readonly strict = true;
|
|
173
174
|
readonly deferrable = true;
|
|
175
|
+
readonly loadMode = "discoverable";
|
|
174
176
|
constructor(private readonly session: ToolSession) {
|
|
175
177
|
this.description = prompt.render(astEditDescription);
|
|
176
178
|
}
|
package/src/tools/ast-grep.ts
CHANGED
|
@@ -122,9 +122,11 @@ export interface AstGrepToolDetails {
|
|
|
122
122
|
export class AstGrepTool implements AgentTool<typeof astGrepSchema, AstGrepToolDetails> {
|
|
123
123
|
readonly name = "ast_grep";
|
|
124
124
|
readonly label = "AST Grep";
|
|
125
|
+
readonly summary = "Search code with AST patterns (structural grep)";
|
|
125
126
|
readonly description: string;
|
|
126
127
|
readonly parameters = astGrepSchema;
|
|
127
128
|
readonly strict = true;
|
|
129
|
+
readonly loadMode = "discoverable";
|
|
128
130
|
|
|
129
131
|
constructor(private readonly session: ToolSession) {
|
|
130
132
|
this.description = prompt.render(astGrepDescription);
|
package/src/tools/bash.ts
CHANGED
|
@@ -236,6 +236,7 @@ function formatTimeoutClampNotice(requestedTimeoutSec: number, effectiveTimeoutS
|
|
|
236
236
|
export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
|
|
237
237
|
readonly name = "bash";
|
|
238
238
|
readonly label = "Bash";
|
|
239
|
+
readonly loadMode = "essential";
|
|
239
240
|
readonly description: string;
|
|
240
241
|
readonly parameters: BashToolSchema;
|
|
241
242
|
readonly concurrency = "exclusive";
|
package/src/tools/browser.ts
CHANGED
|
@@ -110,6 +110,8 @@ function resolveBrowserKind(params: BrowserParams, session: ToolSession): Browse
|
|
|
110
110
|
export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolDetails> {
|
|
111
111
|
readonly name = "browser";
|
|
112
112
|
readonly label = "Browser";
|
|
113
|
+
readonly loadMode = "discoverable";
|
|
114
|
+
readonly summary = "Control a headless browser to navigate and interact with web pages";
|
|
113
115
|
readonly parameters = browserSchema;
|
|
114
116
|
readonly strict = true;
|
|
115
117
|
|
package/src/tools/calculator.ts
CHANGED
|
@@ -396,6 +396,8 @@ type CalculatorParams = Static<typeof calculatorSchema>;
|
|
|
396
396
|
export class CalculatorTool implements AgentTool<typeof calculatorSchema, CalculatorToolDetails> {
|
|
397
397
|
readonly name = "calc";
|
|
398
398
|
readonly label = "Calc";
|
|
399
|
+
readonly summary = "Evaluate a mathematical expression";
|
|
400
|
+
readonly loadMode = "discoverable";
|
|
399
401
|
readonly description: string;
|
|
400
402
|
readonly parameters = calculatorSchema;
|
|
401
403
|
readonly strict = true;
|
package/src/tools/checkpoint.ts
CHANGED
|
@@ -49,9 +49,11 @@ function isTopLevelSession(session: ToolSession): boolean {
|
|
|
49
49
|
export class CheckpointTool implements AgentTool<typeof checkpointSchema, CheckpointToolDetails> {
|
|
50
50
|
readonly name = "checkpoint";
|
|
51
51
|
readonly label = "Checkpoint";
|
|
52
|
+
readonly summary = "Create a git-based checkpoint to save and restore session state";
|
|
52
53
|
readonly description: string;
|
|
53
54
|
readonly parameters = checkpointSchema;
|
|
54
55
|
readonly strict = true;
|
|
56
|
+
readonly loadMode = "discoverable";
|
|
55
57
|
readonly intent = (args: Partial<CheckpointParams>) => (args.goal ? `checkpointing: ${args.goal}` : "checkpointing");
|
|
56
58
|
|
|
57
59
|
constructor(private readonly session: ToolSession) {
|
|
@@ -92,9 +94,11 @@ export class CheckpointTool implements AgentTool<typeof checkpointSchema, Checkp
|
|
|
92
94
|
export class RewindTool implements AgentTool<typeof rewindSchema, RewindToolDetails> {
|
|
93
95
|
readonly name = "rewind";
|
|
94
96
|
readonly label = "Rewind";
|
|
97
|
+
readonly summary = "Rewind to a previously created checkpoint";
|
|
95
98
|
readonly description: string;
|
|
96
99
|
readonly parameters = rewindSchema;
|
|
97
100
|
readonly strict = true;
|
|
101
|
+
readonly loadMode = "discoverable";
|
|
98
102
|
readonly intent = (): string => "rewinding";
|
|
99
103
|
|
|
100
104
|
constructor(private readonly session: ToolSession) {
|
package/src/tools/debug.ts
CHANGED
|
@@ -597,10 +597,12 @@ export const debugToolRenderer = {
|
|
|
597
597
|
export class DebugTool implements AgentTool<typeof debugSchema, DebugToolDetails> {
|
|
598
598
|
readonly name = "debug";
|
|
599
599
|
readonly label = "Debug";
|
|
600
|
+
readonly summary = "Debug a running process with DAP (debugger adapter protocol)";
|
|
600
601
|
readonly description: string;
|
|
601
602
|
readonly parameters = debugSchema;
|
|
602
603
|
readonly strict = true;
|
|
603
604
|
readonly concurrency = "exclusive";
|
|
605
|
+
readonly loadMode = "discoverable";
|
|
604
606
|
|
|
605
607
|
constructor(private readonly session: ToolSession) {
|
|
606
608
|
this.description = prompt.render(debugDescription);
|
package/src/tools/eval.ts
CHANGED
|
@@ -207,6 +207,8 @@ async function resolveBackend(
|
|
|
207
207
|
|
|
208
208
|
export class EvalTool implements AgentTool<typeof evalSchema> {
|
|
209
209
|
readonly name = "eval";
|
|
210
|
+
readonly summary = "Execute Python or JavaScript code in an in-process eval backend";
|
|
211
|
+
readonly loadMode = "discoverable";
|
|
210
212
|
readonly label = "Eval";
|
|
211
213
|
get description(): string {
|
|
212
214
|
if (!this.session) return getEvalToolDescription();
|
package/src/tools/find.ts
CHANGED
|
@@ -88,6 +88,8 @@ export interface FindToolOptions {
|
|
|
88
88
|
|
|
89
89
|
export class FindTool implements AgentTool<typeof findSchema, FindToolDetails> {
|
|
90
90
|
readonly name = "find";
|
|
91
|
+
readonly summary = "Find files and directories matching a glob pattern";
|
|
92
|
+
readonly loadMode = "discoverable";
|
|
91
93
|
readonly label = "Find";
|
|
92
94
|
readonly description: string;
|
|
93
95
|
readonly parameters = findSchema;
|
package/src/tools/gh.ts
CHANGED
|
@@ -2087,6 +2087,8 @@ function buildTextResult(
|
|
|
2087
2087
|
|
|
2088
2088
|
export class GithubTool implements AgentTool<typeof githubSchema, GhToolDetails> {
|
|
2089
2089
|
readonly name = "github";
|
|
2090
|
+
readonly summary = "Interact with GitHub issues, pull requests, and repositories";
|
|
2091
|
+
readonly loadMode = "discoverable";
|
|
2090
2092
|
readonly label = "GitHub";
|
|
2091
2093
|
readonly description = prompt.render(githubDescription);
|
|
2092
2094
|
readonly parameters = githubSchema;
|
|
@@ -19,6 +19,8 @@ export class HindsightRecallTool implements AgentTool<typeof hindsightRecallSche
|
|
|
19
19
|
readonly description = recallDescription;
|
|
20
20
|
readonly parameters = hindsightRecallSchema;
|
|
21
21
|
readonly strict = true;
|
|
22
|
+
readonly loadMode = "discoverable";
|
|
23
|
+
readonly summary = "Search hindsight memory for relevant prior context";
|
|
22
24
|
|
|
23
25
|
constructor(private readonly session: ToolSession) {}
|
|
24
26
|
|
|
@@ -18,6 +18,8 @@ export class HindsightReflectTool implements AgentTool<typeof hindsightReflectSc
|
|
|
18
18
|
readonly description = reflectDescription;
|
|
19
19
|
readonly parameters = hindsightReflectSchema;
|
|
20
20
|
readonly strict = true;
|
|
21
|
+
readonly loadMode = "discoverable";
|
|
22
|
+
readonly summary = "Reflect on recent work and write hindsight memory";
|
|
21
23
|
|
|
22
24
|
constructor(private readonly session: ToolSession) {}
|
|
23
25
|
|
|
@@ -28,6 +28,8 @@ export class HindsightRetainTool implements AgentTool<typeof hindsightRetainSche
|
|
|
28
28
|
readonly description = retainDescription;
|
|
29
29
|
readonly parameters = hindsightRetainSchema;
|
|
30
30
|
readonly strict = true;
|
|
31
|
+
readonly loadMode = "discoverable";
|
|
32
|
+
readonly summary = "Store important facts in hindsight memory";
|
|
31
33
|
|
|
32
34
|
constructor(private readonly session: ToolSession) {}
|
|
33
35
|
|