UNPKG

@draftor/tools

Version:

A simple TypeScript/Javascript functions to openai tool call format

150 lines (149 loc) 5.88 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Tools = void 0; const doctrine = require("doctrine"); class Tools { constructor(funcs) { this.queue = []; this.isProcessing = false; this.funcs = funcs; } extractFirstJsDocComment(func) { const jsDocRegex = /\/\*\*([\s\S]*?)\*\//; const match = jsDocRegex.exec(func.toString()); return match ? match[0] : null; } transformDoctrineToOpenAITool(doctrineOutput, func) { const { description, tags } = doctrineOutput; const params = { type: 'object', properties: {}, }; let returnType = 'void'; let returnDescription = ''; tags.forEach((tag) => { var _a, _b; if (tag.title === 'param') { const param = tag === null || tag === void 0 ? void 0 : tag.name; const type = ((_a = tag === null || tag === void 0 ? void 0 : tag.type) === null || _a === void 0 ? void 0 : _a.name) || 'any'; const desc = (tag === null || tag === void 0 ? void 0 : tag.description) || ''; console.log(typeof desc); params.properties[param] = { type, description: desc, }; } if (tag.title === 'returns') { returnType = ((_b = tag.type) === null || _b === void 0 ? void 0 : _b.name) || 'any'; returnDescription = tag.description || ''; } }); const funcDesc = { name: func.name, description: (description === null || description === void 0 ? void 0 : description.trim()) || 'Description unavailable.', parameters: params, }; const tool = { type: 'function', function: funcDesc, }; return tool; // } toOpenAI(type) { var _a; if (this.funcs && ((_a = this.funcs) === null || _a === void 0 ? void 0 : _a.length) !== 0) { // reducer const processedFunctions = this.funcs.reduce((acc, func) => { const comment = this.extractFirstJsDocComment(func); const doc = doctrine.parse(comment || '', { unwrap: true }); const transformed = this.transformDoctrineToOpenAITool(doc, func); acc.push(transformed); return acc; }, []); return type == 'string' ? JSON.stringify(processedFunctions) : processedFunctions; } return ''; } /** * Processes the queue of function calls * @returns Array of results from executed functions */ processQueue() { return __awaiter(this, void 0, void 0, function* () { this.isProcessing = true; const results = []; 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; }); } /** * Adds function calls to queue and processes them * @param toolCalls Array of tool calls or function names * @param args Optional arguments for each call */ executeAll(toolCalls, args) { return __awaiter(this, void 0, void 0, function* () { // Add calls to queue toolCalls.forEach((call, index) => { this.queue.push({ toolCall: call, args: args === null || args === void 0 ? void 0 : args[index] }); }); // Process queue if not already processing if (!this.isProcessing) { return this.processQueue(); } return []; }); } exec(toolCall, args) { var _a, _b; if (typeof toolCall !== 'string') { const { function: func } = toolCall; const { name, arguments: args } = func; try { const callArgs = JSON.parse(args); const callFunc = (_a = this.funcs) === null || _a === void 0 ? void 0 : _a.filter((e) => e.name == name)[0]; const x = Object.keys(callArgs).map(e => callArgs[e]); return callFunc(...x); } catch (e) { console.log(e); } } else { try { const callFunc = (_b = this.funcs) === null || _b === void 0 ? void 0 : _b.filter((e) => e.name == toolCall)[0]; const y = args !== null && args !== void 0 ? args : {}; const x = Object.keys(y).map((key) => y[key]); return callFunc(...x); } catch (e) { console.log(e); } } } } exports.Tools = Tools;