@nomyx/assistant
Version:
A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)
112 lines (100 loc) • 3.42 kB
text/typescript
import { promises as fs } from 'fs';
import { Tool, ActionContext, GenericToolSchema } from '../types/tool';
import { promisify } from 'util';
import { exec } from 'child_process';
const execPromise = promisify(exec);
export async function loadToolsFromFile(filePath: string): Promise<Tool[]> {
try {
const fileContent = await fs.readFile(filePath, 'utf-8');
const toolsData = JSON.parse(fileContent);
return Object.entries(toolsData).map(([name, data]: [string, any]) => loadToolFromJson(name, data));
} catch (error: unknown) {
console.error(`Error loading tools from ${filePath}:`, error);
throw new Error(`Failed to load tools from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
}
}
export function loadToolFromJson(name: string, toolData: any): Tool {
if (!isValidToolData(toolData)) {
throw new Error(`Invalid tool data for ${name}`);
}
const tool: Tool = {
name,
description: toolData.description,
execute: createExecuteFunction(toolData.code),
getSchema: (): GenericToolSchema => ({
name,
description: toolData.description,
parameters: {
type: 'object',
properties: {
...toolData.input_schema
}
}
}),
validate: createValidateFunction(toolData.input_schema)
};
return tool;
}
function isValidToolData(toolData: any): boolean {
return (
toolData &&
typeof toolData.description === 'string' &&
typeof toolData.code === 'string' &&
isValidSchema(toolData.input_schema) &&
isValidSchema(toolData.output_schema)
);
}
function isValidSchema(schema: any): boolean {
return (
schema &&
typeof schema === 'object'
);
}
function createExecuteFunction(code: string): (params: any, context: ActionContext) => Promise<any> {
return async (params: any, context: ActionContext) => {
try {
const func = new Function('params', 'context', 'execPromise', 'require', `
return (async () => {
${code}
})();
`);
return await func(params, context, execPromise, require);
} catch (error: unknown) {
console.error('Error executing tool:', error);
throw new Error(`Tool execution failed: ${error instanceof Error ? error.message : String(error)}`);
}
};
}
function createValidateFunction(inputSchema: any): (args: Record<string, any>) => boolean {
return (args: Record<string, any>): boolean => {
for (const [key, value] of Object.entries(args)) {
const paramSchema = inputSchema[key];
if (!paramSchema) {
console.error(`Unknown parameter: ${key}`);
return false;
}
if (!validateType(value, paramSchema)) {
console.error(`Invalid type for parameter ${key}. Expected ${paramSchema}, got ${typeof value}`);
return false;
}
}
return true;
};
}
function validateType(value: any, expectedType: string): boolean {
switch (expectedType) {
case 'string':
return typeof value === 'string';
case 'number':
return typeof value === 'number' && !isNaN(value);
case 'boolean':
return typeof value === 'boolean';
case 'array':
return Array.isArray(value);
case 'object':
return typeof value === 'object' && value !== null && !Array.isArray(value);
default:
console.warn(`Unknown type for validation: ${expectedType}`);
return true;
}
}