qlogicagent 0.2.1 → 0.4.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.
- package/README.md +45 -45
- package/package.json +56 -42
- package/dist/agent/agent.d.ts +0 -43
- package/dist/agent/agent.js +0 -113
- package/dist/agent/tool-loop.d.ts +0 -64
- package/dist/agent/tool-loop.js +0 -575
- package/dist/agent/types.d.ts +0 -175
- package/dist/agent/types.js +0 -14
- package/dist/cli/main.d.ts +0 -11
- package/dist/cli/main.js +0 -23
- package/dist/cli/stdio-server.d.ts +0 -45
- package/dist/cli/stdio-server.js +0 -463
- package/dist/config/config.d.ts +0 -17
- package/dist/config/config.js +0 -21
- package/dist/contracts/hooks.d.ts +0 -120
- package/dist/contracts/hooks.js +0 -7
- package/dist/contracts/index.d.ts +0 -10
- package/dist/contracts/index.js +0 -10
- package/dist/contracts/planner.d.ts +0 -35
- package/dist/contracts/planner.js +0 -2
- package/dist/contracts/skill-candidate.d.ts +0 -63
- package/dist/contracts/skill-candidate.js +0 -195
- package/dist/contracts/todo.d.ts +0 -14
- package/dist/contracts/todo.js +0 -9
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -15
- package/dist/llm/builtin-providers.d.ts +0 -10
- package/dist/llm/builtin-providers.js +0 -531
- package/dist/llm/index.d.ts +0 -15
- package/dist/llm/index.js +0 -14
- package/dist/llm/llm-client.d.ts +0 -43
- package/dist/llm/llm-client.js +0 -67
- package/dist/llm/model-catalog.d.ts +0 -53
- package/dist/llm/model-catalog.js +0 -191
- package/dist/llm/provider-def.d.ts +0 -59
- package/dist/llm/provider-def.js +0 -12
- package/dist/llm/provider-registry.d.ts +0 -54
- package/dist/llm/provider-registry.js +0 -147
- package/dist/llm/transport.d.ts +0 -62
- package/dist/llm/transport.js +0 -27
- package/dist/llm/transports/anthropic-messages.d.ts +0 -31
- package/dist/llm/transports/anthropic-messages.js +0 -293
- package/dist/llm/transports/openai-chat.d.ts +0 -36
- package/dist/llm/transports/openai-chat.js +0 -165
- package/dist/orchestration/agent-registry.d.ts +0 -41
- package/dist/orchestration/agent-registry.js +0 -116
- package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
- package/dist/orchestration/approval-aware-tool-plan.js +0 -87
- package/dist/orchestration/context-compression.d.ts +0 -220
- package/dist/orchestration/context-compression.js +0 -583
- package/dist/orchestration/conversation-repair.d.ts +0 -61
- package/dist/orchestration/conversation-repair.js +0 -429
- package/dist/orchestration/curator-scheduler.d.ts +0 -119
- package/dist/orchestration/curator-scheduler.js +0 -135
- package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
- package/dist/orchestration/embedded-failover-policy.js +0 -168
- package/dist/orchestration/error-classification.d.ts +0 -12
- package/dist/orchestration/error-classification.js +0 -77
- package/dist/orchestration/failover-classification.d.ts +0 -8
- package/dist/orchestration/failover-classification.js +0 -381
- package/dist/orchestration/failover-error.d.ts +0 -33
- package/dist/orchestration/failover-error.js +0 -198
- package/dist/orchestration/fork-subagent.d.ts +0 -100
- package/dist/orchestration/fork-subagent.js +0 -98
- package/dist/orchestration/index.d.ts +0 -120
- package/dist/orchestration/index.js +0 -267
- package/dist/orchestration/memory-flush-policy.d.ts +0 -57
- package/dist/orchestration/memory-flush-policy.js +0 -85
- package/dist/orchestration/memory-provider.d.ts +0 -14
- package/dist/orchestration/memory-provider.js +0 -2
- package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
- package/dist/orchestration/parallel-tool-calls.js +0 -59
- package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
- package/dist/orchestration/prompt-cache-strategy.js +0 -228
- package/dist/orchestration/reactive-compact.d.ts +0 -73
- package/dist/orchestration/reactive-compact.js +0 -78
- package/dist/orchestration/retry-loop.d.ts +0 -22
- package/dist/orchestration/retry-loop.js +0 -24
- package/dist/orchestration/skill-candidate.d.ts +0 -52
- package/dist/orchestration/skill-candidate.js +0 -141
- package/dist/orchestration/skill-consolidation.d.ts +0 -123
- package/dist/orchestration/skill-consolidation.js +0 -220
- package/dist/orchestration/skill-improvement.d.ts +0 -59
- package/dist/orchestration/skill-improvement.js +0 -66
- package/dist/orchestration/skill-similarity.d.ts +0 -98
- package/dist/orchestration/skill-similarity.js +0 -131
- package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
- package/dist/orchestration/streaming-tool-executor.js +0 -96
- package/dist/orchestration/team-orchestration.d.ts +0 -195
- package/dist/orchestration/team-orchestration.js +0 -369
- package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
- package/dist/orchestration/team-tool-loop-wiring.js +0 -147
- package/dist/orchestration/tool-choice-policy.d.ts +0 -54
- package/dist/orchestration/tool-choice-policy.js +0 -164
- package/dist/orchestration/tool-loop-state.d.ts +0 -50
- package/dist/orchestration/tool-loop-state.js +0 -133
- package/dist/orchestration/tool-schema.d.ts +0 -39
- package/dist/orchestration/tool-schema.js +0 -297
- package/dist/orchestration/transcript-repair.d.ts +0 -42
- package/dist/orchestration/transcript-repair.js +0 -426
- package/dist/orchestration/turn-loop-guard.d.ts +0 -86
- package/dist/orchestration/turn-loop-guard.js +0 -92
- package/dist/orchestration/web-browser-policy.d.ts +0 -17
- package/dist/orchestration/web-browser-policy.js +0 -39
- package/dist/runtime/context-compression.d.ts +0 -61
- package/dist/runtime/context-compression.js +0 -274
- package/dist/runtime/hook-registry.d.ts +0 -12
- package/dist/runtime/hook-registry.js +0 -53
- package/dist/runtime/memory-hooks.d.ts +0 -23
- package/dist/runtime/memory-hooks.js +0 -65
- package/dist/runtime/tool-eligibility.d.ts +0 -59
- package/dist/runtime/tool-eligibility.js +0 -111
- package/dist/skills/index.d.ts +0 -108
- package/dist/skills/index.js +0 -82
- package/dist/skills/memory-extractor.d.ts +0 -64
- package/dist/skills/memory-extractor.js +0 -173
- package/dist/skills/memory-query-tool.d.ts +0 -43
- package/dist/skills/memory-query-tool.js +0 -127
- package/dist/skills/memory-store.d.ts +0 -66
- package/dist/skills/memory-store.js +0 -228
- package/dist/skills/memory-tool.d.ts +0 -67
- package/dist/skills/memory-tool.js +0 -192
- package/dist/skills/portable-tool.d.ts +0 -71
- package/dist/skills/portable-tool.js +0 -14
- package/dist/skills/qmemory-adapter.d.ts +0 -52
- package/dist/skills/qmemory-adapter.js +0 -165
- package/dist/skills/skill-frontmatter.d.ts +0 -19
- package/dist/skills/skill-frontmatter.js +0 -344
- package/dist/skills/skill-guard.d.ts +0 -23
- package/dist/skills/skill-guard.js +0 -229
- package/dist/skills/skill-loader.d.ts +0 -16
- package/dist/skills/skill-loader.js +0 -303
- package/dist/skills/skill-source.d.ts +0 -119
- package/dist/skills/skill-source.js +0 -126
- package/dist/skills/skill-types.d.ts +0 -199
- package/dist/skills/skill-types.js +0 -6
- package/dist/skills/think-tool.d.ts +0 -16
- package/dist/skills/think-tool.js +0 -59
- package/dist/skills/todo-tool.d.ts +0 -63
- package/dist/skills/todo-tool.js +0 -114
- package/dist/skills/tools/agent-tool.d.ts +0 -91
- package/dist/skills/tools/agent-tool.js +0 -142
- package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
- package/dist/skills/tools/apply-patch-tool.js +0 -184
- package/dist/skills/tools/ask-user-tool.d.ts +0 -80
- package/dist/skills/tools/ask-user-tool.js +0 -121
- package/dist/skills/tools/brief-tool.d.ts +0 -74
- package/dist/skills/tools/brief-tool.js +0 -95
- package/dist/skills/tools/browser-tool.d.ts +0 -114
- package/dist/skills/tools/browser-tool.js +0 -155
- package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
- package/dist/skills/tools/checkpoint-tool.js +0 -102
- package/dist/skills/tools/config-tool.d.ts +0 -63
- package/dist/skills/tools/config-tool.js +0 -143
- package/dist/skills/tools/cron-tool.d.ts +0 -116
- package/dist/skills/tools/cron-tool.js +0 -175
- package/dist/skills/tools/edit-tool.d.ts +0 -43
- package/dist/skills/tools/edit-tool.js +0 -70
- package/dist/skills/tools/exec-tool.d.ts +0 -102
- package/dist/skills/tools/exec-tool.js +0 -133
- package/dist/skills/tools/image-generate-tool.d.ts +0 -62
- package/dist/skills/tools/image-generate-tool.js +0 -67
- package/dist/skills/tools/instructions-tool.d.ts +0 -103
- package/dist/skills/tools/instructions-tool.js +0 -187
- package/dist/skills/tools/lsp-tool.d.ts +0 -153
- package/dist/skills/tools/lsp-tool.js +0 -227
- package/dist/skills/tools/mcp-client-types.d.ts +0 -269
- package/dist/skills/tools/mcp-client-types.js +0 -53
- package/dist/skills/tools/mcp-tool.d.ts +0 -249
- package/dist/skills/tools/mcp-tool.js +0 -503
- package/dist/skills/tools/memory-tool.d.ts +0 -74
- package/dist/skills/tools/memory-tool.js +0 -88
- package/dist/skills/tools/monitor-tool.d.ts +0 -113
- package/dist/skills/tools/monitor-tool.js +0 -131
- package/dist/skills/tools/music-generate-tool.d.ts +0 -55
- package/dist/skills/tools/music-generate-tool.js +0 -62
- package/dist/skills/tools/notify-tool.d.ts +0 -53
- package/dist/skills/tools/notify-tool.js +0 -62
- package/dist/skills/tools/patch-tool.d.ts +0 -45
- package/dist/skills/tools/patch-tool.js +0 -505
- package/dist/skills/tools/pdf-tool.d.ts +0 -66
- package/dist/skills/tools/pdf-tool.js +0 -88
- package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
- package/dist/skills/tools/plan-mode-tool.js +0 -122
- package/dist/skills/tools/read-tool.d.ts +0 -51
- package/dist/skills/tools/read-tool.js +0 -84
- package/dist/skills/tools/repl-tool.d.ts +0 -70
- package/dist/skills/tools/repl-tool.js +0 -69
- package/dist/skills/tools/search-tool.d.ts +0 -112
- package/dist/skills/tools/search-tool.js +0 -225
- package/dist/skills/tools/send-message-tool.d.ts +0 -51
- package/dist/skills/tools/send-message-tool.js +0 -76
- package/dist/skills/tools/skill-list-tool.d.ts +0 -33
- package/dist/skills/tools/skill-list-tool.js +0 -54
- package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
- package/dist/skills/tools/skill-manage-tool.js +0 -153
- package/dist/skills/tools/skill-view-tool.d.ts +0 -37
- package/dist/skills/tools/skill-view-tool.js +0 -72
- package/dist/skills/tools/sleep-tool.d.ts +0 -49
- package/dist/skills/tools/sleep-tool.js +0 -81
- package/dist/skills/tools/structured-output-tool.d.ts +0 -116
- package/dist/skills/tools/structured-output-tool.js +0 -176
- package/dist/skills/tools/task-tool.d.ts +0 -104
- package/dist/skills/tools/task-tool.js +0 -161
- package/dist/skills/tools/team-tool.d.ts +0 -89
- package/dist/skills/tools/team-tool.js +0 -105
- package/dist/skills/tools/tool-search-tool.d.ts +0 -51
- package/dist/skills/tools/tool-search-tool.js +0 -110
- package/dist/skills/tools/tts-tool.d.ts +0 -38
- package/dist/skills/tools/tts-tool.js +0 -45
- package/dist/skills/tools/video-edit-tool.d.ts +0 -69
- package/dist/skills/tools/video-edit-tool.js +0 -74
- package/dist/skills/tools/video-generate-tool.d.ts +0 -62
- package/dist/skills/tools/video-generate-tool.js +0 -66
- package/dist/skills/tools/video-merge-tool.d.ts +0 -105
- package/dist/skills/tools/video-merge-tool.js +0 -92
- package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
- package/dist/skills/tools/video-upscale-tool.js +0 -52
- package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
- package/dist/skills/tools/web-fetch-tool.js +0 -92
- package/dist/skills/tools/web-search-tool.d.ts +0 -57
- package/dist/skills/tools/web-search-tool.js +0 -86
- package/dist/skills/tools/worktree-tool.d.ts +0 -69
- package/dist/skills/tools/worktree-tool.js +0 -147
- package/dist/skills/tools/write-tool.d.ts +0 -45
- package/dist/skills/tools/write-tool.js +0 -81
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// MCP Tool — Full Model Context Protocol integration.
|
|
3
|
-
//
|
|
4
|
-
// Matches Claude Code MCP depth:
|
|
5
|
-
// - Complete transport abstraction (stdio/SSE/HTTP/WS/in-process)
|
|
6
|
-
// - Full OAuth flow with PKCE + token lifecycle + step-up auth
|
|
7
|
-
// - Dynamic tool injection/removal (tools/list_changed protocol)
|
|
8
|
-
// - Resource discovery + binary blob persistence
|
|
9
|
-
// - Prompt support (list + get)
|
|
10
|
-
// - Server lifecycle management (add/remove/restart/healthCheck)
|
|
11
|
-
// - Elicitation support (server→user consent requests)
|
|
12
|
-
//
|
|
13
|
-
// Reference: claude-code-haha/src/services/mcp/ (full client SDK)
|
|
14
|
-
// claude-code-haha/src/tools/MCPTool/MCPTool.ts
|
|
15
|
-
// claude-code-haha/src/tools/McpAuthTool/McpAuthTool.ts
|
|
16
|
-
// claude-code-haha/src/tools/ListMcpResourcesTool/
|
|
17
|
-
// claude-code-haha/src/tools/ReadMcpResourceTool/
|
|
18
|
-
// ============================================================
|
|
19
|
-
import { normalizeNameForMcp } from "./mcp-client-types.js";
|
|
20
|
-
// Re-export name utilities
|
|
21
|
-
export { normalizeNameForMcp, buildMcpToolName, getMcpServerPrefix, parseMcpToolName, isMcpToolName, MCP_CONNECTION_TIMEOUT_MS, MCP_REQUEST_TIMEOUT_MS, MCP_TOOL_CALL_TIMEOUT_MS, MCP_MAX_RECONNECT_ATTEMPTS, MCP_MAX_DESCRIPTION_LENGTH, } from "./mcp-client-types.js";
|
|
22
|
-
// ── Tool Name & Schema ──────────────────────────────────────
|
|
23
|
-
export const MCP_TOOL_NAME = "mcp";
|
|
24
|
-
export const MCP_TOOL_SCHEMA = {
|
|
25
|
-
type: "object",
|
|
26
|
-
properties: {
|
|
27
|
-
action: {
|
|
28
|
-
type: "string",
|
|
29
|
-
enum: [
|
|
30
|
-
"list_servers", "list_tools", "call_tool",
|
|
31
|
-
"list_resources", "read_resource",
|
|
32
|
-
"list_prompts", "get_prompt",
|
|
33
|
-
"authenticate", "manage_server",
|
|
34
|
-
],
|
|
35
|
-
description: "MCP action:\n" +
|
|
36
|
-
"- list_servers: List configured MCP servers, their status and capabilities\n" +
|
|
37
|
-
"- list_tools: List tools provided by a specific server\n" +
|
|
38
|
-
"- call_tool: Execute a tool on an MCP server\n" +
|
|
39
|
-
"- list_resources: List resources from a server (or all servers)\n" +
|
|
40
|
-
"- read_resource: Read a specific resource by URI\n" +
|
|
41
|
-
"- list_prompts: List prompts available from a server\n" +
|
|
42
|
-
"- get_prompt: Get a specific prompt with arguments\n" +
|
|
43
|
-
"- authenticate: Initiate OAuth authentication with a server\n" +
|
|
44
|
-
"- manage_server: Add, remove, restart, or check server status",
|
|
45
|
-
},
|
|
46
|
-
server: {
|
|
47
|
-
type: "string",
|
|
48
|
-
description: "MCP server name. Required for all actions except list_servers.",
|
|
49
|
-
},
|
|
50
|
-
toolName: {
|
|
51
|
-
type: "string",
|
|
52
|
-
description: "Tool name on the MCP server. Required for call_tool.",
|
|
53
|
-
},
|
|
54
|
-
arguments: {
|
|
55
|
-
type: "object",
|
|
56
|
-
description: "Arguments for the tool call or prompt. Used with call_tool and get_prompt.",
|
|
57
|
-
},
|
|
58
|
-
uri: {
|
|
59
|
-
type: "string",
|
|
60
|
-
description: "Resource URI. Required for read_resource.",
|
|
61
|
-
},
|
|
62
|
-
promptName: {
|
|
63
|
-
type: "string",
|
|
64
|
-
description: "Prompt name. Required for get_prompt.",
|
|
65
|
-
},
|
|
66
|
-
manageAction: {
|
|
67
|
-
type: "string",
|
|
68
|
-
enum: ["add", "remove", "restart", "health_check", "enable", "disable"],
|
|
69
|
-
description: "Sub-action for manage_server.",
|
|
70
|
-
},
|
|
71
|
-
config: {
|
|
72
|
-
type: "object",
|
|
73
|
-
description: "Server configuration. Required for manage_server add.",
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
required: ["action"],
|
|
77
|
-
};
|
|
78
|
-
// ── Tool Factory ────────────────────────────────────────────
|
|
79
|
-
export function createMcpTool(deps) {
|
|
80
|
-
return {
|
|
81
|
-
name: MCP_TOOL_NAME,
|
|
82
|
-
label: "MCP",
|
|
83
|
-
description: "Interact with external MCP (Model Context Protocol) servers. " +
|
|
84
|
-
"Discover and call tools, read resources, get prompts, manage servers, " +
|
|
85
|
-
"and handle authentication. MCP servers extend agent capabilities with " +
|
|
86
|
-
"external integrations (databases, APIs, code analysis, custom tools).\n\n" +
|
|
87
|
-
"Dynamic tools: When MCP servers are connected, their tools also appear " +
|
|
88
|
-
"as individual entries in the tool list (prefixed mcp__server__tool) for " +
|
|
89
|
-
"direct invocation without going through this management tool.",
|
|
90
|
-
parameters: MCP_TOOL_SCHEMA,
|
|
91
|
-
shouldDefer: true,
|
|
92
|
-
execute: async (_toolCallId, params, signal) => {
|
|
93
|
-
switch (params.action) {
|
|
94
|
-
// ─── list_servers ─────────────────────────────────
|
|
95
|
-
case "list_servers": {
|
|
96
|
-
const servers = await deps.listServers();
|
|
97
|
-
if (servers.length === 0) {
|
|
98
|
-
return {
|
|
99
|
-
content: [{ type: "text", text: "No MCP servers configured. Use manage_server action to add one." }],
|
|
100
|
-
details: { type: "mcp", action: "list_servers", count: 0 },
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
const lines = [`MCP Servers (${servers.length}):`, ""];
|
|
104
|
-
for (const s of servers) {
|
|
105
|
-
const icon = statusIcon(s.status);
|
|
106
|
-
lines.push(`${icon} **${s.name}** [${s.transport}] — ${s.status}`);
|
|
107
|
-
lines.push(` Tools: ${s.toolCount} | Resources: ${s.resourceCount} | Prompts: ${s.promptCount}`);
|
|
108
|
-
if (s.capabilities) {
|
|
109
|
-
const caps = [];
|
|
110
|
-
if (s.capabilities.tools?.listChanged)
|
|
111
|
-
caps.push("tools/listChanged");
|
|
112
|
-
if (s.capabilities.resources?.subscribe)
|
|
113
|
-
caps.push("resources/subscribe");
|
|
114
|
-
if (s.capabilities.prompts?.listChanged)
|
|
115
|
-
caps.push("prompts/listChanged");
|
|
116
|
-
if (caps.length > 0)
|
|
117
|
-
lines.push(` Capabilities: ${caps.join(", ")}`);
|
|
118
|
-
}
|
|
119
|
-
if (s.serverVersion)
|
|
120
|
-
lines.push(` Version: ${s.serverVersion}`);
|
|
121
|
-
if (s.error)
|
|
122
|
-
lines.push(` ⚠ Error: ${s.error}`);
|
|
123
|
-
lines.push("");
|
|
124
|
-
}
|
|
125
|
-
return {
|
|
126
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
127
|
-
details: { type: "mcp", action: "list_servers", count: servers.length },
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
// ─── list_tools ───────────────────────────────────
|
|
131
|
-
case "list_tools": {
|
|
132
|
-
if (!params.server) {
|
|
133
|
-
return errResult("server is required for list_tools.");
|
|
134
|
-
}
|
|
135
|
-
const tools = await deps.listTools(params.server);
|
|
136
|
-
if (tools.length === 0) {
|
|
137
|
-
return {
|
|
138
|
-
content: [{ type: "text", text: `No tools available from server "${params.server}".` }],
|
|
139
|
-
details: { type: "mcp", action: "list_tools", server: params.server, count: 0 },
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
const lines = [`Tools from "${params.server}" (${tools.length}):`, ""];
|
|
143
|
-
for (const t of tools) {
|
|
144
|
-
const annBadges = formatAnnotations(t.annotations);
|
|
145
|
-
lines.push(`- **${t.name}**${annBadges}${t.description ? `: ${t.description}` : ""}`);
|
|
146
|
-
if (t.prefixedName)
|
|
147
|
-
lines.push(` Direct call: \`${t.prefixedName}\``);
|
|
148
|
-
}
|
|
149
|
-
return {
|
|
150
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
151
|
-
details: { type: "mcp", action: "list_tools", server: params.server, count: tools.length },
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
// ─── call_tool ────────────────────────────────────
|
|
155
|
-
case "call_tool": {
|
|
156
|
-
if (!params.server)
|
|
157
|
-
return errResult("server is required for call_tool.");
|
|
158
|
-
if (!params.toolName)
|
|
159
|
-
return errResult("toolName is required for call_tool.");
|
|
160
|
-
const result = await deps.callTool(params.server, params.toolName, params.arguments, signal);
|
|
161
|
-
if (!result.success || result.isError) {
|
|
162
|
-
return {
|
|
163
|
-
content: [{ type: "text", text: `MCP tool error (${params.server}/${params.toolName}): ${result.error || result.content || "unknown error"}` }],
|
|
164
|
-
details: { type: "mcp", action: "call_tool", server: params.server, toolName: params.toolName, success: false },
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
// Handle structured content blocks (images, etc.)
|
|
168
|
-
if (result.contentBlocks && result.contentBlocks.length > 0) {
|
|
169
|
-
const content = result.contentBlocks.map(block => {
|
|
170
|
-
if (block.type === "image" && block.data) {
|
|
171
|
-
return { type: "image", data: block.data, mimeType: block.mimeType };
|
|
172
|
-
}
|
|
173
|
-
return { type: "text", text: block.text || "" };
|
|
174
|
-
});
|
|
175
|
-
return {
|
|
176
|
-
content,
|
|
177
|
-
details: { type: "mcp", action: "call_tool", server: params.server, toolName: params.toolName, success: true },
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
return {
|
|
181
|
-
content: [{ type: "text", text: result.content || "(no output)" }],
|
|
182
|
-
details: { type: "mcp", action: "call_tool", server: params.server, toolName: params.toolName, success: true },
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
// ─── list_resources ───────────────────────────────
|
|
186
|
-
case "list_resources": {
|
|
187
|
-
const resources = await deps.listResources(params.server);
|
|
188
|
-
if (resources.length === 0) {
|
|
189
|
-
return {
|
|
190
|
-
content: [{ type: "text", text: params.server ? `No resources from "${params.server}".` : "No MCP resources available." }],
|
|
191
|
-
details: { type: "mcp", action: "list_resources", count: 0 },
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
const lines = [`MCP Resources (${resources.length}):`, ""];
|
|
195
|
-
for (const r of resources) {
|
|
196
|
-
lines.push(`- **${r.name}** \`${r.uri}\`${r.mimeType ? ` [${r.mimeType}]` : ""}`);
|
|
197
|
-
if (r.description)
|
|
198
|
-
lines.push(` ${r.description}`);
|
|
199
|
-
if (r.server)
|
|
200
|
-
lines.push(` Server: ${r.server}`);
|
|
201
|
-
}
|
|
202
|
-
return {
|
|
203
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
204
|
-
details: { type: "mcp", action: "list_resources", count: resources.length, server: params.server },
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
// ─── read_resource ────────────────────────────────
|
|
208
|
-
case "read_resource": {
|
|
209
|
-
if (!params.server)
|
|
210
|
-
return errResult("server is required for read_resource.");
|
|
211
|
-
if (!params.uri)
|
|
212
|
-
return errResult("uri is required for read_resource.");
|
|
213
|
-
const contents = await deps.readResource(params.server, params.uri);
|
|
214
|
-
if (contents.length === 0) {
|
|
215
|
-
return {
|
|
216
|
-
content: [{ type: "text", text: "Resource returned no content." }],
|
|
217
|
-
details: { type: "mcp", action: "read_resource", server: params.server, uri: params.uri },
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
const resultContent = [];
|
|
221
|
-
for (const c of contents) {
|
|
222
|
-
if (c.blobSavedTo) {
|
|
223
|
-
resultContent.push({ type: "text", text: `[Binary content saved to: ${c.blobSavedTo}${c.blobSize ? ` (${formatBytes(c.blobSize)})` : ""}]` });
|
|
224
|
-
}
|
|
225
|
-
else if (c.text) {
|
|
226
|
-
resultContent.push({ type: "text", text: c.text });
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (resultContent.length === 0) {
|
|
230
|
-
resultContent.push({ type: "text", text: "(empty content)" });
|
|
231
|
-
}
|
|
232
|
-
return {
|
|
233
|
-
content: resultContent,
|
|
234
|
-
details: { type: "mcp", action: "read_resource", server: params.server, uri: params.uri },
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
// ─── list_prompts ─────────────────────────────────
|
|
238
|
-
case "list_prompts": {
|
|
239
|
-
if (!params.server)
|
|
240
|
-
return errResult("server is required for list_prompts.");
|
|
241
|
-
if (!deps.listPrompts) {
|
|
242
|
-
return errResult("Prompt listing not supported by the current MCP host.");
|
|
243
|
-
}
|
|
244
|
-
const prompts = await deps.listPrompts(params.server);
|
|
245
|
-
if (prompts.length === 0) {
|
|
246
|
-
return {
|
|
247
|
-
content: [{ type: "text", text: `No prompts available from "${params.server}".` }],
|
|
248
|
-
details: { type: "mcp", action: "list_prompts", server: params.server, count: 0 },
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
const lines = [`Prompts from "${params.server}" (${prompts.length}):`, ""];
|
|
252
|
-
for (const p of prompts) {
|
|
253
|
-
lines.push(`- **${p.name}**${p.description ? `: ${p.description}` : ""}`);
|
|
254
|
-
if (p.arguments && p.arguments.length > 0) {
|
|
255
|
-
const argDescs = p.arguments.map(a => `${a.name}${a.required ? " (required)" : ""}${a.description ? `: ${a.description}` : ""}`);
|
|
256
|
-
lines.push(` Arguments: ${argDescs.join(", ")}`);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
261
|
-
details: { type: "mcp", action: "list_prompts", server: params.server, count: prompts.length },
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
// ─── get_prompt ───────────────────────────────────
|
|
265
|
-
case "get_prompt": {
|
|
266
|
-
if (!params.server)
|
|
267
|
-
return errResult("server is required for get_prompt.");
|
|
268
|
-
if (!params.promptName)
|
|
269
|
-
return errResult("promptName is required for get_prompt.");
|
|
270
|
-
if (!deps.getPrompt) {
|
|
271
|
-
return errResult("Prompt retrieval not supported by the current MCP host.");
|
|
272
|
-
}
|
|
273
|
-
const stringArgs = params.arguments
|
|
274
|
-
? Object.fromEntries(Object.entries(params.arguments).map(([k, v]) => [k, String(v)]))
|
|
275
|
-
: undefined;
|
|
276
|
-
const result = await deps.getPrompt(params.server, params.promptName, stringArgs);
|
|
277
|
-
const lines = [];
|
|
278
|
-
if (result.description)
|
|
279
|
-
lines.push(`> ${result.description}`, "");
|
|
280
|
-
for (const msg of result.messages) {
|
|
281
|
-
lines.push(`**[${msg.role}]:**`);
|
|
282
|
-
if (msg.content.type === "text") {
|
|
283
|
-
lines.push(msg.content.text);
|
|
284
|
-
}
|
|
285
|
-
else if (msg.content.type === "resource") {
|
|
286
|
-
lines.push(`[Resource: ${msg.content.resource.uri}]`);
|
|
287
|
-
if (msg.content.resource.text)
|
|
288
|
-
lines.push(msg.content.resource.text);
|
|
289
|
-
}
|
|
290
|
-
else if (msg.content.type === "image") {
|
|
291
|
-
lines.push("[Image content]");
|
|
292
|
-
}
|
|
293
|
-
lines.push("");
|
|
294
|
-
}
|
|
295
|
-
return {
|
|
296
|
-
content: [{ type: "text", text: lines.join("\n") || "(empty prompt)" }],
|
|
297
|
-
details: { type: "mcp", action: "get_prompt", server: params.server, promptName: params.promptName },
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
// ─── authenticate ─────────────────────────────────
|
|
301
|
-
case "authenticate": {
|
|
302
|
-
if (!params.server)
|
|
303
|
-
return errResult("server is required for authenticate.");
|
|
304
|
-
const result = await deps.authenticate(params.server);
|
|
305
|
-
switch (result.status) {
|
|
306
|
-
case "auth_url":
|
|
307
|
-
return {
|
|
308
|
-
content: [{
|
|
309
|
-
type: "text",
|
|
310
|
-
text: `Authentication required for "${params.server}".\n\n` +
|
|
311
|
-
`Please open this URL in your browser:\n${result.authUrl}\n\n` +
|
|
312
|
-
`${result.message || "Once you complete authentication, the server's tools will become available automatically."}`,
|
|
313
|
-
}],
|
|
314
|
-
details: { type: "mcp", action: "authenticate", server: params.server, status: "auth_url" },
|
|
315
|
-
};
|
|
316
|
-
case "already_authenticated":
|
|
317
|
-
return {
|
|
318
|
-
content: [{ type: "text", text: `Server "${params.server}" is already authenticated.` }],
|
|
319
|
-
details: { type: "mcp", action: "authenticate", server: params.server, status: "already_authenticated" },
|
|
320
|
-
};
|
|
321
|
-
case "step_up_required":
|
|
322
|
-
return {
|
|
323
|
-
content: [{
|
|
324
|
-
type: "text",
|
|
325
|
-
text: `Server "${params.server}" requires elevated permissions.\n` +
|
|
326
|
-
`Required scopes: ${result.requiredScopes?.join(", ") || "unknown"}\n\n` +
|
|
327
|
-
(result.authUrl ? `Re-authorize at: ${result.authUrl}` : "Please re-authenticate with elevated permissions."),
|
|
328
|
-
}],
|
|
329
|
-
details: { type: "mcp", action: "authenticate", server: params.server, status: "step_up_required" },
|
|
330
|
-
};
|
|
331
|
-
case "unsupported":
|
|
332
|
-
return {
|
|
333
|
-
content: [{ type: "text", text: `Authentication not supported for "${params.server}" (${result.message || "uses local transport"}).` }],
|
|
334
|
-
details: { type: "mcp", action: "authenticate", server: params.server, status: "unsupported" },
|
|
335
|
-
};
|
|
336
|
-
default:
|
|
337
|
-
return {
|
|
338
|
-
content: [{ type: "text", text: `Authentication error for "${params.server}": ${result.message || "unknown error"}` }],
|
|
339
|
-
details: { type: "mcp", action: "authenticate", server: params.server, status: "error" },
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
// ─── manage_server ────────────────────────────────
|
|
344
|
-
case "manage_server": {
|
|
345
|
-
if (!params.server)
|
|
346
|
-
return errResult("server is required for manage_server.");
|
|
347
|
-
if (!params.manageAction)
|
|
348
|
-
return errResult("manageAction is required for manage_server.");
|
|
349
|
-
switch (params.manageAction) {
|
|
350
|
-
case "add": {
|
|
351
|
-
if (!deps.addServer)
|
|
352
|
-
return errResult("Server addition not supported by the current MCP host.");
|
|
353
|
-
if (!params.config)
|
|
354
|
-
return errResult("config is required for manage_server add.");
|
|
355
|
-
const result = await deps.addServer(params.server, params.config);
|
|
356
|
-
return manageResultToOutput("add", params.server, result);
|
|
357
|
-
}
|
|
358
|
-
case "remove": {
|
|
359
|
-
if (!deps.removeServer)
|
|
360
|
-
return errResult("Server removal not supported by the current MCP host.");
|
|
361
|
-
const result = await deps.removeServer(params.server);
|
|
362
|
-
return manageResultToOutput("remove", params.server, result);
|
|
363
|
-
}
|
|
364
|
-
case "restart": {
|
|
365
|
-
if (!deps.restartServer)
|
|
366
|
-
return errResult("Server restart not supported by the current MCP host.");
|
|
367
|
-
const result = await deps.restartServer(params.server);
|
|
368
|
-
return manageResultToOutput("restart", params.server, result);
|
|
369
|
-
}
|
|
370
|
-
case "health_check": {
|
|
371
|
-
if (!deps.healthCheck)
|
|
372
|
-
return errResult("Health check not supported by the current MCP host.");
|
|
373
|
-
const result = await deps.healthCheck(params.server);
|
|
374
|
-
return manageResultToOutput("health_check", params.server, result);
|
|
375
|
-
}
|
|
376
|
-
case "enable":
|
|
377
|
-
case "disable": {
|
|
378
|
-
if (!deps.setServerEnabled)
|
|
379
|
-
return errResult("Server enable/disable not supported by the current MCP host.");
|
|
380
|
-
const result = await deps.setServerEnabled(params.server, params.manageAction === "enable");
|
|
381
|
-
return manageResultToOutput(params.manageAction, params.server, result);
|
|
382
|
-
}
|
|
383
|
-
default:
|
|
384
|
-
return errResult(`Unknown manageAction: ${params.manageAction}`);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
default:
|
|
388
|
-
return errResult(`Unknown action: "${params.action}".`);
|
|
389
|
-
}
|
|
390
|
-
},
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
// ── Helpers ─────────────────────────────────────────────────
|
|
394
|
-
function errResult(message) {
|
|
395
|
-
return {
|
|
396
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
397
|
-
details: { type: "mcp", error: message },
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
function statusIcon(status) {
|
|
401
|
-
switch (status) {
|
|
402
|
-
case "connected": return "✅";
|
|
403
|
-
case "connecting": return "⏳";
|
|
404
|
-
case "needs-auth": return "🔑";
|
|
405
|
-
case "failed": return "❌";
|
|
406
|
-
case "disconnected": return "⚪";
|
|
407
|
-
case "disabled": return "🚫";
|
|
408
|
-
default: return "❓";
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function formatAnnotations(annotations) {
|
|
412
|
-
if (!annotations)
|
|
413
|
-
return "";
|
|
414
|
-
const badges = [];
|
|
415
|
-
if (annotations.readOnlyHint)
|
|
416
|
-
badges.push("📖");
|
|
417
|
-
if (annotations.destructiveHint)
|
|
418
|
-
badges.push("⚠️");
|
|
419
|
-
if (annotations.idempotentHint)
|
|
420
|
-
badges.push("♻️");
|
|
421
|
-
return badges.length > 0 ? ` ${badges.join("")}` : "";
|
|
422
|
-
}
|
|
423
|
-
function formatBytes(bytes) {
|
|
424
|
-
if (bytes < 1024)
|
|
425
|
-
return `${bytes}B`;
|
|
426
|
-
if (bytes < 1024 * 1024)
|
|
427
|
-
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
428
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
429
|
-
}
|
|
430
|
-
function manageResultToOutput(action, server, result) {
|
|
431
|
-
const lines = [];
|
|
432
|
-
lines.push(`${result.success ? "✅" : "❌"} ${action} "${server}": ${result.message}`);
|
|
433
|
-
if (result.serverState) {
|
|
434
|
-
lines.push("");
|
|
435
|
-
lines.push(` Status: ${result.serverState.status}`);
|
|
436
|
-
lines.push(` Tools: ${result.serverState.toolCount} | Resources: ${result.serverState.resourceCount}`);
|
|
437
|
-
}
|
|
438
|
-
return {
|
|
439
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
440
|
-
details: { type: "mcp", action: "manage_server", manageAction: action, server, success: result.success },
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Create a dynamic per-server authentication proxy tool.
|
|
445
|
-
* One instance per unauthenticated MCP server.
|
|
446
|
-
*
|
|
447
|
-
* Tool name follows CC convention: `mcp__<normalizedServer>__authenticate`
|
|
448
|
-
*/
|
|
449
|
-
export function createMcpAuthProxy(serverName, deps) {
|
|
450
|
-
const normalizedName = normalizeNameForMcp(serverName);
|
|
451
|
-
const toolName = `mcp__${normalizedName}__authenticate`;
|
|
452
|
-
return {
|
|
453
|
-
name: toolName,
|
|
454
|
-
label: `Authenticate ${serverName}`,
|
|
455
|
-
description: `Initiate OAuth authentication with the "${serverName}" MCP server. ` +
|
|
456
|
-
`Call this when the server requires authentication before its tools can be used.`,
|
|
457
|
-
parameters: {
|
|
458
|
-
type: "object",
|
|
459
|
-
properties: {},
|
|
460
|
-
},
|
|
461
|
-
isReadOnly: true,
|
|
462
|
-
searchHint: `mcp auth oauth ${serverName} authenticate login`,
|
|
463
|
-
execute: async (_toolCallId) => {
|
|
464
|
-
const result = await deps.authenticate(serverName);
|
|
465
|
-
switch (result.status) {
|
|
466
|
-
case "auth_url":
|
|
467
|
-
// Trigger background reconnect after auth
|
|
468
|
-
if (deps.onAuthComplete) {
|
|
469
|
-
// Fire-and-forget: host will reconnect in background
|
|
470
|
-
deps.onAuthComplete(serverName).catch(() => { });
|
|
471
|
-
}
|
|
472
|
-
return {
|
|
473
|
-
content: [{ type: "text", text: `Please authenticate with "${serverName}" at:\n${result.authUrl}` }],
|
|
474
|
-
details: { type: "mcp_auth_proxy", server: serverName, status: "auth_url" },
|
|
475
|
-
};
|
|
476
|
-
case "already_authenticated":
|
|
477
|
-
return {
|
|
478
|
-
content: [{ type: "text", text: `Server "${serverName}" is already authenticated.` }],
|
|
479
|
-
details: { type: "mcp_auth_proxy", server: serverName, status: "already_authenticated" },
|
|
480
|
-
};
|
|
481
|
-
case "step_up_required":
|
|
482
|
-
return {
|
|
483
|
-
content: [{
|
|
484
|
-
type: "text",
|
|
485
|
-
text: `Server "${serverName}" requires elevated permissions.\n` +
|
|
486
|
-
(result.authUrl ? `Re-authorize at: ${result.authUrl}` : "Please re-authenticate with elevated permissions."),
|
|
487
|
-
}],
|
|
488
|
-
details: { type: "mcp_auth_proxy", server: serverName, status: "step_up_required" },
|
|
489
|
-
};
|
|
490
|
-
case "unsupported":
|
|
491
|
-
return {
|
|
492
|
-
content: [{ type: "text", text: `Server "${serverName}" does not support authentication (local transport).` }],
|
|
493
|
-
details: { type: "mcp_auth_proxy", server: serverName, status: "unsupported" },
|
|
494
|
-
};
|
|
495
|
-
default:
|
|
496
|
-
return {
|
|
497
|
-
content: [{ type: "text", text: `Authentication failed for "${serverName}": ${result.message || "unknown"}` }],
|
|
498
|
-
details: { type: "mcp_auth_proxy", server: serverName, status: "error", error: result.message },
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
},
|
|
502
|
-
};
|
|
503
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { PortableTool } from "../portable-tool.js";
|
|
2
|
-
export declare const MEMORY_SEARCH_TOOL_NAME: "memory_search";
|
|
3
|
-
export type MemorySource = "memory" | "sessions" | "all";
|
|
4
|
-
export interface MemorySearchToolParams {
|
|
5
|
-
/** Search query */
|
|
6
|
-
query: string;
|
|
7
|
-
/** Source to search in */
|
|
8
|
-
source?: MemorySource;
|
|
9
|
-
/** Maximum results to return */
|
|
10
|
-
maxResults?: number;
|
|
11
|
-
/** Filter by time range (ISO date string, sessions only) */
|
|
12
|
-
after?: string;
|
|
13
|
-
/** Filter by time range (ISO date string, sessions only) */
|
|
14
|
-
before?: string;
|
|
15
|
-
}
|
|
16
|
-
export declare const MEMORY_SEARCH_TOOL_SCHEMA: {
|
|
17
|
-
readonly type: "object";
|
|
18
|
-
readonly properties: {
|
|
19
|
-
readonly query: {
|
|
20
|
-
readonly type: "string";
|
|
21
|
-
readonly description: "Search query. Supports natural language and keywords.";
|
|
22
|
-
};
|
|
23
|
-
readonly source: {
|
|
24
|
-
readonly type: "string";
|
|
25
|
-
readonly enum: readonly ["memory", "sessions", "all"];
|
|
26
|
-
readonly description: string;
|
|
27
|
-
};
|
|
28
|
-
readonly maxResults: {
|
|
29
|
-
readonly type: "number";
|
|
30
|
-
readonly description: "Maximum results to return (default: 5).";
|
|
31
|
-
};
|
|
32
|
-
readonly after: {
|
|
33
|
-
readonly type: "string";
|
|
34
|
-
readonly description: "Only return sessions after this date (ISO format). Sessions source only.";
|
|
35
|
-
};
|
|
36
|
-
readonly before: {
|
|
37
|
-
readonly type: "string";
|
|
38
|
-
readonly description: "Only return sessions before this date (ISO format). Sessions source only.";
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
readonly required: readonly ["query"];
|
|
42
|
-
};
|
|
43
|
-
export interface MemoryEntry {
|
|
44
|
-
content: string;
|
|
45
|
-
source: "memory" | "session";
|
|
46
|
-
relevance: number;
|
|
47
|
-
metadata?: {
|
|
48
|
-
sessionId?: string;
|
|
49
|
-
timestamp?: string;
|
|
50
|
-
summary?: string;
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
export interface MemoryQueryOutput {
|
|
54
|
-
results: MemoryEntry[];
|
|
55
|
-
query: string;
|
|
56
|
-
sources: MemorySource[];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Host-provided memory search backend.
|
|
60
|
-
*/
|
|
61
|
-
export interface MemorySearchToolDeps {
|
|
62
|
-
/**
|
|
63
|
-
* Search memory/sessions.
|
|
64
|
-
* The host routes to QMemory vector search, FTS session search, or both.
|
|
65
|
-
*/
|
|
66
|
-
searchMemory(params: {
|
|
67
|
-
query: string;
|
|
68
|
-
source: MemorySource;
|
|
69
|
-
maxResults: number;
|
|
70
|
-
after?: string;
|
|
71
|
-
before?: string;
|
|
72
|
-
}): Promise<MemoryQueryOutput>;
|
|
73
|
-
}
|
|
74
|
-
export declare function createMemorySearchTool(deps: MemorySearchToolDeps): PortableTool<MemorySearchToolParams>;
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Memory Tool — enhanced memory query with multi-source search.
|
|
3
|
-
// Reference: hermes-agent-main/tools/memory_tool.py
|
|
4
|
-
// hermes-agent-main/tools/session_search_tool.py
|
|
5
|
-
// Category: system
|
|
6
|
-
// ============================================================
|
|
7
|
-
export const MEMORY_SEARCH_TOOL_NAME = "memory_search";
|
|
8
|
-
export const MEMORY_SEARCH_TOOL_SCHEMA = {
|
|
9
|
-
type: "object",
|
|
10
|
-
properties: {
|
|
11
|
-
query: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "Search query. Supports natural language and keywords.",
|
|
14
|
-
},
|
|
15
|
-
source: {
|
|
16
|
-
type: "string",
|
|
17
|
-
enum: ["memory", "sessions", "all"],
|
|
18
|
-
description: "Where to search:\n" +
|
|
19
|
-
'- "memory": curated long-term memory (QMemory vector store)\n' +
|
|
20
|
-
'- "sessions": past conversation history (full-text search)\n' +
|
|
21
|
-
'- "all": both sources merged (default)',
|
|
22
|
-
},
|
|
23
|
-
maxResults: {
|
|
24
|
-
type: "number",
|
|
25
|
-
description: "Maximum results to return (default: 5).",
|
|
26
|
-
},
|
|
27
|
-
after: {
|
|
28
|
-
type: "string",
|
|
29
|
-
description: "Only return sessions after this date (ISO format). Sessions source only.",
|
|
30
|
-
},
|
|
31
|
-
before: {
|
|
32
|
-
type: "string",
|
|
33
|
-
description: "Only return sessions before this date (ISO format). Sessions source only.",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
required: ["query"],
|
|
37
|
-
};
|
|
38
|
-
const DEFAULT_MAX_RESULTS = 5;
|
|
39
|
-
export function createMemorySearchTool(deps) {
|
|
40
|
-
return {
|
|
41
|
-
name: MEMORY_SEARCH_TOOL_NAME,
|
|
42
|
-
label: "Memory Query",
|
|
43
|
-
description: "Search your long-term memory and past conversations. " +
|
|
44
|
-
"Sources: 'memory' (curated knowledge), 'sessions' (conversation history), 'all' (both). " +
|
|
45
|
-
"Use for recalling previous decisions, finding past code/scripts, or checking what was discussed.",
|
|
46
|
-
parameters: MEMORY_SEARCH_TOOL_SCHEMA,
|
|
47
|
-
execute: async (_toolCallId, params) => {
|
|
48
|
-
if (!params.query || params.query.trim().length < 2) {
|
|
49
|
-
return {
|
|
50
|
-
content: [{ type: "text", text: "Error: query must be at least 2 characters." }],
|
|
51
|
-
details: { type: "memory_query", error: "invalid_query" },
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
const source = params.source || "all";
|
|
55
|
-
const maxResults = Math.min(params.maxResults ?? DEFAULT_MAX_RESULTS, 20);
|
|
56
|
-
const output = await deps.searchMemory({
|
|
57
|
-
query: params.query.trim(),
|
|
58
|
-
source,
|
|
59
|
-
maxResults,
|
|
60
|
-
after: params.after,
|
|
61
|
-
before: params.before,
|
|
62
|
-
});
|
|
63
|
-
if (output.results.length === 0) {
|
|
64
|
-
return {
|
|
65
|
-
content: [{ type: "text", text: `No results found for "${params.query}" in ${source} source(s).` }],
|
|
66
|
-
details: { type: "memory_query", query: params.query, source, resultCount: 0 },
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
const lines = [`Found ${output.results.length} result(s) for "${params.query}":\n`];
|
|
70
|
-
for (let i = 0; i < output.results.length; i++) {
|
|
71
|
-
const entry = output.results[i];
|
|
72
|
-
const srcLabel = entry.source === "memory" ? "📝 Memory" : "💬 Session";
|
|
73
|
-
const meta = entry.metadata;
|
|
74
|
-
const timestamp = meta?.timestamp ? ` (${meta.timestamp})` : "";
|
|
75
|
-
lines.push(`${i + 1}. [${srcLabel}]${timestamp}`);
|
|
76
|
-
if (meta?.summary) {
|
|
77
|
-
lines.push(` Summary: ${meta.summary}`);
|
|
78
|
-
}
|
|
79
|
-
lines.push(` ${entry.content.slice(0, 300)}${entry.content.length > 300 ? "..." : ""}`);
|
|
80
|
-
lines.push("");
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
84
|
-
details: { type: "memory_query", query: params.query, source, resultCount: output.results.length },
|
|
85
|
-
};
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|