UNPKG

assistan-ts

Version:

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

124 lines (116 loc) 3.4 kB
import { FunctionTool, toolsToPayload } from "./definition"; import { LinkedDefinition } from "./link"; import { RunOptions, ToolsRequiredResponse, waitForComplete, waitForRequiredAction, } from "./run"; import { ToolBox, ToolOptions, ToolsDefsToToolbox, toolbox as initToolBox, } from "./toolbox"; import { Run, RunCreateParams, OpenAI } from "./types/openai"; export type Assistant<T extends Record<string, FunctionTool>> = { /** A definition that has been "linked" to OpenAI */ definition: LinkedDefinition<T>; /** The toolbox that was created from the definition + tool functions */ toolbox: ToolBox<T>; /** Run related functions */ run: { /** Create a new run */ create: (params: { threadId: string; body?: Omit<RunCreateParams, "assistant_id">; options?: OpenAI.RequestOptions; }) => Promise<SetupRunResponse>; /** Load an existing run */ load: (run: Run) => SetupRunResponse; }; }; type SetupRunResponse = { run: OpenAI.Beta.Threads.Runs.Run; toolsRequired: ( opts?: RunOptions & { timeout?: number } ) => Promise<ToolsRequiredResponse>; complete: ( opts?: RunOptions & { timeout?: number } ) => Promise<OpenAI.Beta.Threads.Runs.Run>; }; type Props<T extends Record<string, FunctionTool>> = { /** A definition that has been "linked" to OpenAI */ definition: LinkedDefinition<T>; /** Functions matching the tool definitions */ tools: ToolsDefsToToolbox<T>; /** Options to pass to the toolbox */ toolOptions?: Partial<ToolOptions>; /** Override the toolbox before creating a run * @param base The toolbox that was created from the definition */ toolBoxOverride?: (base: ToolBox<T>) => ToolBox<any>; }; export const assistant = <T extends Record<string, FunctionTool>>({ definition, tools, toolOptions, toolBoxOverride: overrideToolbox, }: Props<T>): Assistant<T> => { const toolbox = initToolBox(definition.functionTools!, tools, toolOptions); const setupRun = ( run: Run, overriddenToolbox?: ToolBox<any> ): SetupRunResponse => ({ run, toolsRequired: async (opts) => waitForRequiredAction( run, { toolbox: overriddenToolbox ?? toolbox, openai: definition.openai, ...opts, }, opts?.timeout ), complete: async (opts) => waitForComplete( run, { toolbox: overriddenToolbox ?? toolbox, openai: definition.openai, ...opts, }, opts?.timeout ), }); return { definition, toolbox: toolbox, run: { create: async (params) => { const { threadId, body, options } = params; const overriddenToolbox = overrideToolbox?.(toolbox); const run = await definition.openai.beta.threads.runs.create( threadId, { assistant_id: definition.id, ...(body ?? {}), tools: overriddenToolbox ? toolsToPayload({ functionTools: overriddenToolbox.toolDefs, retrieval: definition.retrieval, codeInterpreter: definition.codeInterpreter, }) : undefined, }, options ); return setupRun(run, overriddenToolbox); }, load: (run: Run) => { return setupRun(run); }, }, }; };