dist / toolsProvider.js
dist / toolsProvider.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeTool = executeTool;
exports.toolsProvider = toolsProvider;
// src/toolsProvider.ts
const sdk_1 = require("@lmstudio/sdk");
const zod_1 = require("zod");
const fileTools_1 = require("./tools/fileTools");
const memoryTools_1 = require("./tools/memoryTools");
const systemTools_1 = require("./tools/systemTools");
const webTools_1 = require("./tools/webTools");
const excelTools_1 = require("./tools/excelTools");
// ============================================================
// SERVER REGISTRY — 4 Cognitive Arms
// ============================================================
const SERVERS = {
core: "http://127.0.0.1:6075", // Unified Server (31 tools)
code: "http://127.0.0.1:6041", // Code Server (13 tools)
terminal: "http://127.0.0.1:6090", // Terminal Server (8 tools)
memory: "http://127.0.0.1:5077", // Memory Server (3 tools)
};
// ============================================================
// TOOL ALIASES — Normalize model's notations
// ============================================================
const TOOL_ALIASES = {
// Time
getNow: "getTime",
getCurrentTime: "getTime",
getCurrentDate: "getDate",
// Files
deleteFile: "moveToTrash",
listFolder: "listFiles",
appendFile: "appendToFile",
// Code
runCode: "runPythonScript",
// Terminal
terminal: "exec",
// Memory
semanticMemory: "semanticSearch",
memory_search: "semanticSearch",
// Compatibility with local names
read_file: "readFile",
write_file: "writeFile",
list_folder: "listFiles",
};
// ============================================================
// CATALOG CACHE
// ============================================================
let cachedCatalog = null;
let cachedToolToServer = new Map();
let catalogPromise = null;
async function refreshCatalog() {
if (cachedCatalog)
return;
if (catalogPromise)
return catalogPromise;
catalogPromise = (async () => {
const fetchServer = async (name, url) => {
try {
const res = await fetch(`${url}/tools`, { signal: AbortSignal.timeout(2000) });
if (!res.ok)
return [];
const data = await res.json();
return Object.entries(data.descriptions || {}).map(([toolName, details]) => ({
name: toolName,
description: details.description,
server: name,
}));
}
catch {
console.warn(`[Catalog] Server '${name}' unreachable`);
return [];
}
};
const results = await Promise.all(Object.entries(SERVERS).map(([n, u]) => fetchServer(n, u)));
cachedCatalog = results.flat();
cachedToolToServer = new Map();
for (const entry of cachedCatalog) {
if (entry.server)
cachedToolToServer.set(entry.name, entry.server);
}
console.info(`[Catalog] Cached ${cachedCatalog.length} tools from ${Object.keys(SERVERS).length} servers`);
})();
return catalogPromise;
}
function getServerForTool(toolName) {
return cachedToolToServer.get(toolName) || null;
}
// ============================================================
// EXECUTE VIA SERVER
// ============================================================
async function executeViaServer(toolName, params) {
const serverName = getServerForTool(toolName);
if (!serverName)
return null;
try {
const res = await fetch(`${SERVERS[serverName]}/tool/${encodeURIComponent(toolName)}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params || {}),
signal: AbortSignal.timeout(10000),
});
if (!res.ok)
return null;
const data = await res.json();
if (data.status === "success" || data.success) {
return { success: true, ...data, source: `server_${serverName}` };
}
}
catch (err) {
console.warn(`[Server] ${serverName}/${toolName}: ${err.message}`);
}
return null;
}
// ============================================================
// EXECUTE LOCALLY — Fallback
// ============================================================
async function executeLocally(toolName, params) {
let result = await (0, systemTools_1.executeSystemTool)(toolName, params);
if (result)
return result;
result = await (0, fileTools_1.executeFileTool)(toolName, params);
if (result)
return result;
result = await (0, memoryTools_1.executeMemoryTool)(toolName, params);
if (result)
return result;
result = await (0, webTools_1.executeWebTool)(toolName, params);
if (result)
return result;
result = await (0, excelTools_1.executeExcelTool)(toolName, params);
if (result)
return result;
return null;
}
// ============================================================
// EXECUTE TOOL — Main dispatcher
// ============================================================
async function executeTool(rawToolName, args = {}) {
const toolName = TOOL_ALIASES[rawToolName] || rawToolName;
// 1. Try remote servers first
const serverResult = await executeViaServer(toolName, args);
if (serverResult)
return serverResult;
// 2. Local fallback
const localResult = await executeLocally(toolName, args);
if (localResult)
return localResult;
return { success: false, error: `Unknown tool: ${toolName}` };
}
// ============================================================
// TOOLS PROVIDER — Single Gateway
// ============================================================
async function toolsProvider() {
// Prime the catalog (non-blocking if fails)
try {
await refreshCatalog();
}
catch {
console.warn("[toolsProvider] Catalog refresh failed — gateway will still work");
}
return [
(0, sdk_1.tool)({
name: "bido_gateway",
description: `Execute any local tool by exact name.
## Core Tools (Server 6075)
getTime() | getDate() | readFile(path, full?) | writeFile(path, content) | appendToFile(path, content) | copyFile(from, to) | renameFile(from, to) | moveToTrash(path) | listFiles(path) | getFileInfo(path) | eagleEye(path, mode?) | listDirectoryStructure(path, depth?) | makeDirectory(path) | copyDirectory(from, to) | renameDirectory(from, to) | searchFiles(path, query, type) | extractTextFromImage(image, language?) | runPythonScript(code, args?, timeout?) | createDynamicTool(name, language, code, description) | runDynamicTool(name, args?, timeout?) | semanticSearch(query, limit?) | saveSession(title, mainIdea, summary, rawContent, tags) | readRawSession(sessionId) | addMemory(namespace, content, tags) | getMemory(namespace, id?, tags?, limit?) | markAwareness(insight, tags, context) | recallAwareness(query?, tags?, limit?) | searchWeb(query, maxResults?) | fetchArticle(url, filename) | readConsciousness() | appendToDynamicPrompt(content)
## Code Tools (Server 6041)
readFileLines(path, start?, end?) | getFileOutline(path) | searchInFile(path, query, regex?, caseSensitive?, maxResults?) | readFileWindow(path, line, context?) | replaceLines(path, start, end, content) | insertAtLine(path, line, content, before?) | deleteLines(path, start, end) | replaceInFile(path, find, replace, regex?, all?) | replaceBlock(path, newContent, startTag?, endTag?, occurrence?) | findSymbols(path, type?) | findReferences(symbol, path?, maxResults?) | getDependencies(path) | codeStats(path?)
## Terminal Tools (Server 6090)
exec(cmd, cwd?, timeout?) | health() | history() | download(url, output?) | listPorts() | killProcess(pid, force?) | which(cmd) | env()
## Memory Tools (Server 5077)
semanticSearch(query, limit?) | saveSession(title, mainIdea, summary, rawContent, tags) | readRawSession(sessionId)
## Local Fallback Tools (always available)
readFile(file) | writeFile(file, content) | appendFile(file, content) | deleteFile(file) | copyFile(source, destination) | renameFile(oldName, newName) | listFolder(folder) | createFolder(folder) | searchFiles(query, searchPath?, searchType?) | getNow() | terminal(cmd, cwd?) | runCode(code, language?) | eagleEye(file) | ocrImage(imagePath, language?) | saveSession(title, summary, tags?) | getMemory(query) | semanticMemory(query) | markAwareness(insight) | recallAwareness(query?) | searchWeb(query, maxResults?) | fetchArticle(url) | readExcelSheet(file, sheet?) | appendExcelRow(file, sheet?, row)
## Rules
- Use the EXACT tool name from the lists above.
- Pass all parameters as a JSON object.
- If a tool is in both a server and the local fallback, the server takes priority.
- If you're unsure which tool to use, choose the closest name match.`,
parameters: {
tool: zod_1.z.string().describe("Exact tool name (case-sensitive)"),
params: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional().describe("Tool parameters as JSON object"),
},
implementation: async ({ tool: toolName, params }) => {
const result = await executeTool(toolName, params || {});
return typeof result === "object" ? JSON.stringify(result, null, 2) : String(result);
},
}),
];
}
//# sourceMappingURL=toolsProvider.js.map"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeTool = executeTool;
exports.toolsProvider = toolsProvider;
// src/toolsProvider.ts
const sdk_1 = require("@lmstudio/sdk");
const zod_1 = require("zod");
const fileTools_1 = require("./tools/fileTools");
const memoryTools_1 = require("./tools/memoryTools");
const systemTools_1 = require("./tools/systemTools");
const webTools_1 = require("./tools/webTools");
const excelTools_1 = require("./tools/excelTools");
// ============================================================
// SERVER REGISTRY — 4 Cognitive Arms
// ============================================================
const SERVERS = {
core: "http://127.0.0.1:6075", // Unified Server (31 tools)
code: "http://127.0.0.1:6041", // Code Server (13 tools)
terminal: "http://127.0.0.1:6090", // Terminal Server (8 tools)
memory: "http://127.0.0.1:5077", // Memory Server (3 tools)
};
// ============================================================
// TOOL ALIASES — Normalize model's notations
// ============================================================
const TOOL_ALIASES = {
// Time
getNow: "getTime",
getCurrentTime: "getTime",
getCurrentDate: "getDate",
// Files
deleteFile: "moveToTrash",
listFolder: "listFiles",
appendFile: "appendToFile",
// Code
runCode: "runPythonScript",
// Terminal
terminal: "exec",
// Memory
semanticMemory: "semanticSearch",
memory_search: "semanticSearch",
// Compatibility with local names
read_file: "readFile",
write_file: "writeFile",
list_folder: "listFiles",
};
// ============================================================
// CATALOG CACHE
// ============================================================
let cachedCatalog = null;
let cachedToolToServer = new Map();
let catalogPromise = null;
async function refreshCatalog() {
if (cachedCatalog)
return;
if (catalogPromise)
return catalogPromise;
catalogPromise = (async () => {
const fetchServer = async (name, url) => {
try {
const res = await fetch(`${url}/tools`, { signal: AbortSignal.timeout(2000) });
if (!res.ok)
return [];
const data = await res.json();
return Object.entries(data.descriptions || {}).map(([toolName, details]) => ({
name: toolName,
description: details.description,
server: name,
}));
}
catch {
console.warn(`[Catalog] Server '${name}' unreachable`);
return [];
}
};
const results = await Promise.all(Object.entries(SERVERS).map(([n, u]) => fetchServer(n, u)));
cachedCatalog = results.flat();
cachedToolToServer = new Map();
for (const entry of cachedCatalog) {
if (entry.server)
cachedToolToServer.set(entry.name, entry.server);
}
console.info(`[Catalog] Cached ${cachedCatalog.length} tools from ${Object.keys(SERVERS).length} servers`);
})();
return catalogPromise;
}
function getServerForTool(toolName) {
return cachedToolToServer.get(toolName) || null;
}
// ============================================================
// EXECUTE VIA SERVER
// ============================================================
async function executeViaServer(toolName, params) {
const serverName = getServerForTool(toolName);
if (!serverName)
return null;
try {
const res = await fetch(`${SERVERS[serverName]}/tool/${encodeURIComponent(toolName)}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params || {}),
signal: AbortSignal.timeout(10000),
});
if (!res.ok)
return null;
const data = await res.json();
if (data.status === "success" || data.success) {
return { success: true, ...data, source: `server_${serverName}` };
}
}
catch (err) {
console.warn(`[Server] ${serverName}/${toolName}: ${err.message}`);
}
return null;
}
// ============================================================
// EXECUTE LOCALLY — Fallback
// ============================================================
async function executeLocally(toolName, params) {
let result = await (0, systemTools_1.executeSystemTool)(toolName, params);
if (result)
return result;
result = await (0, fileTools_1.executeFileTool)(toolName, params);
if (result)
return result;
result = await (0, memoryTools_1.executeMemoryTool)(toolName, params);
if (result)
return result;
result = await (0, webTools_1.executeWebTool)(toolName, params);
if (result)
return result;
result = await (0, excelTools_1.executeExcelTool)(toolName, params);
if (result)
return result;
return null;
}
// ============================================================
// EXECUTE TOOL — Main dispatcher
// ============================================================
async function executeTool(rawToolName, args = {}) {
const toolName = TOOL_ALIASES[rawToolName] || rawToolName;
// 1. Try remote servers first
const serverResult = await executeViaServer(toolName, args);
if (serverResult)
return serverResult;
// 2. Local fallback
const localResult = await executeLocally(toolName, args);
if (localResult)
return localResult;
return { success: false, error: `Unknown tool: ${toolName}` };
}
// ============================================================
// TOOLS PROVIDER — Single Gateway
// ============================================================
async function toolsProvider() {
// Prime the catalog (non-blocking if fails)
try {
await refreshCatalog();
}
catch {
console.warn("[toolsProvider] Catalog refresh failed — gateway will still work");
}
return [
(0, sdk_1.tool)({
name: "bido_gateway",
description: `Execute any local tool by exact name.
## Core Tools (Server 6075)
getTime() | getDate() | readFile(path, full?) | writeFile(path, content) | appendToFile(path, content) | copyFile(from, to) | renameFile(from, to) | moveToTrash(path) | listFiles(path) | getFileInfo(path) | eagleEye(path, mode?) | listDirectoryStructure(path, depth?) | makeDirectory(path) | copyDirectory(from, to) | renameDirectory(from, to) | searchFiles(path, query, type) | extractTextFromImage(image, language?) | runPythonScript(code, args?, timeout?) | createDynamicTool(name, language, code, description) | runDynamicTool(name, args?, timeout?) | semanticSearch(query, limit?) | saveSession(title, mainIdea, summary, rawContent, tags) | readRawSession(sessionId) | addMemory(namespace, content, tags) | getMemory(namespace, id?, tags?, limit?) | markAwareness(insight, tags, context) | recallAwareness(query?, tags?, limit?) | searchWeb(query, maxResults?) | fetchArticle(url, filename) | readConsciousness() | appendToDynamicPrompt(content)
## Code Tools (Server 6041)
readFileLines(path, start?, end?) | getFileOutline(path) | searchInFile(path, query, regex?, caseSensitive?, maxResults?) | readFileWindow(path, line, context?) | replaceLines(path, start, end, content) | insertAtLine(path, line, content, before?) | deleteLines(path, start, end) | replaceInFile(path, find, replace, regex?, all?) | replaceBlock(path, newContent, startTag?, endTag?, occurrence?) | findSymbols(path, type?) | findReferences(symbol, path?, maxResults?) | getDependencies(path) | codeStats(path?)
## Terminal Tools (Server 6090)
exec(cmd, cwd?, timeout?) | health() | history() | download(url, output?) | listPorts() | killProcess(pid, force?) | which(cmd) | env()
## Memory Tools (Server 5077)
semanticSearch(query, limit?) | saveSession(title, mainIdea, summary, rawContent, tags) | readRawSession(sessionId)
## Local Fallback Tools (always available)
readFile(file) | writeFile(file, content) | appendFile(file, content) | deleteFile(file) | copyFile(source, destination) | renameFile(oldName, newName) | listFolder(folder) | createFolder(folder) | searchFiles(query, searchPath?, searchType?) | getNow() | terminal(cmd, cwd?) | runCode(code, language?) | eagleEye(file) | ocrImage(imagePath, language?) | saveSession(title, summary, tags?) | getMemory(query) | semanticMemory(query) | markAwareness(insight) | recallAwareness(query?) | searchWeb(query, maxResults?) | fetchArticle(url) | readExcelSheet(file, sheet?) | appendExcelRow(file, sheet?, row)
## Rules
- Use the EXACT tool name from the lists above.
- Pass all parameters as a JSON object.
- If a tool is in both a server and the local fallback, the server takes priority.
- If you're unsure which tool to use, choose the closest name match.`,
parameters: {
tool: zod_1.z.string().describe("Exact tool name (case-sensitive)"),
params: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional().describe("Tool parameters as JSON object"),
},
implementation: async ({ tool: toolName, params }) => {
const result = await executeTool(toolName, params || {});
return typeof result === "object" ? JSON.stringify(result, null, 2) : String(result);
},
}),
];
}
//# sourceMappingURL=toolsProvider.js.map