@crowley/rag-mcp 1.0.4 → 1.0.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.
- package/dist/annotations.d.ts +16 -0
- package/dist/annotations.js +158 -0
- package/dist/context-enrichment.d.ts +2 -2
- package/dist/context-enrichment.js +37 -14
- package/dist/formatters.d.ts +2 -0
- package/dist/formatters.js +12 -0
- package/dist/index.js +64 -47
- package/dist/schemas.d.ts +97 -0
- package/dist/schemas.js +128 -0
- package/dist/tool-middleware.d.ts +40 -0
- package/dist/tool-middleware.js +216 -0
- package/dist/tool-registry.js +2 -1
- package/dist/tools/advanced.d.ts +2 -2
- package/dist/tools/advanced.js +200 -275
- package/dist/tools/agents.d.ts +2 -2
- package/dist/tools/agents.js +59 -78
- package/dist/tools/analytics.d.ts +2 -2
- package/dist/tools/analytics.js +170 -210
- package/dist/tools/architecture.d.ts +2 -2
- package/dist/tools/architecture.js +506 -661
- package/dist/tools/ask.d.ts +2 -2
- package/dist/tools/ask.js +164 -219
- package/dist/tools/cache.d.ts +2 -2
- package/dist/tools/cache.js +63 -82
- package/dist/tools/clustering.d.ts +2 -2
- package/dist/tools/clustering.js +154 -215
- package/dist/tools/confluence.d.ts +2 -2
- package/dist/tools/confluence.js +80 -116
- package/dist/tools/database.d.ts +2 -2
- package/dist/tools/database.js +303 -380
- package/dist/tools/feedback.d.ts +2 -2
- package/dist/tools/feedback.js +143 -184
- package/dist/tools/guidelines.d.ts +2 -2
- package/dist/tools/guidelines.js +123 -135
- package/dist/tools/indexing.d.ts +2 -2
- package/dist/tools/indexing.js +104 -100
- package/dist/tools/memory.d.ts +2 -2
- package/dist/tools/memory.js +299 -485
- package/dist/tools/pm.d.ts +2 -2
- package/dist/tools/pm.js +367 -615
- package/dist/tools/review.d.ts +2 -2
- package/dist/tools/review.js +142 -189
- package/dist/tools/search.d.ts +2 -2
- package/dist/tools/search.js +230 -305
- package/dist/tools/session.d.ts +2 -2
- package/dist/tools/session.js +288 -345
- package/dist/tools/suggestions.d.ts +2 -2
- package/dist/tools/suggestions.js +444 -255
- package/dist/types.d.ts +19 -2
- package/package.json +4 -2
package/dist/tools/agents.js
CHANGED
|
@@ -1,97 +1,78 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent tools module - run specialized agents and list agent types.
|
|
3
3
|
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { TOOL_ANNOTATIONS } from "../annotations.js";
|
|
4
6
|
/**
|
|
5
7
|
* Create the agent tools module with project-specific descriptions.
|
|
6
8
|
*/
|
|
7
9
|
export function createAgentTools(projectName) {
|
|
8
|
-
|
|
10
|
+
return [
|
|
9
11
|
{
|
|
10
12
|
name: "run_agent",
|
|
11
13
|
description: `Run a specialized agent for ${projectName}. Agents autonomously research, review, or analyze using multiple tool calls. Returns result + reasoning trace.`,
|
|
12
|
-
|
|
13
|
-
type: "
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
14
|
+
schema: z.object({
|
|
15
|
+
type: z.enum(["research", "review", "documentation", "refactor", "test"]).describe("Agent type: research, review, documentation, refactor, or test"),
|
|
16
|
+
task: z.string().describe("The task for the agent to perform"),
|
|
17
|
+
context: z.string().optional().describe("Optional additional context (code, requirements, etc.)"),
|
|
18
|
+
maxIterations: z.number().optional().describe("Maximum ReAct iterations (default: varies by agent type)"),
|
|
19
|
+
}),
|
|
20
|
+
annotations: TOOL_ANNOTATIONS["run_agent"],
|
|
21
|
+
handler: async (args, ctx) => {
|
|
22
|
+
const { type, task, context, maxIterations } = args;
|
|
23
|
+
const response = await ctx.api.post("/api/agent/run", {
|
|
24
|
+
projectName: ctx.projectName,
|
|
25
|
+
agentType: type,
|
|
26
|
+
task,
|
|
27
|
+
context,
|
|
28
|
+
maxIterations,
|
|
29
|
+
});
|
|
30
|
+
const data = response.data;
|
|
31
|
+
// Format result with reasoning trace
|
|
32
|
+
let result = `## Agent Result (${data.type})\n`;
|
|
33
|
+
result += `**Task:** ${data.task}\n`;
|
|
34
|
+
result += `**Status:** ${data.status}`;
|
|
35
|
+
result += ` | **Iterations:** ${data.usage?.iterations || 0}`;
|
|
36
|
+
result += ` | **Tool Calls:** ${data.usage?.toolCalls || 0}`;
|
|
37
|
+
result += ` | **Duration:** ${data.usage?.durationMs ? Math.round(data.usage.durationMs / 1000) + "s" : "N/A"}`;
|
|
38
|
+
result += "\n\n";
|
|
39
|
+
if (data.error) {
|
|
40
|
+
result += `**Error:** ${data.error}\n\n`;
|
|
41
|
+
}
|
|
42
|
+
if (data.result) {
|
|
43
|
+
result += `### Result\n${data.result}\n\n`;
|
|
44
|
+
}
|
|
45
|
+
// Reasoning trace
|
|
46
|
+
if (data.steps && data.steps.length > 0) {
|
|
47
|
+
result += `### Reasoning Trace\n`;
|
|
48
|
+
for (const step of data.steps) {
|
|
49
|
+
result += `**Step ${step.iteration}:** ${step.thought?.slice(0, 200) || "..."}\n`;
|
|
50
|
+
if (step.action) {
|
|
51
|
+
result += ` Action: ${step.action.tool}(${JSON.stringify(step.action.input).slice(0, 100)})\n`;
|
|
52
|
+
}
|
|
53
|
+
if (step.observation) {
|
|
54
|
+
const obsPreview = step.observation.result?.slice(0, 150) || "...";
|
|
55
|
+
result += ` Result: ${obsPreview}${step.observation.truncated ? " [truncated]" : ""}\n`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
34
60
|
},
|
|
35
61
|
},
|
|
36
62
|
{
|
|
37
63
|
name: "get_agent_types",
|
|
38
64
|
description: `List available agent types for ${projectName} with descriptions.`,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
65
|
+
schema: z.object({}),
|
|
66
|
+
annotations: TOOL_ANNOTATIONS["get_agent_types"],
|
|
67
|
+
handler: async (_args, ctx) => {
|
|
68
|
+
const response = await ctx.api.get("/api/agent/types");
|
|
69
|
+
const data = response.data;
|
|
70
|
+
let result = `## Available Agent Types\n\n`;
|
|
71
|
+
for (const agent of data.agents || []) {
|
|
72
|
+
result += `- **${agent.name}**: ${agent.description}\n`;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
42
75
|
},
|
|
43
76
|
},
|
|
44
77
|
];
|
|
45
|
-
const handlers = {
|
|
46
|
-
run_agent: async (args, ctx) => {
|
|
47
|
-
const { type, task, context, maxIterations } = args;
|
|
48
|
-
const response = await ctx.api.post("/api/agent/run", {
|
|
49
|
-
projectName: ctx.projectName,
|
|
50
|
-
agentType: type,
|
|
51
|
-
task,
|
|
52
|
-
context,
|
|
53
|
-
maxIterations,
|
|
54
|
-
});
|
|
55
|
-
const data = response.data;
|
|
56
|
-
// Format result with reasoning trace
|
|
57
|
-
let result = `## Agent Result (${data.type})\n`;
|
|
58
|
-
result += `**Task:** ${data.task}\n`;
|
|
59
|
-
result += `**Status:** ${data.status}`;
|
|
60
|
-
result += ` | **Iterations:** ${data.usage?.iterations || 0}`;
|
|
61
|
-
result += ` | **Tool Calls:** ${data.usage?.toolCalls || 0}`;
|
|
62
|
-
result += ` | **Duration:** ${data.usage?.durationMs ? Math.round(data.usage.durationMs / 1000) + "s" : "N/A"}`;
|
|
63
|
-
result += "\n\n";
|
|
64
|
-
if (data.error) {
|
|
65
|
-
result += `**Error:** ${data.error}\n\n`;
|
|
66
|
-
}
|
|
67
|
-
if (data.result) {
|
|
68
|
-
result += `### Result\n${data.result}\n\n`;
|
|
69
|
-
}
|
|
70
|
-
// Reasoning trace
|
|
71
|
-
if (data.steps && data.steps.length > 0) {
|
|
72
|
-
result += `### Reasoning Trace\n`;
|
|
73
|
-
for (const step of data.steps) {
|
|
74
|
-
result += `**Step ${step.iteration}:** ${step.thought?.slice(0, 200) || "..."}\n`;
|
|
75
|
-
if (step.action) {
|
|
76
|
-
result += ` Action: ${step.action.tool}(${JSON.stringify(step.action.input).slice(0, 100)})\n`;
|
|
77
|
-
}
|
|
78
|
-
if (step.observation) {
|
|
79
|
-
const obsPreview = step.observation.result?.slice(0, 150) || "...";
|
|
80
|
-
result += ` Result: ${obsPreview}${step.observation.truncated ? " [truncated]" : ""}\n`;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
85
|
-
},
|
|
86
|
-
get_agent_types: async (_args, ctx) => {
|
|
87
|
-
const response = await ctx.api.get("/api/agent/types");
|
|
88
|
-
const data = response.data;
|
|
89
|
-
let result = `## Available Agent Types\n\n`;
|
|
90
|
-
for (const agent of data.agents || []) {
|
|
91
|
-
result += `- **${agent.name}**: ${agent.description}\n`;
|
|
92
|
-
}
|
|
93
|
-
return result;
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
return { tools, handlers };
|
|
97
78
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Analytics tools module - tool analytics, knowledge gaps, collection analytics,
|
|
3
3
|
* backups, and quantization.
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolSpec } from "../types.js";
|
|
6
6
|
/**
|
|
7
7
|
* Create the analytics tools module with project-specific descriptions.
|
|
8
8
|
*/
|
|
9
|
-
export declare function createAnalyticsTools(projectName: string):
|
|
9
|
+
export declare function createAnalyticsTools(projectName: string): ToolSpec[];
|
package/dist/tools/analytics.js
CHANGED
|
@@ -3,259 +3,219 @@
|
|
|
3
3
|
* backups, and quantization.
|
|
4
4
|
*/
|
|
5
5
|
import { pct } from "../formatters.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { TOOL_ANNOTATIONS } from "../annotations.js";
|
|
6
8
|
/**
|
|
7
9
|
* Create the analytics tools module with project-specific descriptions.
|
|
8
10
|
*/
|
|
9
11
|
export function createAnalyticsTools(projectName) {
|
|
10
|
-
|
|
12
|
+
return [
|
|
11
13
|
{
|
|
12
14
|
name: "get_tool_analytics",
|
|
13
15
|
description: `Get tool usage analytics for ${projectName}. Shows call counts, success rates, and performance.`,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
schema: z.object({}),
|
|
17
|
+
annotations: TOOL_ANNOTATIONS["get_tool_analytics"],
|
|
18
|
+
handler: async (_args, ctx) => {
|
|
19
|
+
const response = await ctx.api.get("/api/tool-analytics");
|
|
20
|
+
const data = response.data;
|
|
21
|
+
let result = `## Tool Analytics\n\n`;
|
|
22
|
+
result += `- **Total Calls:** ${data.totalCalls ?? "N/A"}\n`;
|
|
23
|
+
result += `- **Success Rate:** ${data.successRate !== undefined ? pct(data.successRate) : "N/A"}\n`;
|
|
24
|
+
result += `- **Avg Duration:** ${data.avgDurationMs ? data.avgDurationMs + "ms" : "N/A"}\n\n`;
|
|
25
|
+
if (data.topTools && data.topTools.length > 0) {
|
|
26
|
+
result += `### Top Tools\n`;
|
|
27
|
+
for (const t of data.topTools) {
|
|
28
|
+
result += `- **${t.tool || t.name}**: ${t.count ?? t.calls} calls`;
|
|
29
|
+
if (t.avgDurationMs || t.avgDuration)
|
|
30
|
+
result += ` (avg ${t.avgDurationMs || t.avgDuration}ms)`;
|
|
31
|
+
result += "\n";
|
|
32
|
+
}
|
|
33
|
+
result += "\n";
|
|
34
|
+
}
|
|
35
|
+
if (data.errorsByTool && Object.keys(data.errorsByTool).length > 0) {
|
|
36
|
+
result += `### Errors by Tool\n`;
|
|
37
|
+
for (const [tool, count] of Object.entries(data.errorsByTool)) {
|
|
38
|
+
result += `- **${tool}**: ${count} errors\n`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
17
42
|
},
|
|
18
43
|
},
|
|
19
44
|
{
|
|
20
45
|
name: "get_knowledge_gaps",
|
|
21
46
|
description: `Get knowledge gaps for ${projectName}. Shows queries that returned few or no results.`,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
47
|
+
schema: z.object({}),
|
|
48
|
+
annotations: TOOL_ANNOTATIONS["get_knowledge_gaps"],
|
|
49
|
+
handler: async (_args, ctx) => {
|
|
50
|
+
const response = await ctx.api.get("/api/knowledge-gaps");
|
|
51
|
+
const data = response.data;
|
|
52
|
+
const queries = data.queries || data.gaps || data;
|
|
53
|
+
if (!queries || (Array.isArray(queries) && queries.length === 0)) {
|
|
54
|
+
return "No knowledge gaps identified.";
|
|
55
|
+
}
|
|
56
|
+
let result = `## Knowledge Gaps\n\n`;
|
|
57
|
+
result += `Queries with low or no results:\n\n`;
|
|
58
|
+
for (const q of Array.isArray(queries) ? queries : []) {
|
|
59
|
+
result += `- **"${q.query}"**`;
|
|
60
|
+
if (q.count)
|
|
61
|
+
result += ` (${q.count} times)`;
|
|
62
|
+
if (q.avgResultCount !== undefined)
|
|
63
|
+
result += ` - avg results: ${q.avgResultCount}`;
|
|
64
|
+
if (q.toolName)
|
|
65
|
+
result += ` [${q.toolName}]`;
|
|
66
|
+
result += "\n";
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
25
69
|
},
|
|
26
70
|
},
|
|
27
71
|
{
|
|
28
72
|
name: "get_analytics",
|
|
29
73
|
description: `Get detailed analytics for a ${projectName} collection. Shows vectors, storage, language breakdown, and more.`,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
74
|
+
schema: z.object({
|
|
75
|
+
collectionName: z.string().describe("Collection name to get analytics for (e.g., 'codebase', 'docs', 'memory')"),
|
|
76
|
+
}),
|
|
77
|
+
annotations: TOOL_ANNOTATIONS["get_analytics"],
|
|
78
|
+
handler: async (args, ctx) => {
|
|
79
|
+
const { collectionName } = args;
|
|
80
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
81
|
+
? collectionName
|
|
82
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
83
|
+
const response = await ctx.api.get(`/api/analytics/${fullName}`);
|
|
84
|
+
const data = response.data;
|
|
85
|
+
let result = `## Collection Analytics: ${collectionName}\n\n`;
|
|
86
|
+
result += `- **Vectors:** ${data.vectorCount ?? data.vectors ?? "N/A"}\n`;
|
|
87
|
+
result += `- **Files:** ${data.totalFiles ?? data.files ?? "N/A"}\n`;
|
|
88
|
+
result += `- **Segments:** ${data.segments ?? "N/A"}\n`;
|
|
89
|
+
result += `- **Optimizer:** ${data.optimizerStatus || data.optimizer || "N/A"}\n`;
|
|
90
|
+
result += `- **Quantization:** ${data.quantization || "none"}\n`;
|
|
91
|
+
result += `- **RAM Usage:** ${data.ramUsage || "N/A"}\n`;
|
|
92
|
+
result += `- **Disk Usage:** ${data.diskUsage || "N/A"}\n`;
|
|
93
|
+
if (data.languages && Object.keys(data.languages).length > 0) {
|
|
94
|
+
result += `\n### Language Breakdown\n`;
|
|
95
|
+
for (const [lang, count] of Object.entries(data.languages)) {
|
|
96
|
+
result += `- ${lang}: ${count} files\n`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
result += `\n- **Last Indexed:** ${data.lastIndexed ? new Date(data.lastIndexed).toLocaleString() : "Never"}\n`;
|
|
100
|
+
return result;
|
|
39
101
|
},
|
|
40
102
|
},
|
|
41
103
|
{
|
|
42
104
|
name: "backup_collection",
|
|
43
105
|
description: `Create a backup snapshot of a ${projectName} collection.`,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
106
|
+
schema: z.object({
|
|
107
|
+
collectionName: z.string().describe("Collection name to backup"),
|
|
108
|
+
}),
|
|
109
|
+
annotations: TOOL_ANNOTATIONS["backup_collection"],
|
|
110
|
+
handler: async (args, ctx) => {
|
|
111
|
+
const { collectionName } = args;
|
|
112
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
113
|
+
? collectionName
|
|
114
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
115
|
+
const response = await ctx.api.post(`/api/collections/${fullName}/snapshots`);
|
|
116
|
+
const data = response.data;
|
|
117
|
+
let result = `## Backup Created\n\n`;
|
|
118
|
+
result += `- **Collection:** ${fullName}\n`;
|
|
119
|
+
result += `- **Snapshot:** ${data.name || data.snapshotName || "N/A"}\n`;
|
|
120
|
+
result += `- **Created:** ${data.createdAt ? new Date(data.createdAt).toLocaleString() : new Date().toLocaleString()}\n`;
|
|
121
|
+
return result;
|
|
53
122
|
},
|
|
54
123
|
},
|
|
55
124
|
{
|
|
56
125
|
name: "list_backups",
|
|
57
126
|
description: `List backup snapshots for a ${projectName} collection.`,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
127
|
+
schema: z.object({
|
|
128
|
+
collectionName: z.string().describe("Collection name to list backups for"),
|
|
129
|
+
}),
|
|
130
|
+
annotations: TOOL_ANNOTATIONS["list_backups"],
|
|
131
|
+
handler: async (args, ctx) => {
|
|
132
|
+
const { collectionName } = args;
|
|
133
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
134
|
+
? collectionName
|
|
135
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
136
|
+
const response = await ctx.api.get(`/api/collections/${fullName}/snapshots`);
|
|
137
|
+
const snapshots = response.data.snapshots || response.data;
|
|
138
|
+
if (!snapshots || snapshots.length === 0) {
|
|
139
|
+
return `No backups found for ${fullName}.`;
|
|
140
|
+
}
|
|
141
|
+
let result = `## Backups: ${fullName}\n\n`;
|
|
142
|
+
for (const s of snapshots) {
|
|
143
|
+
const sizeMB = s.size ? (s.size / (1024 * 1024)).toFixed(2) : "?";
|
|
144
|
+
result += `- **${s.name}** - ${sizeMB} MB`;
|
|
145
|
+
if (s.createdAt)
|
|
146
|
+
result += ` (${new Date(s.createdAt).toLocaleString()})`;
|
|
147
|
+
result += "\n";
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
67
150
|
},
|
|
68
151
|
},
|
|
69
152
|
{
|
|
70
153
|
name: "enable_quantization",
|
|
71
154
|
description: `Enable scalar quantization on a ${projectName} collection to reduce memory usage.`,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
155
|
+
schema: z.object({
|
|
156
|
+
collectionName: z.string().describe("Collection name to enable quantization on"),
|
|
157
|
+
quantile: z.number().optional().describe("Quantile for quantization (0-1, default: 0.99)"),
|
|
158
|
+
}),
|
|
159
|
+
annotations: TOOL_ANNOTATIONS["enable_quantization"],
|
|
160
|
+
handler: async (args, ctx) => {
|
|
161
|
+
const { collectionName, quantile = 0.99 } = args;
|
|
162
|
+
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
163
|
+
? collectionName
|
|
164
|
+
: `${ctx.collectionPrefix}${collectionName}`;
|
|
165
|
+
const response = await ctx.api.post(`/api/collections/${fullName}/quantization`, { quantile });
|
|
166
|
+
const data = response.data;
|
|
167
|
+
let result = `## Quantization Enabled\n\n`;
|
|
168
|
+
result += `- **Collection:** ${fullName}\n`;
|
|
169
|
+
result += `- **Quantile:** ${quantile}\n`;
|
|
170
|
+
result += `- **Expected Reduction:** ${data.expectedReduction || "~4x memory reduction"}\n`;
|
|
171
|
+
return result;
|
|
86
172
|
},
|
|
87
173
|
},
|
|
88
174
|
{
|
|
89
175
|
name: "get_platform_stats",
|
|
90
176
|
description: `Get cross-project platform statistics. Shows all projects, their collections, and aggregated metrics.`,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
177
|
+
schema: z.object({}),
|
|
178
|
+
annotations: TOOL_ANNOTATIONS["get_platform_stats"],
|
|
179
|
+
handler: async (_args, ctx) => {
|
|
180
|
+
const response = await ctx.api.get("/api/platform/stats");
|
|
181
|
+
const data = response.data;
|
|
182
|
+
let result = `## Platform Statistics\n\n`;
|
|
183
|
+
result += `- **Total Projects:** ${data.totalProjects ?? 0}\n`;
|
|
184
|
+
result += `- **Total Collections:** ${data.totalCollections ?? 0}\n\n`;
|
|
185
|
+
if (data.projects && data.projects.length > 0) {
|
|
186
|
+
result += `### Projects\n`;
|
|
187
|
+
for (const p of data.projects) {
|
|
188
|
+
result += `- **${p.project}**: ${p.collections} collections, ${p.totalVectors} vectors\n`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
94
192
|
},
|
|
95
193
|
},
|
|
96
194
|
{
|
|
97
195
|
name: "get_prediction_stats",
|
|
98
196
|
description: `Get predictive loader stats for ${projectName}. Shows prediction accuracy, hit rates, and strategy breakdown.`,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
197
|
+
schema: z.object({
|
|
198
|
+
sessionId: z.string().optional().describe("Session ID to get stats for. If omitted, returns aggregate stats."),
|
|
199
|
+
}),
|
|
200
|
+
annotations: TOOL_ANNOTATIONS["get_prediction_stats"],
|
|
201
|
+
handler: async (args, ctx) => {
|
|
202
|
+
const { sessionId } = args;
|
|
203
|
+
const params = sessionId ? `?sessionId=${sessionId}` : "";
|
|
204
|
+
const response = await ctx.api.get(`/api/predictions/stats${params}`);
|
|
205
|
+
const data = response.data;
|
|
206
|
+
let result = `## Prediction Stats${sessionId ? ` (Session ${sessionId})` : ""}\n\n`;
|
|
207
|
+
result += `- **Total Predictions:** ${data.totalPredictions ?? 0}\n`;
|
|
208
|
+
result += `- **Hits:** ${data.totalHits ?? 0}\n`;
|
|
209
|
+
result += `- **Misses:** ${data.totalMisses ?? 0}\n`;
|
|
210
|
+
result += `- **Hit Rate:** ${data.hitRate !== undefined ? pct(data.hitRate) : "N/A"}\n\n`;
|
|
211
|
+
if (data.byStrategy && Object.keys(data.byStrategy).length > 0) {
|
|
212
|
+
result += `### By Strategy\n`;
|
|
213
|
+
for (const [strategy, stats] of Object.entries(data.byStrategy)) {
|
|
214
|
+
result += `- **${strategy}**: ${stats.predictions} predictions, ${stats.hits} hits (${pct(stats.hitRate)})\n`;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
107
218
|
},
|
|
108
219
|
},
|
|
109
220
|
];
|
|
110
|
-
const handlers = {
|
|
111
|
-
get_tool_analytics: async (_args, ctx) => {
|
|
112
|
-
const response = await ctx.api.get("/api/tool-analytics");
|
|
113
|
-
const data = response.data;
|
|
114
|
-
let result = `## Tool Analytics\n\n`;
|
|
115
|
-
result += `- **Total Calls:** ${data.totalCalls ?? "N/A"}\n`;
|
|
116
|
-
result += `- **Success Rate:** ${data.successRate !== undefined ? pct(data.successRate) : "N/A"}\n`;
|
|
117
|
-
result += `- **Avg Duration:** ${data.avgDurationMs ? data.avgDurationMs + "ms" : "N/A"}\n\n`;
|
|
118
|
-
if (data.topTools && data.topTools.length > 0) {
|
|
119
|
-
result += `### Top Tools\n`;
|
|
120
|
-
for (const t of data.topTools) {
|
|
121
|
-
result += `- **${t.tool || t.name}**: ${t.count ?? t.calls} calls`;
|
|
122
|
-
if (t.avgDurationMs || t.avgDuration)
|
|
123
|
-
result += ` (avg ${t.avgDurationMs || t.avgDuration}ms)`;
|
|
124
|
-
result += "\n";
|
|
125
|
-
}
|
|
126
|
-
result += "\n";
|
|
127
|
-
}
|
|
128
|
-
if (data.errorsByTool && Object.keys(data.errorsByTool).length > 0) {
|
|
129
|
-
result += `### Errors by Tool\n`;
|
|
130
|
-
for (const [tool, count] of Object.entries(data.errorsByTool)) {
|
|
131
|
-
result += `- **${tool}**: ${count} errors\n`;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return result;
|
|
135
|
-
},
|
|
136
|
-
get_knowledge_gaps: async (_args, ctx) => {
|
|
137
|
-
const response = await ctx.api.get("/api/knowledge-gaps");
|
|
138
|
-
const data = response.data;
|
|
139
|
-
const queries = data.queries || data.gaps || data;
|
|
140
|
-
if (!queries || (Array.isArray(queries) && queries.length === 0)) {
|
|
141
|
-
return "No knowledge gaps identified.";
|
|
142
|
-
}
|
|
143
|
-
let result = `## Knowledge Gaps\n\n`;
|
|
144
|
-
result += `Queries with low or no results:\n\n`;
|
|
145
|
-
for (const q of Array.isArray(queries) ? queries : []) {
|
|
146
|
-
result += `- **"${q.query}"**`;
|
|
147
|
-
if (q.count)
|
|
148
|
-
result += ` (${q.count} times)`;
|
|
149
|
-
if (q.avgResultCount !== undefined)
|
|
150
|
-
result += ` - avg results: ${q.avgResultCount}`;
|
|
151
|
-
if (q.toolName)
|
|
152
|
-
result += ` [${q.toolName}]`;
|
|
153
|
-
result += "\n";
|
|
154
|
-
}
|
|
155
|
-
return result;
|
|
156
|
-
},
|
|
157
|
-
get_analytics: async (args, ctx) => {
|
|
158
|
-
const { collectionName } = args;
|
|
159
|
-
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
160
|
-
? collectionName
|
|
161
|
-
: `${ctx.collectionPrefix}${collectionName}`;
|
|
162
|
-
const response = await ctx.api.get(`/api/analytics/${fullName}`);
|
|
163
|
-
const data = response.data;
|
|
164
|
-
let result = `## Collection Analytics: ${collectionName}\n\n`;
|
|
165
|
-
result += `- **Vectors:** ${data.vectorCount ?? data.vectors ?? "N/A"}\n`;
|
|
166
|
-
result += `- **Files:** ${data.totalFiles ?? data.files ?? "N/A"}\n`;
|
|
167
|
-
result += `- **Segments:** ${data.segments ?? "N/A"}\n`;
|
|
168
|
-
result += `- **Optimizer:** ${data.optimizerStatus || data.optimizer || "N/A"}\n`;
|
|
169
|
-
result += `- **Quantization:** ${data.quantization || "none"}\n`;
|
|
170
|
-
result += `- **RAM Usage:** ${data.ramUsage || "N/A"}\n`;
|
|
171
|
-
result += `- **Disk Usage:** ${data.diskUsage || "N/A"}\n`;
|
|
172
|
-
if (data.languages && Object.keys(data.languages).length > 0) {
|
|
173
|
-
result += `\n### Language Breakdown\n`;
|
|
174
|
-
for (const [lang, count] of Object.entries(data.languages)) {
|
|
175
|
-
result += `- ${lang}: ${count} files\n`;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
result += `\n- **Last Indexed:** ${data.lastIndexed ? new Date(data.lastIndexed).toLocaleString() : "Never"}\n`;
|
|
179
|
-
return result;
|
|
180
|
-
},
|
|
181
|
-
backup_collection: async (args, ctx) => {
|
|
182
|
-
const { collectionName } = args;
|
|
183
|
-
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
184
|
-
? collectionName
|
|
185
|
-
: `${ctx.collectionPrefix}${collectionName}`;
|
|
186
|
-
const response = await ctx.api.post(`/api/collections/${fullName}/snapshots`);
|
|
187
|
-
const data = response.data;
|
|
188
|
-
let result = `## Backup Created\n\n`;
|
|
189
|
-
result += `- **Collection:** ${fullName}\n`;
|
|
190
|
-
result += `- **Snapshot:** ${data.name || data.snapshotName || "N/A"}\n`;
|
|
191
|
-
result += `- **Created:** ${data.createdAt ? new Date(data.createdAt).toLocaleString() : new Date().toLocaleString()}\n`;
|
|
192
|
-
return result;
|
|
193
|
-
},
|
|
194
|
-
list_backups: async (args, ctx) => {
|
|
195
|
-
const { collectionName } = args;
|
|
196
|
-
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
197
|
-
? collectionName
|
|
198
|
-
: `${ctx.collectionPrefix}${collectionName}`;
|
|
199
|
-
const response = await ctx.api.get(`/api/collections/${fullName}/snapshots`);
|
|
200
|
-
const snapshots = response.data.snapshots || response.data;
|
|
201
|
-
if (!snapshots || snapshots.length === 0) {
|
|
202
|
-
return `No backups found for ${fullName}.`;
|
|
203
|
-
}
|
|
204
|
-
let result = `## Backups: ${fullName}\n\n`;
|
|
205
|
-
for (const s of snapshots) {
|
|
206
|
-
const sizeMB = s.size ? (s.size / (1024 * 1024)).toFixed(2) : "?";
|
|
207
|
-
result += `- **${s.name}** - ${sizeMB} MB`;
|
|
208
|
-
if (s.createdAt)
|
|
209
|
-
result += ` (${new Date(s.createdAt).toLocaleString()})`;
|
|
210
|
-
result += "\n";
|
|
211
|
-
}
|
|
212
|
-
return result;
|
|
213
|
-
},
|
|
214
|
-
get_platform_stats: async (_args, ctx) => {
|
|
215
|
-
const response = await ctx.api.get("/api/platform/stats");
|
|
216
|
-
const data = response.data;
|
|
217
|
-
let result = `## Platform Statistics\n\n`;
|
|
218
|
-
result += `- **Total Projects:** ${data.totalProjects ?? 0}\n`;
|
|
219
|
-
result += `- **Total Collections:** ${data.totalCollections ?? 0}\n\n`;
|
|
220
|
-
if (data.projects && data.projects.length > 0) {
|
|
221
|
-
result += `### Projects\n`;
|
|
222
|
-
for (const p of data.projects) {
|
|
223
|
-
result += `- **${p.project}**: ${p.collections} collections, ${p.totalVectors} vectors\n`;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return result;
|
|
227
|
-
},
|
|
228
|
-
get_prediction_stats: async (args, ctx) => {
|
|
229
|
-
const { sessionId } = args;
|
|
230
|
-
const params = sessionId ? `?sessionId=${sessionId}` : "";
|
|
231
|
-
const response = await ctx.api.get(`/api/predictions/stats${params}`);
|
|
232
|
-
const data = response.data;
|
|
233
|
-
let result = `## Prediction Stats${sessionId ? ` (Session ${sessionId})` : ""}\n\n`;
|
|
234
|
-
result += `- **Total Predictions:** ${data.totalPredictions ?? 0}\n`;
|
|
235
|
-
result += `- **Hits:** ${data.totalHits ?? 0}\n`;
|
|
236
|
-
result += `- **Misses:** ${data.totalMisses ?? 0}\n`;
|
|
237
|
-
result += `- **Hit Rate:** ${data.hitRate !== undefined ? pct(data.hitRate) : "N/A"}\n\n`;
|
|
238
|
-
if (data.byStrategy && Object.keys(data.byStrategy).length > 0) {
|
|
239
|
-
result += `### By Strategy\n`;
|
|
240
|
-
for (const [strategy, stats] of Object.entries(data.byStrategy)) {
|
|
241
|
-
result += `- **${strategy}**: ${stats.predictions} predictions, ${stats.hits} hits (${pct(stats.hitRate)})\n`;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return result;
|
|
245
|
-
},
|
|
246
|
-
enable_quantization: async (args, ctx) => {
|
|
247
|
-
const { collectionName, quantile = 0.99 } = args;
|
|
248
|
-
const fullName = collectionName.startsWith(ctx.collectionPrefix)
|
|
249
|
-
? collectionName
|
|
250
|
-
: `${ctx.collectionPrefix}${collectionName}`;
|
|
251
|
-
const response = await ctx.api.post(`/api/collections/${fullName}/quantization`, { quantile });
|
|
252
|
-
const data = response.data;
|
|
253
|
-
let result = `## Quantization Enabled\n\n`;
|
|
254
|
-
result += `- **Collection:** ${fullName}\n`;
|
|
255
|
-
result += `- **Quantile:** ${quantile}\n`;
|
|
256
|
-
result += `- **Expected Reduction:** ${data.expectedReduction || "~4x memory reduction"}\n`;
|
|
257
|
-
return result;
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
return { tools, handlers };
|
|
261
221
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Architecture tools module - ADRs, patterns, tech debt, and structure analysis.
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
export declare function createArchitectureTools(projectName: string):
|
|
4
|
+
import type { ToolSpec } from "../types.js";
|
|
5
|
+
export declare function createArchitectureTools(projectName: string): ToolSpec[];
|