opencode-toolbox 0.4.0 → 0.5.1
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 +153 -7
- package/dist/index.js +166 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ Create `~/.config/opencode/toolbox.jsonc`:
|
|
|
63
63
|
|
|
64
64
|
## Usage
|
|
65
65
|
|
|
66
|
-
The plugin exposes
|
|
66
|
+
The plugin exposes four tools:
|
|
67
67
|
|
|
68
68
|
### toolbox_search_bm25
|
|
69
69
|
|
|
@@ -135,6 +135,86 @@ Toolbox: { "datetime": "2026-01-07T02:15:00+09:00", "timezone": "Asia/Tokyo" }
|
|
|
135
135
|
LLM: "The current time in Tokyo is 2:15 AM on January 7, 2026."
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
### toolbox_status
|
|
139
|
+
|
|
140
|
+
Get toolbox status including plugin health, MCP server connections, and tool counts:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
toolbox_status({})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Returns a comprehensive status object:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"plugin": {
|
|
151
|
+
"initialized": true,
|
|
152
|
+
"configPath": "/Users/username/.config/opencode/toolbox.jsonc",
|
|
153
|
+
"uptime": 123.45,
|
|
154
|
+
"searches": 23,
|
|
155
|
+
"executions": 15,
|
|
156
|
+
"successRate": "93%"
|
|
157
|
+
},
|
|
158
|
+
"servers": {
|
|
159
|
+
"total": 3,
|
|
160
|
+
"connected": 2,
|
|
161
|
+
"failed": 1,
|
|
162
|
+
"connecting": 0,
|
|
163
|
+
"connectionRatio": "2/3",
|
|
164
|
+
"details": [
|
|
165
|
+
{
|
|
166
|
+
"name": "time",
|
|
167
|
+
"status": "connected",
|
|
168
|
+
"type": "local",
|
|
169
|
+
"toolCount": 5,
|
|
170
|
+
"error": null,
|
|
171
|
+
"healthy": true
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "github",
|
|
175
|
+
"status": "connected",
|
|
176
|
+
"type": "local",
|
|
177
|
+
"toolCount": 12,
|
|
178
|
+
"error": null,
|
|
179
|
+
"healthy": true
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "weather",
|
|
183
|
+
"status": "error",
|
|
184
|
+
"type": "remote",
|
|
185
|
+
"toolCount": 0,
|
|
186
|
+
"error": "Failed to connect: timeout",
|
|
187
|
+
"healthy": false
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"tools": {
|
|
192
|
+
"total": 17,
|
|
193
|
+
"available": 17,
|
|
194
|
+
"serversWithTools": 2
|
|
195
|
+
},
|
|
196
|
+
"health": {
|
|
197
|
+
"status": "degraded",
|
|
198
|
+
"message": "1 server(s) failed to connect"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Health Status:**
|
|
204
|
+
- `healthy`: All servers connected successfully
|
|
205
|
+
- `degraded`: Some servers failed to connect (check `servers.failed`)
|
|
206
|
+
- `unknown`: No servers configured or initialization failed
|
|
207
|
+
|
|
208
|
+
### /toolbox-status Slash Command
|
|
209
|
+
|
|
210
|
+
The plugin automatically creates a `/toolbox-status` slash command on first launch:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
~/.config/opencode/command/toolbox-status.md
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Use it in OpenCode by typing `/toolbox-status` to get a formatted status report.
|
|
217
|
+
|
|
138
218
|
## Search Modes
|
|
139
219
|
|
|
140
220
|
### BM25 (Natural Language)
|
|
@@ -172,13 +252,69 @@ bun test --coverage # Run with coverage
|
|
|
172
252
|
bun run build
|
|
173
253
|
```
|
|
174
254
|
|
|
255
|
+
## Observability
|
|
256
|
+
|
|
257
|
+
The toolbox plugin provides built-in logging and status monitoring to help you understand what's happening.
|
|
258
|
+
|
|
259
|
+
### Logging
|
|
260
|
+
|
|
261
|
+
All plugin operations are logged **silently** to a dedicated log file (no screen output):
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
~/.local/share/opencode/toolbox.log
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Log entries include:
|
|
268
|
+
- Plugin initialization status
|
|
269
|
+
- MCP server connection status (connected/error)
|
|
270
|
+
- Tool search operations (BM25/regex queries + result counts)
|
|
271
|
+
- Tool execution results (success/failure with duration)
|
|
272
|
+
- Errors with details
|
|
273
|
+
|
|
274
|
+
**View logs:**
|
|
275
|
+
```bash
|
|
276
|
+
# Watch logs in real-time
|
|
277
|
+
tail -f ~/.local/share/opencode/toolbox.log
|
|
278
|
+
|
|
279
|
+
# Check for errors only
|
|
280
|
+
grep "ERROR" ~/.local/share/opencode/toolbox.log
|
|
281
|
+
|
|
282
|
+
# Check for warnings
|
|
283
|
+
grep "WARN" ~/.local/share/opencode/toolbox.log
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Log format:**
|
|
287
|
+
```
|
|
288
|
+
2026-01-08T12:34:56.789Z [INFO] Toolbox plugin loaded successfully {"configPath":"...","serverCount":6}
|
|
289
|
+
2026-01-08T12:34:57.123Z [INFO] Initialization complete: 5/6 servers connected, 42 tools indexed
|
|
290
|
+
2026-01-08T12:34:57.124Z [WARN] 1 server(s) failed to connect: weather
|
|
291
|
+
2026-01-08T12:35:00.456Z [INFO] BM25 search completed: "web search" -> 3 results
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Status Tool
|
|
295
|
+
|
|
296
|
+
Use the `toolbox_status` command to check plugin health at any time:
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
toolbox_status({})
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
This shows:
|
|
303
|
+
- **Plugin Status**: Initialization, config path, uptime, search/execution counts
|
|
304
|
+
- **Server Status**: Connection ratio (e.g., "2/3"), details per server
|
|
305
|
+
- **Tools**: Total available tools, servers with tools
|
|
306
|
+
- **Health**: Overall health status (healthy/degraded/unknown)
|
|
307
|
+
|
|
308
|
+
**Connection Ratio**: Shows `success/total` for servers. If `success < total`, it indicates failed connections.
|
|
309
|
+
|
|
175
310
|
## Troubleshooting
|
|
176
311
|
|
|
177
312
|
### Plugin not loading
|
|
178
313
|
|
|
179
|
-
1.
|
|
180
|
-
2.
|
|
181
|
-
3.
|
|
314
|
+
1. Run `toolbox_status({})` to check initialization status
|
|
315
|
+
2. Check OpenCode logs at `~/.local/share/opencode/log/` for plugin errors
|
|
316
|
+
3. Verify `opencode-toolbox` is in the `plugin` array in `opencode.jsonc`
|
|
317
|
+
4. Ensure `toolbox.jsonc` exists and is valid JSON
|
|
182
318
|
|
|
183
319
|
### Search finds no tools
|
|
184
320
|
|
|
@@ -186,11 +322,21 @@ bun run build
|
|
|
186
322
|
2. Check tool descriptions for relevant keywords
|
|
187
323
|
3. Try broader search terms or regex patterns
|
|
188
324
|
|
|
325
|
+
### MCP servers not connecting
|
|
326
|
+
|
|
327
|
+
1. Run `toolbox_status({})` to see which servers failed
|
|
328
|
+
2. Check logs for specific error messages from failed servers
|
|
329
|
+
3. Verify server command works standalone: `npx -y @anthropic/mcp-time`
|
|
330
|
+
4. For remote servers, verify URL is accessible
|
|
331
|
+
5. Check environment variables are set correctly
|
|
332
|
+
|
|
189
333
|
### Execute fails
|
|
190
334
|
|
|
191
|
-
1.
|
|
192
|
-
2.
|
|
193
|
-
3.
|
|
335
|
+
1. Run `toolbox_status({})` to check server health
|
|
336
|
+
2. Verify tool name format: `serverName_toolName`
|
|
337
|
+
3. Check `arguments` is valid JSON
|
|
338
|
+
4. Ensure underlying MCP server is running and connected
|
|
339
|
+
5. Check logs for detailed error messages
|
|
194
340
|
|
|
195
341
|
## License
|
|
196
342
|
|
package/dist/index.js
CHANGED
|
@@ -19266,6 +19266,9 @@ function tool(input) {
|
|
|
19266
19266
|
return input;
|
|
19267
19267
|
}
|
|
19268
19268
|
tool.schema = exports_external;
|
|
19269
|
+
// src/plugin.ts
|
|
19270
|
+
import { appendFile, mkdir, writeFile, access } from "fs/promises";
|
|
19271
|
+
|
|
19269
19272
|
// node_modules/zod/v4/classic/external.js
|
|
19270
19273
|
var exports_external2 = {};
|
|
19271
19274
|
__export(exports_external2, {
|
|
@@ -37910,6 +37913,16 @@ function generateSignature(tool3) {
|
|
|
37910
37913
|
}
|
|
37911
37914
|
// src/plugin.ts
|
|
37912
37915
|
var DEFAULT_CONFIG_PATH = `${process.env.HOME}/.config/opencode/toolbox.jsonc`;
|
|
37916
|
+
var LOG_FILE_PATH = `${process.env.HOME}/.local/share/opencode/toolbox.log`;
|
|
37917
|
+
var LOG_DIR = `${process.env.HOME}/.local/share/opencode`;
|
|
37918
|
+
var COMMAND_DIR = `${process.env.HOME}/.config/opencode/command`;
|
|
37919
|
+
var COMMAND_FILE_PATH = `${COMMAND_DIR}/toolbox-status.md`;
|
|
37920
|
+
var COMMAND_CONTENT = `---
|
|
37921
|
+
description: Check toolbox plugin status and server health
|
|
37922
|
+
---
|
|
37923
|
+
Run toolbox_status({}) tool and show me the results in a readable format.
|
|
37924
|
+
Highlight any failed servers or issues.
|
|
37925
|
+
`;
|
|
37913
37926
|
function parseToolName(fullName) {
|
|
37914
37927
|
const underscoreIndex = fullName.indexOf("_");
|
|
37915
37928
|
if (underscoreIndex === -1) {
|
|
@@ -37948,12 +37961,29 @@ Returns tools with schemas. Use toolbox_execute() to run them.`;
|
|
|
37948
37961
|
var EXECUTE_DESC = `Execute a tool discovered via toolbox_search_bm25 or toolbox_search_regex.
|
|
37949
37962
|
|
|
37950
37963
|
Pass arguments as JSON string matching the tool's schema.`;
|
|
37964
|
+
var STATUS_DESC = `Get toolbox status including plugin initialization, MCP server connections, and tool counts.
|
|
37965
|
+
|
|
37966
|
+
Shows success/total metrics to highlight failures. Use to check if toolbox is working correctly.`;
|
|
37967
|
+
function log(level, message, extra) {
|
|
37968
|
+
const timestamp = new Date().toISOString();
|
|
37969
|
+
const extraStr = extra ? ` ${JSON.stringify(extra)}` : "";
|
|
37970
|
+
const line = `${timestamp} [${level.toUpperCase()}] ${message}${extraStr}
|
|
37971
|
+
`;
|
|
37972
|
+
mkdir(LOG_DIR, { recursive: true }).then(() => appendFile(LOG_FILE_PATH, line)).catch(() => {});
|
|
37973
|
+
}
|
|
37974
|
+
function ensureCommandFile() {
|
|
37975
|
+
access(COMMAND_FILE_PATH).catch(() => {
|
|
37976
|
+
mkdir(COMMAND_DIR, { recursive: true }).then(() => writeFile(COMMAND_FILE_PATH, COMMAND_CONTENT)).then(() => log("info", "Created /toolbox-status command file")).catch(() => {});
|
|
37977
|
+
});
|
|
37978
|
+
}
|
|
37951
37979
|
var SYSTEM_PROMPT_BASE = `# Extended Toolbox
|
|
37952
37980
|
|
|
37953
37981
|
You have access to an extended toolbox with additional capabilities (web search, time utilities, code search, etc.).
|
|
37954
37982
|
|
|
37955
37983
|
## Rule
|
|
37956
37984
|
ALWAYS search before saying "I cannot do that" or "I don't have access to."
|
|
37985
|
+
DO NOT try to execute a tool without having the tool's exact tool schema. If you don't have the tool's schema
|
|
37986
|
+
then run toolbox_search_* to get them.
|
|
37957
37987
|
|
|
37958
37988
|
## Workflow
|
|
37959
37989
|
1. Search: toolbox_search_bm25({ text: "what you need" }) or toolbox_search_regex({ pattern: "prefix_.*" })
|
|
@@ -37981,26 +38011,60 @@ ${JSON.stringify(toolboxSchema, null, 2)}
|
|
|
37981
38011
|
\`\`\``;
|
|
37982
38012
|
}
|
|
37983
38013
|
var ToolboxPlugin = async (ctx) => {
|
|
38014
|
+
const { client } = ctx;
|
|
37984
38015
|
const configPath = process.env.OPENCODE_TOOLBOX_CONFIG || DEFAULT_CONFIG_PATH;
|
|
37985
38016
|
const configResult = await loadConfig(configPath);
|
|
37986
38017
|
if (!configResult.success) {
|
|
37987
|
-
|
|
38018
|
+
const errorMsg = `Failed to load config from ${configPath}: ${configResult.error.issues.map((i) => i.message).join(", ")}`;
|
|
38019
|
+
log("error", errorMsg);
|
|
37988
38020
|
return {};
|
|
37989
38021
|
}
|
|
37990
38022
|
const config3 = configResult.data;
|
|
37991
38023
|
const mcpManager = new MCPManager;
|
|
37992
38024
|
const bm25Index = new BM25Index;
|
|
37993
38025
|
let initialized = false;
|
|
38026
|
+
let searchCount = 0;
|
|
38027
|
+
let executionCount = 0;
|
|
38028
|
+
let executionSuccessCount = 0;
|
|
38029
|
+
ensureCommandFile();
|
|
38030
|
+
const serverNames = Object.keys(config3.mcp);
|
|
38031
|
+
log("info", `Toolbox plugin loaded successfully`, {
|
|
38032
|
+
configPath,
|
|
38033
|
+
serverCount: serverNames.length,
|
|
38034
|
+
servers: serverNames
|
|
38035
|
+
});
|
|
37994
38036
|
async function ensureInitialized() {
|
|
37995
38037
|
if (initialized)
|
|
37996
38038
|
return;
|
|
37997
38039
|
try {
|
|
38040
|
+
log("info", "Initializing MCP servers...");
|
|
37998
38041
|
await mcpManager.initialize(config3.mcp);
|
|
37999
38042
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38000
38043
|
bm25Index.indexTools(allTools);
|
|
38001
38044
|
initialized = true;
|
|
38045
|
+
const servers = mcpManager.getAllServers();
|
|
38046
|
+
const connectedServers = servers.filter((s) => s.status === "connected");
|
|
38047
|
+
const failedServers = servers.filter((s) => s.status === "error");
|
|
38048
|
+
const initMsg = `Initialization complete: ${connectedServers.length}/${servers.length} servers connected, ${allTools.length} tools indexed`;
|
|
38049
|
+
log("info", initMsg, {
|
|
38050
|
+
totalServers: servers.length,
|
|
38051
|
+
connectedServers: connectedServers.length,
|
|
38052
|
+
failedServers: failedServers.length,
|
|
38053
|
+
totalTools: allTools.length,
|
|
38054
|
+
servers: servers.map((s) => ({
|
|
38055
|
+
name: s.name,
|
|
38056
|
+
status: s.status,
|
|
38057
|
+
toolCount: s.tools.length,
|
|
38058
|
+
error: s.error || null
|
|
38059
|
+
}))
|
|
38060
|
+
});
|
|
38061
|
+
if (failedServers.length > 0) {
|
|
38062
|
+
const warnMsg = `${failedServers.length} server(s) failed to connect: ${failedServers.map((s) => s.name).join(", ")}`;
|
|
38063
|
+
log("warn", warnMsg);
|
|
38064
|
+
}
|
|
38002
38065
|
} catch (error92) {
|
|
38003
|
-
|
|
38066
|
+
const errorMsg = `Failed to initialize MCP servers: ${error92 instanceof Error ? error92.message : String(error92)}`;
|
|
38067
|
+
log("error", errorMsg);
|
|
38004
38068
|
throw error92;
|
|
38005
38069
|
}
|
|
38006
38070
|
}
|
|
@@ -38021,9 +38085,16 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38021
38085
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38022
38086
|
});
|
|
38023
38087
|
}
|
|
38088
|
+
searchCount++;
|
|
38024
38089
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38025
38090
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38026
38091
|
const results = bm25Index.search(args.text, searchLimit);
|
|
38092
|
+
log("info", `BM25 search completed: "${args.text}" -> ${results.length} results`, {
|
|
38093
|
+
searchType: "bm25",
|
|
38094
|
+
query: args.text,
|
|
38095
|
+
resultsCount: results.length,
|
|
38096
|
+
limit: searchLimit
|
|
38097
|
+
});
|
|
38027
38098
|
return formatSearchResults(results, allTools);
|
|
38028
38099
|
}
|
|
38029
38100
|
}),
|
|
@@ -38042,15 +38113,23 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38042
38113
|
error: `Failed to initialize: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38043
38114
|
});
|
|
38044
38115
|
}
|
|
38116
|
+
searchCount++;
|
|
38045
38117
|
const searchLimit = args.limit || config3.settings?.defaultLimit || 5;
|
|
38046
38118
|
const allTools = mcpManager.getAllCatalogTools();
|
|
38047
38119
|
const result = searchWithRegex(allTools, args.pattern, searchLimit);
|
|
38048
38120
|
if ("error" in result) {
|
|
38121
|
+
log("warn", `Regex search failed: "${args.pattern}" -> ${result.error}`);
|
|
38049
38122
|
return JSON.stringify({
|
|
38050
38123
|
success: false,
|
|
38051
38124
|
error: result.error
|
|
38052
38125
|
});
|
|
38053
38126
|
}
|
|
38127
|
+
log("info", `Regex search completed: "${args.pattern}" -> ${result.length} results`, {
|
|
38128
|
+
searchType: "regex",
|
|
38129
|
+
pattern: args.pattern,
|
|
38130
|
+
resultsCount: result.length,
|
|
38131
|
+
limit: searchLimit
|
|
38132
|
+
});
|
|
38054
38133
|
return formatSearchResults(result, allTools);
|
|
38055
38134
|
}
|
|
38056
38135
|
}),
|
|
@@ -38071,6 +38150,9 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38071
38150
|
}
|
|
38072
38151
|
const parsed = parseToolName(args.name);
|
|
38073
38152
|
if (!parsed) {
|
|
38153
|
+
log("warn", `Invalid tool name format: ${args.name}`, {
|
|
38154
|
+
toolName: args.name
|
|
38155
|
+
});
|
|
38074
38156
|
return JSON.stringify({
|
|
38075
38157
|
success: false,
|
|
38076
38158
|
error: `Invalid tool name format: ${args.name}. Expected format: serverName_toolName (e.g., 'time_get_current_time')`
|
|
@@ -38081,25 +38163,106 @@ var ToolboxPlugin = async (ctx) => {
|
|
|
38081
38163
|
try {
|
|
38082
38164
|
toolArgs = JSON.parse(args.arguments);
|
|
38083
38165
|
} catch (error92) {
|
|
38166
|
+
log("warn", `Failed to parse arguments as JSON for ${args.name}`, {
|
|
38167
|
+
toolName: args.name,
|
|
38168
|
+
arguments: args.arguments
|
|
38169
|
+
});
|
|
38084
38170
|
return JSON.stringify({
|
|
38085
38171
|
success: false,
|
|
38086
38172
|
error: `Failed to parse arguments as JSON: ${error92 instanceof Error ? error92.message : String(error92)}`
|
|
38087
38173
|
});
|
|
38088
38174
|
}
|
|
38089
38175
|
}
|
|
38176
|
+
executionCount++;
|
|
38090
38177
|
try {
|
|
38178
|
+
const startTime = Date.now();
|
|
38091
38179
|
const result = await mcpManager.callTool(parsed.serverName, parsed.toolName, toolArgs);
|
|
38180
|
+
const duration5 = Date.now() - startTime;
|
|
38181
|
+
executionSuccessCount++;
|
|
38182
|
+
log("info", `Tool executed successfully: ${args.name}`, {
|
|
38183
|
+
server: parsed.serverName,
|
|
38184
|
+
tool: parsed.toolName,
|
|
38185
|
+
durationMs: duration5
|
|
38186
|
+
});
|
|
38092
38187
|
return JSON.stringify({
|
|
38093
38188
|
success: true,
|
|
38094
38189
|
result
|
|
38095
38190
|
});
|
|
38096
38191
|
} catch (error92) {
|
|
38192
|
+
const errorMsg = `Tool execution failed: ${error92 instanceof Error ? error92.message : String(error92)}`;
|
|
38193
|
+
log("error", errorMsg, {
|
|
38194
|
+
server: parsed.serverName,
|
|
38195
|
+
tool: parsed.toolName,
|
|
38196
|
+
error: errorMsg
|
|
38197
|
+
});
|
|
38097
38198
|
return JSON.stringify({
|
|
38098
38199
|
success: false,
|
|
38099
|
-
error:
|
|
38200
|
+
error: errorMsg
|
|
38100
38201
|
});
|
|
38101
38202
|
}
|
|
38102
38203
|
}
|
|
38204
|
+
}),
|
|
38205
|
+
toolbox_status: tool({
|
|
38206
|
+
description: STATUS_DESC,
|
|
38207
|
+
args: {},
|
|
38208
|
+
async execute() {
|
|
38209
|
+
if (!initialized) {
|
|
38210
|
+
try {
|
|
38211
|
+
await ensureInitialized();
|
|
38212
|
+
} catch (error92) {
|
|
38213
|
+
return JSON.stringify({
|
|
38214
|
+
status: "error",
|
|
38215
|
+
message: "Failed to initialize toolbox",
|
|
38216
|
+
error: error92 instanceof Error ? error92.message : String(error92)
|
|
38217
|
+
});
|
|
38218
|
+
}
|
|
38219
|
+
}
|
|
38220
|
+
const servers = mcpManager.getAllServers();
|
|
38221
|
+
const connectedServers = servers.filter((s) => s.status === "connected");
|
|
38222
|
+
const failedServers = servers.filter((s) => s.status === "error");
|
|
38223
|
+
const connectingServers = servers.filter((s) => s.status === "connecting");
|
|
38224
|
+
const totalTools = mcpManager.getAllCatalogTools().length;
|
|
38225
|
+
const status = {
|
|
38226
|
+
plugin: {
|
|
38227
|
+
initialized: true,
|
|
38228
|
+
configPath,
|
|
38229
|
+
uptime: process.uptime(),
|
|
38230
|
+
searches: searchCount,
|
|
38231
|
+
executions: executionCount,
|
|
38232
|
+
successRate: executionCount > 0 ? `${Math.round(executionSuccessCount / executionCount * 100)}%` : "N/A"
|
|
38233
|
+
},
|
|
38234
|
+
servers: {
|
|
38235
|
+
total: servers.length,
|
|
38236
|
+
connected: connectedServers.length,
|
|
38237
|
+
failed: failedServers.length,
|
|
38238
|
+
connecting: connectingServers.length,
|
|
38239
|
+
connectionRatio: `${connectedServers.length}/${servers.length}`,
|
|
38240
|
+
details: servers.map((server) => ({
|
|
38241
|
+
name: server.name,
|
|
38242
|
+
status: server.status,
|
|
38243
|
+
type: server.config.type,
|
|
38244
|
+
toolCount: server.tools.length,
|
|
38245
|
+
error: server.error || null,
|
|
38246
|
+
healthy: server.status === "connected"
|
|
38247
|
+
}))
|
|
38248
|
+
},
|
|
38249
|
+
tools: {
|
|
38250
|
+
total: totalTools,
|
|
38251
|
+
available: totalTools,
|
|
38252
|
+
serversWithTools: servers.filter((s) => s.tools.length > 0).length
|
|
38253
|
+
},
|
|
38254
|
+
health: {
|
|
38255
|
+
status: failedServers.length === 0 && servers.length > 0 ? "healthy" : failedServers.length > 0 ? "degraded" : "unknown",
|
|
38256
|
+
message: servers.length === 0 ? "No servers configured" : failedServers.length === 0 ? "All servers connected" : `${failedServers.length} server(s) failed to connect`
|
|
38257
|
+
}
|
|
38258
|
+
};
|
|
38259
|
+
log("info", `Status requested: ${connectedServers.length}/${servers.length} servers connected`, {
|
|
38260
|
+
connectedServers: connectedServers.length,
|
|
38261
|
+
totalServers: servers.length,
|
|
38262
|
+
totalTools
|
|
38263
|
+
});
|
|
38264
|
+
return JSON.stringify(status, null, 2);
|
|
38265
|
+
}
|
|
38103
38266
|
})
|
|
38104
38267
|
},
|
|
38105
38268
|
"experimental.chat.system.transform": async (_input, output) => {
|
package/package.json
CHANGED