UNPKG

@draftor/tools

Version:

A simple TypeScript/Javascript functions to openai tool call format

96 lines (82 loc) 5.97 kB
prompt: { "messages": [ { "role": "user", "content": "<context>\n```typescript|file:///c%3A/Users/PRAVEEN%20NAIK/Codespace/tool/src/index.ts\nimport * as doctrine from 'doctrine';\r\nimport { IParam, ITools, ITool, IFunctionDescription, IToolCall, IFunctionCall } from './types';\r\n\r\nexport class Tools implements ITools {\r\n public funcs: Function[] | undefined;\r\n constructor(funcs: Function[]) {\r\n this.funcs = funcs;\r\n }\r\n\r\n private extractFirstJsDocComment(func: Function) {\r\n const jsDocRegex = /\\/\\*\\*([\\s\\S]*?)\\*\\//;\r\n const match = jsDocRegex.exec(func.toString());\r\n return match ? match[0] : null;\r\n }\r\n\r\n private transformDoctrineToOpenAITool(\r\n doctrineOutput: any,\r\n func: Function\r\n ): ITool {\r\n const { description, tags } = doctrineOutput;\r\n\r\n const params: IParam = {\r\n type: 'object',\r\n properties: {},\r\n };\r\n\r\n let returnType = 'void';\r\n let returnDescription = '';\r\n\r\n tags.forEach((tag: any) => {\r\n if (tag.title === 'param') {\r\n const param = tag?.name as string;\r\n const type = tag?.type?.name || 'any';\r\n const desc = tag?.description || '';\r\n console.log(typeof desc);\r\n\r\n params.properties[param] = {\r\n type,\r\n description: desc,\r\n };\r\n\r\n // params.required.push(tag?.name);\r\n }\r\n\r\n if (tag.title === 'returns') {\r\n returnType = tag.type?.name || 'any';\r\n returnDescription = tag.description || '';\r\n }\r\n });\r\n\r\n const funcDesc: IFunctionDescription = {\r\n name: func.name,\r\n description: description?.trim() || 'Description unavailable.',\r\n parameters: params,\r\n };\r\n\r\n const tool: ITool = {\r\n type: 'function',\r\n function: funcDesc,\r\n };\r\n\r\n return tool;\r\n }\r\n\r\n toOpenAI(type?: string): ITool[] | string {\r\n if (this.funcs && this.funcs?.length !== 0) {\r\n // reducer\r\n const processedFunctions = this.funcs.reduce((acc, func) => {\r\n const comment = this.extractFirstJsDocComment(func);\r\n const doc = doctrine.parse(comment || '', { unwrap: true });\r\n const transformed = this.transformDoctrineToOpenAITool(\r\n doc,\r\n func\r\n ) as unknown as ITool;\r\n acc.push(transformed);\r\n return acc;\r\n }, [] as ITool[]);\r\n\r\n return type == 'string' ? JSON.stringify(processedFunctions) : processedFunctions;\r\n }\r\n return '';\r\n }\r\n\r\n\r\n exec(toolCall: IToolCall | string, args?: object): any {\r\n if (typeof toolCall !== 'string') {\r\n const { function: func } = toolCall;\r\n const { name, arguments: args } = func;\r\n\r\n try {\r\n const callArgs = JSON.parse(args);\r\n const callFunc = this.funcs?.filter((e) => e.name == name)[0] as unknown as Function;\r\n const x = Object.keys(callArgs).map(e => callArgs[e]);\r\n return callFunc(...x);\r\n } catch (e) {\r\n console.log(e)\r\n }\r\n } else {\r\n try {\r\n const callFunc = this.funcs?.filter((e) => e.name == toolCall)[0] as unknown as Function;\r\n const y = args ?? {};\r\n const x = Object.keys(y).map((key: string) => (y as Record<string, any>)[key]);\r\n return callFunc(...x);\r\n } catch (e) {\r\n console.log(e)\r\n }\r\n }\r\n }\r\n}```\n</context>\n\n\n QUERY: Create a execute all fucntion that queue it and then process it" } ] } context: file:///c%3A/Users/PRAVEEN%20NAIK/Codespace/tool/.cache/draftor/2025-01-16/1737057103-draftor-deepseek-deepseek-chat.md ================================= **Draft changes**: ```bash root/ └── src/ └── index.ts | +40 -0 ``` **Gist** : Key changes 1. Added new `executeAll` method to process queued function calls 2. Added queue management system with error handling ```typescript|file:///c%3A/Users/PRAVEEN%20NAIK/Codespace/tool/src/index.ts // ... existing code ... export class Tools implements ITools { private queue: Array<{ toolCall: IToolCall | string; args?: object }> = []; private isProcessing = false; // ... existing methods ... /** * Adds function calls to queue and processes them * @param toolCalls Array of tool calls or function names * @param args Optional arguments for each call */ async executeAll(toolCalls: Array<IToolCall | string>, args?: object[]): Promise<any[]> { // Add calls to queue toolCalls.forEach((call, index) => { this.queue.push({ toolCall: call, args: args?.[index] }); }); // Process queue if not already processing if (!this.isProcessing) { return this.processQueue(); } return []; } /** * Processes the queue of function calls * @returns Array of results from executed functions */ private async processQueue(): Promise<any[]> { this.isProcessing = true; const results: any[] = []; while (this.queue.length > 0) { const { toolCall, args } = this.queue.shift()!; try { const result = this.exec(toolCall, args); results.push(result); } catch (error) { console.error('Error executing function:', error); results.push(null); } } this.isProcessing = false; return results; } } // ... existing code ... ``` The new implementation adds: 1. A queue system to manage multiple function calls 2. An `executeAll` method to batch process functions 3. Error handling for individual function calls 4. Async processing capability 5. Returns array of results maintaining execution order Usage example: ```typescript const tools = new Tools([func1, func2, func3]); const results = await tools.executeAll([ { name: 'func1', args: '{}' }, 'func2', { name: 'func3', args: '{}' } ]); ```