UNPKG

assistan-ts

Version:

A typesafe and code-first library to define and run OpenAI assistants

129 lines 5.64 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.AssistantVisibleError = exports.toolbox = exports.filter = exports.join = exports.defaultOptions = void 0; const definition_1 = require("./definition"); const value_1 = require("@sinclair/typebox/value"); const formats_1 = require("./lib/formats"); const typebox_1 = require("./lib/typebox"); (0, formats_1.registerTypeboxFormats)(); exports.defaultOptions = { jsonParser: defaultJsonParser, validator: defaultValidator, formatValidationError: defaultValidateFormatter, formatToolError: defaultErrorFormatter, validateArguments: true, formatOutput: defaultOutputFormatter, }; // TODO: how to handle options and tool conflicts? const join = (...toolboxes) => { var _a; const toolDefs = Object.assign({}, ...toolboxes.map((it) => it.toolDefs)); const toolsFn = Object.assign({}, ...toolboxes.map((it) => it.toolsFn)); return (0, exports.toolbox)(toolDefs, toolsFn, (_a = toolboxes[0]) === null || _a === void 0 ? void 0 : _a.options); }; exports.join = join; const filter = (tb, filter) => { const toolDefs = Object.fromEntries(Object.entries(tb.toolDefs).filter(([key, tool]) => filter(key, tool))); const toolsFn = Object.fromEntries(Object.entries(tb.toolsFn).filter(([key, tool]) => filter(key, tool))); return (0, exports.toolbox)(toolDefs, toolsFn, tb.options); }; exports.filter = filter; const toolbox = (toolDefs, toolsFn, options = exports.defaultOptions) => { const opts = Object.assign(Object.assign({}, exports.defaultOptions), options); const { jsonParser, validator, formatOutput, formatToolError } = opts; return { toolDefs, toolsFn, options: opts, payload: (0, definition_1.functionsToPayload)(toolDefs), handleAction: (action) => __awaiter(void 0, void 0, void 0, function* () { const toolDef = toolDefs === null || toolDefs === void 0 ? void 0 : toolDefs[action.function.name]; const ctx = { action, options: opts, toolDef }; try { if (!toolDef) throw new AssistantVisibleError(`Tool key not found: ${action.function.name}. Please select from ${Object.keys(toolDefs).toString()}`); let output; if (!(toolDef === null || toolDef === void 0 ? void 0 : toolDef.parameters) || (0, typebox_1.isNullType)(toolDef.parameters)) { output = yield toolsFn[action.function.name](undefined); } else { const args = jsonParser(action.function.arguments, ctx); validator(args, ctx); output = yield toolsFn[action.function.name](args); } return { tool_call_id: action.id, output: formatOutput(output, ctx), }; } catch (e) { return { tool_call_id: action.id, output: formatToolError(e, ctx), }; } }), }; }; exports.toolbox = toolbox; function defaultJsonParser(args, ctx) { try { return JSON.parse(args); } catch (e) { throw new AssistantVisibleError(`Invalid JSON: ${args}`); } } function defaultValidator(args, ctx) { if (ctx.options.validateArguments && ctx.toolDef) { // const validate = ajv.compile(ctx.toolDef.parameters); const errors = [...value_1.Value.Errors(ctx.toolDef.parameters, args)]; const valid = errors.length === 0; if (valid === false) { throw new AssistantVisibleError(ctx.options.formatValidationError(errors !== null && errors !== void 0 ? errors : [], ctx)); } } } function defaultValidateFormatter(errors) { return errors.map((it) => `arguments${it.path} ${it.message}`).join("\n"); } function defaultOutputFormatter(output) { switch (typeof output) { case "string": return output; case "number": case "boolean": return output + ""; case "object": return JSON.stringify(output); } } function defaultErrorFormatter(error, ctx) { if (error instanceof AssistantVisibleError) { return `Error calling ${ctx.action.function.name}: ${error.message}`; } throw error; } /** * Throw this if you want your assistant to receive the error message */ class AssistantVisibleError extends Error { constructor(message) { super(message); // Pass the message to the parent class Error // This line makes stack traces work correctly, do not remove it! Object.setPrototypeOf(this, AssistantVisibleError.prototype); // Set the name of the error class as CustomError. this.name = "AssistantVisibleError"; } } exports.AssistantVisibleError = AssistantVisibleError; //# sourceMappingURL=toolbox.js.map