@codeany/open-agent-sdk 0.2.1 → 0.2.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/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +2 -0
- package/dist/engine.js.map +1 -1
- package/package.json +5 -6
- package/src/agent.ts +0 -516
- package/src/engine.ts +0 -630
- package/src/hooks.ts +0 -261
- package/src/index.ts +0 -426
- package/src/mcp/client.ts +0 -150
- package/src/providers/anthropic.ts +0 -60
- package/src/providers/index.ts +0 -34
- package/src/providers/openai.ts +0 -315
- package/src/providers/types.ts +0 -85
- package/src/sdk-mcp-server.ts +0 -78
- package/src/session.ts +0 -227
- package/src/skills/bundled/commit.ts +0 -38
- package/src/skills/bundled/debug.ts +0 -48
- package/src/skills/bundled/index.ts +0 -28
- package/src/skills/bundled/review.ts +0 -41
- package/src/skills/bundled/simplify.ts +0 -51
- package/src/skills/bundled/test.ts +0 -43
- package/src/skills/index.ts +0 -25
- package/src/skills/registry.ts +0 -133
- package/src/skills/types.ts +0 -99
- package/src/tool-helper.ts +0 -127
- package/src/tools/agent-tool.ts +0 -164
- package/src/tools/ask-user.ts +0 -79
- package/src/tools/bash.ts +0 -75
- package/src/tools/config-tool.ts +0 -89
- package/src/tools/cron-tools.ts +0 -153
- package/src/tools/edit.ts +0 -74
- package/src/tools/glob.ts +0 -77
- package/src/tools/grep.ts +0 -168
- package/src/tools/index.ts +0 -240
- package/src/tools/lsp-tool.ts +0 -163
- package/src/tools/mcp-resource-tools.ts +0 -125
- package/src/tools/notebook-edit.ts +0 -93
- package/src/tools/plan-tools.ts +0 -88
- package/src/tools/read.ts +0 -73
- package/src/tools/send-message.ts +0 -96
- package/src/tools/skill-tool.ts +0 -133
- package/src/tools/task-tools.ts +0 -290
- package/src/tools/team-tools.ts +0 -128
- package/src/tools/todo-tool.ts +0 -112
- package/src/tools/tool-search.ts +0 -87
- package/src/tools/types.ts +0 -66
- package/src/tools/web-fetch.ts +0 -66
- package/src/tools/web-search.ts +0 -86
- package/src/tools/worktree-tools.ts +0 -140
- package/src/tools/write.ts +0 -42
- package/src/types.ts +0 -486
- package/src/utils/compact.ts +0 -207
- package/src/utils/context.ts +0 -191
- package/src/utils/fileCache.ts +0 -148
- package/src/utils/messages.ts +0 -195
- package/src/utils/retry.ts +0 -140
- package/src/utils/tokens.ts +0 -145
package/src/tools/index.ts
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool Registry - All built-in tool definitions
|
|
3
|
-
*
|
|
4
|
-
* 30+ tools covering file I/O, execution, search, web, agents,
|
|
5
|
-
* tasks, teams, messaging, worktree, planning, scheduling, and more.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ToolDefinition } from '../types.js'
|
|
9
|
-
|
|
10
|
-
// File I/O
|
|
11
|
-
import { BashTool } from './bash.js'
|
|
12
|
-
import { FileReadTool } from './read.js'
|
|
13
|
-
import { FileWriteTool } from './write.js'
|
|
14
|
-
import { FileEditTool } from './edit.js'
|
|
15
|
-
import { GlobTool } from './glob.js'
|
|
16
|
-
import { GrepTool } from './grep.js'
|
|
17
|
-
import { NotebookEditTool } from './notebook-edit.js'
|
|
18
|
-
|
|
19
|
-
// Web
|
|
20
|
-
import { WebFetchTool } from './web-fetch.js'
|
|
21
|
-
import { WebSearchTool } from './web-search.js'
|
|
22
|
-
|
|
23
|
-
// Agent & Multi-agent
|
|
24
|
-
import { AgentTool } from './agent-tool.js'
|
|
25
|
-
import { SendMessageTool } from './send-message.js'
|
|
26
|
-
import { TeamCreateTool, TeamDeleteTool } from './team-tools.js'
|
|
27
|
-
|
|
28
|
-
// Tasks
|
|
29
|
-
import {
|
|
30
|
-
TaskCreateTool,
|
|
31
|
-
TaskListTool,
|
|
32
|
-
TaskUpdateTool,
|
|
33
|
-
TaskGetTool,
|
|
34
|
-
TaskStopTool,
|
|
35
|
-
TaskOutputTool,
|
|
36
|
-
} from './task-tools.js'
|
|
37
|
-
|
|
38
|
-
// Worktree
|
|
39
|
-
import { EnterWorktreeTool, ExitWorktreeTool } from './worktree-tools.js'
|
|
40
|
-
|
|
41
|
-
// Planning
|
|
42
|
-
import { EnterPlanModeTool, ExitPlanModeTool } from './plan-tools.js'
|
|
43
|
-
|
|
44
|
-
// User interaction
|
|
45
|
-
import { AskUserQuestionTool } from './ask-user.js'
|
|
46
|
-
|
|
47
|
-
// Discovery
|
|
48
|
-
import { ToolSearchTool } from './tool-search.js'
|
|
49
|
-
|
|
50
|
-
// MCP Resources
|
|
51
|
-
import { ListMcpResourcesTool, ReadMcpResourceTool } from './mcp-resource-tools.js'
|
|
52
|
-
|
|
53
|
-
// Scheduling
|
|
54
|
-
import { CronCreateTool, CronDeleteTool, CronListTool, RemoteTriggerTool } from './cron-tools.js'
|
|
55
|
-
|
|
56
|
-
// LSP
|
|
57
|
-
import { LSPTool } from './lsp-tool.js'
|
|
58
|
-
|
|
59
|
-
// Config
|
|
60
|
-
import { ConfigTool } from './config-tool.js'
|
|
61
|
-
|
|
62
|
-
// Todo
|
|
63
|
-
import { TodoWriteTool } from './todo-tool.js'
|
|
64
|
-
|
|
65
|
-
// Skill
|
|
66
|
-
import { SkillTool } from './skill-tool.js'
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* All built-in tools (30+).
|
|
70
|
-
*/
|
|
71
|
-
const ALL_TOOLS: ToolDefinition[] = [
|
|
72
|
-
// Core file I/O & execution
|
|
73
|
-
BashTool,
|
|
74
|
-
FileReadTool,
|
|
75
|
-
FileWriteTool,
|
|
76
|
-
FileEditTool,
|
|
77
|
-
GlobTool,
|
|
78
|
-
GrepTool,
|
|
79
|
-
NotebookEditTool,
|
|
80
|
-
|
|
81
|
-
// Web
|
|
82
|
-
WebFetchTool,
|
|
83
|
-
WebSearchTool,
|
|
84
|
-
|
|
85
|
-
// Agent & Multi-agent
|
|
86
|
-
AgentTool,
|
|
87
|
-
SendMessageTool,
|
|
88
|
-
TeamCreateTool,
|
|
89
|
-
TeamDeleteTool,
|
|
90
|
-
|
|
91
|
-
// Tasks
|
|
92
|
-
TaskCreateTool,
|
|
93
|
-
TaskListTool,
|
|
94
|
-
TaskUpdateTool,
|
|
95
|
-
TaskGetTool,
|
|
96
|
-
TaskStopTool,
|
|
97
|
-
TaskOutputTool,
|
|
98
|
-
|
|
99
|
-
// Worktree
|
|
100
|
-
EnterWorktreeTool,
|
|
101
|
-
ExitWorktreeTool,
|
|
102
|
-
|
|
103
|
-
// Planning
|
|
104
|
-
EnterPlanModeTool,
|
|
105
|
-
ExitPlanModeTool,
|
|
106
|
-
|
|
107
|
-
// User interaction
|
|
108
|
-
AskUserQuestionTool,
|
|
109
|
-
|
|
110
|
-
// Discovery
|
|
111
|
-
ToolSearchTool,
|
|
112
|
-
|
|
113
|
-
// MCP Resources
|
|
114
|
-
ListMcpResourcesTool,
|
|
115
|
-
ReadMcpResourceTool,
|
|
116
|
-
|
|
117
|
-
// Scheduling
|
|
118
|
-
CronCreateTool,
|
|
119
|
-
CronDeleteTool,
|
|
120
|
-
CronListTool,
|
|
121
|
-
RemoteTriggerTool,
|
|
122
|
-
|
|
123
|
-
// LSP
|
|
124
|
-
LSPTool,
|
|
125
|
-
|
|
126
|
-
// Config
|
|
127
|
-
ConfigTool,
|
|
128
|
-
|
|
129
|
-
// Todo
|
|
130
|
-
TodoWriteTool,
|
|
131
|
-
|
|
132
|
-
// Skill
|
|
133
|
-
SkillTool,
|
|
134
|
-
]
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Get all built-in tools.
|
|
138
|
-
*/
|
|
139
|
-
export function getAllBaseTools(): ToolDefinition[] {
|
|
140
|
-
return [...ALL_TOOLS]
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Filter tools by allowed/disallowed lists.
|
|
145
|
-
*/
|
|
146
|
-
export function filterTools(
|
|
147
|
-
tools: ToolDefinition[],
|
|
148
|
-
allowedTools?: string[],
|
|
149
|
-
disallowedTools?: string[],
|
|
150
|
-
): ToolDefinition[] {
|
|
151
|
-
let filtered = tools
|
|
152
|
-
|
|
153
|
-
if (allowedTools && allowedTools.length > 0) {
|
|
154
|
-
const allowed = new Set(allowedTools)
|
|
155
|
-
filtered = filtered.filter((t) => allowed.has(t.name))
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (disallowedTools && disallowedTools.length > 0) {
|
|
159
|
-
const disallowed = new Set(disallowedTools)
|
|
160
|
-
filtered = filtered.filter((t) => !disallowed.has(t.name))
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return filtered
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Assemble tool pool: base tools + MCP tools, with deduplication.
|
|
168
|
-
*/
|
|
169
|
-
export function assembleToolPool(
|
|
170
|
-
baseTools: ToolDefinition[],
|
|
171
|
-
mcpTools: ToolDefinition[] = [],
|
|
172
|
-
allowedTools?: string[],
|
|
173
|
-
disallowedTools?: string[],
|
|
174
|
-
): ToolDefinition[] {
|
|
175
|
-
const combined = [...baseTools, ...mcpTools]
|
|
176
|
-
|
|
177
|
-
// Deduplicate by name (later definitions override)
|
|
178
|
-
const byName = new Map<string, ToolDefinition>()
|
|
179
|
-
for (const tool of combined) {
|
|
180
|
-
byName.set(tool.name, tool)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
let tools = Array.from(byName.values())
|
|
184
|
-
return filterTools(tools, allowedTools, disallowedTools)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Re-export individual tools
|
|
188
|
-
export {
|
|
189
|
-
// Core
|
|
190
|
-
BashTool,
|
|
191
|
-
FileReadTool,
|
|
192
|
-
FileWriteTool,
|
|
193
|
-
FileEditTool,
|
|
194
|
-
GlobTool,
|
|
195
|
-
GrepTool,
|
|
196
|
-
NotebookEditTool,
|
|
197
|
-
WebFetchTool,
|
|
198
|
-
WebSearchTool,
|
|
199
|
-
// Agent
|
|
200
|
-
AgentTool,
|
|
201
|
-
SendMessageTool,
|
|
202
|
-
TeamCreateTool,
|
|
203
|
-
TeamDeleteTool,
|
|
204
|
-
// Tasks
|
|
205
|
-
TaskCreateTool,
|
|
206
|
-
TaskListTool,
|
|
207
|
-
TaskUpdateTool,
|
|
208
|
-
TaskGetTool,
|
|
209
|
-
TaskStopTool,
|
|
210
|
-
TaskOutputTool,
|
|
211
|
-
// Worktree
|
|
212
|
-
EnterWorktreeTool,
|
|
213
|
-
ExitWorktreeTool,
|
|
214
|
-
// Planning
|
|
215
|
-
EnterPlanModeTool,
|
|
216
|
-
ExitPlanModeTool,
|
|
217
|
-
// User
|
|
218
|
-
AskUserQuestionTool,
|
|
219
|
-
// Discovery
|
|
220
|
-
ToolSearchTool,
|
|
221
|
-
// MCP
|
|
222
|
-
ListMcpResourcesTool,
|
|
223
|
-
ReadMcpResourceTool,
|
|
224
|
-
// Scheduling
|
|
225
|
-
CronCreateTool,
|
|
226
|
-
CronDeleteTool,
|
|
227
|
-
CronListTool,
|
|
228
|
-
RemoteTriggerTool,
|
|
229
|
-
// LSP
|
|
230
|
-
LSPTool,
|
|
231
|
-
// Config
|
|
232
|
-
ConfigTool,
|
|
233
|
-
// Todo
|
|
234
|
-
TodoWriteTool,
|
|
235
|
-
// Skill
|
|
236
|
-
SkillTool,
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Re-export helpers
|
|
240
|
-
export { defineTool, toApiTool } from './types.js'
|
package/src/tools/lsp-tool.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* LSPTool - Language Server Protocol integration
|
|
3
|
-
*
|
|
4
|
-
* Provides code intelligence: go-to-definition, find-references,
|
|
5
|
-
* hover, document symbols, workspace symbols, etc.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { execSync } from 'child_process'
|
|
9
|
-
import type { ToolDefinition, ToolResult } from '../types.js'
|
|
10
|
-
|
|
11
|
-
export const LSPTool: ToolDefinition = {
|
|
12
|
-
name: 'LSP',
|
|
13
|
-
description: 'Language Server Protocol operations for code intelligence. Supports go-to-definition, find-references, hover, and symbol lookup.',
|
|
14
|
-
inputSchema: {
|
|
15
|
-
type: 'object',
|
|
16
|
-
properties: {
|
|
17
|
-
operation: {
|
|
18
|
-
type: 'string',
|
|
19
|
-
enum: [
|
|
20
|
-
'goToDefinition',
|
|
21
|
-
'findReferences',
|
|
22
|
-
'hover',
|
|
23
|
-
'documentSymbol',
|
|
24
|
-
'workspaceSymbol',
|
|
25
|
-
'goToImplementation',
|
|
26
|
-
'prepareCallHierarchy',
|
|
27
|
-
'incomingCalls',
|
|
28
|
-
'outgoingCalls',
|
|
29
|
-
],
|
|
30
|
-
description: 'LSP operation to perform',
|
|
31
|
-
},
|
|
32
|
-
file_path: { type: 'string', description: 'File path for the operation' },
|
|
33
|
-
line: { type: 'number', description: 'Line number (0-based)' },
|
|
34
|
-
character: { type: 'number', description: 'Character position (0-based)' },
|
|
35
|
-
query: { type: 'string', description: 'Symbol name (for workspace symbol search)' },
|
|
36
|
-
},
|
|
37
|
-
required: ['operation'],
|
|
38
|
-
},
|
|
39
|
-
isReadOnly: () => true,
|
|
40
|
-
isConcurrencySafe: () => true,
|
|
41
|
-
isEnabled: () => true,
|
|
42
|
-
async prompt() { return 'Code intelligence via Language Server Protocol.' },
|
|
43
|
-
async call(input: any, context: { cwd: string }): Promise<ToolResult> {
|
|
44
|
-
const { operation, file_path, line, character, query } = input
|
|
45
|
-
|
|
46
|
-
// LSP requires a running language server. In standalone mode,
|
|
47
|
-
// we fall back to basic grep/ripgrep-based symbol lookup.
|
|
48
|
-
try {
|
|
49
|
-
switch (operation) {
|
|
50
|
-
case 'goToDefinition':
|
|
51
|
-
case 'goToImplementation': {
|
|
52
|
-
if (!file_path || line === undefined) {
|
|
53
|
-
return { type: 'tool_result', tool_use_id: '', content: 'file_path and line required', is_error: true }
|
|
54
|
-
}
|
|
55
|
-
// Use grep to find definition
|
|
56
|
-
const symbol = await getSymbolAtPosition(file_path, line, character || 0, context.cwd)
|
|
57
|
-
if (!symbol) {
|
|
58
|
-
return { type: 'tool_result', tool_use_id: '', content: 'Could not identify symbol at position' }
|
|
59
|
-
}
|
|
60
|
-
const results = execSync(
|
|
61
|
-
`rg -n "(?:function|class|interface|type|const|let|var|export)\\s+${symbol}" --type-add 'src:*.{ts,tsx,js,jsx,py,go,rs,java}' -t src ${context.cwd} 2>/dev/null || grep -rn "(?:function|class|interface|type|const|let|var|export)\\s*${symbol}" ${context.cwd} --include='*.ts' --include='*.js' 2>/dev/null`,
|
|
62
|
-
{ encoding: 'utf-8', timeout: 10000 },
|
|
63
|
-
).trim()
|
|
64
|
-
return { type: 'tool_result', tool_use_id: '', content: results || `No definition found for "${symbol}"` }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
case 'findReferences': {
|
|
68
|
-
if (!file_path || line === undefined) {
|
|
69
|
-
return { type: 'tool_result', tool_use_id: '', content: 'file_path and line required', is_error: true }
|
|
70
|
-
}
|
|
71
|
-
const sym = await getSymbolAtPosition(file_path, line, character || 0, context.cwd)
|
|
72
|
-
if (!sym) {
|
|
73
|
-
return { type: 'tool_result', tool_use_id: '', content: 'Could not identify symbol at position' }
|
|
74
|
-
}
|
|
75
|
-
const refs = execSync(
|
|
76
|
-
`rg -n "${sym}" ${context.cwd} --type-add 'src:*.{ts,tsx,js,jsx,py,go,rs,java}' -t src 2>/dev/null | head -50`,
|
|
77
|
-
{ encoding: 'utf-8', timeout: 10000 },
|
|
78
|
-
).trim()
|
|
79
|
-
return { type: 'tool_result', tool_use_id: '', content: refs || `No references found for "${sym}"` }
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
case 'hover': {
|
|
83
|
-
return {
|
|
84
|
-
type: 'tool_result',
|
|
85
|
-
tool_use_id: '',
|
|
86
|
-
content: 'Hover information requires a running language server. Use Read tool to examine the file content.',
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
case 'documentSymbol': {
|
|
91
|
-
if (!file_path) {
|
|
92
|
-
return { type: 'tool_result', tool_use_id: '', content: 'file_path required', is_error: true }
|
|
93
|
-
}
|
|
94
|
-
const symbols = execSync(
|
|
95
|
-
`rg -n "^\\s*(export\\s+)?(function|class|interface|type|const|let|var|enum)\\s+" ${JSON.stringify(file_path)} 2>/dev/null || grep -n "^\\s*\\(export\\s\\+\\)\\?\\(function\\|class\\|interface\\|type\\|const\\|let\\|var\\|enum\\)\\s" ${JSON.stringify(file_path)} 2>/dev/null`,
|
|
96
|
-
{ encoding: 'utf-8', cwd: context.cwd, timeout: 10000 },
|
|
97
|
-
).trim()
|
|
98
|
-
return { type: 'tool_result', tool_use_id: '', content: symbols || 'No symbols found' }
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
case 'workspaceSymbol': {
|
|
102
|
-
if (!query) {
|
|
103
|
-
return { type: 'tool_result', tool_use_id: '', content: 'query required', is_error: true }
|
|
104
|
-
}
|
|
105
|
-
const wsSymbols = execSync(
|
|
106
|
-
`rg -n "${query}" ${context.cwd} --type-add 'src:*.{ts,tsx,js,jsx,py,go,rs,java}' -t src 2>/dev/null | head -30`,
|
|
107
|
-
{ encoding: 'utf-8', timeout: 10000 },
|
|
108
|
-
).trim()
|
|
109
|
-
return { type: 'tool_result', tool_use_id: '', content: wsSymbols || `No symbols found for "${query}"` }
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
default:
|
|
113
|
-
return {
|
|
114
|
-
type: 'tool_result',
|
|
115
|
-
tool_use_id: '',
|
|
116
|
-
content: `LSP operation "${operation}" requires a running language server.`,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
} catch (err: any) {
|
|
120
|
-
return {
|
|
121
|
-
type: 'tool_result',
|
|
122
|
-
tool_use_id: '',
|
|
123
|
-
content: `LSP error: ${err.message}`,
|
|
124
|
-
is_error: true,
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Get the symbol at a given position in a file.
|
|
132
|
-
*/
|
|
133
|
-
async function getSymbolAtPosition(
|
|
134
|
-
filePath: string,
|
|
135
|
-
line: number,
|
|
136
|
-
character: number,
|
|
137
|
-
cwd: string,
|
|
138
|
-
): Promise<string | null> {
|
|
139
|
-
try {
|
|
140
|
-
const { readFile } = await import('fs/promises')
|
|
141
|
-
const { resolve } = await import('path')
|
|
142
|
-
const content = await readFile(resolve(cwd, filePath), 'utf-8')
|
|
143
|
-
const lines = content.split('\n')
|
|
144
|
-
|
|
145
|
-
if (line >= lines.length) return null
|
|
146
|
-
|
|
147
|
-
const lineText = lines[line]
|
|
148
|
-
if (!lineText || character >= lineText.length) return null
|
|
149
|
-
|
|
150
|
-
// Extract word at position
|
|
151
|
-
const wordMatch = /\b\w+\b/g
|
|
152
|
-
let match
|
|
153
|
-
while ((match = wordMatch.exec(lineText)) !== null) {
|
|
154
|
-
if (match.index <= character && match.index + match[0].length >= character) {
|
|
155
|
-
return match[0]
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return null
|
|
160
|
-
} catch {
|
|
161
|
-
return null
|
|
162
|
-
}
|
|
163
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Resource Tools
|
|
3
|
-
*
|
|
4
|
-
* ListMcpResources / ReadMcpResource - Access resources from MCP servers.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { ToolDefinition, ToolResult } from '../types.js'
|
|
8
|
-
import type { MCPConnection } from '../mcp/client.js'
|
|
9
|
-
|
|
10
|
-
// Registry of MCP connections (set by the agent)
|
|
11
|
-
let mcpConnections: MCPConnection[] = []
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Set MCP connections for resource access.
|
|
15
|
-
*/
|
|
16
|
-
export function setMcpConnections(connections: MCPConnection[]): void {
|
|
17
|
-
mcpConnections = connections
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const ListMcpResourcesTool: ToolDefinition = {
|
|
21
|
-
name: 'ListMcpResources',
|
|
22
|
-
description: 'List available resources from connected MCP servers. Resources can include files, databases, and other data sources.',
|
|
23
|
-
inputSchema: {
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: {
|
|
26
|
-
server: { type: 'string', description: 'Filter by MCP server name' },
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
isReadOnly: () => true,
|
|
30
|
-
isConcurrencySafe: () => true,
|
|
31
|
-
isEnabled: () => true,
|
|
32
|
-
async prompt() { return 'List MCP resources.' },
|
|
33
|
-
async call(input: any): Promise<ToolResult> {
|
|
34
|
-
const connections = input.server
|
|
35
|
-
? mcpConnections.filter(c => c.name === input.server)
|
|
36
|
-
: mcpConnections
|
|
37
|
-
|
|
38
|
-
if (connections.length === 0) {
|
|
39
|
-
return {
|
|
40
|
-
type: 'tool_result',
|
|
41
|
-
tool_use_id: '',
|
|
42
|
-
content: 'No MCP servers connected.',
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const results: string[] = []
|
|
47
|
-
|
|
48
|
-
for (const conn of connections) {
|
|
49
|
-
if (conn.status !== 'connected') continue
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
// Access the underlying client to list resources
|
|
53
|
-
const resources = (conn as any)._client?.listResources?.()
|
|
54
|
-
if (resources) {
|
|
55
|
-
results.push(`Server: ${conn.name}`)
|
|
56
|
-
for (const r of resources) {
|
|
57
|
-
results.push(` - ${r.name}: ${r.description || r.uri || ''}`)
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
results.push(`Server: ${conn.name} (${conn.tools.length} tools available)`)
|
|
61
|
-
}
|
|
62
|
-
} catch {
|
|
63
|
-
results.push(`Server: ${conn.name} (resource listing not supported)`)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
type: 'tool_result',
|
|
69
|
-
tool_use_id: '',
|
|
70
|
-
content: results.join('\n') || 'No resources found.',
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const ReadMcpResourceTool: ToolDefinition = {
|
|
76
|
-
name: 'ReadMcpResource',
|
|
77
|
-
description: 'Read a specific resource from an MCP server.',
|
|
78
|
-
inputSchema: {
|
|
79
|
-
type: 'object',
|
|
80
|
-
properties: {
|
|
81
|
-
server: { type: 'string', description: 'MCP server name' },
|
|
82
|
-
uri: { type: 'string', description: 'Resource URI to read' },
|
|
83
|
-
},
|
|
84
|
-
required: ['server', 'uri'],
|
|
85
|
-
},
|
|
86
|
-
isReadOnly: () => true,
|
|
87
|
-
isConcurrencySafe: () => true,
|
|
88
|
-
isEnabled: () => true,
|
|
89
|
-
async prompt() { return 'Read an MCP resource.' },
|
|
90
|
-
async call(input: any): Promise<ToolResult> {
|
|
91
|
-
const conn = mcpConnections.find(c => c.name === input.server)
|
|
92
|
-
if (!conn) {
|
|
93
|
-
return {
|
|
94
|
-
type: 'tool_result',
|
|
95
|
-
tool_use_id: '',
|
|
96
|
-
content: `MCP server not found: ${input.server}`,
|
|
97
|
-
is_error: true,
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
const result = await (conn as any)._client?.readResource?.({ uri: input.uri })
|
|
103
|
-
if (result?.contents) {
|
|
104
|
-
const texts = result.contents.map((c: any) => c.text || JSON.stringify(c)).join('\n')
|
|
105
|
-
return {
|
|
106
|
-
type: 'tool_result',
|
|
107
|
-
tool_use_id: '',
|
|
108
|
-
content: texts,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
type: 'tool_result',
|
|
113
|
-
tool_use_id: '',
|
|
114
|
-
content: 'Resource read returned no content.',
|
|
115
|
-
}
|
|
116
|
-
} catch (err: any) {
|
|
117
|
-
return {
|
|
118
|
-
type: 'tool_result',
|
|
119
|
-
tool_use_id: '',
|
|
120
|
-
content: `Error reading resource: ${err.message}`,
|
|
121
|
-
is_error: true,
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NotebookEditTool - Edit Jupyter notebooks
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { readFile, writeFile } from 'fs/promises'
|
|
6
|
-
import { resolve } from 'path'
|
|
7
|
-
import { defineTool } from './types.js'
|
|
8
|
-
|
|
9
|
-
export const NotebookEditTool = defineTool({
|
|
10
|
-
name: 'NotebookEdit',
|
|
11
|
-
description: 'Edit Jupyter notebook (.ipynb) cells. Can insert, replace, or delete cells.',
|
|
12
|
-
inputSchema: {
|
|
13
|
-
type: 'object',
|
|
14
|
-
properties: {
|
|
15
|
-
file_path: {
|
|
16
|
-
type: 'string',
|
|
17
|
-
description: 'Path to the .ipynb file',
|
|
18
|
-
},
|
|
19
|
-
command: {
|
|
20
|
-
type: 'string',
|
|
21
|
-
enum: ['insert', 'replace', 'delete'],
|
|
22
|
-
description: 'The edit operation to perform',
|
|
23
|
-
},
|
|
24
|
-
cell_number: {
|
|
25
|
-
type: 'number',
|
|
26
|
-
description: 'Cell index (0-based) to operate on',
|
|
27
|
-
},
|
|
28
|
-
cell_type: {
|
|
29
|
-
type: 'string',
|
|
30
|
-
enum: ['code', 'markdown'],
|
|
31
|
-
description: 'Type of cell (for insert/replace)',
|
|
32
|
-
},
|
|
33
|
-
source: {
|
|
34
|
-
type: 'string',
|
|
35
|
-
description: 'Cell content (for insert/replace)',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
required: ['file_path', 'command', 'cell_number'],
|
|
39
|
-
},
|
|
40
|
-
isReadOnly: false,
|
|
41
|
-
isConcurrencySafe: false,
|
|
42
|
-
async call(input, context) {
|
|
43
|
-
const filePath = resolve(context.cwd, input.file_path)
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
const content = await readFile(filePath, 'utf-8')
|
|
47
|
-
const notebook = JSON.parse(content)
|
|
48
|
-
|
|
49
|
-
if (!notebook.cells || !Array.isArray(notebook.cells)) {
|
|
50
|
-
return { data: 'Error: Invalid notebook format', is_error: true }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const { command, cell_number, cell_type, source } = input
|
|
54
|
-
|
|
55
|
-
switch (command) {
|
|
56
|
-
case 'insert': {
|
|
57
|
-
const newCell = {
|
|
58
|
-
cell_type: cell_type || 'code',
|
|
59
|
-
source: (source || '').split('\n').map((l: string, i: number, arr: string[]) =>
|
|
60
|
-
i < arr.length - 1 ? l + '\n' : l
|
|
61
|
-
),
|
|
62
|
-
metadata: {},
|
|
63
|
-
...(cell_type !== 'markdown' ? { outputs: [], execution_count: null } : {}),
|
|
64
|
-
}
|
|
65
|
-
notebook.cells.splice(cell_number, 0, newCell)
|
|
66
|
-
break
|
|
67
|
-
}
|
|
68
|
-
case 'replace': {
|
|
69
|
-
if (cell_number >= notebook.cells.length) {
|
|
70
|
-
return { data: `Error: Cell ${cell_number} does not exist`, is_error: true }
|
|
71
|
-
}
|
|
72
|
-
notebook.cells[cell_number].source = (source || '').split('\n').map(
|
|
73
|
-
(l: string, i: number, arr: string[]) => i < arr.length - 1 ? l + '\n' : l
|
|
74
|
-
)
|
|
75
|
-
if (cell_type) notebook.cells[cell_number].cell_type = cell_type
|
|
76
|
-
break
|
|
77
|
-
}
|
|
78
|
-
case 'delete': {
|
|
79
|
-
if (cell_number >= notebook.cells.length) {
|
|
80
|
-
return { data: `Error: Cell ${cell_number} does not exist`, is_error: true }
|
|
81
|
-
}
|
|
82
|
-
notebook.cells.splice(cell_number, 1)
|
|
83
|
-
break
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
await writeFile(filePath, JSON.stringify(notebook, null, 1), 'utf-8')
|
|
88
|
-
return `Notebook ${command}: cell ${cell_number} in ${filePath}`
|
|
89
|
-
} catch (err: any) {
|
|
90
|
-
return { data: `Error: ${err.message}`, is_error: true }
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
})
|
package/src/tools/plan-tools.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plan Mode Tools
|
|
3
|
-
*
|
|
4
|
-
* EnterPlanMode / ExitPlanMode - Structured planning workflow.
|
|
5
|
-
* Allows the agent to enter a design/planning phase before execution.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { ToolDefinition, ToolResult } from '../types.js'
|
|
9
|
-
|
|
10
|
-
// Track plan mode state
|
|
11
|
-
let planModeActive = false
|
|
12
|
-
let currentPlan: string | null = null
|
|
13
|
-
|
|
14
|
-
export function isPlanModeActive(): boolean {
|
|
15
|
-
return planModeActive
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function getCurrentPlan(): string | null {
|
|
19
|
-
return currentPlan
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const EnterPlanModeTool: ToolDefinition = {
|
|
23
|
-
name: 'EnterPlanMode',
|
|
24
|
-
description: 'Enter plan/design mode for complex tasks. In plan mode, the agent focuses on designing the approach before executing.',
|
|
25
|
-
inputSchema: {
|
|
26
|
-
type: 'object',
|
|
27
|
-
properties: {},
|
|
28
|
-
},
|
|
29
|
-
isReadOnly: () => false,
|
|
30
|
-
isConcurrencySafe: () => false,
|
|
31
|
-
isEnabled: () => true,
|
|
32
|
-
async prompt() { return 'Enter plan mode for structured planning.' },
|
|
33
|
-
async call(): Promise<ToolResult> {
|
|
34
|
-
if (planModeActive) {
|
|
35
|
-
return {
|
|
36
|
-
type: 'tool_result',
|
|
37
|
-
tool_use_id: '',
|
|
38
|
-
content: 'Already in plan mode.',
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
planModeActive = true
|
|
43
|
-
currentPlan = null
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
type: 'tool_result',
|
|
47
|
-
tool_use_id: '',
|
|
48
|
-
content: 'Entered plan mode. Design your approach before executing. Use ExitPlanMode when the plan is ready.',
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const ExitPlanModeTool: ToolDefinition = {
|
|
54
|
-
name: 'ExitPlanMode',
|
|
55
|
-
description: 'Exit plan mode with a completed plan. The plan will be recorded and execution can proceed.',
|
|
56
|
-
inputSchema: {
|
|
57
|
-
type: 'object',
|
|
58
|
-
properties: {
|
|
59
|
-
plan: { type: 'string', description: 'The completed plan' },
|
|
60
|
-
approved: { type: 'boolean', description: 'Whether the plan is approved for execution' },
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
isReadOnly: () => false,
|
|
64
|
-
isConcurrencySafe: () => false,
|
|
65
|
-
isEnabled: () => true,
|
|
66
|
-
async prompt() { return 'Exit plan mode with a completed plan.' },
|
|
67
|
-
async call(input: any): Promise<ToolResult> {
|
|
68
|
-
if (!planModeActive) {
|
|
69
|
-
return {
|
|
70
|
-
type: 'tool_result',
|
|
71
|
-
tool_use_id: '',
|
|
72
|
-
content: 'Not in plan mode.',
|
|
73
|
-
is_error: true,
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
planModeActive = false
|
|
78
|
-
currentPlan = input.plan || null
|
|
79
|
-
|
|
80
|
-
const status = input.approved !== false ? 'approved' : 'pending approval'
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
type: 'tool_result',
|
|
84
|
-
tool_use_id: '',
|
|
85
|
-
content: `Plan mode exited. Plan status: ${status}.${currentPlan ? `\n\nPlan:\n${currentPlan}` : ''}`,
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
}
|