This commit is contained in:
Zacharias-Brohn
2026-01-14 22:51:46 +01:00
parent e222977f5c
commit c51b3c3fab
14 changed files with 452 additions and 216 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ export const calculatorTool: Tool = {
// Safe math evaluation using Function constructor with limited scope
function safeEvaluate(expression: string): number {
// Replace common math notation
let expr = expression
const expr = expression
.replace(/\^/g, '**') // Exponents
.replace(/sqrt/g, 'Math.sqrt')
.replace(/sin/g, 'Math.sin')
+6 -7
View File
@@ -44,9 +44,9 @@ export const codeExecutionHandler: ToolHandler = async (args): Promise<ToolResul
const logs: string[] = [];
const mockConsole = {
log: (...args: unknown[]) => logs.push(args.map(String).join(' ')),
error: (...args: unknown[]) => logs.push('[ERROR] ' + args.map(String).join(' ')),
warn: (...args: unknown[]) => logs.push('[WARN] ' + args.map(String).join(' ')),
info: (...args: unknown[]) => logs.push('[INFO] ' + args.map(String).join(' ')),
error: (...args: unknown[]) => logs.push(`[ERROR] ${args.map(String).join(' ')}`),
warn: (...args: unknown[]) => logs.push(`[WARN] ${args.map(String).join(' ')}`),
info: (...args: unknown[]) => logs.push(`[INFO] ${args.map(String).join(' ')}`),
};
// Create a sandboxed context with limited globals
@@ -87,7 +87,6 @@ export const codeExecutionHandler: ToolHandler = async (args): Promise<ToolResul
return fn.call(sandbox);
};
let result: unknown;
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error('Execution timed out')), timeoutMs);
});
@@ -100,15 +99,15 @@ export const codeExecutionHandler: ToolHandler = async (args): Promise<ToolResul
}
});
result = await Promise.race([executionPromise, timeoutPromise]);
const result = await Promise.race([executionPromise, timeoutPromise]);
// Format output
let output = '';
if (logs.length > 0) {
output += 'Console output:\n' + logs.join('\n') + '\n\n';
output += `Console output:\n${logs.join('\n')}\n\n`;
}
if (result !== undefined) {
output += 'Result: ' + JSON.stringify(result, null, 2);
output += `Result: ${JSON.stringify(result, null, 2)}`;
} else if (logs.length === 0) {
output = 'Code executed successfully (no output)';
}
+1 -1
View File
@@ -41,7 +41,7 @@ export const dateTimeHandler: ToolHandler = async (args): Promise<ToolResult> =>
switch (format) {
case 'iso':
result = now.toLocaleString('sv-SE', { timeZone: timezone }).replace(' ', 'T') + 'Z';
result = `${now.toLocaleString('sv-SE', { timeZone: timezone }).replace(' ', 'T')}Z`;
break;
case 'date_only':
result = now.toLocaleDateString('en-US', {
+4 -4
View File
@@ -13,11 +13,11 @@ export const imageGenerationTool: Tool = {
type: 'function',
function: {
name: 'generate_image',
description:
'Generate an image based on a text description. Creates images using AI image generation. ' +
(IMAGE_API_URL
description: `Generate an image based on a text description. Creates images using AI image generation. ${
IMAGE_API_URL
? 'Image generation is available.'
: 'NOTE: Image generation is not configured. Set IMAGE_GENERATION_API_URL environment variable.'),
: 'NOTE: Image generation is not configured. Set IMAGE_GENERATION_API_URL environment variable.'
}`,
parameters: {
type: 'object',
properties: {
+1 -1
View File
@@ -18,7 +18,7 @@ import { webSearchHandler, webSearchTool } from './web-search';
export type { ToolHandler, ToolResult } from './types';
// Registry of tool handlers
const toolHandlers: Map<string, ToolHandler> = new Map();
const toolHandlers = new Map<string, ToolHandler>();
/**
* Register a tool handler
+1 -1
View File
@@ -106,7 +106,7 @@ export const urlFetchHandler: ToolHandler = async (args): Promise<ToolResult> =>
// Truncate if needed
if (text.length > maxLength) {
text = text.substring(0, maxLength) + '\n\n[Content truncated...]';
text = `${text.substring(0, maxLength)}\n\n[Content truncated...]`;
}
return {