UNPKG

ai-utils.js

Version:

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

125 lines (124 loc) 4.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenAIImageGenerationResponseFormat = exports.OpenAIImageGenerationModel = exports.calculateOpenAIImageGenerationCostInMillicents = void 0; const zod_1 = require("zod"); const AbstractModel_js_1 = require("../../model-function/AbstractModel.cjs"); const callWithRetryAndThrottle_js_1 = require("../../util/api/callWithRetryAndThrottle.cjs"); const postToApi_js_1 = require("../../util/api/postToApi.cjs"); const OpenAIError_js_1 = require("./OpenAIError.cjs"); /** * @see https://openai.com/pricing */ const sizeToCostInMillicents = { "1024x1024": 2000, "512x512": 1800, "256x256": 1600, }; const calculateOpenAIImageGenerationCostInMillicents = ({ settings, }) => (settings.n ?? 1) * sizeToCostInMillicents[settings.size ?? "1024x1024"]; exports.calculateOpenAIImageGenerationCostInMillicents = calculateOpenAIImageGenerationCostInMillicents; /** * Create an image generation model that calls the OpenAI AI image creation API. * * @see https://platform.openai.com/docs/api-reference/images/create * * @example * const { image } = await generateImage( * new OpenAIImageGenerationModel({ size: "512x512" }), * "the wicked witch of the west in the style of early 19th century painting" * ); */ class OpenAIImageGenerationModel extends AbstractModel_js_1.AbstractModel { constructor(settings) { super({ settings }); Object.defineProperty(this, "provider", { enumerable: true, configurable: true, writable: true, value: "openai" }); Object.defineProperty(this, "modelName", { enumerable: true, configurable: true, writable: true, value: null }); } get apiKey() { const apiKey = this.settings.apiKey ?? process.env.OPENAI_API_KEY; if (apiKey == null) { throw new Error(`OpenAI API key is missing. Pass it as an argument to the constructor or set it as an environment variable named OPENAI_API_KEY.`); } return apiKey; } async callAPI(prompt, options) { const run = options?.run; const settings = options?.settings; const responseFormat = options?.responseFormat; const callSettings = Object.assign({ apiKey: this.apiKey, user: this.settings.isUserIdForwardingEnabled ? run?.userId : undefined, }, this.settings, settings, { abortSignal: run?.abortSignal, prompt, responseFormat, }); return (0, callWithRetryAndThrottle_js_1.callWithRetryAndThrottle)({ retry: callSettings.retry, throttle: callSettings.throttle, call: async () => callOpenAIImageGenerationAPI(callSettings), }); } generateImageResponse(prompt, options) { return this.callAPI(prompt, { responseFormat: exports.OpenAIImageGenerationResponseFormat.base64Json, functionId: options?.functionId, settings: options?.settings, run: options?.run, }); } extractBase64Image(response) { return response.data[0].b64_json; } withSettings(additionalSettings) { return new OpenAIImageGenerationModel(Object.assign({}, this.settings, additionalSettings)); } } exports.OpenAIImageGenerationModel = OpenAIImageGenerationModel; const openAIImageGenerationUrlSchema = zod_1.z.object({ created: zod_1.z.number(), data: zod_1.z.array(zod_1.z.object({ url: zod_1.z.string(), })), }); const openAIImageGenerationBase64JsonSchema = zod_1.z.object({ created: zod_1.z.number(), data: zod_1.z.array(zod_1.z.object({ b64_json: zod_1.z.string(), })), }); exports.OpenAIImageGenerationResponseFormat = { url: { type: "url", handler: (0, postToApi_js_1.createJsonResponseHandler)(openAIImageGenerationUrlSchema), }, base64Json: { type: "b64_json", handler: (0, postToApi_js_1.createJsonResponseHandler)(openAIImageGenerationBase64JsonSchema), }, }; async function callOpenAIImageGenerationAPI({ baseUrl = "https://api.openai.com/v1", abortSignal, apiKey, prompt, n, size, responseFormat, user, }) { return (0, postToApi_js_1.postJsonToApi)({ url: `${baseUrl}/images/generations`, apiKey, body: { prompt, n, size, response_format: responseFormat.type, user, }, failedResponseHandler: OpenAIError_js_1.failedOpenAICallResponseHandler, successfulResponseHandler: responseFormat?.handler, abortSignal, }); }