{"version":3,"sources":["jsdelivr-header.js","/npm/@promptbook/openai@0.111.0-11/umd/index.umd.js"],"names":[],"mappings":"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","file":"/npm/@promptbook/openai@0.111.0-11/umd/index.umd.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@promptbook/openai@0.111.0-11/umd/index.umd.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('spacetrim'), require('path'), require('crypto'), require('crypto-js'), require('crypto-js/enc-hex'), require('bottleneck'), require('openai'), require('socket.io-client'), require('@openai/agents')) :\n    typeof define === 'function' && define.amd ? define(['exports', 'colors', 'spacetrim', 'path', 'crypto', 'crypto-js', 'crypto-js/enc-hex', 'bottleneck', 'openai', 'socket.io-client', '@openai/agents'], factory) :\n    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global[\"promptbook-openai\"] = {}, global.colors, global.spaceTrim$1, null, global.crypto, null, null, global.Bottleneck, global.OpenAI, global.socket_ioClient, global.agents));\n})(this, (function (exports, colors, spaceTrim$1, path, crypto, cryptoJs, hexEncoder, Bottleneck, OpenAI, socket_ioClient, agents) { 'use strict';\n\n    function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }\n\n    var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);\n    var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim$1);\n    var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);\n    var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);\n\n    // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten\n    /**\n     * The version of the Book language\n     *\n     * @generated\n     * @see https://github.com/webgptorg/book\n     */\n    const BOOK_LANGUAGE_VERSION = '2.0.0';\n    /**\n     * The version of the Promptbook engine\n     *\n     * @generated\n     * @see https://github.com/webgptorg/promptbook\n     */\n    const PROMPTBOOK_ENGINE_VERSION = '0.111.0-11';\n    /**\n     * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Detects if the code is running in a browser environment in main thread (Not in a web worker)\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function $isRunningInBrowser() {\n        try {\n            return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n        }\n        catch (e) {\n            return false;\n        }\n    }\n    /**\n     * TODO: [🎺]\n     */\n\n    /**\n     * Detects if the code is running in a web worker\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function $isRunningInWebWorker() {\n        try {\n            // Note: Check for importScripts which is specific to workers\n            //       and not available in the main browser thread\n            return (typeof self !== 'undefined' &&\n                typeof self.importScripts === 'function');\n        }\n        catch (e) {\n            return false;\n        }\n    }\n    /**\n     * TODO: [🎺]\n     */\n\n    /**\n     * Trims string from all 4 sides\n     *\n     * Note: This is a re-exported function from the `spacetrim` package which is\n     *       Developed by same author @hejny as this package\n     *\n     * @public exported from `@promptbook/utils`\n     * @see https://github.com/hejny/spacetrim#usage\n     */\n    const spaceTrim = spaceTrim$1.spaceTrim;\n\n    /**\n     * @private util of `@promptbook/color`\n     * @de\n     */\n    class TakeChain {\n        constructor(value) {\n            this.value = value;\n        }\n        then(callback) {\n            const newValue = callback(this.value);\n            return take(newValue);\n        }\n    }\n\n    /**\n     * A function that takes an initial value and returns a proxy object with chainable methods.\n     *\n     * @param {*} initialValue - The initial value.\n     * @returns {Proxy<WithTake<TValue>>} - A proxy object with a `take` method.\n     *\n     * @private util of `@promptbook/color`\n     * @deprecated [🤡] Use some better functional library instead of `TakeChain`\n     */\n    function take(initialValue) {\n        if (initialValue instanceof TakeChain) {\n            return initialValue;\n        }\n        return new Proxy(new TakeChain(initialValue), {\n            get(target, property, receiver) {\n                if (Reflect.has(target, property)) {\n                    return Reflect.get(target, property, receiver);\n                }\n                else if (Reflect.has(initialValue, property)) {\n                    return Reflect.get(initialValue, property, receiver);\n                }\n                else {\n                    return undefined;\n                }\n            },\n        });\n    }\n\n    /**\n     * 🎨 List of all 140 color names which are supported by CSS\n     *\n     * @public exported from `@promptbook/color`\n     */\n    const CSS_COLORS = {\n        promptbook: '#79EAFD',\n        transparent: 'rgba(0,0,0,0)',\n        aliceblue: '#f0f8ff',\n        antiquewhite: '#faebd7',\n        aqua: '#00ffff',\n        aquamarine: '#7fffd4',\n        azure: '#f0ffff',\n        beige: '#f5f5dc',\n        bisque: '#ffe4c4',\n        black: '#000000',\n        blanchedalmond: '#ffebcd',\n        blue: '#0000ff',\n        blueviolet: '#8a2be2',\n        brown: '#a52a2a',\n        burlywood: '#deb887',\n        cadetblue: '#5f9ea0',\n        chartreuse: '#7fff00',\n        chocolate: '#d2691e',\n        coral: '#ff7f50',\n        cornflowerblue: '#6495ed',\n        cornsilk: '#fff8dc',\n        crimson: '#dc143c',\n        cyan: '#00ffff',\n        darkblue: '#00008b',\n        darkcyan: '#008b8b',\n        darkgoldenrod: '#b8860b',\n        darkgray: '#a9a9a9',\n        darkgrey: '#a9a9a9',\n        darkgreen: '#006400',\n        darkkhaki: '#bdb76b',\n        darkmagenta: '#8b008b',\n        darkolivegreen: '#556b2f',\n        darkorange: '#ff8c00',\n        darkorchid: '#9932cc',\n        darkred: '#8b0000',\n        darksalmon: '#e9967a',\n        darkseagreen: '#8fbc8f',\n        darkslateblue: '#483d8b',\n        darkslategray: '#2f4f4f',\n        darkslategrey: '#2f4f4f',\n        darkturquoise: '#00ced1',\n        darkviolet: '#9400d3',\n        deeppink: '#ff1493',\n        deepskyblue: '#00bfff',\n        dimgray: '#696969',\n        dimgrey: '#696969',\n        dodgerblue: '#1e90ff',\n        firebrick: '#b22222',\n        floralwhite: '#fffaf0',\n        forestgreen: '#228b22',\n        fuchsia: '#ff00ff',\n        gainsboro: '#dcdcdc',\n        ghostwhite: '#f8f8ff',\n        gold: '#ffd700',\n        goldenrod: '#daa520',\n        gray: '#808080',\n        grey: '#808080',\n        green: '#008000',\n        greenyellow: '#adff2f',\n        honeydew: '#f0fff0',\n        hotpink: '#ff69b4',\n        indianred: '#cd5c5c',\n        indigo: '#4b0082',\n        ivory: '#fffff0',\n        khaki: '#f0e68c',\n        lavender: '#e6e6fa',\n        lavenderblush: '#fff0f5',\n        lawngreen: '#7cfc00',\n        lemonchiffon: '#fffacd',\n        lightblue: '#add8e6',\n        lightcoral: '#f08080',\n        lightcyan: '#e0ffff',\n        lightgoldenrodyellow: '#fafad2',\n        lightgray: '#d3d3d3',\n        lightgrey: '#d3d3d3',\n        lightgreen: '#90ee90',\n        lightpink: '#ffb6c1',\n        lightsalmon: '#ffa07a',\n        lightseagreen: '#20b2aa',\n        lightskyblue: '#87cefa',\n        lightslategray: '#778899',\n        lightslategrey: '#778899',\n        lightsteelblue: '#b0c4de',\n        lightyellow: '#ffffe0',\n        lime: '#00ff00',\n        limegreen: '#32cd32',\n        linen: '#faf0e6',\n        magenta: '#ff00ff',\n        maroon: '#800000',\n        mediumaquamarine: '#66cdaa',\n        mediumblue: '#0000cd',\n        mediumorchid: '#ba55d3',\n        mediumpurple: '#9370db',\n        mediumseagreen: '#3cb371',\n        mediumslateblue: '#7b68ee',\n        mediumspringgreen: '#00fa9a',\n        mediumturquoise: '#48d1cc',\n        mediumvioletred: '#c71585',\n        midnightblue: '#191970',\n        mintcream: '#f5fffa',\n        mistyrose: '#ffe4e1',\n        moccasin: '#ffe4b5',\n        navajowhite: '#ffdead',\n        navy: '#000080',\n        oldlace: '#fdf5e6',\n        olive: '#808000',\n        olivedrab: '#6b8e23',\n        orange: '#ffa500',\n        orangered: '#ff4500',\n        orchid: '#da70d6',\n        palegoldenrod: '#eee8aa',\n        palegreen: '#98fb98',\n        paleturquoise: '#afeeee',\n        palevioletred: '#db7093',\n        papayawhip: '#ffefd5',\n        peachpuff: '#ffdab9',\n        peru: '#cd853f',\n        pink: '#ffc0cb',\n        plum: '#dda0dd',\n        powderblue: '#b0e0e6',\n        purple: '#800080',\n        rebeccapurple: '#663399',\n        red: '#ff0000',\n        rosybrown: '#bc8f8f',\n        royalblue: '#4169e1',\n        saddlebrown: '#8b4513',\n        salmon: '#fa8072',\n        sandybrown: '#f4a460',\n        seagreen: '#2e8b57',\n        seashell: '#fff5ee',\n        sienna: '#a0522d',\n        silver: '#c0c0c0',\n        skyblue: '#87ceeb',\n        slateblue: '#6a5acd',\n        slategray: '#708090',\n        slategrey: '#708090',\n        snow: '#fffafa',\n        springgreen: '#00ff7f',\n        steelblue: '#4682b4',\n        tan: '#d2b48c',\n        teal: '#008080',\n        thistle: '#d8bfd8',\n        tomato: '#ff6347',\n        turquoise: '#40e0d0',\n        violet: '#ee82ee',\n        wheat: '#f5deb3',\n        white: '#ffffff',\n        whitesmoke: '#f5f5f5',\n        yellow: '#ffff00',\n        yellowgreen: '#9acd32',\n    };\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Validates that a channel value is a valid number within the range of 0 to 255.\n     * Throws an error if the value is not valid.\n     *\n     * @param channelName - The name of the channel being validated.\n     * @param value - The value of the channel to validate.\n     * @throws Will throw an error if the value is not a valid channel number.\n     *\n     * @private util of `@promptbook/color`\n     */\n    function checkChannelValue(channelName, value) {\n        if (typeof value !== 'number') {\n            throw new Error(`${channelName} channel value is not number but ${typeof value}`);\n        }\n        if (isNaN(value)) {\n            throw new Error(`${channelName} channel value is NaN`);\n        }\n        if (Math.round(value) !== value) {\n            throw new Error(`${channelName} channel is not whole number, it is ${value}`);\n        }\n        if (value < 0) {\n            throw new Error(`${channelName} channel is lower than 0, it is ${value}`);\n        }\n        if (value > 255) {\n            throw new Error(`${channelName} channel is greater than 255, it is ${value}`);\n        }\n    }\n\n    const SHORT_HEX_LENGTHS = new Set([3, 4]);\n    const LONG_HEX_LENGTHS = new Set([6, 8]);\n    /**\n     * Parses a hex string into RGBA channel values.\n     *\n     * @param hex - Hex value such as `#09d`, `009edd`, `#009eddff`.\n     * @returns RGBA channel values.\n     *\n     * @private function of Color\n     */\n    function parseHexColor(hex) {\n        const sanitized = hex.startsWith('#') ? hex.substring(1) : hex;\n        const throwInvalidHex = () => {\n            throw new Error(`Can not parse color from hex string \"${hex}\"`);\n        };\n        if (SHORT_HEX_LENGTHS.has(sanitized.length)) {\n            return {\n                red: parseShortHexChannel(sanitized.charAt(0), throwInvalidHex),\n                green: parseShortHexChannel(sanitized.charAt(1), throwInvalidHex),\n                blue: parseShortHexChannel(sanitized.charAt(2), throwInvalidHex),\n                alpha: sanitized.length === 4 ? parseShortHexChannel(sanitized.charAt(3), throwInvalidHex) : 255,\n            };\n        }\n        if (LONG_HEX_LENGTHS.has(sanitized.length)) {\n            return {\n                red: parseLongHexChannel(sanitized, 0, throwInvalidHex),\n                green: parseLongHexChannel(sanitized, 2, throwInvalidHex),\n                blue: parseLongHexChannel(sanitized, 4, throwInvalidHex),\n                alpha: sanitized.length === 8 ? parseLongHexChannel(sanitized, 6, throwInvalidHex) : 255,\n            };\n        }\n        return throwInvalidHex();\n    }\n    function parseShortHexChannel(char, onError) {\n        if (!char) {\n            return onError();\n        }\n        const parsed = parseInt(char, 16);\n        if (Number.isNaN(parsed)) {\n            return onError();\n        }\n        return parsed * 16;\n    }\n    function parseLongHexChannel(hex, start, onError) {\n        const segment = hex.substr(start, 2);\n        if (segment.length < 2) {\n            return onError();\n        }\n        const parsed = parseInt(segment, 16);\n        if (Number.isNaN(parsed)) {\n            return onError();\n        }\n        return parsed;\n    }\n\n    const HSL_REGEX = /^hsl\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)%\\s*,\\s*([0-9.]+)%\\s*\\)$/;\n    /**\n     * Parses an HSL string into RGBA channel values.\n     *\n     * @param hsl - HSL string such as `hsl(197.1, 100%, 43.3%)`.\n     * @returns RGBA channel values.\n     *\n     * @private function of Color\n     */\n    function parseHslColor(hsl) {\n        const match = hsl.match(HSL_REGEX);\n        if (!match) {\n            throw new Error(`Invalid hsl string format: \"${hsl}\"`);\n        }\n        const hue = parseFloat(match[1]);\n        const saturation = parseFloat(match[2]) / 100;\n        const lightness = parseFloat(match[3]) / 100;\n        const { red, green, blue } = convertHslToRgb(hue, saturation, lightness);\n        return {\n            red,\n            green,\n            blue,\n            alpha: 255,\n        };\n    }\n    function convertHslToRgb(h, s, l) {\n        const c = (1 - Math.abs(2 * l - 1)) * s;\n        const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n        const m = l - c / 2;\n        let r1 = 0;\n        let g1 = 0;\n        let b1 = 0;\n        if (h >= 0 && h < 60) {\n            r1 = c;\n            g1 = x;\n        }\n        else if (h >= 60 && h < 120) {\n            r1 = x;\n            g1 = c;\n        }\n        else if (h >= 120 && h < 180) {\n            g1 = c;\n            b1 = x;\n        }\n        else if (h >= 180 && h < 240) {\n            g1 = x;\n            b1 = c;\n        }\n        else if (h >= 240 && h < 300) {\n            r1 = x;\n            b1 = c;\n        }\n        else if (h >= 300 && h < 360) {\n            r1 = c;\n            b1 = x;\n        }\n        return {\n            red: Math.round((r1 + m) * 255),\n            green: Math.round((g1 + m) * 255),\n            blue: Math.round((b1 + m) * 255),\n        };\n    }\n\n    const RGB_REGEX = /^rgb\\(\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*\\)$/;\n    const RGBA_REGEX = /^rgba\\(\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*\\)$/;\n    /**\n     * Parses an RGB string into RGBA channel values.\n     *\n     * @param rgb - RGB string such as `rgb(0%, 62%, 86.7%)`.\n     * @returns RGBA channel values.\n     *\n     * @private function of Color\n     */\n    function parseRgbColor(rgb) {\n        const match = rgb.match(RGB_REGEX);\n        if (!match) {\n            throw new Error(`Invalid rgb string format: \"${rgb}\"`);\n        }\n        return {\n            red: parseChannelValue(match[1]),\n            green: parseChannelValue(match[2]),\n            blue: parseChannelValue(match[3]),\n            alpha: 255,\n        };\n    }\n    /**\n     * Parses an RGBA string into RGBA channel values.\n     *\n     * @param rgba - RGBA string such as `rgba(0, 158, 221, 0.5)`.\n     * @returns RGBA channel values.\n     *\n     * @private function of Color\n     */\n    function parseRgbaColor(rgba) {\n        const match = rgba.match(RGBA_REGEX);\n        if (!match) {\n            throw new Error(`Invalid rgba string format: \"${rgba}\"`);\n        }\n        return {\n            red: parseChannelValue(match[1]),\n            green: parseChannelValue(match[2]),\n            blue: parseChannelValue(match[3]),\n            alpha: parseAlphaValue(match[4]),\n        };\n    }\n    function parseChannelValue(value) {\n        if (value.endsWith('%')) {\n            const percent = parseFloat(value);\n            return Math.round((percent / 100) * 255);\n        }\n        return Math.round(parseFloat(value));\n    }\n    function parseAlphaValue(value) {\n        if (value.endsWith('%')) {\n            const percent = parseFloat(value);\n            return Math.round((percent / 100) * 255);\n        }\n        const parsed = parseFloat(value);\n        if (parsed <= 1) {\n            return Math.round(parsed * 255);\n        }\n        return Math.round(parsed);\n    }\n\n    const HSL_REGEX_PATTERN = /^hsl\\(\\s*([0-9.]+)\\s*,\\s*([0-9.]+)%\\s*,\\s*([0-9.]+)%\\s*\\)$/;\n    const RGB_REGEX_PATTERN = /^rgb\\(\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*\\)$/;\n    const RGBA_REGEX_PATTERN = /^rgba\\(\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*,\\s*([0-9.%-]+)\\s*\\)$/;\n    /**\n     * Color object represents an RGB color with alpha channel\n     *\n     * Note: There is no fromObject/toObject because the most logical way to serialize color is as a hex string (#009edd)\n     *\n     * @public exported from `@promptbook/color`\n     */\n    class Color {\n        /**\n         * Creates a new Color instance from miscellaneous formats\n         * - It can receive Color instance and just return the same instance\n         * - It can receive color in string format for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`\n         *\n         * Note: This is not including fromImage because detecting color from an image is heavy task which requires async stuff and we cannot safely determine with overloading if return value will be a promise\n         *\n         * @param color\n         * @returns Color object\n         */\n        static from(color, _isSingleValue = false) {\n            if (color === '') {\n                throw new Error(`Can not create color from empty string`);\n            }\n            else if (color instanceof Color) {\n                return take(color);\n            }\n            else if (Color.isColor(color)) {\n                return take(color);\n            }\n            else if (typeof color === 'string') {\n                try {\n                    return Color.fromString(color);\n                }\n                catch (error) {\n                    // <- Note: Can not use `assertsError(error)` here because it causes circular dependency\n                    if (_isSingleValue) {\n                        throw error;\n                    }\n                    const parts = color.split(/[\\s+,;|]/);\n                    if (parts.length > 0) {\n                        return Color.from(parts[0].trim(), true);\n                    }\n                    else {\n                        throw new Error(`Can not create color from given string \"${color}\"`);\n                    }\n                }\n            }\n            else {\n                console.error({ color });\n                throw new Error(`Can not create color from given object`);\n            }\n        }\n        /**\n         * Creates a new Color instance from miscellaneous formats\n         * It just does not throw error when it fails, it returns PROMPTBOOK_COLOR instead\n         *\n         * @param color\n         * @returns Color object\n         */\n        static fromSafe(color) {\n            try {\n                return Color.from(color);\n            }\n            catch (error) {\n                // <- Note: Can not use `assertsError(error)` here because it causes circular dependency\n                console.warn(spaceTrim((block) => `\n                        Color.fromSafe error:\n                        ${block(error.message)}\n\n                        Returning default PROMPTBOOK_COLOR.\n                    `));\n                return Color.fromString('promptbook');\n            }\n        }\n        /**\n         * Creates a new Color instance from miscellaneous string formats\n         *\n         * @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...\n         * @returns Color object\n         */\n        static fromString(color) {\n            const trimmed = color.trim();\n            if (CSS_COLORS[trimmed]) {\n                return Color.fromString(CSS_COLORS[trimmed]);\n            }\n            else if (Color.isHexColorString(trimmed)) {\n                return Color.fromHex(trimmed);\n            }\n            if (HSL_REGEX_PATTERN.test(trimmed)) {\n                return Color.fromHsl(trimmed);\n            }\n            else if (RGB_REGEX_PATTERN.test(trimmed)) {\n                return Color.fromRgbString(trimmed);\n            }\n            else if (RGBA_REGEX_PATTERN.test(trimmed)) {\n                return Color.fromRgbaString(trimmed);\n            }\n            else {\n                throw new Error(`Can not create a new Color instance from string \"${trimmed}\".`);\n            }\n        }\n        /**\n         * Gets common color\n         *\n         * @param key as a css string like `midnightblue`\n         * @returns Color object\n         */\n        static get(key) {\n            if (!CSS_COLORS[key]) {\n                throw new Error(`\"${key}\" is not a common css color.`);\n            }\n            return Color.fromString(CSS_COLORS[key]);\n        }\n        /**\n         * Creates a new Color instance from average color of given image\n         *\n         * @param image as a source for example `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYJh39z8ABJgCe/ZvAS4AAAAASUVORK5CYII=`\n         * @returns Color object\n         */\n        static async fromImage(image) {\n            return Color.fromHex(`#009edd`);\n        }\n        /**\n         * Creates a new Color instance from color in hex format\n         *\n         * @param color in hex for example `#009edd`, `009edd`, `#555`,...\n         * @returns Color object\n         */\n        static fromHex(hex) {\n            const { red, green, blue, alpha } = parseHexColor(hex);\n            return take(new Color(red, green, blue, alpha));\n        }\n        /**\n         * Creates a new Color instance from color in hsl format\n         *\n         * @param color as a hsl for example `hsl(197.1,100%,43.3%)`\n         * @returns Color object\n         */\n        static fromHsl(hsl) {\n            const { red, green, blue, alpha } = parseHslColor(hsl);\n            return take(new Color(red, green, blue, alpha));\n        }\n        /**\n         * Creates a new Color instance from color in rgb format\n         *\n         * @param color as a rgb for example `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`\n         * @returns Color object\n         */\n        static fromRgbString(rgb) {\n            const { red, green, blue, alpha } = parseRgbColor(rgb);\n            return take(new Color(red, green, blue, alpha));\n        }\n        /**\n         * Creates a new Color instance from color in rbga format\n         *\n         * @param color as a rgba for example `rgba(0,158,221,0.5)`, `rgb(0%,62%,86.7%,50%)`\n         * @returns Color object\n         */\n        static fromRgbaString(rgba) {\n            const { red, green, blue, alpha } = parseRgbaColor(rgba);\n            return take(new Color(red, green, blue, alpha));\n        }\n        /**\n         * Creates a new Color for color channels values\n         *\n         * @param red number from 0 to 255\n         * @param green number from 0 to 255\n         * @param blue number from 0 to 255\n         * @param alpha number from 0 (transparent) to 255 (opaque = default)\n         * @returns Color object\n         */\n        static fromValues(red, green, blue, alpha = 255) {\n            return take(new Color(red, green, blue, alpha));\n        }\n        /**\n         * Checks if the given value is a valid Color object.\n         *\n         * @param {unknown} value - The value to check.\n         * @return {value is WithTake<Color>} Returns true if the value is a valid Color object, false otherwise.\n         */\n        static isColor(value) {\n            if (typeof value !== 'object') {\n                return false;\n            }\n            if (value === null) {\n                return false;\n            }\n            if (typeof value.red !== 'number' ||\n                typeof value.green !== 'number' ||\n                typeof value.blue !== 'number' ||\n                typeof value.alpha !== 'number') {\n                return false;\n            }\n            if (typeof value.then !== 'function') {\n                return false;\n            }\n            return true;\n        }\n        /**\n         * Checks if the given value is a valid hex color string\n         *\n         * @param value - value to check\n         * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)\n         */\n        static isHexColorString(value) {\n            return (typeof value === 'string' &&\n                /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));\n        }\n        /**\n         * Creates new Color object\n         *\n         * Note: Consider using one of static methods like `from` or `fromString`\n         *\n         * @param red number from 0 to 255\n         * @param green number from 0 to 255\n         * @param blue number from 0 to 255\n         * @param alpha number from 0 (transparent) to 255 (opaque)\n         */\n        constructor(red, green, blue, alpha = 255) {\n            this.red = red;\n            this.green = green;\n            this.blue = blue;\n            this.alpha = alpha;\n            checkChannelValue('Red', red);\n            checkChannelValue('Green', green);\n            checkChannelValue('Blue', blue);\n            checkChannelValue('Alpha', alpha);\n        }\n        /**\n         * Shortcut for `red` property\n         * Number from 0 to 255\n         * @alias red\n         */\n        get r() {\n            return this.red;\n        }\n        /**\n         * Shortcut for `green` property\n         * Number from 0 to 255\n         * @alias green\n         */\n        get g() {\n            return this.green;\n        }\n        /**\n         * Shortcut for `blue` property\n         * Number from 0 to 255\n         * @alias blue\n         */\n        get b() {\n            return this.blue;\n        }\n        /**\n         * Shortcut for `alpha` property\n         * Number from 0 (transparent) to 255 (opaque)\n         * @alias alpha\n         */\n        get a() {\n            return this.alpha;\n        }\n        /**\n         * Shortcut for `alpha` property\n         * Number from 0 (transparent) to 255 (opaque)\n         * @alias alpha\n         */\n        get opacity() {\n            return this.alpha;\n        }\n        /**\n         * Shortcut for 1-`alpha` property\n         */\n        get transparency() {\n            return 255 - this.alpha;\n        }\n        clone() {\n            return take(new Color(this.red, this.green, this.blue, this.alpha));\n        }\n        toString() {\n            return this.toHex();\n        }\n        toHex() {\n            if (this.alpha === 255) {\n                return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue\n                .toString(16)\n                .padStart(2, '0')}`;\n            }\n            else {\n                return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue\n                .toString(16)\n                .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;\n            }\n        }\n        toRgb() {\n            if (this.alpha === 255) {\n                return `rgb(${this.red}, ${this.green}, ${this.blue})`;\n            }\n            else {\n                return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;\n            }\n        }\n        toHsl() {\n            throw new Error(`Getting HSL is not implemented`);\n        }\n    }\n\n    /**\n     * Makes color transformer which returns a grayscale version of the color\n     *\n     * @param amount from 0 to 1\n     *\n     * @public exported from `@promptbook/color`\n     */\n    function grayscale(amount) {\n        return ({ red, green, blue, alpha }) => {\n            const average = (red + green + blue) / 3;\n            red = Math.round(average * amount + red * (1 - amount));\n            green = Math.round(average * amount + green * (1 - amount));\n            blue = Math.round(average * amount + blue * (1 - amount));\n            return Color.fromValues(red, green, blue, alpha);\n        };\n    }\n\n    /**\n     * Converts HSL values to RGB values\n     *\n     * @param hue [0-1]\n     * @param saturation [0-1]\n     * @param lightness [0-1]\n     * @returns [red, green, blue] [0-255]\n     *\n     * @private util of `@promptbook/color`\n     */\n    function hslToRgb(hue, saturation, lightness) {\n        let red;\n        let green;\n        let blue;\n        if (saturation === 0) {\n            // achromatic\n            red = lightness;\n            green = lightness;\n            blue = lightness;\n        }\n        else {\n            // TODO: Extract to separate function\n            const hue2rgb = (p, q, t) => {\n                if (t < 0)\n                    t += 1;\n                if (t > 1)\n                    t -= 1;\n                if (t < 1 / 6)\n                    return p + (q - p) * 6 * t;\n                if (t < 1 / 2)\n                    return q;\n                if (t < 2 / 3)\n                    return p + (q - p) * (2 / 3 - t) * 6;\n                return p;\n            };\n            const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;\n            const p = 2 * lightness - q;\n            red = hue2rgb(p, q, hue + 1 / 3);\n            green = hue2rgb(p, q, hue);\n            blue = hue2rgb(p, q, hue - 1 / 3);\n        }\n        return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];\n    }\n    /**\n     * TODO: Properly name all used internal variables\n     */\n\n    /**\n     * Converts RGB values to HSL values\n     *\n     * @param red [0-255]\n     * @param green [0-255]\n     * @param blue [0-255]\n     * @returns [hue, saturation, lightness] [0-1]\n     *\n     * @private util of `@promptbook/color`\n     */\n    function rgbToHsl(red, green, blue) {\n        red /= 255;\n        green /= 255;\n        blue /= 255;\n        const max = Math.max(red, green, blue);\n        const min = Math.min(red, green, blue);\n        let hue;\n        let saturation;\n        const lightness = (max + min) / 2;\n        if (max === min) {\n            // achromatic\n            hue = 0;\n            saturation = 0;\n        }\n        else {\n            const d = max - min;\n            saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);\n            switch (max) {\n                case red:\n                    hue = (green - blue) / d + (green < blue ? 6 : 0);\n                    break;\n                case green:\n                    hue = (blue - red) / d + 2;\n                    break;\n                case blue:\n                    hue = (red - green) / d + 4;\n                    break;\n                default:\n                    hue = 0;\n            }\n            hue /= 6;\n        }\n        return [hue, saturation, lightness];\n    }\n    /**\n     * TODO: Properly name all used internal variables\n     */\n\n    /**\n     * Makes color transformer which lighten the given color\n     *\n     * @param amount from 0 to 1\n     *\n     * @public exported from `@promptbook/color`\n     */\n    function lighten(amount) {\n        return ({ red, green, blue, alpha }) => {\n            const [h, s, lInitial] = rgbToHsl(red, green, blue);\n            let l = lInitial + amount;\n            l = Math.max(0, Math.min(l, 1)); // Replace lodash clamp with Math.max and Math.min\n            const [r, g, b] = hslToRgb(h, s, l);\n            return Color.fromValues(r, g, b, alpha);\n        };\n    }\n    /**\n     * TODO: Maybe implement by mix+hsl\n     */\n\n    /**\n     * Makes color transformer which saturate the given color\n     *\n     * @param amount from -1 to 1\n     *\n     * @public exported from `@promptbook/color`\n     */\n    function saturate(amount) {\n        return ({ red, green, blue, alpha }) => {\n            const [h, sInitial, l] = rgbToHsl(red, green, blue);\n            let s = sInitial + amount;\n            s = Math.max(0, Math.min(s, 1));\n            const [r, g, b] = hslToRgb(h, s, l);\n            return Color.fromValues(r, g, b, alpha);\n        };\n    }\n    /**\n     * TODO: Maybe implement by mix+hsl\n     */\n\n    /**\n     * Name for the Promptbook\n     *\n     * TODO: [🗽] Unite branding and make single place for it\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const NAME = `Promptbook`;\n    /**\n     * Email of the responsible person\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const ADMIN_EMAIL = 'pavol@ptbk.io';\n    /**\n     * Name of the responsible person for the Promptbook on GitHub\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const ADMIN_GITHUB_NAME = 'hejny';\n    //            <- TODO: [🐊] Pick the best claim\n    /**\n     * Color of the Promptbook\n     *\n     * TODO: [🗽] Unite branding and make single place for it\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const PROMPTBOOK_COLOR = Color.fromString('promptbook');\n    // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it\n    /**\n     * Colors for syntax highlighting in the `<BookEditor/>`\n     *\n     * TODO: [🗽] Unite branding and make single place for it\n     *\n     * @public exported from `@promptbook/core`\n     */\n    ({\n        TITLE: Color.fromHex('#244EA8'),\n        LINE: Color.fromHex('#eeeeee'),\n        SEPARATOR: Color.fromHex('#cccccc'),\n        COMMITMENT: Color.fromHex('#DA0F78'),\n        PARAMETER: Color.fromHex('#8e44ad'),\n        CODE_BLOCK: Color.fromHex('#7700ffff'),\n    });\n    // <- TODO: [🧠][🈵] Using `Color` here increases the package size approx 3kb, maybe remove it\n    /**\n     * Chat color of the Promptbook (in chat)\n     *\n     * TODO: [🗽] Unite branding and make single place for it\n     *\n     * @public exported from `@promptbook/core`\n     */\n    PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));\n    // <- TODO: [🧠][🈵] Using `Color` and `lighten`, `saturate`,... here increases the package size approx 3kb, maybe remove it\n    /**\n     * Color of the user (in chat)\n     *\n     * TODO: [🗽] Unite branding and make single place for it\n     *\n     * @public exported from `@promptbook/core`\n     */\n    Color.fromHex('#1D4ED8');\n    // <- TODO: [🧠] Better system for generator warnings - not always \"code\" and \"by `@promptbook/cli`\"\n    /**\n     * The maximum number of iterations for a loops\n     *\n     * @private within the repository - too low-level in comparison with other `MAX_...`\n     */\n    const LOOP_LIMIT = 1000;\n    /**\n     * Strings to represent various values in the context of parameter values\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    const VALUE_STRINGS = {\n        empty: '(nothing; empty string)',\n        null: '(no value; null)',\n        undefined: '(unknown value; undefined)',\n        nan: '(not a number; NaN)',\n        infinity: '(infinity; ∞)',\n        negativeInfinity: '(negative infinity; -∞)',\n        unserializable: '(unserializable value)',\n        circular: '(circular JSON)',\n    };\n    /**\n     * Small number limit\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    const SMALL_NUMBER = 0.001;\n    /**\n     * Timeout for the connections in milliseconds\n     *\n     * @private within the repository - too low-level in comparison with other `MAX_...`\n     */\n    const CONNECTION_TIMEOUT_MS = 7 * 1000;\n    // <- TODO: [⏳] Standardize timeouts, Make DEFAULT_TIMEOUT_MS as global constant\n    /**\n     * How many times to retry the connections\n     *\n     * @private within the repository - too low-level in comparison with other `MAX_...`\n     */\n    const CONNECTION_RETRIES_LIMIT = 5;\n    // <- TODO: [🧜‍♂️]\n    /**\n     * Default settings for parsing and generating CSV files in Promptbook.\n     *\n     * @public exported from `@promptbook/core`\n     */\n    Object.freeze({\n        delimiter: ',',\n        quoteChar: '\"',\n        newline: '\\n',\n        skipEmptyLines: true,\n    });\n    /**\n     * Default rate limits (requests per minute)\n     *\n     * Note: Adjust based on the provider tier you are have\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const DEFAULT_MAX_REQUESTS_PER_MINUTE = 60;\n    /**\n     * API request timeout in milliseconds\n     * Can be overridden via API_REQUEST_TIMEOUT environment variable\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const API_REQUEST_TIMEOUT = parseInt(process.env.API_REQUEST_TIMEOUT || '90000');\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value\n     */\n\n    /**\n     * Orders JSON object by keys\n     *\n     * @returns The same type of object as the input re-ordered\n     * @public exported from `@promptbook/utils`\n     */\n    function orderJson(options) {\n        const { value, order } = options;\n        const orderedValue = {\n            ...(order === undefined ? {} : Object.fromEntries(order.map((key) => [key, undefined]))),\n            ...value,\n        };\n        return orderedValue;\n    }\n\n    /**\n     * Freezes the given object and all its nested objects recursively\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it mutates given object\n     * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object\n     *\n     * @returns The same object as the input, but deeply frozen\n     * @public exported from `@promptbook/utils`\n     */\n    function $deepFreeze(objectValue) {\n        if (Array.isArray(objectValue)) {\n            return Object.freeze(objectValue.map((item) => $deepFreeze(item)));\n        }\n        const propertyNames = Object.getOwnPropertyNames(objectValue);\n        for (const propertyName of propertyNames) {\n            const value = objectValue[propertyName];\n            if (value && typeof value === 'object') {\n                $deepFreeze(value);\n            }\n        }\n        Object.freeze(objectValue);\n        return objectValue;\n    }\n    /**\n     * TODO: [🧠] Is there a way how to meaningfully test this utility\n     */\n\n    /**\n     * Make error report URL for the given error\n     *\n     * @private private within the repository\n     */\n    function getErrorReportUrl(error) {\n        const report = {\n            title: `🐜 Error report from ${NAME}`,\n            body: spaceTrim__default[\"default\"]((block) => `\n\n\n            \\`${error.name || 'Error'}\\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.\n\n            \\`\\`\\`\n            ${block(error.message || '(no error message)')}\n            \\`\\`\\`\n\n\n            ## More info:\n\n            - **Promptbook engine version:** ${PROMPTBOOK_ENGINE_VERSION}\n            - **Book language version:** ${BOOK_LANGUAGE_VERSION}\n            - **Time:** ${new Date().toISOString()}\n\n            <details>\n            <summary>Stack trace:</summary>\n\n            ## Stack trace:\n\n            \\`\\`\\`stacktrace\n            ${block(error.stack || '(empty)')}\n            \\`\\`\\`\n            </details>\n\n        `),\n        };\n        const reportUrl = new URL(`https://github.com/webgptorg/promptbook/issues/new`);\n        reportUrl.searchParams.set('labels', 'bug');\n        reportUrl.searchParams.set('assignees', ADMIN_GITHUB_NAME);\n        reportUrl.searchParams.set('title', report.title);\n        reportUrl.searchParams.set('body', report.body);\n        return reportUrl;\n    }\n\n    /**\n     * This error type indicates that the error should not happen and its last check before crashing with some other error\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class UnexpectedError extends Error {\n        constructor(message) {\n            super(spaceTrim$1.spaceTrim((block) => `\n                    ${block(message)}\n\n                    Note: This error should not happen.\n                    It's probably a bug in the pipeline collection\n\n                    Please report issue:\n                    ${block(getErrorReportUrl(new Error(message)).href)}\n\n                    Or contact us on ${ADMIN_EMAIL}\n\n                `));\n            this.name = 'UnexpectedError';\n            Object.setPrototypeOf(this, UnexpectedError.prototype);\n        }\n    }\n\n    /**\n     * This error type indicates that somewhere in the code non-Error object was thrown and it was wrapped into the `WrappedError`\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class WrappedError extends Error {\n        constructor(whatWasThrown) {\n            const tag = `[🤮]`;\n            console.error(tag, whatWasThrown);\n            super(spaceTrim$1.spaceTrim(`\n                Non-Error object was thrown\n\n                Note: Look for ${tag} in the console for more details\n                Please report issue on ${ADMIN_EMAIL}\n            `));\n            this.name = 'WrappedError';\n            Object.setPrototypeOf(this, WrappedError.prototype);\n        }\n    }\n\n    /**\n     * Helper used in catch blocks to assert that the error is an instance of `Error`\n     *\n     * @param whatWasThrown Any object that was thrown\n     * @returns Nothing if the error is an instance of `Error`\n     * @throws `WrappedError` or `UnexpectedError` if the error is not standard\n     *\n     * @private within the repository\n     */\n    function assertsError(whatWasThrown) {\n        // Case 1: Handle error which was rethrown as `WrappedError`\n        if (whatWasThrown instanceof WrappedError) {\n            const wrappedError = whatWasThrown;\n            throw wrappedError;\n        }\n        // Case 2: Handle unexpected errors\n        if (whatWasThrown instanceof UnexpectedError) {\n            const unexpectedError = whatWasThrown;\n            throw unexpectedError;\n        }\n        // Case 3: Handle standard errors - keep them up to consumer\n        if (whatWasThrown instanceof Error) {\n            return;\n        }\n        // Case 4: Handle non-standard errors - wrap them into `WrappedError` and throw\n        throw new WrappedError(whatWasThrown);\n    }\n\n    /**\n     * Checks if the value is [🚉] serializable as JSON\n     * If not, throws an UnexpectedError with a rich error message and tracking\n     *\n     * - Almost all primitives are serializable BUT:\n     * - `undefined` is not serializable\n     * - `NaN` is not serializable\n     * - Objects and arrays are serializable if all their properties are serializable\n     * - Functions are not serializable\n     * - Circular references are not serializable\n     * - `Date` objects are not serializable\n     * - `Map` and `Set` objects are not serializable\n     * - `RegExp` objects are not serializable\n     * - `Error` objects are not serializable\n     * - `Symbol` objects are not serializable\n     * - And much more...\n     *\n     * @throws UnexpectedError if the value is not serializable as JSON\n     * @public exported from `@promptbook/utils`\n     */\n    function checkSerializableAsJson(options) {\n        const { value, name, message } = options;\n        if (value === undefined) {\n            throw new UnexpectedError(`${name} is undefined`);\n        }\n        else if (value === null) {\n            return;\n        }\n        else if (typeof value === 'boolean') {\n            return;\n        }\n        else if (typeof value === 'number' && !isNaN(value)) {\n            return;\n        }\n        else if (typeof value === 'string') {\n            return;\n        }\n        else if (typeof value === 'symbol') {\n            throw new UnexpectedError(`${name} is symbol`);\n        }\n        else if (typeof value === 'function') {\n            throw new UnexpectedError(`${name} is function`);\n        }\n        else if (typeof value === 'object' && Array.isArray(value)) {\n            for (let i = 0; i < value.length; i++) {\n                checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });\n            }\n        }\n        else if (typeof value === 'object') {\n            if (value instanceof Date) {\n                throw new UnexpectedError(spaceTrim__default[\"default\"]((block) => `\n                        \\`${name}\\` is Date\n\n                        Use \\`string_date_iso8601\\` instead\n\n                        Additional message for \\`${name}\\`:\n                        ${block(message || '(nothing)')}\n                    `));\n            }\n            else if (value instanceof Map) {\n                throw new UnexpectedError(`${name} is Map`);\n            }\n            else if (value instanceof Set) {\n                throw new UnexpectedError(`${name} is Set`);\n            }\n            else if (value instanceof RegExp) {\n                throw new UnexpectedError(`${name} is RegExp`);\n            }\n            else if (value instanceof Error) {\n                throw new UnexpectedError(spaceTrim__default[\"default\"]((block) => `\n                        \\`${name}\\` is unserialized Error\n\n                        Use function \\`serializeError\\`\n\n                        Additional message for \\`${name}\\`:\n                        ${block(message || '(nothing)')}\n\n                    `));\n            }\n            else {\n                for (const [subName, subValue] of Object.entries(value)) {\n                    if (subValue === undefined) {\n                        // Note: undefined in object is serializable - it is just omitted\n                        continue;\n                    }\n                    checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });\n                }\n                try {\n                    JSON.stringify(value); // <- TODO: [0]\n                }\n                catch (error) {\n                    assertsError(error);\n                    throw new UnexpectedError(spaceTrim__default[\"default\"]((block) => `\n                            \\`${name}\\` is not serializable\n\n                            ${block(error.stack || error.message)}\n\n                            Additional message for \\`${name}\\`:\n                            ${block(message || '(nothing)')}\n                        `));\n                }\n                /*\n                TODO: [0] Is there some more elegant way to check circular references?\n                const seen = new Set();\n                const stack = [{ value }];\n                while (stack.length > 0) {\n                    const { value } = stack.pop()!;\n                    if (typeof value === 'object' && value !== null) {\n                        if (seen.has(value)) {\n                            throw new UnexpectedError(`${name} has circular reference`);\n                        }\n                        seen.add(value);\n                        if (Array.isArray(value)) {\n                            stack.push(...value.map((value) => ({ value })));\n                        } else {\n                            stack.push(...Object.values(value).map((value) => ({ value })));\n                        }\n                    }\n                }\n                */\n                return;\n            }\n        }\n        else {\n            throw new UnexpectedError(spaceTrim__default[\"default\"]((block) => `\n                    \\`${name}\\` is unknown type\n\n                    Additional message for \\`${name}\\`:\n                    ${block(message || '(nothing)')}\n                `));\n        }\n    }\n    /**\n     * TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`\n     * TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks\n     * Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message\n     */\n\n    /**\n     * Creates a deep clone of the given object\n     *\n     * Note: [🔂] This function is idempotent.\n     * Note: This method only works for objects that are fully serializable to JSON and do not contain functions, Dates, or special types.\n     *\n     * @param objectValue The object to clone.\n     * @returns A deep, writable clone of the input object.\n     * @public exported from `@promptbook/utils`\n     */\n    function deepClone(objectValue) {\n        return JSON.parse(JSON.stringify(objectValue));\n        /*\n        TODO: [🧠] Is there a better implementation?\n        > const propertyNames = Object.getOwnPropertyNames(objectValue);\n        > for (const propertyName of propertyNames) {\n        >     const value = (objectValue as chococake)[propertyName];\n        >     if (value && typeof value === 'object') {\n        >         deepClone(value);\n        >     }\n        > }\n        > return Object.assign({}, objectValue);\n        */\n    }\n    /**\n     * TODO: [🧠] Is there a way how to meaningfully test this utility\n     */\n\n    /**\n     * Utility to export a JSON object from a function\n     *\n     * 1) Checks if the value is serializable as JSON\n     * 2) Makes a deep clone of the object\n     * 2) Orders the object properties\n     * 2) Deeply freezes the cloned object\n     *\n     * Note: This function does not mutates the given object\n     *\n     * @returns The same type of object as the input but read-only and re-ordered\n     * @public exported from `@promptbook/utils`\n     */\n    function exportJson(options) {\n        const { name, value, order, message } = options;\n        checkSerializableAsJson({ name, value, message });\n        const orderedValue = \n        // TODO: Fix error \"Type instantiation is excessively deep and possibly infinite.\"\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        order === undefined\n            ? deepClone(value)\n            : orderJson({\n                value: value,\n                // <- Note: checkSerializableAsJson asserts that the value is serializable as JSON\n                order: order,\n            });\n        $deepFreeze(orderedValue);\n        return orderedValue;\n    }\n    /**\n     * TODO: [🧠] Is there a way how to meaningfully test this utility\n     */\n\n    /**\n     * Nonce which is used for replacing things in strings\n     *\n     * @private within the repository\n     */\n    const REPLACING_NONCE = 'ptbkauk42kV2dzao34faw7FudQUHYPtW';\n    /**\n     * Nonce which is used as string which is not occurring in normal text\n     *\n     * @private within the repository\n     */\n    const SALT_NONCE = 'ptbkghhewbvruets21t54et5';\n    /**\n     * Placeholder value indicating a parameter is missing its value.\n     *\n     * @private within the repository\n     */\n    const RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;\n    /**\n     * Placeholder value indicating a parameter is restricted and cannot be used directly.\n     *\n     * @private within the repository\n     */\n    const RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;\n    /**\n     * The names of the parameters that are reserved for special purposes\n     *\n     * @public exported from `@promptbook/core`\n     */\n    exportJson({\n        name: 'RESERVED_PARAMETER_NAMES',\n        message: `The names of the parameters that are reserved for special purposes`,\n        value: [\n            'content',\n            'context',\n            'knowledge',\n            'examples',\n            'modelName',\n            'currentDate',\n            // <- TODO: list here all command names\n            // <- TODO: Add more like 'date', 'modelName',...\n            // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter\n        ],\n    });\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Tests if given string is valid URL.\n     *\n     * Note: [🔂] This function is idempotent.\n     * Note: Dataurl are considered perfectly valid.\n     * Note: There are few similar functions:\n     * - `isValidUrl` *(this one)* which tests any URL\n     * - `isValidAgentUrl` which tests just agent URL\n     * - `isValidPipelineUrl` which tests just pipeline URL\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function isValidUrl(url) {\n        if (typeof url !== 'string') {\n            return false;\n        }\n        try {\n            if (url.startsWith('blob:')) {\n                url = url.replace(/^blob:/, '');\n            }\n            const urlObject = new URL(url /* because fail is handled */);\n            if (!['http:', 'https:', 'data:'].includes(urlObject.protocol)) {\n                return false;\n            }\n            return true;\n        }\n        catch (error) {\n            return false;\n        }\n    }\n\n    const defaultDiacriticsRemovalMap = [\n        {\n            base: 'A',\n            letters: '\\u0041\\u24B6\\uFF21\\u00C0\\u00C1\\u00C2\\u1EA6\\u1EA4\\u1EAA\\u1EA8\\u00C3\\u0100\\u0102\\u1EB0\\u1EAE\\u1EB4\\u1EB2\\u0226\\u01E0\\u00C4\\u01DE\\u1EA2\\u00C5\\u01FA\\u01CD\\u0200\\u0202\\u1EA0\\u1EAC\\u1EB6\\u1E00\\u0104\\u023A\\u2C6F',\n        },\n        { base: 'AA', letters: '\\uA732' },\n        { base: 'AE', letters: '\\u00C6\\u01FC\\u01E2' },\n        { base: 'AO', letters: '\\uA734' },\n        { base: 'AU', letters: '\\uA736' },\n        { base: 'AV', letters: '\\uA738\\uA73A' },\n        { base: 'AY', letters: '\\uA73C' },\n        {\n            base: 'B',\n            letters: '\\u0042\\u24B7\\uFF22\\u1E02\\u1E04\\u1E06\\u0243\\u0182\\u0181',\n        },\n        {\n            base: 'C',\n            letters: '\\u0043\\u24B8\\uFF23\\u0106\\u0108\\u010A\\u010C\\u00C7\\u1E08\\u0187\\u023B\\uA73E',\n        },\n        {\n            base: 'D',\n            letters: '\\u0044\\u24B9\\uFF24\\u1E0A\\u010E\\u1E0C\\u1E10\\u1E12\\u1E0E\\u0110\\u018B\\u018A\\u0189\\uA779\\u00D0',\n        },\n        { base: 'DZ', letters: '\\u01F1\\u01C4' },\n        { base: 'Dz', letters: '\\u01F2\\u01C5' },\n        {\n            base: 'E',\n            letters: '\\u0045\\u24BA\\uFF25\\u00C8\\u00C9\\u00CA\\u1EC0\\u1EBE\\u1EC4\\u1EC2\\u1EBC\\u0112\\u1E14\\u1E16\\u0114\\u0116\\u00CB\\u1EBA\\u011A\\u0204\\u0206\\u1EB8\\u1EC6\\u0228\\u1E1C\\u0118\\u1E18\\u1E1A\\u0190\\u018E',\n        },\n        { base: 'F', letters: '\\u0046\\u24BB\\uFF26\\u1E1E\\u0191\\uA77B' },\n        {\n            base: 'G',\n            letters: '\\u0047\\u24BC\\uFF27\\u01F4\\u011C\\u1E20\\u011E\\u0120\\u01E6\\u0122\\u01E4\\u0193\\uA7A0\\uA77D\\uA77E',\n        },\n        {\n            base: 'H',\n            letters: '\\u0048\\u24BD\\uFF28\\u0124\\u1E22\\u1E26\\u021E\\u1E24\\u1E28\\u1E2A\\u0126\\u2C67\\u2C75\\uA78D',\n        },\n        {\n            base: 'I',\n            letters: '\\u0049\\u24BE\\uFF29\\u00CC\\u00CD\\u00CE\\u0128\\u012A\\u012C\\u0130\\u00CF\\u1E2E\\u1EC8\\u01CF\\u0208\\u020A\\u1ECA\\u012E\\u1E2C\\u0197',\n        },\n        { base: 'J', letters: '\\u004A\\u24BF\\uFF2A\\u0134\\u0248' },\n        {\n            base: 'K',\n            letters: '\\u004B\\u24C0\\uFF2B\\u1E30\\u01E8\\u1E32\\u0136\\u1E34\\u0198\\u2C69\\uA740\\uA742\\uA744\\uA7A2',\n        },\n        {\n            base: 'L',\n            letters: '\\u004C\\u24C1\\uFF2C\\u013F\\u0139\\u013D\\u1E36\\u1E38\\u013B\\u1E3C\\u1E3A\\u0141\\u023D\\u2C62\\u2C60\\uA748\\uA746\\uA780',\n        },\n        { base: 'LJ', letters: '\\u01C7' },\n        { base: 'Lj', letters: '\\u01C8' },\n        { base: 'M', letters: '\\u004D\\u24C2\\uFF2D\\u1E3E\\u1E40\\u1E42\\u2C6E\\u019C' },\n        {\n            base: 'N',\n            letters: '\\u004E\\u24C3\\uFF2E\\u01F8\\u0143\\u00D1\\u1E44\\u0147\\u1E46\\u0145\\u1E4A\\u1E48\\u0220\\u019D\\uA790\\uA7A4',\n        },\n        { base: 'NJ', letters: '\\u01CA' },\n        { base: 'Nj', letters: '\\u01CB' },\n        {\n            base: 'O',\n            letters: '\\u004F\\u24C4\\uFF2F\\u00D2\\u00D3\\u00D4\\u1ED2\\u1ED0\\u1ED6\\u1ED4\\u00D5\\u1E4C\\u022C\\u1E4E\\u014C\\u1E50\\u1E52\\u014E\\u022E\\u0230\\u00D6\\u022A\\u1ECE\\u0150\\u01D1\\u020C\\u020E\\u01A0\\u1EDC\\u1EDA\\u1EE0\\u1EDE\\u1EE2\\u1ECC\\u1ED8\\u01EA\\u01EC\\u00D8\\u01FE\\u0186\\u019F\\uA74A\\uA74C',\n        },\n        { base: 'OI', letters: '\\u01A2' },\n        { base: 'OO', letters: '\\uA74E' },\n        { base: 'OU', letters: '\\u0222' },\n        { base: 'OE', letters: '\\u008C\\u0152' },\n        { base: 'oe', letters: '\\u009C\\u0153' },\n        {\n            base: 'P',\n            letters: '\\u0050\\u24C5\\uFF30\\u1E54\\u1E56\\u01A4\\u2C63\\uA750\\uA752\\uA754',\n        },\n        { base: 'Q', letters: '\\u0051\\u24C6\\uFF31\\uA756\\uA758\\u024A' },\n        {\n            base: 'R',\n            letters: '\\u0052\\u24C7\\uFF32\\u0154\\u1E58\\u0158\\u0210\\u0212\\u1E5A\\u1E5C\\u0156\\u1E5E\\u024C\\u2C64\\uA75A\\uA7A6\\uA782',\n        },\n        {\n            base: 'S',\n            letters: '\\u0053\\u24C8\\uFF33\\u1E9E\\u015A\\u1E64\\u015C\\u1E60\\u0160\\u1E66\\u1E62\\u1E68\\u0218\\u015E\\u2C7E\\uA7A8\\uA784',\n        },\n        {\n            base: 'T',\n            letters: '\\u0054\\u24C9\\uFF34\\u1E6A\\u0164\\u1E6C\\u021A\\u0162\\u1E70\\u1E6E\\u0166\\u01AC\\u01AE\\u023E\\uA786',\n        },\n        { base: 'TZ', letters: '\\uA728' },\n        {\n            base: 'U',\n            letters: '\\u0055\\u24CA\\uFF35\\u00D9\\u00DA\\u00DB\\u0168\\u1E78\\u016A\\u1E7A\\u016C\\u00DC\\u01DB\\u01D7\\u01D5\\u01D9\\u1EE6\\u016E\\u0170\\u01D3\\u0214\\u0216\\u01AF\\u1EEA\\u1EE8\\u1EEE\\u1EEC\\u1EF0\\u1EE4\\u1E72\\u0172\\u1E76\\u1E74\\u0244',\n        },\n        { base: 'V', letters: '\\u0056\\u24CB\\uFF36\\u1E7C\\u1E7E\\u01B2\\uA75E\\u0245' },\n        { base: 'VY', letters: '\\uA760' },\n        {\n            base: 'W',\n            letters: '\\u0057\\u24CC\\uFF37\\u1E80\\u1E82\\u0174\\u1E86\\u1E84\\u1E88\\u2C72',\n        },\n        { base: 'X', letters: '\\u0058\\u24CD\\uFF38\\u1E8A\\u1E8C' },\n        {\n            base: 'Y',\n            letters: '\\u0059\\u24CE\\uFF39\\u1EF2\\u00DD\\u0176\\u1EF8\\u0232\\u1E8E\\u0178\\u1EF6\\u1EF4\\u01B3\\u024E\\u1EFE',\n        },\n        {\n            base: 'Z',\n            letters: '\\u005A\\u24CF\\uFF3A\\u0179\\u1E90\\u017B\\u017D\\u1E92\\u1E94\\u01B5\\u0224\\u2C7F\\u2C6B\\uA762',\n        },\n        {\n            base: 'a',\n            letters: '\\u0061\\u24D0\\uFF41\\u1E9A\\u00E0\\u00E1\\u00E2\\u1EA7\\u1EA5\\u1EAB\\u1EA9\\u00E3\\u0101\\u0103\\u1EB1\\u1EAF\\u1EB5\\u1EB3\\u0227\\u01E1\\u00E4\\u01DF\\u1EA3\\u00E5\\u01FB\\u01CE\\u0201\\u0203\\u1EA1\\u1EAD\\u1EB7\\u1E01\\u0105\\u2C65\\u0250',\n        },\n        { base: 'aa', letters: '\\uA733' },\n        { base: 'ae', letters: '\\u00E6\\u01FD\\u01E3' },\n        { base: 'ao', letters: '\\uA735' },\n        { base: 'au', letters: '\\uA737' },\n        { base: 'av', letters: '\\uA739\\uA73B' },\n        { base: 'ay', letters: '\\uA73D' },\n        {\n            base: 'b',\n            letters: '\\u0062\\u24D1\\uFF42\\u1E03\\u1E05\\u1E07\\u0180\\u0183\\u0253',\n        },\n        {\n            base: 'c',\n            letters: '\\u0063\\u24D2\\uFF43\\u0107\\u0109\\u010B\\u010D\\u00E7\\u1E09\\u0188\\u023C\\uA73F\\u2184',\n        },\n        {\n            base: 'd',\n            letters: '\\u0064\\u24D3\\uFF44\\u1E0B\\u010F\\u1E0D\\u1E11\\u1E13\\u1E0F\\u0111\\u018C\\u0256\\u0257\\uA77A',\n        },\n        { base: 'dz', letters: '\\u01F3\\u01C6' },\n        {\n            base: 'e',\n            letters: '\\u0065\\u24D4\\uFF45\\u00E8\\u00E9\\u00EA\\u1EC1\\u1EBF\\u1EC5\\u1EC3\\u1EBD\\u0113\\u1E15\\u1E17\\u0115\\u0117\\u00EB\\u1EBB\\u011B\\u0205\\u0207\\u1EB9\\u1EC7\\u0229\\u1E1D\\u0119\\u1E19\\u1E1B\\u0247\\u025B\\u01DD',\n        },\n        { base: 'f', letters: '\\u0066\\u24D5\\uFF46\\u1E1F\\u0192\\uA77C' },\n        {\n            base: 'g',\n            letters: '\\u0067\\u24D6\\uFF47\\u01F5\\u011D\\u1E21\\u011F\\u0121\\u01E7\\u0123\\u01E5\\u0260\\uA7A1\\u1D79\\uA77F',\n        },\n        {\n            base: 'h',\n            letters: '\\u0068\\u24D7\\uFF48\\u0125\\u1E23\\u1E27\\u021F\\u1E25\\u1E29\\u1E2B\\u1E96\\u0127\\u2C68\\u2C76\\u0265',\n        },\n        { base: 'hv', letters: '\\u0195' },\n        {\n            base: 'i',\n            letters: '\\u0069\\u24D8\\uFF49\\u00EC\\u00ED\\u00EE\\u0129\\u012B\\u012D\\u00EF\\u1E2F\\u1EC9\\u01D0\\u0209\\u020B\\u1ECB\\u012F\\u1E2D\\u0268\\u0131',\n        },\n        { base: 'j', letters: '\\u006A\\u24D9\\uFF4A\\u0135\\u01F0\\u0249' },\n        {\n            base: 'k',\n            letters: '\\u006B\\u24DA\\uFF4B\\u1E31\\u01E9\\u1E33\\u0137\\u1E35\\u0199\\u2C6A\\uA741\\uA743\\uA745\\uA7A3',\n        },\n        {\n            base: 'l',\n            letters: '\\u006C\\u24DB\\uFF4C\\u0140\\u013A\\u013E\\u1E37\\u1E39\\u013C\\u1E3D\\u1E3B\\u017F\\u0142\\u019A\\u026B\\u2C61\\uA749\\uA781\\uA747',\n        },\n        { base: 'lj', letters: '\\u01C9' },\n        { base: 'm', letters: '\\u006D\\u24DC\\uFF4D\\u1E3F\\u1E41\\u1E43\\u0271\\u026F' },\n        {\n            base: 'n',\n            letters: '\\u006E\\u24DD\\uFF4E\\u01F9\\u0144\\u00F1\\u1E45\\u0148\\u1E47\\u0146\\u1E4B\\u1E49\\u019E\\u0272\\u0149\\uA791\\uA7A5',\n        },\n        { base: 'nj', letters: '\\u01CC' },\n        {\n            base: 'o',\n            letters: '\\u006F\\u24DE\\uFF4F\\u00F2\\u00F3\\u00F4\\u1ED3\\u1ED1\\u1ED7\\u1ED5\\u00F5\\u1E4D\\u022D\\u1E4F\\u014D\\u1E51\\u1E53\\u014F\\u022F\\u0231\\u00F6\\u022B\\u1ECF\\u0151\\u01D2\\u020D\\u020F\\u01A1\\u1EDD\\u1EDB\\u1EE1\\u1EDF\\u1EE3\\u1ECD\\u1ED9\\u01EB\\u01ED\\u00F8\\u01FF\\u0254\\uA74B\\uA74D\\u0275',\n        },\n        { base: 'oi', letters: '\\u01A3' },\n        { base: 'ou', letters: '\\u0223' },\n        { base: 'oo', letters: '\\uA74F' },\n        {\n            base: 'p',\n            letters: '\\u0070\\u24DF\\uFF50\\u1E55\\u1E57\\u01A5\\u1D7D\\uA751\\uA753\\uA755',\n        },\n        { base: 'q', letters: '\\u0071\\u24E0\\uFF51\\u024B\\uA757\\uA759' },\n        {\n            base: 'r',\n            letters: '\\u0072\\u24E1\\uFF52\\u0155\\u1E59\\u0159\\u0211\\u0213\\u1E5B\\u1E5D\\u0157\\u1E5F\\u024D\\u027D\\uA75B\\uA7A7\\uA783',\n        },\n        {\n            base: 's',\n            letters: '\\u0073\\u24E2\\uFF53\\u00DF\\u015B\\u1E65\\u015D\\u1E61\\u0161\\u1E67\\u1E63\\u1E69\\u0219\\u015F\\u023F\\uA7A9\\uA785\\u1E9B',\n        },\n        {\n            base: 't',\n            letters: '\\u0074\\u24E3\\uFF54\\u1E6B\\u1E97\\u0165\\u1E6D\\u021B\\u0163\\u1E71\\u1E6F\\u0167\\u01AD\\u0288\\u2C66\\uA787',\n        },\n        { base: 'tz', letters: '\\uA729' },\n        {\n            base: 'u',\n            letters: '\\u0075\\u24E4\\uFF55\\u00F9\\u00FA\\u00FB\\u0169\\u1E79\\u016B\\u1E7B\\u016D\\u00FC\\u01DC\\u01D8\\u01D6\\u01DA\\u1EE7\\u016F\\u0171\\u01D4\\u0215\\u0217\\u01B0\\u1EEB\\u1EE9\\u1EEF\\u1EED\\u1EF1\\u1EE5\\u1E73\\u0173\\u1E77\\u1E75\\u0289',\n        },\n        { base: 'v', letters: '\\u0076\\u24E5\\uFF56\\u1E7D\\u1E7F\\u028B\\uA75F\\u028C' },\n        { base: 'vy', letters: '\\uA761' },\n        {\n            base: 'w',\n            letters: '\\u0077\\u24E6\\uFF57\\u1E81\\u1E83\\u0175\\u1E87\\u1E85\\u1E98\\u1E89\\u2C73',\n        },\n        { base: 'x', letters: '\\u0078\\u24E7\\uFF58\\u1E8B\\u1E8D' },\n        {\n            base: 'y',\n            letters: '\\u0079\\u24E8\\uFF59\\u1EF3\\u00FD\\u0177\\u1EF9\\u0233\\u1E8F\\u00FF\\u1EF7\\u1E99\\u1EF5\\u01B4\\u024F\\u1EFF',\n        },\n        {\n            base: 'z',\n            letters: '\\u007A\\u24E9\\uFF5A\\u017A\\u1E91\\u017C\\u017E\\u1E93\\u1E95\\u01B6\\u0225\\u0240\\u2C6C\\uA763',\n        },\n    ];\n    /**\n     * Map of letters from diacritic variant to diacritless variant\n     * Contains lowercase and uppercase separatelly\n     *\n     * > \"á\" => \"a\"\n     * > \"ě\" => \"e\"\n     * > \"Ă\" => \"A\"\n     * > ...\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    const DIACRITIC_VARIANTS_LETTERS = {};\n    // tslint:disable-next-line: prefer-for-of\n    for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {\n        const letters = defaultDiacriticsRemovalMap[i].letters;\n        // tslint:disable-next-line: prefer-for-of\n        for (let j = 0; j < letters.length; j++) {\n            DIACRITIC_VARIANTS_LETTERS[letters[j]] = defaultDiacriticsRemovalMap[i].base;\n        }\n    }\n    // <- TODO: [🍓] Put to maker function to save execution time if not needed\n    /*\n      @see https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript\n       Licensed under the Apache License, Version 2.0 (the \"License\");\n       you may not use this file except in compliance with the License.\n       You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing, software\n       distributed under the License is distributed on an \"AS IS\" BASIS,\n       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n       See the License for the specific language governing permissions and\n       limitations under the License.\n    */\n\n    /**\n     * Removes diacritic marks (accents) from characters in a string.\n     *\n     * Note: [🔂] This function is idempotent.\n     *\n     * @param input The string containing diacritics to be normalized.\n     * @returns The string with diacritics removed or normalized.\n     * @public exported from `@promptbook/utils`\n     */\n    function removeDiacritics(input) {\n        /*eslint no-control-regex: \"off\"*/\n        return input.replace(/[^\\u0000-\\u007E]/g, (character) => {\n            return DIACRITIC_VARIANTS_LETTERS[character] || character;\n        });\n    }\n    /**\n     * TODO: [Ж] Variant for cyrillic (and in general non-latin) letters\n     */\n\n    /**\n     * This error indicates problems parsing the format value\n     *\n     * For example, when the format value is not a valid JSON or CSV\n     * This is not thrown directly but in extended classes\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class AbstractFormatError extends Error {\n        // Note: To allow instanceof do not put here error `name`\n        // public readonly name = 'AbstractFormatError';\n        constructor(message) {\n            super(message);\n            Object.setPrototypeOf(this, AbstractFormatError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates problem with parsing of CSV\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class CsvFormatError extends AbstractFormatError {\n        constructor(message) {\n            super(message);\n            this.name = 'CsvFormatError';\n            Object.setPrototypeOf(this, CsvFormatError.prototype);\n        }\n    }\n\n    /**\n     * AuthenticationError is thrown from login function which is dependency of remote server\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class AuthenticationError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'AuthenticationError';\n            Object.setPrototypeOf(this, AuthenticationError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates that the pipeline collection cannot be properly loaded\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class CollectionError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'CollectionError';\n            Object.setPrototypeOf(this, CollectionError.prototype);\n        }\n    }\n\n    /**\n     * Signals that the requested operation could not be completed because the target already exists.\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class ConflictError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'ConflictError';\n            Object.setPrototypeOf(this, ConflictError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates error from the database\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class DatabaseError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'DatabaseError';\n            Object.setPrototypeOf(this, DatabaseError.prototype);\n        }\n    }\n    /**\n     * TODO: [🐱‍🚀] Explain that NotFoundError ([🐱‍🚀] and other specific errors) has priority over DatabaseError in some contexts\n     */\n\n    /**\n     * This error type indicates that you try to use a feature that is not available in the current environment\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class EnvironmentMismatchError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'EnvironmentMismatchError';\n            Object.setPrototypeOf(this, EnvironmentMismatchError.prototype);\n        }\n    }\n\n    /**\n     * This error occurs when some expectation is not met in the execution of the pipeline\n     *\n     * @public exported from `@promptbook/core`\n     * Note: Do not throw this error, its reserved for `checkExpectations` and `createPipelineExecutor` and public ONLY to be serializable through remote server\n     * Note: Always thrown in `checkExpectations` and catched in `createPipelineExecutor` and rethrown as `PipelineExecutionError`\n     * Note: This is a kindof subtype of PipelineExecutionError\n     */\n    class ExpectError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'ExpectError';\n            Object.setPrototypeOf(this, ExpectError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates that the promptbook can not retrieve knowledge from external sources\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class KnowledgeScrapeError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'KnowledgeScrapeError';\n            Object.setPrototypeOf(this, KnowledgeScrapeError.prototype);\n        }\n    }\n\n    /**\n     * This error type indicates that some limit was reached\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class LimitReachedError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'LimitReachedError';\n            Object.setPrototypeOf(this, LimitReachedError.prototype);\n        }\n    }\n\n    /**\n     * This error type indicates that some tools are missing for pipeline execution or preparation\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class MissingToolsError extends Error {\n        constructor(message) {\n            super(spaceTrim$1.spaceTrim((block) => `\n                    ${block(message)}\n\n                    Note: You have probably forgot to provide some tools for pipeline execution or preparation\n\n                `));\n            this.name = 'MissingToolsError';\n            Object.setPrototypeOf(this, MissingToolsError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates that promptbook operation is not allowed\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class NotAllowed extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'NotAllowed';\n            Object.setPrototypeOf(this, NotAllowed.prototype);\n        }\n    }\n\n    /**\n     * This error indicates that promptbook not found in the collection\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class NotFoundError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'NotFoundError';\n            Object.setPrototypeOf(this, NotFoundError.prototype);\n        }\n    }\n\n    /**\n     * This error type indicates that some part of the code is not implemented yet\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class NotYetImplementedError extends Error {\n        constructor(message) {\n            super(spaceTrim$1.spaceTrim((block) => `\n                    ${block(message)}\n\n                    Note: This feature is not implemented yet but it will be soon.\n\n                    If you want speed up the implementation or just read more, look here:\n                    https://github.com/webgptorg/promptbook\n\n                    Or contact us on pavol@ptbk.io\n\n                `));\n            this.name = 'NotYetImplementedError';\n            Object.setPrototypeOf(this, NotYetImplementedError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class ParseError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'ParseError';\n            Object.setPrototypeOf(this, ParseError.prototype);\n        }\n    }\n    /**\n     * TODO: Maybe split `ParseError` and `ApplyError`\n     */\n\n    /**\n     * Generates random token\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic\n     * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)\n     *\n     * @private internal helper function\n     * @returns secure random token\n     */\n    function $randomToken(randomness) {\n        return crypto.randomBytes(randomness).toString('hex');\n    }\n    /**\n     * TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package\n     * TODO: Maybe use nanoid instead https://github.com/ai/nanoid\n     */\n\n    /**\n     * This error indicates errors during the execution of the pipeline\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class PipelineExecutionError extends Error {\n        constructor(message) {\n            // Added id parameter\n            super(message);\n            this.name = 'PipelineExecutionError';\n            // TODO: [🐙] DRY - Maybe $randomId\n            this.id = `error-${$randomToken(8 /* <- TODO: To global config + Use Base58 to avoid similar char conflicts   */)}`;\n            Object.setPrototypeOf(this, PipelineExecutionError.prototype);\n        }\n    }\n    /**\n     * TODO: [🧠][🌂] Add id to all errors\n     */\n\n    /**\n     * This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class PipelineLogicError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'PipelineLogicError';\n            Object.setPrototypeOf(this, PipelineLogicError.prototype);\n        }\n    }\n\n    /**\n     * This error indicates errors in referencing promptbooks between each other\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class PipelineUrlError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'PipelineUrlError';\n            Object.setPrototypeOf(this, PipelineUrlError.prototype);\n        }\n    }\n\n    /**\n     * Error thrown when a fetch request fails\n     *\n     * @public exported from `@promptbook/core`\n     */\n    class PromptbookFetchError extends Error {\n        constructor(message) {\n            super(message);\n            this.name = 'PromptbookFetchError';\n            Object.setPrototypeOf(this, PromptbookFetchError.prototype);\n        }\n    }\n\n    /**\n     * Index of all custom errors\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const PROMPTBOOK_ERRORS = {\n        AbstractFormatError,\n        CsvFormatError,\n        CollectionError,\n        EnvironmentMismatchError,\n        ExpectError,\n        KnowledgeScrapeError,\n        LimitReachedError,\n        MissingToolsError,\n        NotFoundError,\n        NotYetImplementedError,\n        ParseError,\n        PipelineExecutionError,\n        PipelineLogicError,\n        PipelineUrlError,\n        AuthenticationError,\n        PromptbookFetchError,\n        UnexpectedError,\n        WrappedError,\n        NotAllowed,\n        DatabaseError,\n        ConflictError,\n        // TODO: [🪑]> VersionMismatchError,\n    };\n    /**\n     * Index of all javascript errors\n     *\n     * @private for internal usage\n     */\n    const COMMON_JAVASCRIPT_ERRORS = {\n        Error,\n        EvalError,\n        RangeError,\n        ReferenceError,\n        SyntaxError,\n        TypeError,\n        URIError,\n        AggregateError,\n        /*\n      Note: Not widely supported\n      > InternalError,\n      > ModuleError,\n      > HeapError,\n      > WebAssemblyCompileError,\n      > WebAssemblyRuntimeError,\n      */\n    };\n    /**\n     * Index of all errors\n     *\n     * @private for internal usage\n     */\n    const ALL_ERRORS = {\n        ...PROMPTBOOK_ERRORS,\n        ...COMMON_JAVASCRIPT_ERRORS,\n    };\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Deserializes the error object\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function deserializeError(error, isStackAddedToMessage = true) {\n        const { name, stack, id } = error; // Added id\n        let { message } = error;\n        let ErrorClass = ALL_ERRORS[error.name];\n        if (ErrorClass === undefined) {\n            ErrorClass = Error;\n            message = `${name}: ${message}`;\n        }\n        if (isStackAddedToMessage && stack !== undefined && stack !== '') {\n            message = spaceTrim__default[\"default\"]((block) => `\n                ${block(message)}\n\n                Original stack trace:\n                ${block(stack || '')}\n            `);\n        }\n        const deserializedError = new ErrorClass(message);\n        deserializedError.id = id; // Assign id to the error object\n        return deserializedError;\n    }\n\n    /**\n     * Serializes an error into a [🚉] JSON-serializable object\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function serializeError(error) {\n        const { name, message, stack } = error;\n        const { id } = error;\n        if (!Object.keys(ALL_ERRORS).includes(name)) {\n            console.error(spaceTrim__default[\"default\"]((block) => `\n\n                    Cannot serialize error with name \"${name}\"\n\n                    Authors of Promptbook probably forgot to add this error into the list of errors:\n                    https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts\n\n\n                    ${block(stack || message)}\n\n                `));\n        }\n        return {\n            name: name,\n            message,\n            stack,\n            id, // Include id in the serialized object\n        };\n    }\n\n    /**\n     * Async version of Array.forEach\n     *\n     * @param array - Array to iterate over\n     * @param options - Options for the function\n     * @param callbackfunction - Function to call for each item\n     * @public exported from `@promptbook/utils`\n     * @deprecated [🪂] Use queues instead\n     */\n    async function forEachAsync(array, options, callbackfunction) {\n        const { maxParallelCount = Infinity } = options;\n        let index = 0;\n        let runningTasks = [];\n        const tasks = [];\n        for (const item of array) {\n            const currentIndex = index++;\n            const task = callbackfunction(item, currentIndex, array);\n            tasks.push(task);\n            runningTasks.push(task);\n            /* not await */ Promise.resolve(task).then(() => {\n                runningTasks = runningTasks.filter((runningTask) => runningTask !== task);\n            });\n            if (maxParallelCount < runningTasks.length) {\n                await Promise.race(runningTasks);\n            }\n        }\n        await Promise.all(tasks);\n    }\n\n    /**\n     * Format either small or big number\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function numberToString(value) {\n        if (value === 0) {\n            return '0';\n        }\n        else if (Number.isNaN(value)) {\n            return VALUE_STRINGS.nan;\n        }\n        else if (value === Infinity) {\n            return VALUE_STRINGS.infinity;\n        }\n        else if (value === -Infinity) {\n            return VALUE_STRINGS.negativeInfinity;\n        }\n        for (let exponent = 0; exponent < 15; exponent++) {\n            const factor = 10 ** exponent;\n            const valueRounded = Math.round(value * factor) / factor;\n            if (Math.abs(value - valueRounded) / value < SMALL_NUMBER) {\n                return valueRounded.toFixed(exponent);\n            }\n        }\n        return value.toString();\n    }\n\n    /**\n     * Function `valueToString` will convert the given value to string\n     * This is useful and used in the `templateParameters` function\n     *\n     * Note: This function is not just calling `toString` method\n     *       It's more complex and can handle this conversion specifically for LLM models\n     *       See `VALUE_STRINGS`\n     *\n     * Note: There are 2 similar functions\n     * - `valueToString` converts value to string for LLM models as human-readable string\n     * - `asSerializable` converts value to string to preserve full information to be able to convert it back\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function valueToString(value) {\n        try {\n            if (value === '') {\n                return VALUE_STRINGS.empty;\n            }\n            else if (value === null) {\n                return VALUE_STRINGS.null;\n            }\n            else if (value === undefined) {\n                return VALUE_STRINGS.undefined;\n            }\n            else if (typeof value === 'string') {\n                return value;\n            }\n            else if (typeof value === 'number') {\n                return numberToString(value);\n            }\n            else if (value instanceof Date) {\n                return value.toISOString();\n            }\n            else {\n                try {\n                    return JSON.stringify(value);\n                }\n                catch (error) {\n                    if (error instanceof TypeError && error.message.includes('circular structure')) {\n                        return VALUE_STRINGS.circular;\n                    }\n                    throw error;\n                }\n            }\n        }\n        catch (error) {\n            assertsError(error);\n            console.error(error);\n            return VALUE_STRINGS.unserializable;\n        }\n    }\n\n    /**\n     * Replaces parameters in template with values from parameters object\n     *\n     * Note: This function is not places strings into string,\n     *       It's more complex and can handle this operation specifically for LLM models\n     *\n     * @param template the template with parameters in {curly} braces\n     * @param parameters the object with parameters\n     * @returns the template with replaced parameters\n     * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened\n     * @public exported from `@promptbook/utils`\n     */\n    function templateParameters(template, parameters) {\n        for (const [parameterName, parameterValue] of Object.entries(parameters)) {\n            if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {\n                throw new UnexpectedError(`Parameter \\`{${parameterName}}\\` has missing value`);\n            }\n            else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {\n                // TODO: [🍵]\n                throw new UnexpectedError(`Parameter \\`{${parameterName}}\\` is restricted to use`);\n            }\n        }\n        let replacedTemplates = template;\n        let match;\n        let loopLimit = LOOP_LIMIT;\n        while ((match = /^(?<precol>.*){(?<parameterName>\\w+)}(.*)/m /* <- Not global */\n            .exec(replacedTemplates))) {\n            if (loopLimit-- < 0) {\n                throw new LimitReachedError('Loop limit reached during parameters replacement in `templateParameters`');\n            }\n            const precol = match.groups.precol;\n            const parameterName = match.groups.parameterName;\n            if (parameterName === '') {\n                // Note: Skip empty placeholders. It's used to avoid confusion with JSON-like strings\n                continue;\n            }\n            if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {\n                throw new PipelineExecutionError('Parameter is already opened or not closed');\n            }\n            if (parameters[parameterName] === undefined) {\n                throw new PipelineExecutionError(`Parameter \\`{${parameterName}}\\` is not defined`);\n            }\n            let parameterValue = parameters[parameterName];\n            if (parameterValue === undefined) {\n                throw new PipelineExecutionError(`Parameter \\`{${parameterName}}\\` is not defined`);\n            }\n            parameterValue = valueToString(parameterValue);\n            // Escape curly braces in parameter values to prevent prompt-injection\n            parameterValue = parameterValue.replace(/[{}]/g, '\\\\$&');\n            if (parameterValue.includes('\\n') && /^\\s*\\W{0,3}\\s*$/.test(precol)) {\n                parameterValue = parameterValue\n                    .split(/\\r?\\n/)\n                    .map((line, index) => (index === 0 ? line : `${precol}${line}`))\n                    .join('\\n');\n            }\n            replacedTemplates =\n                replacedTemplates.substring(0, match.index + precol.length) +\n                    parameterValue +\n                    replacedTemplates.substring(match.index + precol.length + parameterName.length + 2);\n        }\n        // [💫] Check if there are parameters that are not closed properly\n        if (/{\\w+$/.test(replacedTemplates)) {\n            throw new PipelineExecutionError('Parameter is not closed');\n        }\n        // [💫] Check if there are parameters that are not opened properly\n        if (/^\\w+}/.test(replacedTemplates)) {\n            throw new PipelineExecutionError('Parameter is not opened');\n        }\n        return replacedTemplates;\n    }\n\n    /**\n     * Number of characters per standard line with 11pt Arial font size.\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    const CHARACTERS_PER_STANDARD_LINE = 63;\n    /**\n     * Number of lines per standard A4 page with 11pt Arial font size and standard margins and spacing.\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    const LINES_PER_STANDARD_PAGE = 44;\n    /**\n     * TODO: [🧠] Should be this `constants.ts` or `config.ts`?\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Counts number of characters in the text\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countCharacters(text) {\n        // Remove null characters\n        text = text.replace(/\\0/g, '');\n        // Replace emojis (and also ZWJ sequence) with hyphens\n        text = text.replace(/(\\p{Extended_Pictographic})\\p{Modifier_Symbol}/gu, '$1');\n        text = text.replace(/(\\p{Extended_Pictographic})[\\u{FE00}-\\u{FE0F}]/gu, '$1');\n        text = text.replace(/\\p{Extended_Pictographic}(\\u{200D}\\p{Extended_Pictographic})*/gu, '-');\n        return text.length;\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     */\n\n    /**\n     * Counts number of lines in the text\n     *\n     * Note: This does not check only for the presence of newlines, but also for the length of the standard line.\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countLines(text) {\n        if (text === '') {\n            return 0;\n        }\n        text = text.replace('\\r\\n', '\\n');\n        text = text.replace('\\r', '\\n');\n        const lines = text.split(/\\r?\\n/);\n        return lines.reduce((count, line) => count + Math.max(Math.ceil(line.length / CHARACTERS_PER_STANDARD_LINE), 1), 0);\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     */\n\n    /**\n     * Counts number of pages in the text\n     *\n     * Note: This does not check only for the count of newlines, but also for the length of the standard line and length of the standard page.\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countPages(text) {\n        return Math.ceil(countLines(text) / LINES_PER_STANDARD_PAGE);\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     */\n\n    /**\n     * Counts number of paragraphs in the text\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countParagraphs(text) {\n        return text.split(/\\n\\s*\\n/).filter((paragraph) => paragraph.trim() !== '').length;\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     */\n\n    /**\n     * Split text into sentences\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function splitIntoSentences(text) {\n        return text.split(/[.!?]+/).filter((sentence) => sentence.trim() !== '');\n    }\n    /**\n     * Counts number of sentences in the text\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countSentences(text) {\n        return splitIntoSentences(text).length;\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     */\n\n    /**\n     * Counts number of words in the text\n     *\n     * @public exported from `@promptbook/utils`\n     */\n    function countWords(text) {\n        text = text.replace(/[\\p{Extended_Pictographic}]/gu, 'a');\n        text = removeDiacritics(text);\n        // Add spaces before uppercase letters preceded by lowercase letters (for camelCase)\n        text = text.replace(/([a-z])([A-Z])/g, '$1 $2');\n        return text.split(/[^a-zа-я0-9]+/i).filter((word) => word.length > 0).length;\n    }\n    /**\n     * TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...\n     * TODO: [🧠][✌️] Make some Promptbook-native token system\n     * TODO: [✌️] `countWords` should be just `splitWords(...).length`, and all other counters should use this pattern as well\n     */\n\n    /**\n     * Simple wrapper `new Date().toISOString()`\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic because it depends on the current time\n     *\n     * @returns string_date branded type\n     * @public exported from `@promptbook/utils`\n     */\n    function $getCurrentDate() {\n        return new Date().toISOString();\n    }\n\n    /**\n     * Normalizes a text string to SCREAMING_CASE (all uppercase with underscores).\n     *\n     * Note: [🔂] This function is idempotent.\n     *\n     * @param text The text string to be converted to SCREAMING_CASE format.\n     * @returns The normalized text in SCREAMING_CASE format.\n     * @example 'HELLO_WORLD'\n     * @example 'I_LOVE_PROMPTBOOK'\n     * @public exported from `@promptbook/utils`\n     */\n    function normalizeTo_SCREAMING_CASE(text) {\n        let charType;\n        let lastCharType = 'OTHER';\n        let normalizedName = '';\n        for (const char of text) {\n            let normalizedChar;\n            if (/^[a-z]$/.test(char)) {\n                charType = 'LOWERCASE';\n                normalizedChar = char.toUpperCase();\n            }\n            else if (/^[A-Z]$/.test(char)) {\n                charType = 'UPPERCASE';\n                normalizedChar = char;\n            }\n            else if (/^[0-9]$/.test(char)) {\n                charType = 'NUMBER';\n                normalizedChar = char;\n            }\n            else {\n                charType = 'OTHER';\n                normalizedChar = '_';\n            }\n            if (charType !== lastCharType &&\n                !(lastCharType === 'UPPERCASE' && charType === 'LOWERCASE') &&\n                !(lastCharType === 'NUMBER') &&\n                !(charType === 'NUMBER')) {\n                normalizedName += '_';\n            }\n            normalizedName += normalizedChar;\n            lastCharType = charType;\n        }\n        normalizedName = normalizedName.replace(/_+/g, '_');\n        normalizedName = normalizedName.replace(/_?\\/_?/g, '/');\n        normalizedName = normalizedName.replace(/^_/, '');\n        normalizedName = normalizedName.replace(/_$/, '');\n        return normalizedName;\n    }\n    /**\n     * TODO: Tests\n     *     > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'Moje tabule' })).toEqual('/VtG7sR9rRJqwNEdM2/Moje tabule');\n     *     > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: 'ěščřžžýáíúů' })).toEqual('/VtG7sR9rRJqwNEdM2/escrzyaieuu');\n     *     > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: '  ahoj  ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj');\n     *     > expect(encodeRoutePath({ uriId: 'VtG7sR9rRJqwNEdM2', name: '  ahoj_ahojAhoj    ahoj  ' })).toEqual('/VtG7sR9rRJqwNEdM2/ahoj-ahoj-ahoj-ahoj');\n     * TODO: [🌺] Use some intermediate util splitWords\n     */\n\n    /**\n     * Normalizes a text string to snake_case format.\n     *\n     * Note: [🔂] This function is idempotent.\n     *\n     * @param text The text string to be converted to snake_case format.\n     * @returns The normalized text in snake_case format.\n     * @example 'hello_world'\n     * @example 'i_love_promptbook'\n     * @public exported from `@promptbook/utils`\n     */\n    function normalizeTo_snake_case(text) {\n        return normalizeTo_SCREAMING_CASE(text).toLowerCase();\n    }\n\n    /**\n     * Represents the uncertain value\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const ZERO_VALUE = $deepFreeze({ value: 0 });\n    /**\n     * Represents the uncertain value\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const UNCERTAIN_ZERO_VALUE = $deepFreeze({ value: 0, isUncertain: true });\n    /**\n     * Represents the usage with no resources consumed\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const ZERO_USAGE = $deepFreeze({\n        price: ZERO_VALUE,\n        input: {\n            tokensCount: ZERO_VALUE,\n            charactersCount: ZERO_VALUE,\n            wordsCount: ZERO_VALUE,\n            sentencesCount: ZERO_VALUE,\n            linesCount: ZERO_VALUE,\n            paragraphsCount: ZERO_VALUE,\n            pagesCount: ZERO_VALUE,\n        },\n        output: {\n            tokensCount: ZERO_VALUE,\n            charactersCount: ZERO_VALUE,\n            wordsCount: ZERO_VALUE,\n            sentencesCount: ZERO_VALUE,\n            linesCount: ZERO_VALUE,\n            paragraphsCount: ZERO_VALUE,\n            pagesCount: ZERO_VALUE,\n        },\n    });\n    /**\n     * Represents the usage with unknown resources consumed\n     *\n     * @public exported from `@promptbook/core`\n     */\n    const UNCERTAIN_USAGE = $deepFreeze({\n        price: UNCERTAIN_ZERO_VALUE,\n        input: {\n            tokensCount: UNCERTAIN_ZERO_VALUE,\n            charactersCount: UNCERTAIN_ZERO_VALUE,\n            wordsCount: UNCERTAIN_ZERO_VALUE,\n            sentencesCount: UNCERTAIN_ZERO_VALUE,\n            linesCount: UNCERTAIN_ZERO_VALUE,\n            paragraphsCount: UNCERTAIN_ZERO_VALUE,\n            pagesCount: UNCERTAIN_ZERO_VALUE,\n        },\n        output: {\n            tokensCount: UNCERTAIN_ZERO_VALUE,\n            charactersCount: UNCERTAIN_ZERO_VALUE,\n            wordsCount: UNCERTAIN_ZERO_VALUE,\n            sentencesCount: UNCERTAIN_ZERO_VALUE,\n            linesCount: UNCERTAIN_ZERO_VALUE,\n            paragraphsCount: UNCERTAIN_ZERO_VALUE,\n            pagesCount: UNCERTAIN_ZERO_VALUE,\n        },\n    });\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Helper of usage compute\n     *\n     * @param content the content of prompt or response\n     * @returns part of UsageCounts\n     *\n     * @private internal utility of LlmExecutionTools\n     */\n    function computeUsageCounts(content) {\n        return {\n            charactersCount: { value: countCharacters(content) },\n            wordsCount: { value: countWords(content) },\n            sentencesCount: { value: countSentences(content) },\n            linesCount: { value: countLines(content) },\n            paragraphsCount: { value: countParagraphs(content) },\n            pagesCount: { value: countPages(content) },\n        };\n    }\n\n    /**\n     * Make UncertainNumber\n     *\n     * @param value value of the uncertain number, if `NaN` or `undefined`, it will be set to 0 and `isUncertain=true`\n     * @param isUncertain if `true`, the value is uncertain, otherwise depends on the value\n     *\n     * @private utility for initializating UncertainNumber\n     */\n    function uncertainNumber(value, isUncertain) {\n        if (value === null || value === undefined || Number.isNaN(value)) {\n            return UNCERTAIN_ZERO_VALUE;\n        }\n        if (isUncertain === true) {\n            return { value, isUncertain };\n        }\n        return { value };\n    }\n\n    /**\n     * Create price per one token based on the string value found on openai page\n     *\n     * @private within the repository, used only as internal helper for `OPENAI_MODELS`\n     */\n    function pricing(value) {\n        const [price, tokens] = value.split(' / ');\n        return parseFloat(price.replace('$', '')) / parseFloat(tokens.replace('M tokens', '')) / 1000000;\n    }\n\n    /**\n     * List of available OpenAI models with pricing\n     *\n     * Note: Synced with official API docs at 2025-11-19\n     *\n     * @see https://platform.openai.com/docs/models/\n     * @see https://openai.com/api/pricing/\n     * @public exported from `@promptbook/openai`\n     */\n    const OPENAI_MODELS = exportJson({\n        name: 'OPENAI_MODELS',\n        value: [\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5.1',\n                modelName: 'gpt-5.1',\n                modelDescription: 'The best model for coding and agentic tasks with configurable reasoning effort.',\n                pricing: {\n                    prompt: pricing(`$1.25 / 1M tokens`),\n                    output: pricing(`$10.00 / 1M tokens`),\n                },\n            },\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5',\n                modelName: 'gpt-5',\n                modelDescription: \"OpenAI's most advanced language model with unprecedented reasoning capabilities and 200K context window. Features revolutionary improvements in complex problem-solving, scientific reasoning, and creative tasks. Demonstrates human-level performance across diverse domains with enhanced safety measures and alignment. Represents the next generation of AI with superior understanding, nuanced responses, and advanced multimodal capabilities. DEPRECATED: Use gpt-5.1 instead.\",\n                pricing: {\n                    prompt: pricing(`$1.25 / 1M tokens`),\n                    output: pricing(`$10.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5.2-codex',\n                modelName: 'gpt-5.2-codex',\n                modelDescription: 'High-capability Codex variant tuned for agentic code generation with large contexts and reasoning effort controls. Ideal for long-horizon coding workflows and multi-step reasoning.',\n                pricing: {\n                    prompt: pricing(`$1.75 / 1M tokens`),\n                    output: pricing(`$14.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5.1-codex-max',\n                modelName: 'gpt-5.1-codex-max',\n                modelDescription: 'Premium GPT-5.1 Codex flavor that mirrors gpt-5.1 in capability and pricing while adding Codex tooling optimizations.',\n                pricing: {\n                    prompt: pricing(`$1.25 / 1M tokens`),\n                    output: pricing(`$10.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5.1-codex',\n                modelName: 'gpt-5.1-codex',\n                modelDescription: 'Core GPT-5.1 Codex model focused on agentic coding tasks with a balanced trade-off between reasoning and cost.',\n                pricing: {\n                    prompt: pricing(`$1.25 / 1M tokens`),\n                    output: pricing(`$10.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5.1-codex-mini',\n                modelName: 'gpt-5.1-codex-mini',\n                modelDescription: 'Compact, cost-effective GPT-5.1 Codex variant with a smaller context window ideal for cheap assistant iterations that still require coding awareness.',\n                pricing: {\n                    prompt: pricing(`$0.25 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5-codex',\n                modelName: 'gpt-5-codex',\n                modelDescription: 'Legacy GPT-5 Codex model built for agentic coding workloads with the same pricing as GPT-5 and a focus on stability.',\n                pricing: {\n                    prompt: pricing(`$1.25 / 1M tokens`),\n                    output: pricing(`$10.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5-mini',\n                modelName: 'gpt-5-mini',\n                modelDescription: 'A faster, cost-efficient version of GPT-5 for well-defined tasks with 200K context window. Maintains core GPT-5 capabilities while offering 5x faster inference and significantly lower costs. Features enhanced instruction following and reduced latency for production applications requiring quick responses with high quality.',\n                pricing: {\n                    prompt: pricing(`$0.25 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-5-nano',\n                modelName: 'gpt-5-nano',\n                modelDescription: 'The fastest, most cost-efficient version of GPT-5 with 200K context window. Optimized for summarization, classification, and simple reasoning tasks. Features 10x faster inference than base GPT-5 while maintaining good quality for straightforward applications. Ideal for high-volume, cost-sensitive deployments.',\n                pricing: {\n                    prompt: pricing(`$0.05 / 1M tokens`),\n                    output: pricing(`$0.40 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4.1',\n                modelName: 'gpt-4.1',\n                modelDescription: 'Smartest non-reasoning model with 128K context window. Enhanced version of GPT-4 with improved instruction following, better factual accuracy, and reduced hallucinations. Features advanced function calling capabilities and superior performance on coding tasks. Ideal for applications requiring high intelligence without reasoning overhead.',\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$12.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4.1-mini',\n                modelName: 'gpt-4.1-mini',\n                modelDescription: 'Smaller, faster version of GPT-4.1 with 128K context window. Balances intelligence and efficiency with 3x faster inference than base GPT-4.1. Maintains strong capabilities across text generation, reasoning, and coding while offering better cost-performance ratio for most applications.',\n                pricing: {\n                    prompt: pricing(`$0.80 / 1M tokens`),\n                    output: pricing(`$3.20 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4.1-nano',\n                modelName: 'gpt-4.1-nano',\n                modelDescription: 'Fastest, most cost-efficient version of GPT-4.1 with 128K context window. Optimized for high-throughput applications requiring good quality at minimal cost. Features 5x faster inference than GPT-4.1 while maintaining adequate performance for most general-purpose tasks.',\n                pricing: {\n                    prompt: pricing(`$0.20 / 1M tokens`),\n                    output: pricing(`$0.80 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o3',\n                modelName: 'o3',\n                modelDescription: 'Advanced reasoning model with 128K context window specializing in complex logical, mathematical, and analytical tasks. Successor to o1 with enhanced step-by-step problem-solving capabilities and superior performance on STEM-focused problems. Ideal for professional applications requiring deep analytical thinking and precise reasoning.',\n                pricing: {\n                    prompt: pricing(`$15.00 / 1M tokens`),\n                    output: pricing(`$60.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o3-pro',\n                modelName: 'o3-pro',\n                modelDescription: 'Enhanced version of o3 with more compute allocated for better responses on the most challenging problems. Features extended reasoning time and improved accuracy on complex analytical tasks. Designed for applications where maximum reasoning quality is more important than response speed.',\n                pricing: {\n                    prompt: pricing(`$30.00 / 1M tokens`),\n                    output: pricing(`$120.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o4-mini',\n                modelName: 'o4-mini',\n                modelDescription: 'Fast, cost-efficient reasoning model with 128K context window. Successor to o1-mini with improved analytical capabilities while maintaining speed advantages. Features enhanced mathematical reasoning and logical problem-solving at significantly lower cost than full reasoning models.',\n                pricing: {\n                    prompt: pricing(`$4.00 / 1M tokens`),\n                    output: pricing(`$16.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o3-deep-research',\n                modelName: 'o3-deep-research',\n                modelDescription: 'Most powerful deep research model with 128K context window. Specialized for comprehensive research tasks, literature analysis, and complex information synthesis. Features advanced citation capabilities and enhanced factual accuracy for academic and professional research applications.',\n                pricing: {\n                    prompt: pricing(`$25.00 / 1M tokens`),\n                    output: pricing(`$100.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o4-mini-deep-research',\n                modelName: 'o4-mini-deep-research',\n                modelDescription: 'Faster, more affordable deep research model with 128K context window. Balances research capabilities with cost efficiency, offering good performance on literature review, fact-checking, and information synthesis tasks at a more accessible price point.',\n                pricing: {\n                    prompt: pricing(`$12.00 / 1M tokens`),\n                    output: pricing(`$48.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'IMAGE_GENERATION',\n                modelTitle: 'dall-e-3',\n                modelName: 'dall-e-3',\n                modelDescription: 'DALL·E 3 is the latest version of the DALL·E art generation model. It understands significantly more nuance and detail than our previous systems, allowing you to easily translate your ideas into exceptionally accurate images.',\n                pricing: {\n                    prompt: 0,\n                    output: 0.04,\n                },\n            },\n            /**/\n            /*/\n              {\n                  modelTitle: 'whisper-1',\n                  modelName: 'whisper-1',\n              },\n            /**/\n            /**/\n            {\n                modelVariant: 'COMPLETION',\n                modelTitle: 'davinci-002',\n                modelName: 'davinci-002',\n                modelDescription: 'Legacy completion model with 4K token context window. Excels at complex text generation, creative writing, and detailed content creation with strong contextual understanding. Optimized for instructions requiring nuanced outputs and extended reasoning. Suitable for applications needing high-quality text generation without conversation management.',\n                pricing: {\n                    prompt: pricing(`$2.00 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'IMAGE_GENERATION',\n                modelTitle: 'dall-e-2',\n                modelName: 'dall-e-2',\n                modelDescription: 'DALL·E 2 is an AI system that can create realistic images and art from a description in natural language.',\n                pricing: {\n                    prompt: 0,\n                    output: 0.02,\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-16k',\n                modelName: 'gpt-3.5-turbo-16k',\n                modelDescription: 'Extended context GPT-3.5 Turbo with 16K token window. Maintains core capabilities of standard 3.5 Turbo while supporting longer conversations and documents. Features good balance of performance and cost for applications requiring more context than standard 4K models. Effective for document analysis, extended conversations, and multi-step reasoning tasks.',\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$4.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /*/\n            {\n                modelTitle: 'tts-1-hd-1106',\n                modelName: 'tts-1-hd-1106',\n            },\n            /**/\n            /*/\n            {\n                modelTitle: 'tts-1-hd',\n                modelName: 'tts-1-hd',\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4',\n                modelName: 'gpt-4',\n                modelDescription: 'Powerful language model with 8K context window featuring sophisticated reasoning, instruction-following, and knowledge capabilities. Demonstrates strong performance on complex tasks requiring deep understanding and multi-step reasoning. Excels at code generation, logical analysis, and nuanced content creation. Suitable for advanced applications requiring high-quality outputs.',\n                pricing: {\n                    prompt: pricing(`$30.00 / 1M tokens`),\n                    output: pricing(`$60.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-32k',\n                modelName: 'gpt-4-32k',\n                modelDescription: 'Extended context version of GPT-4 with 32K token window. Maintains all capabilities of standard GPT-4 while supporting analysis of very lengthy documents, code bases, and conversations. Features enhanced ability to maintain context over long interactions and process detailed information from large inputs. Ideal for document analysis, legal review, and complex problem-solving.',\n                pricing: {\n                    prompt: pricing(`$60.00 / 1M tokens`),\n                    output: pricing(`$120.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /*/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-0613',\n                modelName: 'gpt-4-0613',\n                pricing: {\n                    prompt: computeUsage(` / 1M tokens`),\n                    output: computeUsage(` / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-turbo-2024-04-09',\n                modelName: 'gpt-4-turbo-2024-04-09',\n                modelDescription: 'Latest stable GPT-4 Turbo from April 2024 with 128K context window. Features enhanced reasoning chains, improved factual accuracy with 40% reduction in hallucinations, and better instruction following compared to earlier versions. Includes advanced function calling capabilities and knowledge up to April 2024. Provides optimal performance for enterprise applications requiring reliability.',\n                pricing: {\n                    prompt: pricing(`$10.00 / 1M tokens`),\n                    output: pricing(`$30.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-1106',\n                modelName: 'gpt-3.5-turbo-1106',\n                modelDescription: 'November 2023 version of GPT-3.5 Turbo with 16K token context window. Features improved instruction following, more consistent output formatting, and enhanced function calling capabilities. Includes knowledge cutoff from April 2023. Suitable for applications requiring good performance at lower cost than GPT-4 models.',\n                pricing: {\n                    prompt: pricing(`$1.00 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-turbo',\n                modelName: 'gpt-4-turbo',\n                modelDescription: 'More capable and cost-efficient version of GPT-4 with 128K token context window. Features improved instruction following, advanced function calling capabilities, and better performance on coding tasks. Maintains superior reasoning and knowledge while offering substantial cost reduction compared to base GPT-4. Ideal for complex applications requiring extensive context processing.',\n                pricing: {\n                    prompt: pricing(`$10.00 / 1M tokens`),\n                    output: pricing(`$30.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'COMPLETION',\n                modelTitle: 'gpt-3.5-turbo-instruct-0914',\n                modelName: 'gpt-3.5-turbo-instruct-0914',\n                modelDescription: 'September 2023 version of GPT-3.5 Turbo Instruct with 4K context window. Optimized for completion-style instruction following with deterministic responses. Better suited than chat models for applications requiring specific formatted outputs without conversation management. Knowledge cutoff from September 2021.',\n                pricing: {\n                    prompt: pricing(`$1.50  / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'COMPLETION',\n                modelTitle: 'gpt-3.5-turbo-instruct',\n                modelName: 'gpt-3.5-turbo-instruct',\n                modelDescription: 'Optimized version of GPT-3.5 for completion-style API with 4K token context window. Features strong instruction following with single-turn design rather than multi-turn conversation. Provides more consistent, deterministic outputs compared to chat models. Well-suited for templated content generation and structured text transformation tasks.',\n                pricing: {\n                    prompt: pricing(`$1.50  / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /*/\n          {\n              modelTitle: 'tts-1',\n              modelName: 'tts-1',\n          },\n          /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo',\n                modelName: 'gpt-3.5-turbo',\n                modelDescription: 'Latest version of GPT-3.5 Turbo with 4K token default context window (16K available). Features continually improved performance with enhanced instruction following and reduced hallucinations. Offers excellent balance between capability and cost efficiency. Suitable for most general-purpose applications requiring good AI capabilities at reasonable cost.',\n                pricing: {\n                    prompt: pricing(`$0.50 / 1M tokens`),\n                    output: pricing(`$1.50 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-0301',\n                modelName: 'gpt-3.5-turbo-0301',\n                modelDescription: 'March 2023 version of GPT-3.5 Turbo with 4K token context window. Legacy model maintained for backward compatibility with specific application behaviors. Features solid conversational abilities and basic instruction following. Knowledge cutoff from September 2021. Suitable for applications explicitly designed for this version.',\n                pricing: {\n                    prompt: pricing(`$1.50 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'COMPLETION',\n                modelTitle: 'babbage-002',\n                modelName: 'babbage-002',\n                modelDescription: 'Efficient legacy completion model with 4K context window balancing performance and speed. Features moderate reasoning capabilities with focus on straightforward text generation tasks. Significantly more efficient than davinci models while maintaining adequate quality for many applications. Suitable for high-volume, cost-sensitive text generation needs.',\n                pricing: {\n                    prompt: pricing(`$0.40 / 1M tokens`),\n                    output: pricing(`$0.40 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-1106-preview',\n                modelName: 'gpt-4-1106-preview',\n                modelDescription: 'November 2023 preview version of GPT-4 Turbo with 128K token context window. Features improved instruction following, better function calling capabilities, and enhanced reasoning. Includes knowledge cutoff from April 2023. Suitable for complex applications requiring extensive document understanding and sophisticated interactions.',\n                pricing: {\n                    prompt: pricing(`$10.00 / 1M tokens`),\n                    output: pricing(`$30.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-0125-preview',\n                modelName: 'gpt-4-0125-preview',\n                modelDescription: 'January 2024 preview version of GPT-4 Turbo with 128K token context window. Features improved reasoning capabilities, enhanced tool use, and more reliable function calling. Includes knowledge cutoff from October 2023. Offers better performance on complex logical tasks and more consistent outputs than previous preview versions.',\n                pricing: {\n                    prompt: pricing(`$10.00 / 1M tokens`),\n                    output: pricing(`$30.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /*/\n          {\n              modelTitle: 'tts-1-1106',\n              modelName: 'tts-1-1106',\n          },\n          /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-0125',\n                modelName: 'gpt-3.5-turbo-0125',\n                modelDescription: 'January 2024 version of GPT-3.5 Turbo with 16K token context window. Features improved reasoning capabilities, better instruction adherence, and reduced hallucinations compared to previous versions. Includes knowledge cutoff from September 2021. Provides good performance for most general applications at reasonable cost.',\n                pricing: {\n                    prompt: pricing(`$0.50 / 1M tokens`),\n                    output: pricing(`$1.50  / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4-turbo-preview',\n                modelName: 'gpt-4-turbo-preview',\n                modelDescription: 'Preview version of GPT-4 Turbo with 128K token context window that points to the latest development model. Features cutting-edge improvements to instruction following, knowledge representation, and tool use capabilities. Provides access to newest features but may have occasional behavior changes. Best for non-critical applications wanting latest capabilities.',\n                pricing: {\n                    prompt: pricing(`$10.00 / 1M tokens`),\n                    output: pricing(`$30.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'EMBEDDING',\n                modelTitle: 'text-embedding-3-large',\n                modelName: 'text-embedding-3-large',\n                modelDescription: \"OpenAI's most capable text embedding model generating 3072-dimensional vectors. Designed for high-quality embeddings for complex similarity tasks, clustering, and information retrieval. Features enhanced cross-lingual capabilities and significantly improved performance on retrieval and classification benchmarks. Ideal for sophisticated RAG systems and semantic search applications.\",\n                pricing: {\n                    prompt: pricing(`$0.13 / 1M tokens`),\n                    output: 0,\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'EMBEDDING',\n                modelTitle: 'text-embedding-3-small',\n                modelName: 'text-embedding-3-small',\n                modelDescription: 'Cost-effective embedding model generating 1536-dimensional vectors. Balances quality and efficiency for simpler tasks while maintaining good performance on text similarity and retrieval applications. Offers 20% better quality than ada-002 at significantly lower cost. Ideal for production embedding applications with cost constraints.',\n                pricing: {\n                    prompt: pricing(`$0.02 / 1M tokens`),\n                    output: 0,\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-0613',\n                modelName: 'gpt-3.5-turbo-0613',\n                modelDescription: \"June 2023 version of GPT-3.5 Turbo with 4K token context window. Features function calling capabilities for structured data extraction and API interaction. Includes knowledge cutoff from September 2021. Maintained for applications specifically designed for this version's behaviors and capabilities.\",\n                pricing: {\n                    prompt: pricing(`$1.50 / 1M tokens`),\n                    output: pricing(`$2.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'EMBEDDING',\n                modelTitle: 'text-embedding-ada-002',\n                modelName: 'text-embedding-ada-002',\n                modelDescription: 'Legacy text embedding model generating 1536-dimensional vectors suitable for text similarity and retrieval applications. Processes up to 8K tokens per request with consistent embedding quality. While superseded by newer embedding-3 models, still maintains adequate performance for many semantic search and classification tasks.',\n                pricing: {\n                    prompt: pricing(`$0.1 / 1M tokens`),\n                    output: 0,\n                },\n            },\n            /**/\n            /*/\n          {\n              modelVariant: 'CHAT',\n              modelTitle: 'gpt-4-1106-vision-preview',\n              modelName: 'gpt-4-1106-vision-preview',\n          },\n          /**/\n            /*/\n          {\n              modelVariant: 'CHAT',\n              modelTitle: 'gpt-4-vision-preview',\n              modelName: 'gpt-4-vision-preview',\n              pricing: {\n                  prompt: computeUsage(`$10.00 / 1M tokens`),\n                  output: computeUsage(`$30.00 / 1M tokens`),\n              },\n          },\n          /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4o-2024-05-13',\n                modelName: 'gpt-4o-2024-05-13',\n                modelDescription: 'May 2024 version of GPT-4o with 128K context window. Features enhanced multimodal capabilities including superior image understanding (up to 20MP), audio processing, and improved reasoning. Optimized for 2x lower latency than GPT-4 Turbo while maintaining high performance. Includes knowledge up to October 2023. Ideal for production applications requiring reliable multimodal capabilities.',\n                pricing: {\n                    prompt: pricing(`$5.00 / 1M tokens`),\n                    output: pricing(`$15.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4o',\n                modelName: 'gpt-4o',\n                modelDescription: \"OpenAI's most advanced general-purpose multimodal model with 128K context window. Optimized for balanced performance, speed, and cost with 2x faster responses than GPT-4 Turbo. Features excellent vision processing, audio understanding, reasoning, and text generation quality. Represents optimal balance of capability and efficiency for most advanced applications.\",\n                pricing: {\n                    prompt: pricing(`$5.00 / 1M tokens`),\n                    output: pricing(`$15.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-4o-mini',\n                modelName: 'gpt-4o-mini',\n                modelDescription: 'Smaller, more cost-effective version of GPT-4o with 128K context window. Maintains impressive capabilities across text, vision, and audio tasks while operating at significantly lower cost. Features 3x faster inference than GPT-4o with good performance on general tasks. Excellent for applications requiring good quality multimodal capabilities at scale.',\n                pricing: {\n                    prompt: pricing(`$0.15 / 1M tokens`),\n                    output: pricing(`$0.60 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o1-preview',\n                modelName: 'o1-preview',\n                modelDescription: 'Advanced reasoning model with 128K context window specializing in complex logical, mathematical, and analytical tasks. Features exceptional step-by-step problem-solving capabilities, advanced mathematical and scientific reasoning, and superior performance on STEM-focused problems. Significantly outperforms GPT-4 on quantitative reasoning benchmarks. Ideal for professional and specialized applications.',\n                pricing: {\n                    prompt: pricing(`$15.00 / 1M tokens`),\n                    output: pricing(`$60.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o1-preview-2024-09-12',\n                modelName: 'o1-preview-2024-09-12',\n                modelDescription: 'September 2024 version of O1 preview with 128K context window. Features specialized reasoning capabilities with 30% improvement on mathematical and scientific accuracy over previous versions. Includes enhanced support for formal logic, statistical analysis, and technical domains. Optimized for professional applications requiring precise analytical thinking and rigorous methodologies.',\n                pricing: {\n                    prompt: pricing(`$15.00 / 1M tokens`),\n                    output: pricing(`$60.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o1-mini',\n                modelName: 'o1-mini',\n                modelDescription: 'Smaller, cost-effective version of the O1 model with 128K context window. Maintains strong analytical reasoning abilities while reducing computational requirements by 70%. Features good performance on mathematical, logical, and scientific tasks at significantly lower cost than full O1. Excellent for everyday analytical applications that benefit from reasoning focus.',\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$12.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o1',\n                modelName: 'o1',\n                modelDescription: \"OpenAI's advanced reasoning model with 128K context window focusing on logical problem-solving and analytical thinking. Features exceptional performance on quantitative tasks, step-by-step deduction, and complex technical problems. Maintains 95%+ of o1-preview capabilities with production-ready stability. Ideal for scientific computing, financial analysis, and professional applications.\",\n                pricing: {\n                    prompt: pricing(`$15.00 / 1M tokens`),\n                    output: pricing(`$60.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o3-mini',\n                modelName: 'o3-mini',\n                modelDescription: 'Cost-effective reasoning model with 128K context window optimized for academic and scientific problem-solving. Features efficient performance on STEM tasks with specialized capabilities in mathematics, physics, chemistry, and computer science. Offers 80% of O1 performance on technical domains at significantly lower cost. Ideal for educational applications and research support.',\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$12.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'o1-mini-2024-09-12',\n                modelName: 'o1-mini-2024-09-12',\n                modelDescription: \"September 2024 version of O1-mini with 128K context window featuring balanced reasoning capabilities and cost-efficiency. Includes 25% improvement in mathematical accuracy and enhanced performance on coding tasks compared to previous versions. Maintains efficient resource utilization while delivering improved results for analytical applications that don't require the full O1 model.\",\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$12.00 / 1M tokens`),\n                },\n            },\n            /**/\n            /**/\n            {\n                modelVariant: 'CHAT',\n                modelTitle: 'gpt-3.5-turbo-16k-0613',\n                modelName: 'gpt-3.5-turbo-16k-0613',\n                modelDescription: \"June 2023 version of GPT-3.5 Turbo with extended 16K token context window. Features good handling of longer conversations and documents with improved memory management across extended contexts. Includes knowledge cutoff from September 2021. Maintained for applications specifically designed for this version's behaviors and capabilities.\",\n                pricing: {\n                    prompt: pricing(`$3.00 / 1M tokens`),\n                    output: pricing(`$4.00 / 1M tokens`),\n                },\n            },\n            /**/\n            // <- [🕕]\n        ],\n    });\n    /**\n     * Note: [🤖] Add models of new variant\n     * TODO: [🧠] Some mechanism to propagate unsureness\n     * TODO: [🎰] Some mechanism to auto-update available models\n     * TODO: [🎰][👮‍♀️] Make this list dynamic - dynamically can be listed modelNames but not modelVariant, legacy status, context length and pricing\n     * TODO: [🧠][👮‍♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths (\tTop-level performance, intelligence, fluency, and understanding), contextWindow,...\n     * @see https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4\n     * @see https://openai.com/api/pricing/\n     * @see /other/playground/playground.ts\n     * TODO: [🍓][💩] Make better\n     * TODO: Change model titles to human eg: \"gpt-4-turbo-2024-04-09\" -> \"GPT-4 Turbo (2024-04-09)\"\n     * TODO: [🚸] Not all models are compatible with JSON mode, add this information here and use it\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Computes the usage of the OpenAI API based on the response from OpenAI\n     *\n     * @param promptContent The content of the prompt\n     * @param resultContent The content of the result (for embedding prompts or failed prompts pass empty string)\n     * @param rawResponse The raw response from OpenAI API\n     * @throws {PipelineExecutionError} If the usage is not defined in the response from OpenAI\n     * @private internal utility of `OpenAiExecutionTools`\n     */\n    function computeOpenAiUsage(promptContent, // <- Note: Intentionally using [] to access type properties to bring jsdoc from Prompt/PromptResult to consumer\n    resultContent, rawResponse) {\n        var _a, _b;\n        if (rawResponse.usage === undefined) {\n            throw new PipelineExecutionError('The usage is not defined in the response from OpenAI');\n        }\n        if (((_a = rawResponse.usage) === null || _a === void 0 ? void 0 : _a.prompt_tokens) === undefined) {\n            throw new PipelineExecutionError('In OpenAI response `usage.prompt_tokens` not defined');\n        }\n        const inputTokens = rawResponse.usage.prompt_tokens;\n        const outputTokens = ((_b = rawResponse.usage) === null || _b === void 0 ? void 0 : _b.completion_tokens) || 0;\n        let isUncertain = false;\n        let modelInfo = OPENAI_MODELS.find((model) => model.modelName === rawResponse.model);\n        if (modelInfo === undefined) {\n            // Note: Model is not in the list of known models, fallback to the family of the models and mark price as uncertain\n            modelInfo = OPENAI_MODELS.find((model) => (rawResponse.model || SALT_NONCE).startsWith(model.modelName));\n            if (modelInfo !== undefined) {\n                isUncertain = true;\n            }\n        }\n        let price;\n        if (modelInfo === undefined || modelInfo.pricing === undefined) {\n            price = uncertainNumber();\n        }\n        else {\n            price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output, isUncertain);\n        }\n        return {\n            price,\n            input: {\n                tokensCount: uncertainNumber(rawResponse.usage.prompt_tokens),\n                ...computeUsageCounts(promptContent),\n            },\n            output: {\n                tokensCount: uncertainNumber(outputTokens),\n                ...computeUsageCounts(resultContent),\n            },\n        };\n    }\n    /**\n     * TODO: [🤝] DRY Maybe some common abstraction between `computeOpenAiUsage` and `computeAnthropicClaudeUsage`\n     */\n\n    /**\n     * Function `addUsage` will add multiple usages into one\n     *\n     * Note: If you provide 0 values, it returns ZERO_USAGE\n     *\n     * @public exported from `@promptbook/core`\n     */\n    function addUsage(...usageItems) {\n        return usageItems.reduce((acc, item) => {\n            var _a;\n            acc.price.value += ((_a = item.price) === null || _a === void 0 ? void 0 : _a.value) || 0;\n            for (const key of Object.keys(acc.input)) {\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                //@ts-ignore\n                if (item.input[key]) {\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    //@ts-ignore\n                    acc.input[key].value += item.input[key].value || 0;\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    //@ts-ignore\n                    if (item.input[key].isUncertain) {\n                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                        //@ts-ignore\n                        acc.input[key].isUncertain = true;\n                    }\n                }\n            }\n            for (const key of Object.keys(acc.output)) {\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                //@ts-ignore\n                if (item.output[key]) {\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    //@ts-ignore\n                    acc.output[key].value += item.output[key].value || 0;\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    //@ts-ignore\n                    if (item.output[key].isUncertain) {\n                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                        //@ts-ignore\n                        acc.output[key].isUncertain = true;\n                    }\n                }\n            }\n            return acc;\n        }, deepClone(ZERO_USAGE));\n    }\n\n    /**\n     * Maps Promptbook tools to OpenAI tools.\n     *\n     * @private\n     */\n    function mapToolsToOpenAi(tools) {\n        return tools.map((tool) => ({\n            type: 'function',\n            function: {\n                name: tool.name,\n                description: tool.description,\n                parameters: tool.parameters,\n            },\n        }));\n    }\n\n    /**\n     * Prompt parameter key used to pass hidden runtime context to tool execution.\n     *\n     * @private internal runtime wiring for commitment tools\n     */\n    const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';\n    /**\n     * Hidden argument key used to pass runtime context into individual tool calls.\n     *\n     * @private internal runtime wiring for commitment tools\n     */\n    const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    /**\n     * Builds a tool invocation script that injects hidden runtime context into tool args.\n     *\n     * @private utility of OpenAI tool execution wrappers\n     */\n    function buildToolInvocationScript(options) {\n        const { functionName, functionArgsExpression } = options;\n        return `\n        const args = ${functionArgsExpression};\n        const runtimeContextRaw =\n            typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'\n                ? undefined\n                : ${TOOL_RUNTIME_CONTEXT_PARAMETER};\n\n        if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {\n            args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;\n        }\n\n        return await ${functionName}(args);\n    `;\n    }\n\n    /**\n     * Parses an OpenAI error message to identify which parameter is unsupported\n     *\n     * @param errorMessage The error message from OpenAI API\n     * @returns The parameter name that is unsupported, or null if not an unsupported parameter error\n     * @private utility of LLM Tools\n     */\n    function parseUnsupportedParameterError(errorMessage) {\n        // Pattern to match \"Unsupported value: 'parameter' does not support ...\"\n        const unsupportedValueMatch = errorMessage.match(/Unsupported value:\\s*'([^']+)'\\s*does not support/i);\n        if (unsupportedValueMatch === null || unsupportedValueMatch === void 0 ? void 0 : unsupportedValueMatch[1]) {\n            return unsupportedValueMatch[1];\n        }\n        // Pattern to match \"'parameter' of type ... is not supported with this model\"\n        const parameterTypeMatch = errorMessage.match(/'([^']+)'\\s*of type.*is not supported with this model/i);\n        if (parameterTypeMatch === null || parameterTypeMatch === void 0 ? void 0 : parameterTypeMatch[1]) {\n            return parameterTypeMatch[1];\n        }\n        return null;\n    }\n    /**\n     * Creates a copy of model requirements with the specified parameter removed\n     *\n     * @param modelRequirements Original model requirements\n     * @param unsupportedParameter The parameter to remove\n     * @returns New model requirements without the unsupported parameter\n     * @private utility of LLM Tools\n     */\n    function removeUnsupportedModelRequirement(modelRequirements, unsupportedParameter) {\n        const newRequirements = { ...modelRequirements };\n        // Map of parameter names that might appear in error messages to ModelRequirements properties\n        const parameterMap = {\n            temperature: 'temperature',\n            max_tokens: 'maxTokens',\n            maxTokens: 'maxTokens',\n            seed: 'seed',\n        };\n        const propertyToRemove = parameterMap[unsupportedParameter];\n        if (propertyToRemove && propertyToRemove in newRequirements) {\n            delete newRequirements[propertyToRemove];\n        }\n        return newRequirements;\n    }\n    /**\n     * Checks if an error is an \"Unsupported value\" error from OpenAI\n     * @param error The error to check\n     * @returns true if this is an unsupported parameter error\n     * @private utility of LLM Tools\n     */\n    function isUnsupportedParameterError(error) {\n        const errorMessage = error.message.toLowerCase();\n        return (errorMessage.includes('unsupported value:') ||\n            errorMessage.includes('is not supported with this model') ||\n            errorMessage.includes('does not support'));\n    }\n\n    /**\n     * Provides access to the structured clone implementation when available.\n     */\n    function getStructuredCloneFunction() {\n        return globalThis.structuredClone;\n    }\n    /**\n     * Checks whether the prompt is a chat prompt that carries file attachments.\n     */\n    function hasChatPromptFiles(prompt) {\n        return 'files' in prompt && Array.isArray(prompt.files);\n    }\n    /**\n     * Creates a deep copy of the prompt while keeping attached files intact when structured clone is not available.\n     */\n    function clonePromptPreservingFiles(prompt) {\n        const structuredCloneFn = getStructuredCloneFunction();\n        if (typeof structuredCloneFn === 'function') {\n            return structuredCloneFn(prompt);\n        }\n        const clonedPrompt = JSON.parse(JSON.stringify(prompt));\n        if (hasChatPromptFiles(prompt)) {\n            clonedPrompt.files = prompt.files;\n        }\n        return clonedPrompt;\n    }\n    /**\n     * Execution Tools for calling OpenAI API or other OpenAI compatible provider\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    class OpenAiCompatibleExecutionTools {\n        // Removed retriedUnsupportedParameters and attemptHistory instance fields\n        /**\n         * Creates OpenAI compatible Execution Tools.\n         *\n         * @param options which are relevant are directly passed to the OpenAI compatible client\n         */\n        constructor(options) {\n            this.options = options;\n            /**\n             * OpenAI API client.\n             */\n            this.client = null;\n            // TODO: Allow configuring rate limits via options\n            this.limiter = new Bottleneck__default[\"default\"]({\n                minTime: 60000 / (this.options.maxRequestsPerMinute || DEFAULT_MAX_REQUESTS_PER_MINUTE),\n            });\n        }\n        async getClient() {\n            if (this.client === null) {\n                // Note: Passing only OpenAI relevant options to OpenAI constructor\n                const openAiOptions = { ...this.options };\n                delete openAiOptions.isVerbose;\n                delete openAiOptions.userId;\n                // Enhanced configuration with retries and timeouts.\n                const enhancedOptions = {\n                    ...openAiOptions,\n                    timeout: API_REQUEST_TIMEOUT,\n                    maxRetries: CONNECTION_RETRIES_LIMIT,\n                };\n                this.client = new OpenAI__default[\"default\"](enhancedOptions);\n            }\n            return this.client;\n        }\n        /**\n         * Check the `options` passed to `constructor`\n         */\n        async checkConfiguration() {\n            await this.getClient();\n            // TODO: [🎍] Do here a real check that API is online, working and API key is correct\n        }\n        /**\n         * List all available OpenAI compatible models that can be used\n         */\n        async listModels() {\n            const client = await this.getClient();\n            const rawModelsList = await client.models.list();\n            const availableModels = rawModelsList.data\n                .sort((a, b) => (a.created > b.created ? 1 : -1))\n                .map((modelFromApi) => {\n                const modelFromList = this.HARDCODED_MODELS.find(({ modelName }) => modelName === modelFromApi.id ||\n                    modelName.startsWith(modelFromApi.id) ||\n                    modelFromApi.id.startsWith(modelName));\n                if (modelFromList !== undefined) {\n                    return modelFromList;\n                }\n                return {\n                    modelVariant: 'CHAT',\n                    modelTitle: modelFromApi.id,\n                    modelName: modelFromApi.id,\n                    modelDescription: '',\n                };\n            });\n            return availableModels;\n        }\n        /**\n         * Calls OpenAI compatible API to use a chat model.\n         */\n        /**\n         * Calls OpenAI compatible API to use a chat model.\n         */\n        async callChatModel(prompt) {\n            return this.callChatModelStream(prompt, () => { });\n        }\n        /**\n         * Calls OpenAI compatible API to use a chat model with streaming.\n         */\n        async callChatModelStream(prompt, onProgress, options) {\n            // Deep clone prompt and modelRequirements to avoid mutation across calls\n            const clonedPrompt = clonePromptPreservingFiles(prompt);\n            // Use local Set for retried parameters to ensure independence and thread safety\n            const retriedUnsupportedParameters = new Set();\n            return this.callChatModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters, onProgress, options);\n        }\n        /**\n         * Internal method that handles parameter retry for chat model calls\n         */\n        async callChatModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set(), onProgress, options) {\n            var _a;\n            if (this.options.isVerbose) {\n                console.info(`💬 ${this.title} callChatModel call`, { prompt, currentModelRequirements });\n            }\n            const { content, parameters, format } = prompt;\n            const client = await this.getClient();\n            // TODO: [☂] Use here more modelRequirements\n            if (currentModelRequirements.modelVariant !== 'CHAT') {\n                throw new PipelineExecutionError('Use callChatModel only for CHAT variant');\n            }\n            const modelName = currentModelRequirements.modelName || this.getDefaultChatModel().modelName;\n            const modelSettings = {\n                model: modelName,\n                max_tokens: currentModelRequirements.maxTokens,\n                temperature: currentModelRequirements.temperature,\n                // <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools\n                // <- Note: [🧆]\n            }; // <- TODO: [💩] Guard here types better\n            if (currentModelRequirements.responseFormat !== undefined) {\n                modelSettings.response_format = currentModelRequirements.responseFormat;\n            }\n            else if (format === 'JSON') {\n                modelSettings.response_format = {\n                    type: 'json_object',\n                };\n            }\n            // <- TODO: [🚸] Not all models are compatible with JSON mode\n            //        > 'response_format' of type 'json_object' is not supported with this model.\n            const rawPromptContent = templateParameters(content, { ...parameters, modelName });\n            // Convert thread to OpenAI format if present\n            let threadMessages = [];\n            if ('thread' in prompt && Array.isArray(prompt.thread)) {\n                threadMessages = prompt.thread.map((msg) => ({\n                    role: msg.sender === 'assistant' ? 'assistant' : 'user',\n                    content: msg.content,\n                }));\n            }\n            const messages = [\n                ...(currentModelRequirements.systemMessage === undefined\n                    ? []\n                    : [\n                        {\n                            role: 'system',\n                            content: currentModelRequirements.systemMessage,\n                        },\n                    ]),\n                ...threadMessages,\n            ];\n            if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {\n                const filesContent = await Promise.all(prompt.files.map(async (file) => {\n                    const arrayBuffer = await file.arrayBuffer();\n                    const base64 = Buffer.from(arrayBuffer).toString('base64');\n                    return {\n                        type: 'image_url',\n                        image_url: {\n                            url: `data:${file.type};base64,${base64}`,\n                        },\n                    };\n                }));\n                messages.push({\n                    role: 'user',\n                    content: [\n                        {\n                            type: 'text',\n                            text: rawPromptContent,\n                        },\n                        ...filesContent,\n                    ],\n                });\n            }\n            else {\n                messages.push({\n                    role: 'user',\n                    content: rawPromptContent,\n                });\n            }\n            let totalUsage = {\n                price: uncertainNumber(0),\n                input: {\n                    tokensCount: uncertainNumber(0),\n                    charactersCount: uncertainNumber(0),\n                    wordsCount: uncertainNumber(0),\n                    sentencesCount: uncertainNumber(0),\n                    linesCount: uncertainNumber(0),\n                    paragraphsCount: uncertainNumber(0),\n                    pagesCount: uncertainNumber(0),\n                },\n                output: {\n                    tokensCount: uncertainNumber(0),\n                    charactersCount: uncertainNumber(0),\n                    wordsCount: uncertainNumber(0),\n                    sentencesCount: uncertainNumber(0),\n                    linesCount: uncertainNumber(0),\n                    paragraphsCount: uncertainNumber(0),\n                    pagesCount: uncertainNumber(0),\n                },\n            };\n            const toolCalls = [];\n            const start = $getCurrentDate();\n            const tools = 'tools' in prompt && Array.isArray(prompt.tools) ? prompt.tools : currentModelRequirements.tools;\n            let isLooping = true;\n            while (isLooping) {\n                const rawRequest = {\n                    ...modelSettings,\n                    messages,\n                    user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),\n                    tools: tools === undefined ? undefined : mapToolsToOpenAi(tools),\n                };\n                if (this.options.isVerbose) {\n                    console.info(colors__default[\"default\"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));\n                }\n                try {\n                    const rawResponse = await this.limiter\n                        .schedule(() => this.makeRequestWithNetworkRetry(() => client.chat.completions.create(rawRequest)))\n                        .catch((error) => {\n                        assertsError(error);\n                        if (this.options.isVerbose) {\n                            console.info(colors__default[\"default\"].bgRed('error'), error);\n                        }\n                        throw error;\n                    });\n                    if (this.options.isVerbose) {\n                        console.info(colors__default[\"default\"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));\n                    }\n                    if (!rawResponse.choices[0]) {\n                        throw new PipelineExecutionError(`No choises from ${this.title}`);\n                    }\n                    const responseMessage = rawResponse.choices[0].message;\n                    messages.push(responseMessage);\n                    const usage = this.computeUsage(content || '', responseMessage.content || '', rawResponse);\n                    totalUsage = addUsage(totalUsage, usage);\n                    if (responseMessage.tool_calls && responseMessage.tool_calls.length > 0) {\n                        const toolCallStartedAt = new Map();\n                        if (onProgress) {\n                            onProgress({\n                                content: responseMessage.content || '',\n                                modelName: rawResponse.model || modelName,\n                                timing: { start, complete: $getCurrentDate() },\n                                usage: totalUsage,\n                                toolCalls: responseMessage.tool_calls.map((toolCall) => {\n                                    const calledAt = $getCurrentDate();\n                                    if (toolCall.id) {\n                                        toolCallStartedAt.set(toolCall.id, calledAt);\n                                    }\n                                    return {\n                                        name: toolCall.function.name,\n                                        arguments: toolCall.function.arguments,\n                                        result: '',\n                                        rawToolCall: toolCall,\n                                        createdAt: calledAt,\n                                    };\n                                }),\n                                rawPromptContent,\n                                rawRequest,\n                                rawResponse,\n                            });\n                        }\n                        await forEachAsync(responseMessage.tool_calls, {}, async (toolCall) => {\n                            const functionName = toolCall.function.name;\n                            const functionArgs = toolCall.function.arguments;\n                            const calledAt = toolCall.id\n                                ? toolCallStartedAt.get(toolCall.id) || $getCurrentDate()\n                                : $getCurrentDate();\n                            const executionTools = this.options\n                                .executionTools;\n                            if (!executionTools || !executionTools.script) {\n                                throw new PipelineExecutionError(`Model requested tool '${functionName}' but no executionTools.script were provided in OpenAiCompatibleExecutionTools options`);\n                            }\n                            // TODO: [DRY] Use some common tool caller\n                            const scriptTools = Array.isArray(executionTools.script)\n                                ? executionTools.script\n                                : [executionTools.script];\n                            let functionResponse;\n                            let errors;\n                            try {\n                                const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?\n                                functionResponse = await scriptTool.execute({\n                                    scriptLanguage: 'javascript',\n                                    script: buildToolInvocationScript({\n                                        functionName,\n                                        functionArgsExpression: functionArgs,\n                                    }),\n                                    parameters: prompt.parameters,\n                                });\n                            }\n                            catch (error) {\n                                assertsError(error);\n                                functionResponse = `Error: ${error.message}`;\n                                errors = [serializeError(error)];\n                            }\n                            messages.push({\n                                role: 'tool',\n                                tool_call_id: toolCall.id,\n                                content: functionResponse,\n                            });\n                            toolCalls.push({\n                                name: functionName,\n                                arguments: functionArgs,\n                                result: functionResponse,\n                                rawToolCall: toolCall,\n                                createdAt: calledAt,\n                                errors,\n                            });\n                        });\n                        continue;\n                    }\n                    const complete = $getCurrentDate();\n                    const resultContent = responseMessage.content;\n                    if (resultContent === null) {\n                        throw new PipelineExecutionError(`No response message from ${this.title}`);\n                    }\n                    isLooping = false;\n                    return exportJson({\n                        name: 'promptResult',\n                        message: `Result of \\`OpenAiCompatibleExecutionTools.callChatModel\\``,\n                        order: [],\n                        value: {\n                            content: resultContent,\n                            modelName: rawResponse.model || modelName,\n                            timing: {\n                                start,\n                                complete,\n                            },\n                            usage: totalUsage,\n                            toolCalls,\n                            rawPromptContent,\n                            rawRequest,\n                            rawResponse,\n                        },\n                    });\n                }\n                catch (error) {\n                    isLooping = false;\n                    assertsError(error);\n                    // Check if this is an unsupported parameter error\n                    if (!isUnsupportedParameterError(error)) {\n                        // If we have attemptStack, include it in the error message\n                        if (attemptStack.length > 0) {\n                            throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                                attemptStack\n                                    .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                                    (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                                    `, Error: ${a.errorMessage}` +\n                                    (a.stripped ? ' (stripped and retried)' : ''))\n                                    .join('\\n') +\n                                `\\nFinal error: ${error.message}`);\n                        }\n                        throw error;\n                    }\n                    // Parse which parameter is unsupported\n                    const unsupportedParameter = parseUnsupportedParameterError(error.message);\n                    if (!unsupportedParameter) {\n                        if (this.options.isVerbose) {\n                            console.warn(colors__default[\"default\"].bgYellow('Warning'), 'Could not parse unsupported parameter from error:', error.message);\n                        }\n                        throw error;\n                    }\n                    // Create a unique key for this model + parameter combination to prevent infinite loops\n                    const retryKey = `${modelName}-${unsupportedParameter}`;\n                    if (retriedUnsupportedParameters.has(retryKey)) {\n                        // Already retried this parameter, throw the error with attemptStack\n                        attemptStack.push({\n                            modelName,\n                            unsupportedParameter,\n                            errorMessage: error.message,\n                            stripped: true,\n                        });\n                        throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                            attemptStack\n                                .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                                (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                                `, Error: ${a.errorMessage}` +\n                                (a.stripped ? ' (stripped and retried)' : ''))\n                                .join('\\n') +\n                            `\\nFinal error: ${error.message}`);\n                    }\n                    // Mark this parameter as retried\n                    retriedUnsupportedParameters.add(retryKey);\n                    // Log warning in verbose mode\n                    if (this.options.isVerbose) {\n                        console.warn(colors__default[\"default\"].bgYellow('Warning'), `Removing unsupported parameter '${unsupportedParameter}' for model '${modelName}' and retrying request`);\n                    }\n                    // Add to attemptStack\n                    attemptStack.push({\n                        modelName,\n                        unsupportedParameter,\n                        errorMessage: error.message,\n                        stripped: true,\n                    });\n                    // Remove the unsupported parameter and retry\n                    const modifiedModelRequirements = removeUnsupportedModelRequirement(currentModelRequirements, unsupportedParameter);\n                    return this.callChatModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters, onProgress, options);\n                }\n            }\n            throw new PipelineExecutionError(`Tool calling loop did not return a result from ${this.title}`);\n        }\n        /**\n         * Calls OpenAI API to use a complete model.\n         */\n        async callCompletionModel(prompt) {\n            // Deep clone prompt and modelRequirements to avoid mutation across calls\n            const clonedPrompt = JSON.parse(JSON.stringify(prompt));\n            const retriedUnsupportedParameters = new Set();\n            return this.callCompletionModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters);\n        }\n        /**\n         * Internal method that handles parameter retry for completion model calls\n         */\n        async callCompletionModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set()) {\n            var _a;\n            if (this.options.isVerbose) {\n                console.info(`🖋 ${this.title} callCompletionModel call`, { prompt, currentModelRequirements });\n            }\n            const { content, parameters } = prompt;\n            const client = await this.getClient();\n            // TODO: [☂] Use here more modelRequirements\n            if (currentModelRequirements.modelVariant !== 'COMPLETION') {\n                throw new PipelineExecutionError('Use callCompletionModel only for COMPLETION variant');\n            }\n            const modelName = currentModelRequirements.modelName || this.getDefaultCompletionModel().modelName;\n            const modelSettings = {\n                model: modelName,\n                max_tokens: currentModelRequirements.maxTokens,\n                temperature: currentModelRequirements.temperature,\n            };\n            const rawPromptContent = templateParameters(content, { ...parameters, modelName });\n            const rawRequest = {\n                ...modelSettings,\n                model: modelName,\n                prompt: rawPromptContent,\n                user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),\n            };\n            const start = $getCurrentDate();\n            if (this.options.isVerbose) {\n                console.info(colors__default[\"default\"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));\n            }\n            try {\n                const rawResponse = await this.limiter\n                    .schedule(() => this.makeRequestWithNetworkRetry(() => client.completions.create(rawRequest)))\n                    .catch((error) => {\n                    assertsError(error);\n                    if (this.options.isVerbose) {\n                        console.info(colors__default[\"default\"].bgRed('error'), error);\n                    }\n                    throw error;\n                });\n                if (this.options.isVerbose) {\n                    console.info(colors__default[\"default\"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));\n                }\n                const complete = $getCurrentDate();\n                if (!rawResponse.choices[0]) {\n                    throw new PipelineExecutionError(`No choises from ${this.title}`);\n                }\n                if (rawResponse.choices.length > 1) {\n                    throw new PipelineExecutionError(`More than one choise from ${this.title}`);\n                }\n                const resultContent = rawResponse.choices[0].text;\n                const usage = this.computeUsage(content || '', resultContent || '', rawResponse);\n                return exportJson({\n                    name: 'promptResult',\n                    message: `Result of \\`OpenAiCompatibleExecutionTools.callCompletionModel\\``,\n                    order: [],\n                    value: {\n                        content: resultContent,\n                        modelName: rawResponse.model || modelName,\n                        timing: {\n                            start,\n                            complete,\n                        },\n                        usage,\n                        rawPromptContent,\n                        rawRequest,\n                        rawResponse,\n                    },\n                });\n            }\n            catch (error) {\n                assertsError(error);\n                if (!isUnsupportedParameterError(error)) {\n                    if (attemptStack.length > 0) {\n                        throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                            attemptStack\n                                .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                                (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                                `, Error: ${a.errorMessage}` +\n                                (a.stripped ? ' (stripped and retried)' : ''))\n                                .join('\\n') +\n                            `\\nFinal error: ${error.message}`);\n                    }\n                    throw error;\n                }\n                const unsupportedParameter = parseUnsupportedParameterError(error.message);\n                if (!unsupportedParameter) {\n                    if (this.options.isVerbose) {\n                        console.warn(colors__default[\"default\"].bgYellow('Warning'), 'Could not parse unsupported parameter from error:', error.message);\n                    }\n                    throw error;\n                }\n                const retryKey = `${modelName}-${unsupportedParameter}`;\n                if (retriedUnsupportedParameters.has(retryKey)) {\n                    attemptStack.push({\n                        modelName,\n                        unsupportedParameter,\n                        errorMessage: error.message,\n                        stripped: true,\n                    });\n                    throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                        attemptStack\n                            .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                            (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                            `, Error: ${a.errorMessage}` +\n                            (a.stripped ? ' (stripped and retried)' : ''))\n                            .join('\\n') +\n                        `\\nFinal error: ${error.message}`);\n                }\n                retriedUnsupportedParameters.add(retryKey);\n                if (this.options.isVerbose) {\n                    console.warn(colors__default[\"default\"].bgYellow('Warning'), `Removing unsupported parameter '${unsupportedParameter}' for model '${modelName}' and retrying request`);\n                }\n                attemptStack.push({\n                    modelName,\n                    unsupportedParameter,\n                    errorMessage: error.message,\n                    stripped: true,\n                });\n                const modifiedModelRequirements = removeUnsupportedModelRequirement(currentModelRequirements, unsupportedParameter);\n                return this.callCompletionModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters);\n            }\n        }\n        /**\n         * Calls OpenAI compatible API to use a embedding model\n         */\n        async callEmbeddingModel(prompt) {\n            // Deep clone prompt and modelRequirements to avoid mutation across calls\n            const clonedPrompt = JSON.parse(JSON.stringify(prompt));\n            const retriedUnsupportedParameters = new Set();\n            return this.callEmbeddingModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters);\n        }\n        /**\n         * Internal method that handles parameter retry for embedding model calls\n         */\n        async callEmbeddingModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set()) {\n            if (this.options.isVerbose) {\n                console.info(`🖋 ${this.title} embedding call`, { prompt, currentModelRequirements });\n            }\n            const { content, parameters } = prompt;\n            const client = await this.getClient();\n            if (currentModelRequirements.modelVariant !== 'EMBEDDING') {\n                throw new PipelineExecutionError('Use embed only for EMBEDDING variant');\n            }\n            const modelName = currentModelRequirements.modelName || this.getDefaultEmbeddingModel().modelName;\n            const rawPromptContent = templateParameters(content, { ...parameters, modelName });\n            const rawRequest = {\n                input: rawPromptContent,\n                model: modelName,\n            };\n            const start = $getCurrentDate();\n            if (this.options.isVerbose) {\n                console.info(colors__default[\"default\"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));\n            }\n            try {\n                const rawResponse = await this.limiter\n                    .schedule(() => this.makeRequestWithNetworkRetry(() => client.embeddings.create(rawRequest)))\n                    .catch((error) => {\n                    assertsError(error);\n                    if (this.options.isVerbose) {\n                        console.info(colors__default[\"default\"].bgRed('error'), error);\n                    }\n                    throw error;\n                });\n                if (this.options.isVerbose) {\n                    console.info(colors__default[\"default\"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));\n                }\n                const complete = $getCurrentDate();\n                if (rawResponse.data.length !== 1) {\n                    throw new PipelineExecutionError(`Expected exactly 1 data item in response, got ${rawResponse.data.length}`);\n                }\n                const resultContent = rawResponse.data[0].embedding;\n                const usage = this.computeUsage(content || '', '', rawResponse);\n                return exportJson({\n                    name: 'promptResult',\n                    message: `Result of \\`OpenAiCompatibleExecutionTools.callEmbeddingModel\\``,\n                    order: [],\n                    value: {\n                        content: resultContent,\n                        modelName: rawResponse.model || modelName,\n                        timing: {\n                            start,\n                            complete,\n                        },\n                        usage,\n                        rawPromptContent,\n                        rawRequest,\n                        rawResponse,\n                    },\n                });\n            }\n            catch (error) {\n                assertsError(error);\n                if (!isUnsupportedParameterError(error)) {\n                    if (attemptStack.length > 0) {\n                        throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                            attemptStack\n                                .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                                (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                                `, Error: ${a.errorMessage}` +\n                                (a.stripped ? ' (stripped and retried)' : ''))\n                                .join('\\n') +\n                            `\\nFinal error: ${error.message}`);\n                    }\n                    throw error;\n                }\n                const unsupportedParameter = parseUnsupportedParameterError(error.message);\n                if (!unsupportedParameter) {\n                    if (this.options.isVerbose) {\n                        console.warn(colors__default[\"default\"].bgYellow('Warning'), 'Could not parse unsupported parameter from error:', error.message);\n                    }\n                    throw error;\n                }\n                const retryKey = `${modelName}-${unsupportedParameter}`;\n                if (retriedUnsupportedParameters.has(retryKey)) {\n                    attemptStack.push({\n                        modelName,\n                        unsupportedParameter,\n                        errorMessage: error.message,\n                        stripped: true,\n                    });\n                    throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                        attemptStack\n                            .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                            (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                            `, Error: ${a.errorMessage}` +\n                            (a.stripped ? ' (stripped and retried)' : ''))\n                            .join('\\n') +\n                        `\\nFinal error: ${error.message}`);\n                }\n                retriedUnsupportedParameters.add(retryKey);\n                if (this.options.isVerbose) {\n                    console.warn(colors__default[\"default\"].bgYellow('Warning'), `Removing unsupported parameter '${unsupportedParameter}' for model '${modelName}' and retrying request`);\n                }\n                attemptStack.push({\n                    modelName,\n                    unsupportedParameter,\n                    errorMessage: error.message,\n                    stripped: true,\n                });\n                const modifiedModelRequirements = removeUnsupportedModelRequirement(currentModelRequirements, unsupportedParameter);\n                return this.callEmbeddingModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters);\n            }\n        }\n        /**\n         * Calls OpenAI compatible API to use a image generation model\n         */\n        async callImageGenerationModel(prompt) {\n            // Deep clone prompt and modelRequirements to avoid mutation across calls\n            const clonedPrompt = JSON.parse(JSON.stringify(prompt));\n            const retriedUnsupportedParameters = new Set();\n            return this.callImageGenerationModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters);\n        }\n        /**\n         * Internal method that handles parameter retry for image generation model calls\n         */\n        async callImageGenerationModelWithRetry(prompt, currentModelRequirements, attemptStack = [], retriedUnsupportedParameters = new Set()) {\n            var _a, _b;\n            if (this.options.isVerbose) {\n                console.info(`🎨 ${this.title} callImageGenerationModel call`, { prompt, currentModelRequirements });\n            }\n            const { content, parameters } = prompt;\n            const client = await this.getClient();\n            // TODO: [☂] Use here more modelRequirements\n            if (currentModelRequirements.modelVariant !== 'IMAGE_GENERATION') {\n                throw new PipelineExecutionError('Use callImageGenerationModel only for IMAGE_GENERATION variant');\n            }\n            const modelName = currentModelRequirements.modelName || this.getDefaultImageGenerationModel().modelName;\n            const modelSettings = {\n                model: modelName,\n                size: currentModelRequirements.size,\n                quality: currentModelRequirements.quality,\n                style: currentModelRequirements.style,\n            };\n            let rawPromptContent = templateParameters(content, { ...parameters, modelName });\n            if ('attachments' in prompt && Array.isArray(prompt.attachments) && prompt.attachments.length > 0) {\n                rawPromptContent +=\n                    '\\n\\n' +\n                        prompt.attachments.map((attachment) => `Image attachment: ${attachment.url}`).join('\\n');\n            }\n            const rawRequest = {\n                ...modelSettings,\n                prompt: rawPromptContent,\n                size: modelSettings.size || '1024x1024',\n                user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),\n                response_format: 'url', // TODO: [🧠] Maybe allow b64_json\n            };\n            const start = $getCurrentDate();\n            if (this.options.isVerbose) {\n                console.info(colors__default[\"default\"].bgWhite('rawRequest'), JSON.stringify(rawRequest, null, 4));\n            }\n            try {\n                const rawResponse = await this.limiter\n                    .schedule(() => this.makeRequestWithNetworkRetry(() => client.images.generate(rawRequest)))\n                    .catch((error) => {\n                    assertsError(error);\n                    if (this.options.isVerbose) {\n                        console.info(colors__default[\"default\"].bgRed('error'), error);\n                    }\n                    throw error;\n                });\n                if (this.options.isVerbose) {\n                    console.info(colors__default[\"default\"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));\n                }\n                const complete = $getCurrentDate();\n                if (!rawResponse.data[0]) {\n                    throw new PipelineExecutionError(`No choises from ${this.title}`);\n                }\n                if (rawResponse.data.length > 1) {\n                    throw new PipelineExecutionError(`More than one choise from ${this.title}`);\n                }\n                const resultContent = rawResponse.data[0].url;\n                const modelInfo = this.HARDCODED_MODELS.find((model) => model.modelName === modelName);\n                const price = ((_b = modelInfo === null || modelInfo === void 0 ? void 0 : modelInfo.pricing) === null || _b === void 0 ? void 0 : _b.output) ? uncertainNumber(modelInfo.pricing.output) : uncertainNumber();\n                return exportJson({\n                    name: 'promptResult',\n                    message: `Result of \\`OpenAiCompatibleExecutionTools.callImageGenerationModel\\``,\n                    order: [],\n                    value: {\n                        content: resultContent,\n                        modelName: modelName,\n                        timing: {\n                            start,\n                            complete,\n                        },\n                        usage: {\n                            price,\n                            input: {\n                                tokensCount: uncertainNumber(0),\n                                ...computeUsageCounts(rawPromptContent),\n                            },\n                            output: {\n                                tokensCount: uncertainNumber(0),\n                                ...computeUsageCounts(''),\n                            },\n                        },\n                        rawPromptContent,\n                        rawRequest,\n                        rawResponse,\n                    },\n                });\n            }\n            catch (error) {\n                assertsError(error);\n                if (!isUnsupportedParameterError(error)) {\n                    if (attemptStack.length > 0) {\n                        throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                            attemptStack\n                                .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                                (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                                `, Error: ${a.errorMessage}` +\n                                (a.stripped ? ' (stripped and retried)' : ''))\n                                .join('\\n') +\n                            `\\nFinal error: ${error.message}`);\n                    }\n                    throw error;\n                }\n                const unsupportedParameter = parseUnsupportedParameterError(error.message);\n                if (!unsupportedParameter) {\n                    if (this.options.isVerbose) {\n                        console.warn(colors__default[\"default\"].bgYellow('Warning'), 'Could not parse unsupported parameter from error:', error.message);\n                    }\n                    throw error;\n                }\n                const retryKey = `${modelName}-${unsupportedParameter}`;\n                if (retriedUnsupportedParameters.has(retryKey)) {\n                    attemptStack.push({\n                        modelName,\n                        unsupportedParameter,\n                        errorMessage: error.message,\n                        stripped: true,\n                    });\n                    throw new PipelineExecutionError(`All attempts failed. Attempt history:\\n` +\n                        attemptStack\n                            .map((a, i) => `  ${i + 1}. Model: ${a.modelName}` +\n                            (a.unsupportedParameter ? `, Stripped: ${a.unsupportedParameter}` : '') +\n                            `, Error: ${a.errorMessage}` +\n                            (a.stripped ? ' (stripped and retried)' : ''))\n                            .join('\\n') +\n                        `\\nFinal error: ${error.message}`);\n                }\n                retriedUnsupportedParameters.add(retryKey);\n                if (this.options.isVerbose) {\n                    console.warn(colors__default[\"default\"].bgYellow('Warning'), `Removing unsupported parameter '${unsupportedParameter}' for model '${modelName}' and retrying request`);\n                }\n                attemptStack.push({\n                    modelName,\n                    unsupportedParameter,\n                    errorMessage: error.message,\n                    stripped: true,\n                });\n                const modifiedModelRequirements = removeUnsupportedModelRequirement(currentModelRequirements, unsupportedParameter);\n                return this.callImageGenerationModelWithRetry(prompt, modifiedModelRequirements, attemptStack, retriedUnsupportedParameters);\n            }\n        }\n        // <- Note: [🤖] callXxxModel\n        /**\n         * Get the model that should be used as default\n         */\n        getDefaultModel(defaultModelName) {\n            // Note: Match exact or prefix for model families\n            const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));\n            if (model === undefined) {\n                throw new PipelineExecutionError(spaceTrim__default[\"default\"]((block) => `\n                            Cannot find model in ${this.title} models with name \"${defaultModelName}\" which should be used as default.\n\n                            Available models:\n                            ${block(this.HARDCODED_MODELS.map(({ modelName }) => `- \"${modelName}\"`).join('\\n'))}\n\n                            Model \"${defaultModelName}\" is probably not available anymore, not installed, inaccessible or misconfigured.\n\n                        `));\n            }\n            return model;\n        }\n        // <- Note: [🤖] getDefaultXxxModel\n        /**\n         * Makes a request with retry logic for network errors like ECONNRESET\n         */\n        async makeRequestWithNetworkRetry(requestFn) {\n            let lastError;\n            for (let attempt = 1; attempt <= CONNECTION_RETRIES_LIMIT; attempt++) {\n                try {\n                    return await requestFn();\n                }\n                catch (error) {\n                    assertsError(error);\n                    lastError = error;\n                    // Check if this is a retryable network error\n                    const isRetryableError = this.isRetryableNetworkError(error);\n                    if (!isRetryableError || attempt === CONNECTION_RETRIES_LIMIT) {\n                        if (this.options.isVerbose && this.isRetryableNetworkError(error)) {\n                            console.info(colors__default[\"default\"].bgRed('Final network error after retries'), `Attempt ${attempt}/${CONNECTION_RETRIES_LIMIT}:`, error);\n                        }\n                        throw error;\n                    }\n                    // Calculate exponential backoff delay\n                    const baseDelay = 1000; // 1 second\n                    const backoffDelay = baseDelay * Math.pow(2, attempt - 1);\n                    const jitterDelay = Math.random() * 500; // Add some randomness\n                    const totalDelay = backoffDelay + jitterDelay;\n                    if (this.options.isVerbose) {\n                        console.info(colors__default[\"default\"].bgYellow('Retrying network request'), `Attempt ${attempt}/${CONNECTION_RETRIES_LIMIT}, waiting ${Math.round(totalDelay)}ms:`, error.message);\n                    }\n                    // Wait before retrying\n                    await new Promise((resolve) => setTimeout(resolve, totalDelay));\n                }\n            }\n            throw lastError;\n        }\n        /**\n         * Determines if an error is retryable (network-related errors)\n         */\n        isRetryableNetworkError(error) {\n            const errorMessage = error.message.toLowerCase();\n            const errorCode = error.code;\n            // Network connection errors that should be retried\n            const retryableErrors = [\n                'econnreset',\n                'enotfound',\n                'econnrefused',\n                'etimedout',\n                'socket hang up',\n                'network error',\n                'fetch failed',\n                'connection reset',\n                'connection refused',\n                'timeout',\n            ];\n            // Check error message\n            if (retryableErrors.some((retryableError) => errorMessage.includes(retryableError))) {\n                return true;\n            }\n            // Check error code\n            if (errorCode && retryableErrors.includes(errorCode.toLowerCase())) {\n                return true;\n            }\n            // Check for specific HTTP status codes that are retryable\n            const errorWithStatus = error;\n            const httpStatus = errorWithStatus.status || errorWithStatus.statusCode;\n            if (httpStatus && [429, 500, 502, 503, 504].includes(httpStatus)) {\n                return true;\n            }\n            return false;\n        }\n    }\n    /**\n     * TODO: [🛄] Some way how to re-wrap the errors from `OpenAiCompatibleExecutionTools`\n     * TODO: [🛄] Maybe make custom `OpenAiCompatibleError`\n     * TODO: [🧠][🈁] Maybe use `isDeterministic` from options\n     * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes\n     * TODO: [🧠][🦢] Make reverse adapter from LlmExecutionTools to OpenAI-compatible:\n     */\n\n    /**\n     * Profile for OpenAI provider\n     */\n    const OPENAI_PROVIDER_PROFILE = {\n        name: 'OPENAI',\n        fullname: 'OpenAI GPT',\n        color: '#10a37f',\n    };\n    /**\n     * Execution Tools for calling OpenAI API\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    class OpenAiExecutionTools extends OpenAiCompatibleExecutionTools {\n        constructor() {\n            super(...arguments);\n            /**\n             * Computes the usage of the OpenAI API based on the response from OpenAI\n             */\n            this.computeUsage = computeOpenAiUsage;\n            // <- Note: [🤖] getDefaultXxxModel\n        }\n        /* <- TODO: [🍚] `, Destroyable` */\n        get title() {\n            return 'OpenAI';\n        }\n        get description() {\n            return 'Use all models provided by OpenAI';\n        }\n        get profile() {\n            return OPENAI_PROVIDER_PROFILE;\n        }\n        /**\n         * List all available models (non dynamically)\n         *\n         * Note: Purpose of this is to provide more information about models than standard listing from API\n         */\n        get HARDCODED_MODELS() {\n            return OPENAI_MODELS;\n        }\n        /**\n         * Default model for chat variant.\n         */\n        getDefaultChatModel() {\n            return this.getDefaultModel('gpt-5');\n        }\n        /**\n         * Default model for completion variant.\n         */\n        getDefaultCompletionModel() {\n            return this.getDefaultModel('gpt-3.5-turbo-instruct');\n        }\n        /**\n         * Default model for completion variant.\n         */\n        getDefaultEmbeddingModel() {\n            return this.getDefaultModel('text-embedding-3-large');\n        }\n        /**\n         * Default model for image generation variant.\n         */\n        getDefaultImageGenerationModel() {\n            return this.getDefaultModel('dall-e-3');\n        }\n    }\n\n    /** @private The default base name for inline knowledge files when the content lacks identifying text */\n    const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';\n    /** @private The default file extension used for inline knowledge uploads */\n    const INLINE_KNOWLEDGE_EXTENSION = '.txt';\n    /** @private Prefix that identifies base64 data URLs */\n    const DATA_URL_PREFIX = 'data:';\n    /**\n     * Checks whether the provided source string is a data URL that can be decoded.\n     *\n     * @private thing of inline knowledge\n     */\n    function isDataUrlKnowledgeSource(source) {\n        return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);\n    }\n    /**\n     * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.\n     *\n     * @private utility of inline knowledge processing\n     */\n    function parseDataUrlKnowledgeSource(source) {\n        if (!isDataUrlKnowledgeSource(source)) {\n            return null;\n        }\n        const commaIndex = source.indexOf(',');\n        if (commaIndex === -1) {\n            return null;\n        }\n        const header = source.slice(DATA_URL_PREFIX.length, commaIndex);\n        const payload = source.slice(commaIndex + 1);\n        const tokens = header.split(';');\n        const mediaType = tokens[0] || 'text/plain';\n        let filename = `${INLINE_KNOWLEDGE_BASE_NAME}${INLINE_KNOWLEDGE_EXTENSION}`;\n        let isBase64 = false;\n        for (let i = 1; i < tokens.length; i++) {\n            const token = tokens[i];\n            if (!token) {\n                continue;\n            }\n            if (token.toLowerCase() === 'base64') {\n                isBase64 = true;\n                continue;\n            }\n            const [key, value] = token.split('=');\n            if (key === 'name' && value !== undefined) {\n                try {\n                    filename = decodeURIComponent(value);\n                }\n                catch (_a) {\n                    filename = value;\n                }\n            }\n        }\n        if (!isBase64) {\n            return null;\n        }\n        try {\n            const buffer = Buffer.from(payload, 'base64');\n            return {\n                buffer,\n                filename,\n                mimeType: mediaType,\n            };\n        }\n        catch (_b) {\n            return null;\n        }\n    }\n    /**\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    const DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS = 30000;\n    const DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS = 900000;\n    const VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS = 15000;\n    const VECTOR_STORE_STALL_LOG_THRESHOLD_MS = 30000;\n    /**\n     * Base class for OpenAI execution tools that need hosted vector stores.\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    class OpenAiVectorStoreHandler extends OpenAiExecutionTools {\n        /**\n         * Returns the per-knowledge-source download timeout in milliseconds.\n         */\n        getKnowledgeSourceDownloadTimeoutMs() {\n            var _a;\n            return (_a = this.vectorStoreOptions.knowledgeSourceDownloadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_DOWNLOAD_TIMEOUT_MS;\n        }\n        /**\n         * Returns the max concurrency for knowledge source uploads.\n         */\n        getKnowledgeSourceUploadMaxConcurrency() {\n            var _a;\n            return (_a = this.vectorStoreOptions.knowledgeSourceUploadMaxConcurrency) !== null && _a !== void 0 ? _a : 5;\n        }\n        /**\n         * Returns the polling interval in milliseconds for vector store uploads.\n         */\n        getKnowledgeSourceUploadPollIntervalMs() {\n            var _a;\n            return (_a = this.vectorStoreOptions.knowledgeSourceUploadPollIntervalMs) !== null && _a !== void 0 ? _a : 5000;\n        }\n        /**\n         * Returns the overall upload timeout in milliseconds for vector store uploads.\n         */\n        getKnowledgeSourceUploadTimeoutMs() {\n            var _a;\n            return (_a = this.vectorStoreOptions.knowledgeSourceUploadTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_KNOWLEDGE_SOURCE_UPLOAD_TIMEOUT_MS;\n        }\n        /**\n         * Returns true if we should continue even if vector store ingestion stalls.\n         */\n        shouldContinueOnVectorStoreStall() {\n            var _a;\n            return (_a = this.vectorStoreOptions.shouldContinueOnVectorStoreStall) !== null && _a !== void 0 ? _a : true;\n        }\n        /**\n         * Returns vector-store-specific options with extended settings.\n         */\n        get vectorStoreOptions() {\n            return this.options;\n        }\n        /**\n         * Returns the OpenAI vector stores API surface, supporting stable and beta SDKs.\n         */\n        getVectorStoresApi(client) {\n            var _a, _b;\n            const vectorStores = (_a = client.vectorStores) !== null && _a !== void 0 ? _a : (_b = client.beta) === null || _b === void 0 ? void 0 : _b.vectorStores;\n            if (!vectorStores) {\n                throw new Error('OpenAI client does not support vector stores. Please ensure you are using a compatible version of the OpenAI SDK with vector store support.');\n            }\n            return vectorStores;\n        }\n        /**\n         * Downloads a knowledge source URL into a File for vector store upload.\n         */\n        async downloadKnowledgeSourceFile(options) {\n            var _a;\n            const { source, timeoutMs, logLabel } = options;\n            const startedAtMs = Date.now();\n            const controller = new AbortController();\n            const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Downloading knowledge source', {\n                    source,\n                    timeoutMs,\n                    logLabel,\n                });\n            }\n            try {\n                const response = await fetch(source, { signal: controller.signal });\n                const contentType = (_a = response.headers.get('content-type')) !== null && _a !== void 0 ? _a : undefined;\n                if (!response.ok) {\n                    console.error('[🤰]', 'Failed to download knowledge source', {\n                        source,\n                        status: response.status,\n                        statusText: response.statusText,\n                        contentType,\n                        elapsedMs: Date.now() - startedAtMs,\n                        logLabel,\n                    });\n                    return null;\n                }\n                const buffer = await response.arrayBuffer();\n                let filename = source.split('/').pop() || 'downloaded-file';\n                try {\n                    const url = new URL(source);\n                    filename = url.pathname.split('/').pop() || filename;\n                }\n                catch (error) {\n                    // Keep default filename\n                }\n                const file = new File([buffer], filename, contentType ? { type: contentType } : undefined);\n                const elapsedMs = Date.now() - startedAtMs;\n                const sizeBytes = buffer.byteLength;\n                if (this.options.isVerbose) {\n                    console.info('[🤰]', 'Downloaded knowledge source', {\n                        source,\n                        filename,\n                        sizeBytes,\n                        contentType,\n                        elapsedMs,\n                        logLabel,\n                    });\n                }\n                return { file, sizeBytes, filename, elapsedMs };\n            }\n            catch (error) {\n                assertsError(error);\n                console.error('[🤰]', 'Error downloading knowledge source', {\n                    source,\n                    elapsedMs: Date.now() - startedAtMs,\n                    logLabel,\n                    error: serializeError(error),\n                });\n                return null;\n            }\n            finally {\n                clearTimeout(timeoutId);\n            }\n        }\n        /**\n         * Logs vector store file batch diagnostics to help trace ingestion stalls or failures.\n         */\n        async logVectorStoreFileBatchDiagnostics(options) {\n            var _a, _b, _c, _d, _e;\n            const { client, vectorStoreId, batchId, uploadedFiles, logLabel, reason } = options;\n            if (reason === 'stalled' && !this.options.isVerbose) {\n                return;\n            }\n            if (!batchId.startsWith('vsfb_')) {\n                console.error('[🤰]', 'Vector store file batch diagnostics skipped (invalid batch id)', {\n                    vectorStoreId,\n                    batchId,\n                    reason,\n                    logLabel,\n                });\n                return;\n            }\n            const fileIdToMetadata = new Map();\n            for (const file of uploadedFiles) {\n                fileIdToMetadata.set(file.fileId, file);\n            }\n            try {\n                const vectorStores = this.getVectorStoresApi(client);\n                const limit = Math.min(100, Math.max(10, uploadedFiles.length));\n                const batchFilesPage = await vectorStores.fileBatches.listFiles(batchId, {\n                    vector_store_id: vectorStoreId,\n                    limit,\n                });\n                const batchFiles = (_a = batchFilesPage.data) !== null && _a !== void 0 ? _a : [];\n                const statusCounts = {\n                    in_progress: 0,\n                    completed: 0,\n                    failed: 0,\n                    cancelled: 0,\n                };\n                const errorSamples = [];\n                const inProgressSamples = [];\n                const batchFileIds = new Set();\n                for (const file of batchFiles) {\n                    const status = (_b = file.status) !== null && _b !== void 0 ? _b : 'unknown';\n                    statusCounts[status] = ((_c = statusCounts[status]) !== null && _c !== void 0 ? _c : 0) + 1;\n                    const vectorStoreFileId = file.id;\n                    const uploadedFileId = (_d = file.file_id) !== null && _d !== void 0 ? _d : file.fileId;\n                    const fileId = uploadedFileId !== null && uploadedFileId !== void 0 ? uploadedFileId : vectorStoreFileId;\n                    batchFileIds.add(fileId);\n                    const metadata = fileIdToMetadata.get(fileId);\n                    if (status === 'failed') {\n                        errorSamples.push({\n                            fileId,\n                            status,\n                            error: (_e = file.last_error) === null || _e === void 0 ? void 0 : _e.message,\n                            filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,\n                            vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,\n                        });\n                    }\n                    if (status === 'in_progress') {\n                        inProgressSamples.push({\n                            fileId,\n                            filename: metadata === null || metadata === void 0 ? void 0 : metadata.filename,\n                            vectorStoreFileId: uploadedFileId ? vectorStoreFileId : undefined,\n                        });\n                    }\n                }\n                const missingSamples = uploadedFiles\n                    .filter((file) => !batchFileIds.has(file.fileId))\n                    .slice(0, 5)\n                    .map((file) => ({\n                    fileId: file.fileId,\n                    filename: file.filename,\n                    sizeBytes: file.sizeBytes,\n                }));\n                const vectorStore = await vectorStores.retrieve(vectorStoreId);\n                const logPayload = {\n                    vectorStoreId,\n                    batchId,\n                    reason,\n                    vectorStoreStatus: vectorStore.status,\n                    vectorStoreFileCounts: vectorStore.file_counts,\n                    vectorStoreUsageBytes: vectorStore.usage_bytes,\n                    batchFileCount: batchFiles.length,\n                    statusCounts,\n                    errorSamples: errorSamples.slice(0, 5),\n                    inProgressSamples,\n                    missingFileCount: uploadedFiles.length - batchFileIds.size,\n                    missingSamples,\n                    logLabel,\n                };\n                const logFunction = reason === 'stalled' ? console.info : console.error;\n                logFunction('[🤰]', 'Vector store file batch diagnostics', logPayload);\n            }\n            catch (error) {\n                assertsError(error);\n                console.error('[🤰]', 'Vector store file batch diagnostics failed', {\n                    vectorStoreId,\n                    batchId,\n                    reason,\n                    logLabel,\n                    error: serializeError(error),\n                });\n            }\n        }\n        /**\n         * Uploads knowledge source files to the vector store and polls until processing completes.\n         */\n        async uploadKnowledgeSourceFilesToVectorStore(options) {\n            var _a, _b, _c, _d, _e, _f;\n            const { client, vectorStoreId, files, totalBytes, logLabel } = options;\n            const vectorStores = this.getVectorStoresApi(client);\n            const uploadStartedAtMs = Date.now();\n            const maxConcurrency = Math.max(1, this.getKnowledgeSourceUploadMaxConcurrency());\n            const pollIntervalMs = Math.max(1000, this.getKnowledgeSourceUploadPollIntervalMs());\n            const uploadTimeoutMs = Math.max(1000, this.getKnowledgeSourceUploadTimeoutMs());\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Uploading knowledge source files to OpenAI', {\n                    vectorStoreId,\n                    fileCount: files.length,\n                    totalBytes,\n                    maxConcurrency,\n                    pollIntervalMs,\n                    uploadTimeoutMs,\n                    logLabel,\n                });\n            }\n            const fileTypeSummary = {};\n            for (const file of files) {\n                const filename = (_a = file.name) !== null && _a !== void 0 ? _a : '';\n                const extension = filename.includes('.')\n                    ? (_c = (_b = filename.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'unknown'\n                    : 'unknown';\n                const sizeBytes = typeof file.size === 'number' ? file.size : 0;\n                const summary = (_d = fileTypeSummary[extension]) !== null && _d !== void 0 ? _d : { count: 0, totalBytes: 0 };\n                summary.count += 1;\n                summary.totalBytes += sizeBytes;\n                fileTypeSummary[extension] = summary;\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Knowledge source file summary', {\n                    vectorStoreId,\n                    fileCount: files.length,\n                    totalBytes,\n                    fileTypeSummary,\n                    logLabel,\n                });\n            }\n            const fileEntries = files.map((file, index) => ({ file, index }));\n            const fileIterator = fileEntries.values();\n            const fileIds = [];\n            const uploadedFiles = [];\n            const failedUploads = [];\n            let uploadedCount = 0;\n            const processFiles = async (iterator) => {\n                var _a, _b;\n                for (const { file, index } of iterator) {\n                    const uploadIndex = index + 1;\n                    const filename = file.name || `knowledge-source-${uploadIndex}`;\n                    const extension = filename.includes('.')\n                        ? (_b = (_a = filename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'unknown'\n                        : 'unknown';\n                    const sizeBytes = typeof file.size === 'number' ? file.size : undefined;\n                    const fileUploadStartedAtMs = Date.now();\n                    if (this.options.isVerbose) {\n                        console.info('[🤰]', 'Uploading knowledge source file', {\n                            index: uploadIndex,\n                            total: files.length,\n                            filename,\n                            extension,\n                            sizeBytes,\n                            logLabel,\n                        });\n                    }\n                    try {\n                        const uploaded = await client.files.create({ file, purpose: 'assistants' });\n                        fileIds.push(uploaded.id);\n                        uploadedFiles.push({ fileId: uploaded.id, filename, sizeBytes });\n                        uploadedCount += 1;\n                        if (this.options.isVerbose) {\n                            console.info('[🤰]', 'Uploaded knowledge source file', {\n                                index: uploadIndex,\n                                total: files.length,\n                                filename,\n                                sizeBytes,\n                                fileId: uploaded.id,\n                                elapsedMs: Date.now() - fileUploadStartedAtMs,\n                                logLabel,\n                            });\n                        }\n                    }\n                    catch (error) {\n                        assertsError(error);\n                        const serializedError = serializeError(error);\n                        failedUploads.push({ index: uploadIndex, filename, error: serializedError });\n                        console.error('[🤰]', 'Failed to upload knowledge source file', {\n                            index: uploadIndex,\n                            total: files.length,\n                            filename,\n                            sizeBytes,\n                            elapsedMs: Date.now() - fileUploadStartedAtMs,\n                            logLabel,\n                            error: serializedError,\n                        });\n                    }\n                }\n            };\n            const workerCount = Math.min(maxConcurrency, files.length);\n            const workers = Array.from({ length: workerCount }, () => processFiles(fileIterator));\n            await Promise.all(workers);\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Finished uploading knowledge source files', {\n                    vectorStoreId,\n                    fileCount: files.length,\n                    uploadedCount,\n                    failedCount: failedUploads.length,\n                    elapsedMs: Date.now() - uploadStartedAtMs,\n                    failedSamples: failedUploads.slice(0, 3),\n                    logLabel,\n                });\n            }\n            if (fileIds.length === 0) {\n                console.error('[🤰]', 'No knowledge source files were uploaded', {\n                    vectorStoreId,\n                    fileCount: files.length,\n                    failedCount: failedUploads.length,\n                    logLabel,\n                });\n                return null;\n            }\n            const batch = await vectorStores.fileBatches.create(vectorStoreId, {\n                file_ids: fileIds,\n            });\n            const expectedBatchId = batch.id;\n            const expectedBatchIdValid = expectedBatchId.startsWith('vsfb_');\n            if (!expectedBatchIdValid) {\n                console.error('[🤰]', 'Vector store file batch id looks invalid', {\n                    vectorStoreId,\n                    batchId: expectedBatchId,\n                    batchVectorStoreId: batch.vector_store_id,\n                    logLabel,\n                });\n            }\n            else if (batch.vector_store_id !== vectorStoreId) {\n                console.error('[🤰]', 'Vector store file batch vector store id mismatch', {\n                    vectorStoreId,\n                    batchId: expectedBatchId,\n                    batchVectorStoreId: batch.vector_store_id,\n                    logLabel,\n                });\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Created vector store file batch', {\n                    vectorStoreId,\n                    batchId: expectedBatchId,\n                    fileCount: fileIds.length,\n                    logLabel,\n                });\n            }\n            const pollStartedAtMs = Date.now();\n            const progressLogIntervalMs = Math.max(VECTOR_STORE_PROGRESS_LOG_INTERVAL_MIN_MS, pollIntervalMs);\n            const diagnosticsIntervalMs = Math.max(60000, pollIntervalMs * 5);\n            // let lastStatus: string | undefined;\n            let lastCountsKey = '';\n            let lastProgressKey = '';\n            let lastLogAtMs = 0;\n            let lastProgressAtMs = pollStartedAtMs;\n            let lastDiagnosticsAtMs = pollStartedAtMs;\n            let latestBatch = batch;\n            let loggedBatchIdMismatch = false;\n            let loggedBatchIdFallback = false;\n            let loggedBatchIdInvalid = false;\n            let shouldPoll = true;\n            while (shouldPoll) {\n                const nowMs = Date.now();\n                // [🤰] Note: Sometimes OpenAI returns Vector Store object instead of Batch object, or IDs get swapped.\n                const rawBatchId = typeof latestBatch.id === 'string' ? latestBatch.id : '';\n                const rawVectorStoreId = latestBatch.vector_store_id;\n                let returnedBatchId = rawBatchId;\n                let returnedBatchIdValid = typeof returnedBatchId === 'string' && returnedBatchId.startsWith('vsfb_');\n                if (!returnedBatchIdValid && expectedBatchIdValid) {\n                    if (!loggedBatchIdFallback) {\n                        console.error('[🤰]', 'Vector store file batch id missing from response; falling back to expected', {\n                            vectorStoreId,\n                            expectedBatchId,\n                            returnedBatchId,\n                            rawVectorStoreId,\n                            logLabel,\n                        });\n                        loggedBatchIdFallback = true;\n                    }\n                    returnedBatchId = expectedBatchId;\n                    returnedBatchIdValid = true;\n                }\n                if (!returnedBatchIdValid && !loggedBatchIdInvalid) {\n                    console.error('[🤰]', 'Vector store file batch id is invalid; stopping polling', {\n                        vectorStoreId,\n                        expectedBatchId,\n                        returnedBatchId,\n                        rawVectorStoreId,\n                        logLabel,\n                    });\n                    loggedBatchIdInvalid = true;\n                }\n                const batchIdMismatch = expectedBatchIdValid && returnedBatchIdValid && returnedBatchId !== expectedBatchId;\n                if (batchIdMismatch && !loggedBatchIdMismatch) {\n                    console.error('[🤰]', 'Vector store file batch id mismatch', {\n                        vectorStoreId,\n                        expectedBatchId,\n                        returnedBatchId,\n                        logLabel,\n                    });\n                    loggedBatchIdMismatch = true;\n                }\n                if (returnedBatchIdValid) {\n                    latestBatch = await vectorStores.fileBatches.retrieve(returnedBatchId, {\n                        vector_store_id: vectorStoreId,\n                    });\n                }\n                else {\n                    shouldPoll = false;\n                    continue;\n                }\n                const status = (_e = latestBatch.status) !== null && _e !== void 0 ? _e : 'unknown';\n                const fileCounts = (_f = latestBatch.file_counts) !== null && _f !== void 0 ? _f : {};\n                const progressKey = JSON.stringify(fileCounts);\n                const statusCountsKey = `${status}-${progressKey}`;\n                const isProgressing = progressKey !== lastProgressKey;\n                if (isProgressing) {\n                    lastProgressAtMs = nowMs;\n                    lastProgressKey = progressKey;\n                }\n                if (this.options.isVerbose &&\n                    (statusCountsKey !== lastCountsKey || nowMs - lastLogAtMs >= progressLogIntervalMs)) {\n                    console.info('[🤰]', 'Vector store file batch status', {\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        status,\n                        fileCounts,\n                        elapsedMs: nowMs - pollStartedAtMs,\n                        logLabel,\n                    });\n                    lastCountsKey = statusCountsKey;\n                    lastLogAtMs = nowMs;\n                }\n                if (status === 'in_progress' &&\n                    nowMs - lastProgressAtMs >= VECTOR_STORE_STALL_LOG_THRESHOLD_MS &&\n                    nowMs - lastDiagnosticsAtMs >= diagnosticsIntervalMs) {\n                    lastDiagnosticsAtMs = nowMs;\n                    await this.logVectorStoreFileBatchDiagnostics({\n                        client,\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        uploadedFiles,\n                        logLabel,\n                        reason: 'stalled',\n                    });\n                }\n                if (status === 'completed') {\n                    if (this.options.isVerbose) {\n                        console.info('[🤰]', 'Vector store file batch completed', {\n                            vectorStoreId,\n                            batchId: returnedBatchId,\n                            fileCounts,\n                            elapsedMs: nowMs - pollStartedAtMs,\n                            logLabel,\n                        });\n                    }\n                    shouldPoll = false;\n                    continue;\n                }\n                if (status === 'failed') {\n                    console.error('[🤰]', 'Vector store file batch completed with failures', {\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        fileCounts,\n                        elapsedMs: nowMs - pollStartedAtMs,\n                        logLabel,\n                    });\n                    await this.logVectorStoreFileBatchDiagnostics({\n                        client,\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        uploadedFiles,\n                        logLabel,\n                        reason: 'failed',\n                    });\n                    shouldPoll = false;\n                    continue;\n                }\n                if (status === 'cancelled') {\n                    console.error('[🤰]', 'Vector store file batch did not complete', {\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        status,\n                        fileCounts,\n                        elapsedMs: nowMs - pollStartedAtMs,\n                        logLabel,\n                    });\n                    await this.logVectorStoreFileBatchDiagnostics({\n                        client,\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        uploadedFiles,\n                        logLabel,\n                        reason: 'failed',\n                    });\n                    shouldPoll = false;\n                    continue;\n                }\n                if (nowMs - pollStartedAtMs >= uploadTimeoutMs) {\n                    console.error('[🤰]', 'Timed out waiting for vector store file batch', {\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        fileCounts,\n                        elapsedMs: nowMs - pollStartedAtMs,\n                        uploadTimeoutMs,\n                        logLabel,\n                    });\n                    await this.logVectorStoreFileBatchDiagnostics({\n                        client,\n                        vectorStoreId,\n                        batchId: returnedBatchId,\n                        uploadedFiles,\n                        logLabel,\n                        reason: 'timeout',\n                    });\n                    if (this.shouldContinueOnVectorStoreStall()) {\n                        console.warn('[🤰]', 'Continuing despite vector store timeout as requested', {\n                            vectorStoreId,\n                            logLabel,\n                        });\n                        shouldPoll = false;\n                        continue;\n                    }\n                    try {\n                        const cancelBatchId = batchIdMismatch && returnedBatchId.startsWith('vsfb_') ? returnedBatchId : expectedBatchId;\n                        if (!cancelBatchId.startsWith('vsfb_')) {\n                            console.error('[🤰]', 'Skipping vector store file batch cancel (invalid batch id)', {\n                                vectorStoreId,\n                                batchId: cancelBatchId,\n                                logLabel,\n                            });\n                        }\n                        else {\n                            await vectorStores.fileBatches.cancel(cancelBatchId, {\n                                vector_store_id: vectorStoreId,\n                            });\n                        }\n                        if (this.options.isVerbose) {\n                            console.info('[🤰]', 'Cancelled vector store file batch after timeout', {\n                                vectorStoreId,\n                                batchId: batchIdMismatch && returnedBatchId.startsWith('vsfb_')\n                                    ? returnedBatchId\n                                    : expectedBatchId,\n                                ...(batchIdMismatch ? { returnedBatchId } : {}),\n                                logLabel,\n                            });\n                        }\n                    }\n                    catch (error) {\n                        assertsError(error);\n                        console.error('[🤰]', 'Failed to cancel vector store file batch after timeout', {\n                            vectorStoreId,\n                            batchId: expectedBatchId,\n                            ...(batchIdMismatch ? { returnedBatchId } : {}),\n                            logLabel,\n                            error: serializeError(error),\n                        });\n                    }\n                    shouldPoll = false;\n                    continue;\n                }\n                await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n            }\n            return latestBatch;\n        }\n        /**\n         * Creates a vector store and uploads knowledge sources, returning its ID.\n         */\n        async createVectorStoreWithKnowledgeSources(options) {\n            const { client, name, knowledgeSources, logLabel } = options;\n            const vectorStores = this.getVectorStoresApi(client);\n            const knowledgeSourcesCount = knowledgeSources.length;\n            const downloadTimeoutMs = this.getKnowledgeSourceDownloadTimeoutMs();\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Creating vector store with knowledge sources', {\n                    name,\n                    knowledgeSourcesCount,\n                    downloadTimeoutMs,\n                    logLabel,\n                });\n            }\n            const vectorStore = await vectorStores.create({\n                name: `${name} Knowledge Base`,\n            });\n            const vectorStoreId = vectorStore.id;\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Vector store created', {\n                    vectorStoreId,\n                    logLabel,\n                });\n            }\n            const fileStreams = [];\n            const skippedSources = [];\n            let totalBytes = 0;\n            const processingStartedAtMs = Date.now();\n            for (const [index, source] of knowledgeSources.entries()) {\n                try {\n                    const isDataUrl = isDataUrlKnowledgeSource(source);\n                    const isHttp = source.startsWith('http://') || source.startsWith('https://');\n                    const sourceType = isDataUrl ? 'data_url' : isHttp ? 'url' : 'file';\n                    if (this.options.isVerbose) {\n                        console.info('[🤰]', 'Processing knowledge source', {\n                            index: index + 1,\n                            total: knowledgeSourcesCount,\n                            source,\n                            sourceType,\n                            logLabel,\n                        });\n                    }\n                    if (isDataUrl) {\n                        const parsed = parseDataUrlKnowledgeSource(source);\n                        if (!parsed) {\n                            skippedSources.push({ source, reason: 'invalid_data_url' });\n                            if (this.options.isVerbose) {\n                                console.info('[🤰]', 'Skipping knowledge source (invalid data URL)', {\n                                    source,\n                                    sourceType,\n                                    logLabel,\n                                });\n                            }\n                            continue;\n                        }\n                        const dataUrlFile = new File([parsed.buffer], parsed.filename, {\n                            type: parsed.mimeType,\n                        });\n                        fileStreams.push(dataUrlFile);\n                        totalBytes += parsed.buffer.length;\n                        continue;\n                    }\n                    if (isHttp) {\n                        const downloadResult = await this.downloadKnowledgeSourceFile({\n                            source,\n                            timeoutMs: downloadTimeoutMs,\n                            logLabel,\n                        });\n                        if (downloadResult) {\n                            fileStreams.push(downloadResult.file);\n                            totalBytes += downloadResult.sizeBytes;\n                        }\n                        else {\n                            skippedSources.push({ source, reason: 'download_failed' });\n                        }\n                    }\n                    else {\n                        skippedSources.push({ source, reason: 'unsupported_source_type' });\n                        if (this.options.isVerbose) {\n                            console.info('[🤰]', 'Skipping knowledge source (unsupported type)', {\n                                source,\n                                sourceType,\n                                logLabel,\n                            });\n                        }\n                        /*\n                        TODO: [🤰] Resolve problem with browser environment\n                        // Assume it's a local file path\n                        // Note: This will work in Node.js environment\n                        // For browser environments, this would need different handling\n                        const fs = await import('fs');\n                        const fileStream = fs.createReadStream(source);\n                        fileStreams.push(fileStream);\n                        */\n                    }\n                }\n                catch (error) {\n                    assertsError(error);\n                    skippedSources.push({ source, reason: 'processing_error' });\n                    console.error('[🤰]', 'Error processing knowledge source', {\n                        source,\n                        logLabel,\n                        error: serializeError(error),\n                    });\n                }\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Finished processing knowledge sources', {\n                    total: knowledgeSourcesCount,\n                    downloadedCount: fileStreams.length,\n                    skippedCount: skippedSources.length,\n                    totalBytes,\n                    elapsedMs: Date.now() - processingStartedAtMs,\n                    skippedSamples: skippedSources.slice(0, 3),\n                    logLabel,\n                });\n            }\n            if (fileStreams.length > 0) {\n                if (this.options.isVerbose) {\n                    console.info('[🤰]', 'Uploading files to vector store', {\n                        vectorStoreId,\n                        fileCount: fileStreams.length,\n                        totalBytes,\n                        maxConcurrency: this.getKnowledgeSourceUploadMaxConcurrency(),\n                        pollIntervalMs: this.getKnowledgeSourceUploadPollIntervalMs(),\n                        uploadTimeoutMs: this.getKnowledgeSourceUploadTimeoutMs(),\n                        logLabel,\n                    });\n                }\n                try {\n                    await this.uploadKnowledgeSourceFilesToVectorStore({\n                        client,\n                        vectorStoreId,\n                        files: fileStreams,\n                        totalBytes,\n                        logLabel,\n                    });\n                }\n                catch (error) {\n                    assertsError(error);\n                    console.error('[🤰]', 'Error uploading files to vector store', {\n                        vectorStoreId,\n                        logLabel,\n                        error: serializeError(error),\n                    });\n                }\n            }\n            else if (this.options.isVerbose) {\n                console.info('[🤰]', 'No knowledge source files to upload', {\n                    vectorStoreId,\n                    skippedCount: skippedSources.length,\n                    logLabel,\n                });\n            }\n            return {\n                vectorStoreId,\n                uploadedFileCount: fileStreams.length,\n                skippedCount: skippedSources.length,\n                totalBytes,\n            };\n        }\n    }\n\n    /**\n     * Uploads files to OpenAI and returns their IDs\n     *\n     * @private utility for `OpenAiAssistantExecutionTools` and `OpenAiCompatibleExecutionTools`\n     */\n    async function uploadFilesToOpenAi(client, files) {\n        const fileIds = [];\n        for (const file of files) {\n            // Note: OpenAI API expects a File object or a ReadStream\n            // In browser environment, we can pass the File object directly\n            // In Node.js environment, we might need to convert it or use a different approach\n            // But since `Prompt.files` already contains `File` objects, we try to pass them directly\n            const uploadedFile = await client.files.create({\n                file: file,\n                purpose: 'assistants',\n            });\n            fileIds.push(uploadedFile.id);\n        }\n        return fileIds;\n    }\n\n    /**\n     * Execution Tools for calling OpenAI API Assistants\n     *\n     * This is useful for calling OpenAI API with a single assistant, for more wide usage use `OpenAiExecutionTools`.\n     *\n     * Note: [🦖] There are several different things in Promptbook:\n     * - `Agent` - which represents an AI Agent with its source, memories, actions, etc. Agent is a higher-level abstraction which is internally using:\n     * - `LlmExecutionTools` - which wraps one or more LLM models and provides an interface to execute them\n     * - `AgentLlmExecutionTools` - which is a specific implementation of `LlmExecutionTools` that wraps another LlmExecutionTools and applies agent-specific system prompts and requirements\n     * - `OpenAiAssistantExecutionTools` - which is a specific implementation of `LlmExecutionTools` for OpenAI models with assistant capabilities, recommended for usage in `Agent` or `AgentLlmExecutionTools`\n     * - `RemoteAgent` - which is an `Agent` that connects to a Promptbook Agents Server\n     *\n     * @deprecated Use `OpenAiAgentKitExecutionTools` instead.\n     * @public exported from `@promptbook/openai`\n     */\n    class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {\n        /**\n         * Creates OpenAI Execution Tools.\n         *\n         * @param options which are relevant are directly passed to the OpenAI client\n         */\n        constructor(options) {\n            var _a;\n            if (options.isProxied) {\n                throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI assistants`);\n            }\n            super(options);\n            this.isCreatingNewAssistantsAllowed = false;\n            this.assistantId = options.assistantId;\n            this.isCreatingNewAssistantsAllowed = (_a = options.isCreatingNewAssistantsAllowed) !== null && _a !== void 0 ? _a : false;\n            if (this.assistantId === null && !this.isCreatingNewAssistantsAllowed) {\n                throw new NotAllowed(`Assistant ID is null and creating new assistants is not allowed - this configuration does not make sense`);\n            }\n            // <- TODO: !!! `OpenAiAssistantExecutionToolsOptions` - Allow `assistantId: null` together with `isCreatingNewAssistantsAllowed: true`\n            // TODO: [👱] Make limiter same as in `OpenAiExecutionTools`\n        }\n        get title() {\n            return 'OpenAI Assistant';\n        }\n        get description() {\n            return 'Use single assistant provided by OpenAI';\n        }\n        /**\n         * Calls OpenAI API to use a chat model.\n         */\n        async callChatModel(prompt) {\n            return this.callChatModelStream(prompt, () => { });\n        }\n        /**\n         * Calls OpenAI API to use a chat model with streaming.\n         */\n        async callChatModelStream(prompt, onProgress, options) {\n            var _a, _b, _c, _d, _e, _f;\n            if (this.options.isVerbose) {\n                console.info('💬 OpenAI callChatModel call', { prompt });\n            }\n            const { content, parameters, modelRequirements /*, format*/ } = prompt;\n            const client = await this.getClient();\n            // TODO: [☂] Use here more modelRequirements\n            if (modelRequirements.modelVariant !== 'CHAT') {\n                throw new PipelineExecutionError('Use callChatModel only for CHAT variant');\n            }\n            // TODO: [👨‍👨‍👧‍👧] Remove:\n            for (const key of ['maxTokens', 'modelName', 'seed', 'temperature']) {\n                if (modelRequirements[key] !== undefined) {\n                    throw new NotYetImplementedError(`In \\`OpenAiAssistantExecutionTools\\` you cannot specify \\`${key}\\``);\n                }\n            }\n            /*\n            TODO: [👨‍👨‍👧‍👧] Implement all of this for Assistants\n            const modelName = modelRequirements.modelName || this.getDefaultChatModel().modelName;\n            const modelSettings = {\n                model: modelName,\n\n                temperature: modelRequirements.temperature,\n\n                // <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools\n                // <- Note: [🧆]\n            } as OpenAI.Chat.Completions.CompletionCreateParamsNonStreaming; // <- TODO: Guard here types better\n\n            if (format === 'JSON') {\n                modelSettings.response_format = {\n                    type: 'json_object',\n                };\n            }\n            */\n            // <- TODO: [🚸] Not all models are compatible with JSON mode\n            //        > 'response_format' of type 'json_object' is not supported with this model.\n            const rawPromptContent = templateParameters(content, {\n                ...parameters,\n                modelName: 'assistant',\n                //          <- [🧠] What is the best value here\n            });\n            // Build thread messages: include previous thread messages + current user message\n            const threadMessages = [];\n            // TODO: [🈹] Maybe this should not be here but in other place, look at commit 39d705e75e5bcf7a818c3af36bc13e1c8475c30c\n            // Add previous messages from thread (if any)\n            if ('thread' in prompt && Array.isArray(prompt.thread)) {\n                const previousMessages = prompt.thread.map((msg) => ({\n                    role: (msg.sender === 'assistant' ? 'assistant' : 'user'),\n                    content: msg.content,\n                }));\n                threadMessages.push(...previousMessages);\n            }\n            // Always add the current user message\n            const currentUserMessage = {\n                role: 'user',\n                content: rawPromptContent,\n            };\n            if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {\n                const fileIds = await uploadFilesToOpenAi(client, prompt.files);\n                currentUserMessage.attachments = fileIds.map((fileId) => ({\n                    file_id: fileId,\n                    tools: [{ type: 'file_search' }, { type: 'code_interpreter' }],\n                }));\n            }\n            threadMessages.push(currentUserMessage);\n            // Check if tools are being used - if so, use non-streaming mode\n            const hasTools = modelRequirements.tools !== undefined && modelRequirements.tools.length > 0;\n            const start = $getCurrentDate();\n            let complete;\n            // [🐱‍🚀] When tools are present, we need to use the non-streaming Runs API\n            // because streaming doesn't support tool execution flow properly\n            if (hasTools) {\n                onProgress({\n                    content: '',\n                    modelName: 'assistant',\n                    timing: { start, complete: $getCurrentDate() },\n                    usage: UNCERTAIN_USAGE,\n                    rawPromptContent,\n                    rawRequest: null,\n                    rawResponse: null,\n                });\n                const rawRequest = {\n                    assistant_id: this.assistantId,\n                    thread: {\n                        messages: threadMessages,\n                    },\n                    tools: mapToolsToOpenAi(modelRequirements.tools),\n                };\n                if (this.options.isVerbose) {\n                    console.info(colors__default[\"default\"].bgWhite('rawRequest (non-streaming with tools)'), JSON.stringify(rawRequest, null, 4));\n                }\n                // Create thread and run\n                let run = (await client.beta.threads.createAndRun(rawRequest));\n                const completedToolCalls = [];\n                const toolCallStartedAt = new Map();\n                // Poll until run completes or requires action\n                while (run.status === 'queued' || run.status === 'in_progress' || run.status === 'requires_action') {\n                    if (run.status === 'requires_action' && ((_a = run.required_action) === null || _a === void 0 ? void 0 : _a.type) === 'submit_tool_outputs') {\n                        // Execute tools\n                        const toolCalls = run.required_action.submit_tool_outputs.tool_calls;\n                        const toolOutputs = [];\n                        for (const toolCall of toolCalls) {\n                            if (toolCall.type === 'function') {\n                                const functionName = toolCall.function.name;\n                                const functionArgs = JSON.parse(toolCall.function.arguments);\n                                const calledAt = $getCurrentDate();\n                                if (toolCall.id) {\n                                    toolCallStartedAt.set(toolCall.id, calledAt);\n                                }\n                                onProgress({\n                                    content: '',\n                                    modelName: 'assistant',\n                                    timing: { start, complete: $getCurrentDate() },\n                                    usage: UNCERTAIN_USAGE,\n                                    rawPromptContent,\n                                    rawRequest: null,\n                                    rawResponse: null,\n                                    toolCalls: [\n                                        {\n                                            name: functionName,\n                                            arguments: toolCall.function.arguments,\n                                            result: '',\n                                            rawToolCall: toolCall,\n                                            createdAt: calledAt,\n                                        },\n                                    ],\n                                });\n                                if (this.options.isVerbose) {\n                                    console.info(`🔧 Executing tool: ${functionName}`, functionArgs);\n                                }\n                                // Get execution tools for script execution\n                                const executionTools = this.options\n                                    .executionTools;\n                                if (!executionTools || !executionTools.script) {\n                                    throw new PipelineExecutionError(`Model requested tool '${functionName}' but no executionTools.script were provided in OpenAiAssistantExecutionTools options`);\n                                }\n                                // TODO: [DRY] Use some common tool caller (similar to OpenAiCompatibleExecutionTools)\n                                const scriptTools = Array.isArray(executionTools.script)\n                                    ? executionTools.script\n                                    : [executionTools.script];\n                                let functionResponse;\n                                let errors;\n                                try {\n                                    const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?\n                                    functionResponse = await scriptTool.execute({\n                                        scriptLanguage: 'javascript',\n                                        script: buildToolInvocationScript({\n                                            functionName,\n                                            functionArgsExpression: JSON.stringify(functionArgs),\n                                        }),\n                                        parameters: prompt.parameters,\n                                    });\n                                    if (this.options.isVerbose) {\n                                        console.info(`✅ Tool ${functionName} executed:`, functionResponse);\n                                    }\n                                }\n                                catch (error) {\n                                    assertsError(error);\n                                    const serializedError = serializeError(error);\n                                    errors = [serializedError];\n                                    functionResponse = spaceTrim__default[\"default\"]((block) => `\n                                    \n                                        The invoked tool \\`${functionName}\\` failed with error:\n                                        \n                                        \\`\\`\\`json\n                                        ${block(JSON.stringify(serializedError, null, 4))}\n                                        \\`\\`\\`\n\n                                    `);\n                                    console.error(colors__default[\"default\"].bgRed(`❌ Error executing tool ${functionName}:`));\n                                    console.error(error);\n                                }\n                                toolOutputs.push({\n                                    tool_call_id: toolCall.id,\n                                    output: functionResponse,\n                                });\n                                completedToolCalls.push({\n                                    name: functionName,\n                                    arguments: toolCall.function.arguments,\n                                    result: functionResponse,\n                                    rawToolCall: toolCall,\n                                    createdAt: toolCall.id ? toolCallStartedAt.get(toolCall.id) || calledAt : calledAt,\n                                    errors,\n                                });\n                            }\n                        }\n                        // Submit tool outputs\n                        run = (await client.beta.threads.runs.submitToolOutputs(run.thread_id, run.id, {\n                            tool_outputs: toolOutputs,\n                        }));\n                    }\n                    else {\n                        // Wait a bit before polling again\n                        await new Promise((resolve) => setTimeout(resolve, 500));\n                        run = (await client.beta.threads.runs.retrieve(run.thread_id, run.id));\n                    }\n                }\n                if (run.status !== 'completed') {\n                    throw new PipelineExecutionError(`Assistant run failed with status: ${run.status}`);\n                }\n                // Get messages from the thread\n                const messages = await client.beta.threads.messages.list(run.thread_id);\n                const assistantMessages = messages.data.filter((msg) => msg.role === 'assistant');\n                if (assistantMessages.length === 0) {\n                    throw new PipelineExecutionError('No assistant messages found after run completion');\n                }\n                const lastMessage = assistantMessages[0];\n                const textContent = lastMessage.content.find((c) => c.type === 'text');\n                if (!textContent || textContent.type !== 'text') {\n                    throw new PipelineExecutionError('No text content in assistant response');\n                }\n                complete = $getCurrentDate();\n                const resultContent = textContent.text.value;\n                const usage = UNCERTAIN_USAGE;\n                // Progress callback with final result\n                const finalChunk = {\n                    content: resultContent,\n                    modelName: 'assistant',\n                    timing: { start, complete },\n                    usage,\n                    rawPromptContent,\n                    rawRequest,\n                    rawResponse: { run, messages: messages.data },\n                    toolCalls: completedToolCalls.length > 0 ? completedToolCalls : undefined,\n                };\n                onProgress(finalChunk);\n                return exportJson({\n                    name: 'promptResult',\n                    message: `Result of \\`OpenAiAssistantExecutionTools.callChatModelStream\\` (with tools)`,\n                    order: [],\n                    value: finalChunk,\n                });\n            }\n            // Streaming mode (without tools)\n            const rawRequest = {\n                // TODO: [👨‍👨‍👧‍👧] ...modelSettings,\n                // TODO: [👨‍👨‍👧‍👧][🧠] What about system message for assistants, does it make sense - combination of OpenAI assistants with Promptbook Personas\n                assistant_id: this.assistantId,\n                thread: {\n                    messages: threadMessages,\n                },\n                tools: modelRequirements.tools === undefined ? undefined : mapToolsToOpenAi(modelRequirements.tools),\n                // <- TODO: Add user identification here> user: this.options.user,\n            };\n            if (this.options.isVerbose) {\n                console.info(colors__default[\"default\"].bgWhite('rawRequest (streaming)'), JSON.stringify(rawRequest, null, 4));\n            }\n            const stream = await client.beta.threads.createAndRunStream(rawRequest);\n            stream.on('connect', () => {\n                if (this.options.isVerbose) {\n                    console.info('connect', stream.currentEvent);\n                }\n            });\n            stream.on('textDelta', (textDelta, snapshot) => {\n                if (this.options.isVerbose && textDelta.value) {\n                    console.info('textDelta', textDelta.value);\n                }\n                const chunk = {\n                    content: snapshot.value,\n                    modelName: 'assistant',\n                    timing: {\n                        start,\n                        complete: $getCurrentDate(),\n                    },\n                    usage: UNCERTAIN_USAGE,\n                    rawPromptContent,\n                    rawRequest,\n                    rawResponse: snapshot,\n                };\n                onProgress(chunk);\n            });\n            stream.on('messageCreated', (message) => {\n                if (this.options.isVerbose) {\n                    console.info('messageCreated', message);\n                }\n            });\n            stream.on('messageDone', (message) => {\n                if (this.options.isVerbose) {\n                    console.info('messageDone', message);\n                }\n            });\n            // TODO: [🐱‍🚀] Handle tool calls in assistants\n            // Note: OpenAI Assistant streaming with tool calls requires special handling.\n            // The stream will pause when a tool call is needed, and we need to:\n            // 1. Wait for the run to reach 'requires_action' status\n            // 2. Execute the tool calls\n            // 3. Submit tool outputs via a separate API call (not on the stream)\n            // 4. Continue the run\n            // This requires switching to non-streaming mode or using the Runs API directly.\n            // For now, tools with assistants should use the non-streaming chat completions API instead.\n            const rawResponse = await stream.finalMessages();\n            if (this.options.isVerbose) {\n                console.info(colors__default[\"default\"].bgWhite('rawResponse'), JSON.stringify(rawResponse, null, 4));\n            }\n            if (rawResponse.length !== 1) {\n                throw new PipelineExecutionError(`There is NOT 1 BUT ${rawResponse.length} finalMessages from OpenAI`);\n            }\n            if (rawResponse[0].content.length !== 1) {\n                throw new PipelineExecutionError(`There is NOT 1 BUT ${rawResponse[0].content.length} finalMessages content from OpenAI`);\n            }\n            if (((_b = rawResponse[0].content[0]) === null || _b === void 0 ? void 0 : _b.type) !== 'text') {\n                throw new PipelineExecutionError(`There is NOT 'text' BUT ${(_c = rawResponse[0].content[0]) === null || _c === void 0 ? void 0 : _c.type} finalMessages content type from OpenAI`);\n            }\n            let resultContent = (_d = rawResponse[0].content[0]) === null || _d === void 0 ? void 0 : _d.text.value;\n            // Process annotations to replace file IDs with filenames\n            if ((_e = rawResponse[0].content[0]) === null || _e === void 0 ? void 0 : _e.text.annotations) {\n                const annotations = (_f = rawResponse[0].content[0]) === null || _f === void 0 ? void 0 : _f.text.annotations;\n                // Map to store file ID -> filename to avoid duplicate requests\n                const fileIdToName = new Map();\n                for (const annotation of annotations) {\n                    if (annotation.type === 'file_citation') {\n                        const fileId = annotation.file_citation.file_id;\n                        let filename = fileIdToName.get(fileId);\n                        if (!filename) {\n                            try {\n                                const file = await client.files.retrieve(fileId);\n                                filename = file.filename;\n                                fileIdToName.set(fileId, filename);\n                            }\n                            catch (error) {\n                                console.error(`Failed to retrieve file info for ${fileId}`, error);\n                                // Fallback to \"Source\" or keep original if fetch fails\n                                filename = 'Source';\n                            }\n                        }\n                        if (filename && resultContent) {\n                            // Replace the citation marker with filename\n                            // Regex to match the second part of the citation: 【id†source】 -> 【id†filename】\n                            // Note: annotation.text contains the exact marker like 【4:0†source】\n                            const newText = annotation.text.replace(/†.*?】/, `†${filename}】`);\n                            resultContent = resultContent.replace(annotation.text, newText);\n                        }\n                    }\n                }\n            }\n            // eslint-disable-next-line prefer-const\n            complete = $getCurrentDate();\n            const usage = UNCERTAIN_USAGE;\n            // <- TODO: [🥘] Compute real usage for assistant\n            //       ?> const usage = computeOpenAiUsage(content, resultContent || '', rawResponse);\n            if (resultContent === null) {\n                throw new PipelineExecutionError('No response message from OpenAI');\n            }\n            return exportJson({\n                name: 'promptResult',\n                message: `Result of \\`OpenAiAssistantExecutionTools.callChatModelStream\\``,\n                order: [],\n                value: {\n                    content: resultContent,\n                    modelName: 'assistant',\n                    // <- TODO: [🥘] Detect used model in assistant\n                    //       ?> model: rawResponse.model || modelName,\n                    timing: {\n                        start,\n                        complete,\n                    },\n                    usage,\n                    rawPromptContent,\n                    rawRequest,\n                    rawResponse,\n                    // <- [🗯]\n                },\n            });\n        }\n        /*\n        public async playground() {\n            const client = await this.getClient();\n\n            // List all assistants\n            const assistants = await client.beta.assistants.list();\n         \n            // Get details of a specific assistant\n            const assistantId = 'asst_MO8fhZf4dGloCfXSHeLcIik0';\n            const assistant = await client.beta.assistants.retrieve(assistantId);\n\n            // Update an assistant\n            const updatedAssistant = await client.beta.assistants.update(assistantId, {\n                name: assistant.name + '(M)',\n                description: 'Updated description via Promptbook',\n                metadata: {\n                    [Math.random().toString(36).substring(2, 15)]: new Date().toISOString(),\n                },\n            });\n      \n            await forEver();\n        }\n        */\n        /**\n         * Get an existing assistant tool wrapper\n         */\n        getAssistant(assistantId) {\n            return new OpenAiAssistantExecutionTools({\n                ...this.options,\n                isCreatingNewAssistantsAllowed: this.isCreatingNewAssistantsAllowed,\n                assistantId,\n            });\n        }\n        async createNewAssistant(options) {\n            var _a, _b, _c;\n            if (!this.isCreatingNewAssistantsAllowed) {\n                throw new NotAllowed(`Creating new assistants is not allowed. Set \\`isCreatingNewAssistantsAllowed: true\\` in options to enable this feature.`);\n            }\n            // await this.playground();\n            const { name, instructions, knowledgeSources, tools } = options;\n            const preparationStartedAtMs = Date.now();\n            const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;\n            const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Starting OpenAI assistant creation', {\n                    name,\n                    knowledgeSourcesCount,\n                    toolsCount,\n                    instructionsLength: instructions.length,\n                });\n            }\n            const client = await this.getClient();\n            let vectorStoreId;\n            // If knowledge sources are provided, create a vector store with them\n            if (knowledgeSources && knowledgeSources.length > 0) {\n                const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({\n                    client,\n                    name,\n                    knowledgeSources,\n                    logLabel: 'assistant creation',\n                });\n                vectorStoreId = vectorStoreResult.vectorStoreId;\n            }\n            // Create assistant with vector store attached\n            const assistantConfig = {\n                name,\n                description: 'Assistant created via Promptbook',\n                model: 'gpt-4o',\n                instructions,\n                tools: [\n                    /* TODO: [🧠] Maybe add { type: 'code_interpreter' }, */\n                    { type: 'file_search' },\n                    ...(tools === undefined ? [] : mapToolsToOpenAi(tools)),\n                ],\n            };\n            // Attach vector store if created\n            if (vectorStoreId) {\n                assistantConfig.tool_resources = {\n                    file_search: {\n                        vector_store_ids: [vectorStoreId],\n                    },\n                };\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Creating OpenAI assistant', {\n                    name,\n                    model: assistantConfig.model,\n                    toolCount: (_c = assistantConfig === null || assistantConfig === void 0 ? void 0 : assistantConfig.tools) === null || _c === void 0 ? void 0 : _c.length,\n                    hasVectorStore: Boolean(vectorStoreId),\n                });\n            }\n            const assistant = await client.beta.assistants.create(assistantConfig);\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'OpenAI assistant created', {\n                    assistantId: assistant.id,\n                    elapsedMs: Date.now() - preparationStartedAtMs,\n                });\n            }\n            // TODO: [🐱‍🚀] Try listing existing assistants\n            // TODO: [🐱‍🚀] Try marking existing assistants by DISCRIMINANT\n            // TODO: [🐱‍🚀] Allow to update and reconnect to existing assistants\n            return new OpenAiAssistantExecutionTools({\n                ...this.options,\n                isCreatingNewAssistantsAllowed: false,\n                assistantId: assistant.id,\n            });\n        }\n        async updateAssistant(options) {\n            var _a, _b, _c, _d;\n            if (!this.isCreatingNewAssistantsAllowed) {\n                throw new NotAllowed(`Updating assistants is not allowed. Set \\`isCreatingNewAssistantsAllowed: true\\` in options to enable this feature.`);\n            }\n            const { assistantId, name, instructions, knowledgeSources, tools } = options;\n            const preparationStartedAtMs = Date.now();\n            const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;\n            const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Starting OpenAI assistant update', {\n                    assistantId,\n                    name,\n                    knowledgeSourcesCount,\n                    toolsCount,\n                    instructionsLength: (_c = instructions === null || instructions === void 0 ? void 0 : instructions.length) !== null && _c !== void 0 ? _c : 0,\n                });\n            }\n            const client = await this.getClient();\n            let vectorStoreId;\n            // If knowledge sources are provided, create a vector store with them\n            if (knowledgeSources && knowledgeSources.length > 0) {\n                const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({\n                    client,\n                    name: name !== null && name !== void 0 ? name : assistantId,\n                    knowledgeSources,\n                    logLabel: 'assistant update',\n                });\n                vectorStoreId = vectorStoreResult.vectorStoreId;\n            }\n            const assistantUpdate = {\n                name,\n                instructions,\n                tools: [\n                    /* TODO: [🧠] Maybe add { type: 'code_interpreter' }, */\n                    { type: 'file_search' },\n                    ...(tools === undefined ? [] : mapToolsToOpenAi(tools)),\n                ],\n            };\n            if (vectorStoreId) {\n                assistantUpdate.tool_resources = {\n                    file_search: {\n                        vector_store_ids: [vectorStoreId],\n                    },\n                };\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Updating OpenAI assistant', {\n                    assistantId,\n                    name,\n                    toolCount: (_d = assistantUpdate === null || assistantUpdate === void 0 ? void 0 : assistantUpdate.tools) === null || _d === void 0 ? void 0 : _d.length,\n                    hasVectorStore: Boolean(vectorStoreId),\n                });\n            }\n            const assistant = await client.beta.assistants.update(assistantId, assistantUpdate);\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'OpenAI assistant updated', {\n                    assistantId: assistant.id,\n                    elapsedMs: Date.now() - preparationStartedAtMs,\n                });\n            }\n            return new OpenAiAssistantExecutionTools({\n                ...this.options,\n                isCreatingNewAssistantsAllowed: false,\n                assistantId: assistant.id,\n            });\n        }\n        /**\n         * Discriminant for type guards\n         */\n        get discriminant() {\n            return DISCRIMINANT$1;\n        }\n        /**\n         * Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAssistantExecutionTools`\n         *\n         * Note: This is useful when you can possibly have multiple versions of `@promptbook/openai` installed\n         */\n        static isOpenAiAssistantExecutionTools(llmExecutionTools) {\n            return llmExecutionTools.discriminant === DISCRIMINANT$1;\n        }\n    }\n    /**\n     * Discriminant for type guards\n     *\n     * @private const of `OpenAiAssistantExecutionTools`\n     */\n    const DISCRIMINANT$1 = 'OPEN_AI_ASSISTANT_V1';\n    /**\n     * TODO: !!!!! [✨🥚] Knowledge should work both with and without scrapers\n     * TODO: [🙎] In `OpenAiAssistantExecutionTools` Allow to create abstract assistants with `isCreatingNewAssistantsAllowed`\n     * TODO: [🧠][🧙‍♂️] Maybe there can be some wizard for those who want to use just OpenAI\n     * TODO: Maybe make custom OpenAiError\n     * TODO: [🧠][🈁] Maybe use `isDeterministic` from options\n     * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes\n     */\n\n    /**\n     * Execution Tools for calling OpenAI API\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    const createOpenAiAssistantExecutionTools = Object.assign((options) => {\n        // TODO: [🧠][main] !!4 If browser, auto add `dangerouslyAllowBrowser`\n        if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {\n            options = { ...options, dangerouslyAllowBrowser: true };\n        }\n        return new OpenAiAssistantExecutionTools(options);\n    }, {\n        packageName: '@promptbook/openai',\n        className: 'OpenAiAssistantExecutionTools',\n    });\n    /**\n     * TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?\n     * TODO: [🎶] Naming \"constructor\" vs \"creator\" vs \"factory\"\n     */\n\n    /**\n     * Creates a connection to the remote proxy server.\n     *\n     * Note: This function creates a connection to the remote server and returns a socket but responsibility of closing the connection is on the caller\n     *\n     * @private internal utility function\n     */\n    async function createRemoteClient(options) {\n        const { remoteServerUrl } = options;\n        if (!isValidUrl(remoteServerUrl)) {\n            throw new Error(`Invalid \\`remoteServerUrl\\`: \"${remoteServerUrl}\"`);\n        }\n        const remoteServerUrlParsed = new URL(remoteServerUrl);\n        if (remoteServerUrlParsed.pathname !== '/' && remoteServerUrlParsed.pathname !== '') {\n            remoteServerUrlParsed.pathname = '/';\n            throw new Error(spaceTrim__default[\"default\"]((block) => `\n                        Remote server requires root url \\`/\\`\n\n                        You have provided \\`remoteServerUrl\\`:\n                        ${block(remoteServerUrl)}\n\n                        But something like this is expected:\n                        ${block(remoteServerUrlParsed.href)}\n\n                        Note: If you need to run multiple services on the same server, use 3rd or 4th degree subdomain\n\n                    `));\n        }\n        return new Promise((resolve, reject) => {\n            const socket = socket_ioClient.io(remoteServerUrl, {\n                retries: CONNECTION_RETRIES_LIMIT,\n                timeout: CONNECTION_TIMEOUT_MS,\n                path: '/socket.io',\n                transports: ['polling', 'websocket' /*, <- TODO: [🌬] Allow to pass `transports`, add 'webtransport' */],\n            });\n            // console.log('Connecting to', this.options.remoteServerUrl.href, { socket });\n            socket.on('connect', () => {\n                resolve(socket);\n            });\n            // TODO: [💩] Better timeout handling\n            setTimeout(() => {\n                reject(new Error(`Timeout while connecting to ${remoteServerUrl}`));\n            }, CONNECTION_TIMEOUT_MS);\n        });\n    }\n\n    /**\n     * Profile for Remote provider\n     */\n    const REMOTE_PROVIDER_PROFILE = {\n        name: 'REMOTE',\n        fullname: 'Remote Server',\n        color: '#6b7280',\n    };\n    /**\n     * Remote server is a proxy server that uses its execution tools internally and exposes the executor interface externally.\n     *\n     * You can simply use `RemoteExecutionTools` on client-side javascript and connect to your remote server.\n     * This is useful to make all logic on browser side but not expose your API keys or no need to use customer's GPU.\n     *\n     * @see https://github.com/webgptorg/promptbook#remote-server\n     * @public exported from `@promptbook/remote-client`\n     */\n    class RemoteLlmExecutionTools {\n        /* <- TODO: [🍚] `, Destroyable` */\n        constructor(options) {\n            this.options = options;\n        }\n        get title() {\n            // TODO: [🧠] Maybe fetch title+description from the remote server (as well as if model methods are defined)\n            return 'Promptbook remote server';\n        }\n        get description() {\n            return `Models from Promptbook remote server ${this.options.remoteServerUrl}`;\n        }\n        get profile() {\n            return REMOTE_PROVIDER_PROFILE;\n        }\n        /**\n         * Check the configuration of all execution tools\n         */\n        async checkConfiguration() {\n            const socket = await createRemoteClient(this.options);\n            socket.disconnect();\n            // TODO: [main] !!3 Check version of the remote server and compatibility\n            // TODO: [🎍] Send checkConfiguration\n        }\n        /**\n         * List all available models that can be used\n         */\n        async listModels() {\n            // TODO: [👒] Listing models (and checking configuration) probably should go through REST API not Socket.io\n            const socket = await createRemoteClient(this.options);\n            socket.emit('listModels-request', {\n                identification: this.options.identification,\n            } /* <- Note: [🤛] */);\n            const promptResult = await new Promise((resolve, reject) => {\n                socket.on('listModels-response', (response) => {\n                    resolve(response.models);\n                    socket.disconnect();\n                });\n                socket.on('error', (error) => {\n                    reject(deserializeError(error));\n                    socket.disconnect();\n                });\n            });\n            socket.disconnect();\n            return promptResult;\n        }\n        /**\n         * Calls remote proxy server to use a chat model\n         */\n        callChatModel(prompt) {\n            if (this.options.isVerbose) {\n                console.info(`🖋 Remote callChatModel call`);\n            }\n            return /* not await */ this.callCommonModel(prompt);\n        }\n        /**\n         * Calls remote proxy server to use a completion model\n         */\n        callCompletionModel(prompt) {\n            if (this.options.isVerbose) {\n                console.info(`💬 Remote callCompletionModel call`);\n            }\n            return /* not await */ this.callCommonModel(prompt);\n        }\n        /**\n         * Calls remote proxy server to use a embedding model\n         */\n        callEmbeddingModel(prompt) {\n            if (this.options.isVerbose) {\n                console.info(`💬 Remote callEmbeddingModel call`);\n            }\n            return /* not await */ this.callCommonModel(prompt);\n        }\n        // <- Note: [🤖] callXxxModel\n        /**\n         * Calls remote proxy server to use both completion or chat model\n         */\n        async callCommonModel(prompt) {\n            const socket = await createRemoteClient(this.options);\n            socket.emit('prompt-request', {\n                identification: this.options.identification,\n                prompt,\n            } /* <- Note: [🤛] */);\n            const promptResult = await new Promise((resolve, reject) => {\n                socket.on('prompt-response', (response) => {\n                    resolve(response.promptResult);\n                    socket.disconnect();\n                });\n                socket.on('error', (error) => {\n                    reject(deserializeError(error));\n                    socket.disconnect();\n                });\n            });\n            socket.disconnect();\n            return promptResult;\n        }\n    }\n    /**\n     * TODO: [🕴] Deprecate pipeline server and all of its components\n     * TODO: Maybe use `$exportJson`\n     * TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`\n     * TODO: [🍓] Allow to list compatible models with each variant\n     * TODO: [🗯] RemoteLlmExecutionTools should extend Destroyable and implement IDestroyable\n     * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes\n     * TODO: [🧠] Maybe remove `@promptbook/remote-client` and just use `@promptbook/core`\n     */\n\n    /**\n     * Execution Tools for calling OpenAI compatible API\n     *\n     * Note: This can be used for any OpenAI compatible APIs\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    const createOpenAiCompatibleExecutionTools = Object.assign((options) => {\n        if (options.isProxied) {\n            return new RemoteLlmExecutionTools({\n                ...options,\n                identification: {\n                    isAnonymous: true,\n                    llmToolsConfiguration: [\n                        {\n                            title: 'OpenAI Compatible (proxied)',\n                            packageName: '@promptbook/openai',\n                            className: 'OpenAiCompatibleExecutionTools',\n                            options: {\n                                ...options,\n                                isProxied: false,\n                            },\n                        },\n                    ],\n                },\n            });\n        }\n        if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {\n            options = { ...options, dangerouslyAllowBrowser: true };\n        }\n        return new HardcodedOpenAiCompatibleExecutionTools(options.defaultModelName, options);\n    }, {\n        packageName: '@promptbook/openai',\n        className: 'OpenAiCompatibleExecutionTools',\n    });\n    /**\n     * Execution Tools for calling ONE SPECIFIC PRECONFIGURED OpenAI compatible provider\n     *\n     * @private for `createOpenAiCompatibleExecutionTools`\n     */\n    class HardcodedOpenAiCompatibleExecutionTools extends OpenAiCompatibleExecutionTools {\n        /**\n         * Creates OpenAI compatible Execution Tools.\n         *\n         * @param options which are relevant are directly passed to the OpenAI compatible client\n         */\n        constructor(defaultModelName, options) {\n            super(options);\n            this.defaultModelName = defaultModelName;\n            this.options = options;\n        }\n        get title() {\n            return `${this.defaultModelName} on ${this.options.baseURL}`;\n        }\n        get description() {\n            return `OpenAI compatible connected to \"${this.options.baseURL}\" model \"${this.defaultModelName}\"`;\n        }\n        /**\n         * List all available models (non dynamically)\n         *\n         * Note: Purpose of this is to provide more information about models than standard listing from API\n         */\n        get HARDCODED_MODELS() {\n            return [\n                {\n                    modelName: this.defaultModelName,\n                    modelVariant: 'CHAT',\n                    modelDescription: '', // <- TODO: What is the best value here, maybe `this.description`?\n                },\n            ];\n        }\n        /**\n         * Computes the usage\n         */\n        computeUsage(...args) {\n            return {\n                ...computeOpenAiUsage(...args),\n                price: UNCERTAIN_ZERO_VALUE, // <- TODO: Maybe in future pass this counting mechanism, but for now, we dont know\n            };\n        }\n        /**\n         * Default model for chat variant.\n         */\n        getDefaultChatModel() {\n            return this.getDefaultModel(this.defaultModelName);\n        }\n        /**\n         * Default model for completion variant.\n         */\n        getDefaultCompletionModel() {\n            throw new PipelineExecutionError(`${this.title} does not support COMPLETION model variant`);\n        }\n        /**\n         * Default model for completion variant.\n         */\n        getDefaultEmbeddingModel() {\n            throw new PipelineExecutionError(`${this.title} does not support EMBEDDING model variant`);\n        }\n        /**\n         * Default model for completion variant.\n         */\n        getDefaultImageGenerationModel() {\n            throw new PipelineExecutionError(`${this.title} does not support IMAGE_GENERATION model variant`);\n        }\n    }\n    /**\n     * TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?\n     * TODO: [🎶] Naming \"constructor\" vs \"creator\" vs \"factory\"\n     */\n\n    /**\n     * Execution Tools for calling OpenAI API\n     *\n     * Note: This can be also used for other OpenAI compatible APIs, like Ollama\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    const createOpenAiExecutionTools = Object.assign((options) => {\n        if (($isRunningInBrowser() || $isRunningInWebWorker()) && !options.dangerouslyAllowBrowser) {\n            options = { ...options, dangerouslyAllowBrowser: true };\n        }\n        if (options.isProxied) {\n            throw new NotYetImplementedError(`Proxy mode is not yet implemented in createOpenAiExecutionTools`);\n        }\n        return new OpenAiExecutionTools(options);\n    }, {\n        packageName: '@promptbook/openai',\n        className: 'OpenAiExecutionTools',\n    });\n    /**\n     * TODO: [🦺] Is there some way how to put `packageName` and `className` on top and function definition on bottom?\n     * TODO: [🎶] Naming \"constructor\" vs \"creator\" vs \"factory\"\n     */\n\n    const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.2';\n    const DEFAULT_JSON_SCHEMA_NAME = 'StructuredOutput';\n    /*\n    TODO: Use or remove\n    const EMPTY_JSON_SCHEMA: JsonSchemaDefinition['schema'] = {\n        type: 'object',\n        properties: {},\n        required: [],\n        additionalProperties: true,\n    };\n    */\n    function buildJsonSchemaDefinition(jsonSchema) {\n        var _a, _b, _c;\n        const schema = (_a = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.schema) !== null && _a !== void 0 ? _a : {};\n        return {\n            type: 'json_schema',\n            name: (_b = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.name) !== null && _b !== void 0 ? _b : DEFAULT_JSON_SCHEMA_NAME,\n            strict: Boolean(jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.strict),\n            schema: {\n                type: 'object',\n                properties: ((_c = schema.properties) !== null && _c !== void 0 ? _c : {}),\n                required: Array.isArray(schema.required) ? schema.required : [],\n                additionalProperties: schema.additionalProperties === undefined ? true : Boolean(schema.additionalProperties),\n                description: schema.description,\n            },\n        };\n    }\n    /**\n     * Maps OpenAI `response_format` payloads to AgentKit output types so the runner can forward\n     * structured-output preferences to OpenAI while still reusing the same AgentKit agent instance.\n     *\n     * @param responseFormat - The OpenAI `response_format` payload from the user request.\n     * @returns An Agent output type compatible with the requested schema or `undefined` when no impact is required.\n     * @private utility of Open AI\n     */\n    function mapResponseFormatToAgentOutputType(responseFormat) {\n        if (!responseFormat) {\n            return undefined;\n        }\n        if (typeof responseFormat === 'string') {\n            if (responseFormat === 'text') {\n                return 'text';\n            }\n            if (responseFormat === 'json_schema' || responseFormat === 'json_object') {\n                return buildJsonSchemaDefinition();\n            }\n            return 'text';\n        }\n        switch (responseFormat.type) {\n            case 'text':\n                return 'text';\n            case 'json_schema':\n                return buildJsonSchemaDefinition(responseFormat.json_schema);\n            case 'json_object':\n                return buildJsonSchemaDefinition();\n            default:\n                return undefined;\n        }\n    }\n    /**\n     * Execution tools for OpenAI AgentKit (Agents SDK).\n     *\n     * @public exported from `@promptbook/openai`\n     */\n    class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {\n        /**\n         * Creates OpenAI AgentKit execution tools.\n         */\n        constructor(options) {\n            var _a;\n            if (options.isProxied) {\n                throw new NotYetImplementedError(`Proxy mode is not yet implemented for OpenAI AgentKit`);\n            }\n            super(options);\n            this.preparedAgentKitAgent = null;\n            this.agentKitModelName = (_a = options.agentKitModelName) !== null && _a !== void 0 ? _a : DEFAULT_AGENT_KIT_MODEL_NAME;\n        }\n        get title() {\n            return 'OpenAI AgentKit';\n        }\n        get description() {\n            return 'Use OpenAI AgentKit for agent-style chat with tools and knowledge';\n        }\n        /**\n         * Calls OpenAI AgentKit with a chat prompt (non-streaming).\n         */\n        async callChatModel(prompt) {\n            return this.callChatModelStream(prompt, () => { });\n        }\n        /**\n         * Calls OpenAI AgentKit with a chat prompt (streaming).\n         */\n        async callChatModelStream(prompt, onProgress, options) {\n            const { content, parameters, modelRequirements } = prompt;\n            if (modelRequirements.modelVariant !== 'CHAT') {\n                throw new PipelineExecutionError('Use callChatModel only for CHAT variant');\n            }\n            for (const key of ['maxTokens', 'modelName', 'seed', 'temperature']) {\n                if (modelRequirements[key] !== undefined) {\n                    throw new NotYetImplementedError(`In \\`OpenAiAgentKitExecutionTools\\` you cannot specify \\`${key}\\``);\n                }\n            }\n            const rawPromptContent = templateParameters(content, {\n                ...parameters,\n                modelName: this.agentKitModelName,\n            });\n            const responseFormatOutputType = mapResponseFormatToAgentOutputType(modelRequirements.responseFormat);\n            const preparedAgentKitAgent = await this.prepareAgentKitAgent({\n                name: (prompt.title || 'Agent'),\n                instructions: modelRequirements.systemMessage || '',\n                knowledgeSources: modelRequirements.knowledgeSources,\n                tools: 'tools' in prompt && Array.isArray(prompt.tools) ? prompt.tools : modelRequirements.tools,\n            });\n            return this.callChatModelStreamWithPreparedAgent({\n                openAiAgentKitAgent: preparedAgentKitAgent.agent,\n                prompt,\n                rawPromptContent,\n                onProgress,\n                responseFormatOutputType,\n                signal: options === null || options === void 0 ? void 0 : options.signal,\n            });\n        }\n        /**\n         * Returns a prepared AgentKit agent when the server wants to manage caching externally.\n         */\n        getPreparedAgentKitAgent() {\n            return this.preparedAgentKitAgent;\n        }\n        /**\n         * Stores a prepared AgentKit agent for later reuse by external cache managers.\n         */\n        setPreparedAgentKitAgent(preparedAgent) {\n            this.preparedAgentKitAgent = preparedAgent;\n        }\n        /**\n         * Creates a new tools instance bound to a prepared AgentKit agent.\n         */\n        getPreparedAgentTools(preparedAgent) {\n            const tools = new OpenAiAgentKitExecutionTools(this.agentKitOptions);\n            tools.setPreparedAgentKitAgent(preparedAgent);\n            return tools;\n        }\n        /**\n         * Prepares an AgentKit agent with optional knowledge sources and tool definitions.\n         */\n        async prepareAgentKitAgent(options) {\n            var _a, _b;\n            const { name, instructions, knowledgeSources, tools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;\n            await this.ensureAgentKitDefaults();\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {\n                    name,\n                    instructionsLength: instructions.length,\n                    knowledgeSourcesCount: (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0,\n                    toolsCount: (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0,\n                });\n            }\n            let vectorStoreId = cachedVectorStoreId;\n            if (!vectorStoreId && knowledgeSources && knowledgeSources.length > 0) {\n                const vectorStoreResult = await this.createVectorStoreWithKnowledgeSources({\n                    client: await this.getClient(),\n                    name,\n                    knowledgeSources,\n                    logLabel: 'agentkit preparation',\n                });\n                vectorStoreId = vectorStoreResult.vectorStoreId;\n            }\n            else if (vectorStoreId && this.options.isVerbose) {\n                console.info('[🤰]', 'Using cached vector store for AgentKit agent', {\n                    name,\n                    vectorStoreId,\n                });\n            }\n            const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });\n            const openAiAgentKitAgent = new agents.Agent({\n                name,\n                model: this.agentKitModelName,\n                instructions: instructions || 'You are a helpful assistant.',\n                tools: agentKitTools,\n            });\n            const preparedAgent = {\n                agent: openAiAgentKitAgent,\n                vectorStoreId,\n            };\n            if (storeAsPrepared) {\n                this.setPreparedAgentKitAgent(preparedAgent);\n            }\n            if (this.options.isVerbose) {\n                console.info('[🤰]', 'OpenAI AgentKit agent ready', {\n                    name,\n                    model: this.agentKitModelName,\n                    toolCount: agentKitTools.length,\n                    hasVectorStore: Boolean(vectorStoreId),\n                });\n            }\n            return preparedAgent;\n        }\n        /**\n         * Ensures the AgentKit SDK is wired to the OpenAI client and API key.\n         */\n        async ensureAgentKitDefaults() {\n            const client = await this.getClient();\n            agents.setDefaultOpenAIClient(client);\n            const apiKey = this.agentKitOptions.apiKey;\n            if (apiKey && typeof apiKey === 'string') {\n                agents.setDefaultOpenAIKey(apiKey);\n            }\n        }\n        /**\n         * Builds the tool list for AgentKit, including hosted file search when applicable.\n         */\n        buildAgentKitTools(options) {\n            var _a;\n            const { tools, vectorStoreId } = options;\n            const agentKitTools = [];\n            if (vectorStoreId) {\n                agentKitTools.push(agents.fileSearchTool(vectorStoreId));\n            }\n            if (tools && tools.length > 0) {\n                const scriptTools = this.resolveScriptTools();\n                for (const toolDefinition of tools) {\n                    agentKitTools.push(agents.tool({\n                        name: toolDefinition.name,\n                        description: toolDefinition.description,\n                        parameters: toolDefinition.parameters\n                            ? {\n                                ...toolDefinition.parameters,\n                                additionalProperties: false,\n                                required: (_a = toolDefinition.parameters.required) !== null && _a !== void 0 ? _a : [],\n                            }\n                            : undefined,\n                        strict: false,\n                        execute: async (input, runContext, details) => {\n                            var _a, _b, _c;\n                            const scriptTool = scriptTools[0];\n                            const functionName = toolDefinition.name;\n                            const calledAt = $getCurrentDate();\n                            const callId = (_a = details === null || details === void 0 ? void 0 : details.toolCall) === null || _a === void 0 ? void 0 : _a.callId;\n                            const functionArgs = input !== null && input !== void 0 ? input : {};\n                            if (this.options.isVerbose) {\n                                console.info('[🤰]', 'Executing AgentKit tool', {\n                                    functionName,\n                                    callId,\n                                    calledAt,\n                                });\n                            }\n                            try {\n                                return await scriptTool.execute({\n                                    scriptLanguage: 'javascript',\n                                    script: buildToolInvocationScript({\n                                        functionName,\n                                        functionArgsExpression: JSON.stringify(functionArgs),\n                                    }),\n                                    parameters: (_c = (_b = runContext === null || runContext === void 0 ? void 0 : runContext.context) === null || _b === void 0 ? void 0 : _b.parameters) !== null && _c !== void 0 ? _c : {},\n                                });\n                            }\n                            catch (error) {\n                                assertsError(error);\n                                const serializedError = serializeError(error);\n                                const errorMessage = spaceTrim__default[\"default\"]((block) => `\n\n                                        The invoked tool \\`${functionName}\\` failed with error:\n\n                                        \\`\\`\\`json\n                                        ${block(JSON.stringify(serializedError, null, 4))}\n                                        \\`\\`\\`\n\n                                    `);\n                                console.error('[🤰]', 'AgentKit tool execution failed', {\n                                    functionName,\n                                    callId,\n                                    error: serializedError,\n                                });\n                                return errorMessage;\n                            }\n                        },\n                    }));\n                }\n            }\n            return agentKitTools;\n        }\n        /**\n         * Resolves the configured script tools for tool execution.\n         */\n        resolveScriptTools() {\n            const executionTools = this.options.executionTools;\n            if (!executionTools || !executionTools.script) {\n                throw new PipelineExecutionError(`Model requested tools but no executionTools.script were provided in OpenAiAgentKitExecutionTools options`);\n            }\n            return Array.isArray(executionTools.script) ? executionTools.script : [executionTools.script];\n        }\n        /**\n         * Runs a prepared AgentKit agent and streams results back to the caller.\n         */\n        async callChatModelStreamWithPreparedAgent(options) {\n            var _a, _b, _c, _d;\n            const { openAiAgentKitAgent, prompt, onProgress } = options;\n            const rawPromptContent = (_a = options.rawPromptContent) !== null && _a !== void 0 ? _a : templateParameters(prompt.content, {\n                ...prompt.parameters,\n                modelName: this.agentKitModelName,\n            });\n            const agentForRun = options.responseFormatOutputType !== undefined\n                ? openAiAgentKitAgent.clone({\n                    outputType: options.responseFormatOutputType,\n                })\n                : openAiAgentKitAgent;\n            const start = $getCurrentDate();\n            let latestContent = '';\n            const toolCalls = [];\n            const toolCallIndexById = new Map();\n            const inputItems = await this.buildAgentKitInputItems(prompt, rawPromptContent);\n            const rawRequest = {\n                agentName: agentForRun.name,\n                input: inputItems,\n            };\n            const streamResult = await agents.run(agentForRun, inputItems, {\n                stream: true,\n                context: { parameters: prompt.parameters },\n                signal: options.signal,\n            });\n            for await (const event of streamResult) {\n                if (event.type === 'raw_model_stream_event' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.type) === 'output_text_delta') {\n                    latestContent += event.data.delta;\n                    onProgress({\n                        content: latestContent,\n                        modelName: this.agentKitModelName,\n                        timing: { start, complete: $getCurrentDate() },\n                        usage: UNCERTAIN_USAGE,\n                        rawPromptContent: rawPromptContent,\n                        rawRequest: null,\n                        rawResponse: {},\n                    });\n                    continue;\n                }\n                if (event.type === 'run_item_stream_event') {\n                    const rawItem = (_c = event.item) === null || _c === void 0 ? void 0 : _c.rawItem;\n                    if (event.name === 'tool_called' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call') {\n                        const toolCall = {\n                            name: rawItem.name,\n                            arguments: rawItem.arguments,\n                            rawToolCall: rawItem,\n                            createdAt: $getCurrentDate(),\n                        };\n                        toolCallIndexById.set(rawItem.callId, toolCalls.length);\n                        toolCalls.push(toolCall);\n                        onProgress({\n                            content: latestContent,\n                            modelName: this.agentKitModelName,\n                            timing: { start, complete: $getCurrentDate() },\n                            usage: UNCERTAIN_USAGE,\n                            rawPromptContent: rawPromptContent,\n                            rawRequest: null,\n                            rawResponse: {},\n                            toolCalls: [toolCall],\n                        });\n                    }\n                    if (event.name === 'tool_output' && (rawItem === null || rawItem === void 0 ? void 0 : rawItem.type) === 'function_call_result') {\n                        const index = toolCallIndexById.get(rawItem.callId);\n                        const result = this.formatAgentKitToolOutput(rawItem.output);\n                        if (index !== undefined) {\n                            const existingToolCall = toolCalls[index];\n                            const completedToolCall = {\n                                ...existingToolCall,\n                                result,\n                                rawToolCall: rawItem,\n                            };\n                            toolCalls[index] = completedToolCall;\n                            onProgress({\n                                content: latestContent,\n                                modelName: this.agentKitModelName,\n                                timing: { start, complete: $getCurrentDate() },\n                                usage: UNCERTAIN_USAGE,\n                                rawPromptContent: rawPromptContent,\n                                rawRequest: null,\n                                rawResponse: {},\n                                toolCalls: [completedToolCall],\n                            });\n                        }\n                    }\n                }\n            }\n            await streamResult.completed;\n            const complete = $getCurrentDate();\n            const finalContent = ((_d = streamResult.finalOutput) !== null && _d !== void 0 ? _d : latestContent);\n            const finalResult = {\n                content: finalContent,\n                modelName: this.agentKitModelName,\n                timing: { start, complete },\n                usage: UNCERTAIN_USAGE,\n                rawPromptContent: rawPromptContent,\n                rawRequest,\n                rawResponse: { runResult: streamResult },\n                toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n            };\n            onProgress(finalResult);\n            return finalResult;\n        }\n        /**\n         * Builds AgentKit input items from the prompt and optional thread.\n         */\n        async buildAgentKitInputItems(prompt, rawPromptContent) {\n            var _a;\n            const inputItems = [];\n            if ('thread' in prompt && Array.isArray(prompt.thread)) {\n                for (const message of prompt.thread) {\n                    const sender = message.sender;\n                    const content = (_a = message.content) !== null && _a !== void 0 ? _a : '';\n                    if (sender === 'assistant' || sender === 'agent') {\n                        inputItems.push({\n                            role: 'assistant',\n                            status: 'completed',\n                            content: [{ type: 'output_text', text: content }],\n                        });\n                    }\n                    else {\n                        inputItems.push({\n                            role: 'user',\n                            content,\n                        });\n                    }\n                }\n            }\n            const userContent = await this.buildAgentKitUserContent(prompt, rawPromptContent);\n            inputItems.push({\n                role: 'user',\n                content: userContent,\n            });\n            return inputItems;\n        }\n        /**\n         * Builds the user message content for AgentKit runs, including file inputs when provided.\n         */\n        async buildAgentKitUserContent(prompt, rawPromptContent) {\n            if ('files' in prompt && Array.isArray(prompt.files) && prompt.files.length > 0) {\n                const fileItems = await Promise.all(prompt.files.map(async (file) => {\n                    const arrayBuffer = await file.arrayBuffer();\n                    const base64 = Buffer.from(arrayBuffer).toString('base64');\n                    return {\n                        type: 'input_image',\n                        image: `data:${file.type};base64,${base64}`,\n                    };\n                }));\n                return [{ type: 'input_text', text: rawPromptContent }, ...fileItems];\n            }\n            return rawPromptContent;\n        }\n        /**\n         * Normalizes AgentKit tool outputs into a string for Promptbook tool call results.\n         */\n        formatAgentKitToolOutput(output) {\n            if (typeof output === 'string') {\n                return output;\n            }\n            if (output && typeof output === 'object') {\n                const textOutput = output;\n                if (textOutput.type === 'text' && typeof textOutput.text === 'string') {\n                    return textOutput.text;\n                }\n            }\n            return JSON.stringify(output !== null && output !== void 0 ? output : null);\n        }\n        /**\n         * Returns AgentKit-specific options.\n         */\n        get agentKitOptions() {\n            return this.options;\n        }\n        /**\n         * Discriminant for type guards.\n         */\n        get discriminant() {\n            return DISCRIMINANT;\n        }\n        /**\n         * Type guard to check if given `LlmExecutionTools` are instanceof `OpenAiAgentKitExecutionTools`.\n         */\n        static isOpenAiAgentKitExecutionTools(llmExecutionTools) {\n            return llmExecutionTools.discriminant === DISCRIMINANT;\n        }\n    }\n    /**\n     * Discriminant for type guards.\n     *\n     * @private const of `OpenAiAgentKitExecutionTools`\n     */\n    const DISCRIMINANT = 'OPEN_AI_AGENT_KIT_V1';\n\n    /**\n     * Safely retrieves the global scope object (window in browser, global in Node.js)\n     * regardless of the JavaScript environment in which the code is running\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it access global scope\n     *\n     *  @private internal function of `$Register`\n     */\n    function $getGlobalScope() {\n        return Function('return this')();\n    }\n\n    /**\n     * Global registry for storing and managing registered entities of a given type.\n     *\n     * Note: `$` is used to indicate that this function is not a pure function - it accesses and adds variables in global scope.\n     *\n     * @private internal utility, exported are only singleton instances of this class\n     */\n    class $Register {\n        constructor(registerName) {\n            this.registerName = registerName;\n            const storageName = `_promptbook_${normalizeTo_snake_case(registerName)}`;\n            const globalScope = $getGlobalScope();\n            if (globalScope[storageName] === undefined) {\n                globalScope[storageName] = [];\n            }\n            else if (!Array.isArray(globalScope[storageName])) {\n                throw new UnexpectedError(`Expected (global) ${storageName} to be an array, but got ${typeof globalScope[storageName]}`);\n            }\n            this.storage = globalScope[storageName];\n        }\n        list() {\n            // <- TODO: ReadonlyDeep<ReadonlyArray<TRegistered>>\n            return this.storage;\n        }\n        register(registered) {\n            const { packageName, className } = registered;\n            const existingRegistrationIndex = this.storage.findIndex((item) => item.packageName === packageName && item.className === className);\n            const existingRegistration = this.storage[existingRegistrationIndex];\n            if (!existingRegistration) {\n                this.storage.push(registered);\n            }\n            else {\n                this.storage[existingRegistrationIndex] = registered;\n            }\n            return {\n                registerName: this.registerName,\n                packageName,\n                className,\n                get isDestroyed() {\n                    return false;\n                },\n                destroy() {\n                    throw new NotYetImplementedError(`Registration to ${this.registerName} is permanent in this version of Promptbook`);\n                },\n            };\n        }\n    }\n\n    /**\n     * Register for LLM tools.\n     *\n     * Note: `$` is used to indicate that this interacts with the global scope\n     * @singleton Only one instance of each register is created per build, but there can be more instances across different builds or environments.\n     * @public exported from `@promptbook/core`\n     */\n    const $llmToolsRegister = new $Register('llm_execution_tools_constructors');\n    /**\n     * TODO: [®] DRY Register logic\n     */\n\n    // Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be instantiated directly\n    /**\n     * Registration of LLM provider\n     *\n     * Warning: This is not useful for the end user, it is just a side effect of the mechanism that handles all available LLM tools\n     *\n     * @public exported from `@promptbook/openai`\n     * @public exported from `@promptbook/wizard`\n     * @public exported from `@promptbook/cli`\n     */\n    const _OpenAiRegistration = $llmToolsRegister.register(createOpenAiExecutionTools);\n    /**\n     * Registration of the OpenAI Assistant provider\n     *\n     * Note: [🏐] Configurations registrations are done in register-constructor.ts BUT constructor register-constructor.ts\n     *\n     * @public exported from `@promptbook/openai`\n     * @public exported from `@promptbook/wizard`\n     * @public exported from `@promptbook/cli`\n     */\n    const _OpenAiAssistantRegistration = $llmToolsRegister.register(createOpenAiAssistantExecutionTools);\n    /**\n     * Registration of the OpenAI Compatible provider\n     *\n     * Note: [🏐] Configurations registrations are done in register-constructor.ts BUT constructor register-constructor.ts\n     *\n     * @public exported from `@promptbook/openai`\n     * @public exported from `@promptbook/wizard`\n     * @public exported from `@promptbook/cli`\n     */\n    const _OpenAiCompatibleRegistration = $llmToolsRegister.register(createOpenAiCompatibleExecutionTools);\n    /**\n     * Note: OpenAiCompatibleExecutionTools is an abstract class and cannot be registered directly.\n     * It serves as a base class for OpenAiExecutionTools and other compatible implementations.\n     */\n    /**\n     * TODO: [🎶] Naming \"constructor\" vs \"creator\" vs \"factory\"\n     * Note: [💞] Ignore a discrepancy between file name and entity name\n     */\n\n    exports.BOOK_LANGUAGE_VERSION = BOOK_LANGUAGE_VERSION;\n    exports.OPENAI_MODELS = OPENAI_MODELS;\n    exports.OpenAiAgentKitExecutionTools = OpenAiAgentKitExecutionTools;\n    exports.OpenAiAssistantExecutionTools = OpenAiAssistantExecutionTools;\n    exports.OpenAiCompatibleExecutionTools = OpenAiCompatibleExecutionTools;\n    exports.OpenAiExecutionTools = OpenAiExecutionTools;\n    exports.OpenAiVectorStoreHandler = OpenAiVectorStoreHandler;\n    exports.PROMPTBOOK_ENGINE_VERSION = PROMPTBOOK_ENGINE_VERSION;\n    exports._OpenAiAssistantRegistration = _OpenAiAssistantRegistration;\n    exports._OpenAiCompatibleRegistration = _OpenAiCompatibleRegistration;\n    exports._OpenAiRegistration = _OpenAiRegistration;\n    exports.createOpenAiAssistantExecutionTools = createOpenAiAssistantExecutionTools;\n    exports.createOpenAiCompatibleExecutionTools = createOpenAiCompatibleExecutionTools;\n    exports.createOpenAiExecutionTools = createOpenAiExecutionTools;\n\n    Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n\n"]}