UNPKG

@draftor/tools

Version:

A simple TypeScript/Javascript functions to openai tool call format

75 lines (64 loc) 8.55 kB
prompt: { "messages": [ { "role": "user", "content": "Create a execute all fucntion that queue it and then process it" }, { "role": "assistant", "content": "**Draft changes**:\n\n```bash\nroot/\n└── src/\n └── index.ts | +40 -0\n```\n\n**Gist** : Key changes\n1. Added new `executeAll` method to process queued function calls\n2. Added queue management system with error handling\n\n```typescript|file:///c%3A/Users/PRAVEEN%20NAIK/Codespace/tool/src/index.ts\n// ... existing code ...\n\nexport class Tools implements ITools {\n private queue: Array<{ toolCall: IToolCall | string; args?: object }> = [];\n private isProcessing = false;\n\n // ... existing methods ...\n\n /**\n * Adds function calls to queue and processes them\n * @param toolCalls Array of tool calls or function names\n * @param args Optional arguments for each call\n */\n async executeAll(toolCalls: Array<IToolCall | string>, args?: object[]): Promise<any[]> {\n // Add calls to queue\n toolCalls.forEach((call, index) => {\n this.queue.push({\n toolCall: call,\n args: args?.[index]\n });\n });\n\n // Process queue if not already processing\n if (!this.isProcessing) {\n return this.processQueue();\n }\n\n return [];\n }\n\n /**\n * Processes the queue of function calls\n * @returns Array of results from executed functions\n */\n private async processQueue(): Promise<any[]> {\n this.isProcessing = true;\n const results: any[] = [];\n\n while (this.queue.length > 0) {\n const { toolCall, args } = this.queue.shift()!;\n try {\n const result = this.exec(toolCall, args);\n results.push(result);\n } catch (error) {\n console.error('Error executing function:', error);\n results.push(null);\n }\n }\n\n this.isProcessing = false;\n return results;\n }\n}\n\n// ... existing code ...\n```\n\nThe new implementation adds:\n1. A queue system to manage multiple function calls\n2. An `executeAll` method to batch process functions\n3. Error handling for individual function calls\n4. Async processing capability\n5. Returns array of results maintaining execution order\n\nUsage example:\n```typescript\nconst tools = new Tools([func1, func2, func3]);\nconst results = await tools.executeAll([\n { name: 'func1', args: '{}' },\n 'func2',\n { name: 'func3', args: '{}' }\n]);\n```" }, { "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 private queue: Array<{ toolCall: IToolCall | string; args?: object }> = [];\r\n private isProcessing = false;\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 * Adds function calls to queue and processes them\r\n * @param toolCalls Array of tool calls or function names\r\n * @param args Optional arguments for each call\r\n */\r\n async executeAll(toolCalls: Array<IToolCall | string>, args?: object[]): Promise<any[]> {\r\n // Add calls to queue\r\n toolCalls.forEach((call, index) => {\r\n this.queue.push({\r\n toolCall: call,\r\n args: args?.[index]\r\n });\r\n });\r\n\r\n // Process queue if not already processing\r\n if (!this.isProcessing) {\r\n return this.processQueue();\r\n }\r\n\r\n return [];\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: Property 'processQueue' does not exist on type 'Tools'.ts(2339)" } ] } context: file:///c%3A/Users/PRAVEEN%20NAIK/Codespace/tool/.cache/draftor/2025-01-16/1737057278-draftor-deepseek-deepseek-chat.md ================================= **Draft changes**: ```bash root/ └── src/ └── index.ts | +20 -0 ``` **Gist** : Key changes 1. Added missing `processQueue` method implementation 2. Fixed TypeScript error TS2339 ```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; public funcs: Function[] | undefined; // ... existing methods ... /** * 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 changes: 1. Added the missing `processQueue` method implementation 2. Maintained the existing queue processing logic 3. Added proper TypeScript return type annotations 4. Kept the error handling consistent with the rest of the codebase 5. Ensured proper state management with `isProcessing` flag The method is now properly integrated with the existing `executeAll` functionality and handles the queue processing as expected.