UNPKG

ai-utils.js

Version:

Build AI applications, chatbots, and agents with JavaScript and TypeScript.

57 lines (56 loc) 2.21 kB
import { nanoid as createId } from "nanoid"; import { startDurationMeasurement } from "../util/DurationMeasurement.js"; import { AbortError } from "../util/api/AbortError.js"; import { runSafe } from "../util/runSafe.js"; import { ModelCallEventSource } from "./ModelCallEventSource.js"; export async function executeCall({ model, options, getStartEvent, getAbortEvent, getFailureEvent, getSuccessEvent, generateResponse, extractOutputValue, }) { if (options?.settings != null) { model = model.withSettings(options.settings); options = { functionId: options.functionId, run: options.run, }; } const run = options?.run; const settings = model.settings; const eventSource = new ModelCallEventSource({ observers: [...(settings.observers ?? []), ...(run?.observers ?? [])], errorHandler: run?.errorHandler, }); const durationMeasurement = startDurationMeasurement(); const startMetadata = { callId: `call-${createId()}`, runId: run?.runId, sessionId: run?.sessionId, userId: run?.userId, functionId: options?.functionId, model: model.modelInformation, startEpochSeconds: durationMeasurement.startEpochSeconds, }; eventSource.notifyModelCallStarted(getStartEvent(startMetadata, settings)); const result = await runSafe(() => generateResponse({ functionId: options?.functionId, settings, run, })); const finishMetadata = { ...startMetadata, durationInMs: durationMeasurement.durationInMs, }; if (!result.ok) { if (result.isAborted) { eventSource.notifyModelCallFinished(getAbortEvent(finishMetadata, settings)); throw new AbortError(); } eventSource.notifyModelCallFinished(getFailureEvent(finishMetadata, settings, result.error)); throw result.error; } const response = result.output; const output = extractOutputValue(response); eventSource.notifyModelCallFinished(getSuccessEvent(finishMetadata, settings, response, output)); return { output, response, metadata: finishMetadata, }; }