@raphtlw/hyperfunc
Version:
Streamlined Function Calling for LLMs
64 lines (63 loc) • 1.94 kB
JavaScript
import { ind } from "@raphtlw/indoc";
import assert from "assert";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
export const hyperFunctionToTool = (name, data) => {
let parameters;
const schema = zodToJsonSchema(data._schema);
if ("type" in schema && "properties" in schema && "required" in schema) {
parameters = {
type: schema.type,
properties: schema.properties,
required: schema.required,
};
}
else {
parameters = {};
}
const tool = {
function: {
name,
description: data._description,
parameters,
},
type: "function",
};
return tool;
};
/**
* Storage for HyperFunction(s) with associated methods
*/
export const hyperStore = (functions) => ({
functions: new Map(Object.entries(functions)),
set(name, hf) {
this.functions.set(name, hf);
},
async callTool(data, context) {
const hyperFunction = this.functions.get(data.function.name);
assert(hyperFunction);
const result = hyperFunction._schema.safeParse(JSON.parse(data.function.arguments));
if (!result.success) {
throw new Error(ind(`
There was an issue with parsing the function arguments,
please rewrite it by calling the ${data.function.name} function with the correct parameters.`));
}
const response = hyperFunction._handler(result.data, context);
if (response instanceof Promise)
return await response;
return response;
},
asTools() {
return Array.from(this.functions).map(([k, v]) => hyperFunctionToTool(k, v));
},
});
/**
* Define new HyperFunction
*/
export const hyper = ({ description, args, handler, }) => {
return {
_schema: z.object(args),
_handler: handler,
_description: description,
};
};