@elizaos/plugin-local-ai 1.0.0-alpha.7 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -28
- package/dist/index.js +627 -2085
- package/dist/index.js.map +1 -1
- package/package.json +68 -100
- package/dist/chunk-TIOOHHYI.js +0 -4727
- package/dist/chunk-TIOOHHYI.js.map +0 -1
- package/dist/multipart-parser-IQPIHJ5G.js +0 -359
- package/dist/multipart-parser-IQPIHJ5G.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/environment.ts","../src/types.ts","../src/utils/downloadManager.ts","../src/utils/ollamaManager.ts","../../../node_modules/node-fetch/src/index.js","../../../node_modules/data-uri-to-buffer/src/index.ts","../../../node_modules/node-fetch/src/body.js","../../../node_modules/node-fetch/src/errors/base.js","../../../node_modules/node-fetch/src/errors/fetch-error.js","../../../node_modules/node-fetch/src/utils/is.js","../../../node_modules/node-fetch/src/headers.js","../../../node_modules/node-fetch/src/utils/is-redirect.js","../../../node_modules/node-fetch/src/response.js","../../../node_modules/node-fetch/src/request.js","../../../node_modules/node-fetch/src/utils/get-search.js","../../../node_modules/node-fetch/src/utils/referrer.js","../../../node_modules/node-fetch/src/errors/abort-error.js","../src/utils/platform.ts","../src/utils/studiolmManager.ts","../src/utils/tokenizerManager.ts","../src/utils/transcribeManager.ts","../src/utils/ttsManager.ts","../src/utils/audioUtils.ts","../src/utils/visionManager.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { fileURLToPath } from \"node:url\";\nimport type { GenerateTextParams, ModelType } from \"@elizaos/core\";\nimport {\n\ttype IAgentRuntime,\n\tModelTypes,\n\ttype Plugin,\n\tlogger,\n} from \"@elizaos/core\";\nimport { EmbeddingModel, FlagEmbedding } from \"fastembed\";\nimport {\n\ttype Llama,\n\tLlamaChatSession,\n\ttype LlamaContext,\n\ttype LlamaContextSequence,\n\ttype LlamaModel,\n\tgetLlama,\n} from \"node-llama-cpp\";\nimport { validateConfig } from \"./environment\";\nimport { MODEL_SPECS, type ModelSpec } from \"./types\";\nimport { DownloadManager } from \"./utils/downloadManager\";\nimport { OllamaManager } from \"./utils/ollamaManager\";\nimport { getPlatformManager } from \"./utils/platform\";\nimport { StudioLMManager } from \"./utils/studiolmManager\";\nimport { TokenizerManager } from \"./utils/tokenizerManager\";\nimport { TranscribeManager } from \"./utils/transcribeManager\";\nimport { TTSManager } from \"./utils/ttsManager\";\nimport { VisionManager } from \"./utils/visionManager\";\n\n// const execAsync = promisify(exec);\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Words to punish in LLM responses\n/**\n * Array containing words that should trigger a punishment when used in a message.\n * This array includes words like \"please\", \"feel\", \"free\", punctuation marks, and various topic-related words.\n * @type {string[]}\n */\nconst wordsToPunish = [\n\t\" please\",\n\t\" feel\",\n\t\" free\",\n\t\"!\",\n\t\"–\",\n\t\"—\",\n\t\"?\",\n\t\".\",\n\t\",\",\n\t\"; \",\n\t\" cosmos\",\n\t\" tapestry\",\n\t\" tapestries\",\n\t\" glitch\",\n\t\" matrix\",\n\t\" cyberspace\",\n\t\" troll\",\n\t\" questions\",\n\t\" topics\",\n\t\" discuss\",\n\t\" basically\",\n\t\" simulation\",\n\t\" simulate\",\n\t\" universe\",\n\t\" like\",\n\t\" debug\",\n\t\" debugging\",\n\t\" wild\",\n\t\" existential\",\n\t\" juicy\",\n\t\" circuits\",\n\t\" help\",\n\t\" ask\",\n\t\" happy\",\n\t\" just\",\n\t\" cosmic\",\n\t\" cool\",\n\t\" joke\",\n\t\" punchline\",\n\t\" fancy\",\n\t\" glad\",\n\t\" assist\",\n\t\" algorithm\",\n\t\" Indeed\",\n\t\" Furthermore\",\n\t\" However\",\n\t\" Notably\",\n\t\" Therefore\",\n];\n\n// Add type definitions for model source selection\n/**\n * Represents the available sources for a text model: \"local\", \"studiolm\", or \"ollama\".\n */\ntype TextModelSource = \"local\" | \"studiolm\" | \"ollama\";\n\n/**\n * Interface representing the configuration for a text model.\n *\n * @property {TextModelSource} source - The source of the text model.\n * @property {ModelType} modelType - The type of the model.\n */\ninterface TextModelConfig {\n\tsource: TextModelSource;\n\tmodelType: ModelType;\n}\n\n/**\n * Class representing a LocalAIManager.\n * @property {LocalAIManager | null} instance - The static instance of LocalAIManager.\n * @property {Llama | undefined} llama - The llama object.\n * @property {LlamaModel | undefined} smallModel - The small LlamaModel object.\n * @property {LlamaModel | undefined} mediumModel - The medium LlamaModel object.\n * @property {LlamaContext | undefined} ctx - The LlamaContext object.\n * @property {LlamaContextSequence | undefined} sequence - The LlamaContextSequence object.\n * @property {LlamaChatSession | undefined} chatSession - The LlamaChatSession object.\n * @property {string} modelPath - The path to the model.\n */\nclass LocalAIManager {\n\tprivate static instance: LocalAIManager | null = null;\n\tprivate llama: Llama | undefined;\n\tprivate smallModel: LlamaModel | undefined;\n\tprivate mediumModel: LlamaModel | undefined;\n\tprivate ctx: LlamaContext | undefined;\n\tprivate sequence: LlamaContextSequence | undefined;\n\tprivate chatSession: LlamaChatSession | undefined;\n\tprivate modelPath: string;\n\tprivate mediumModelPath: string;\n\tprivate cacheDir: string;\n\tprivate embeddingModel: FlagEmbedding | null = null;\n\tprivate tokenizerManager: TokenizerManager;\n\tprivate downloadManager: DownloadManager;\n\tprivate visionManager: VisionManager;\n\tprivate activeModelConfig: ModelSpec;\n\tprivate transcribeManager: TranscribeManager;\n\tprivate ttsManager: TTSManager;\n\tprivate studioLMManager: StudioLMManager;\n\tprivate ollamaManager: OllamaManager;\n\tprivate ollamaInitialized = false;\n\tprivate studioLMInitialized = false;\n\tprivate modelsDir: string;\n\n\t/**\n\t * Private constructor function to initialize various managers and services.\n\t * This function sets up model directories, initializes managers for download, tokenizer, vision, transcribe, and TTS.\n\t * It also initializes StudioLM and Ollama managers if enabled in the environment.\n\t * Additionally, this function initializes the environment, checks platform capabilities, sets up embeddings,\n\t * and initializes various models and services sequentially and in parallel to avoid conflicts.\n\t */\n\tprivate constructor() {\n\t\t// Set up models directory consistently, similar to cacheDir\n\t\tconst modelsDir = path.join(process.cwd(), \"models\");\n\n\t\t// logger.info(\"Models directory configuration:\", {\n\t\t// resolvedModelsDir: modelsDir,\n\t\t// cwd: process.cwd()\n\t\t// });\n\n\t\tthis.activeModelConfig = MODEL_SPECS.small;\n\t\tthis.modelPath = path.join(modelsDir, MODEL_SPECS.small.name);\n\t\tthis.mediumModelPath = path.join(modelsDir, MODEL_SPECS.medium.name);\n\t\tthis.cacheDir = path.join(process.cwd(), \"./cache\");\n\t\tthis.modelsDir = modelsDir;\n\n\t\t// logger.info(\"Path configuration:\", {\n\t\t// smallModelPath: this.modelPath,\n\t\t// mediumModelPath: this.mediumModelPath,\n\t\t// cacheDir: this.cacheDir,\n\t\t// modelsDir: this.modelsDir\n\t\t// });\n\n\t\tthis.downloadManager = DownloadManager.getInstance(\n\t\t\tthis.cacheDir,\n\t\t\tthis.modelsDir,\n\t\t);\n\t\tthis.tokenizerManager = TokenizerManager.getInstance(\n\t\t\tthis.cacheDir,\n\t\t\tthis.modelsDir,\n\t\t);\n\t\tthis.visionManager = VisionManager.getInstance(this.cacheDir);\n\t\tthis.transcribeManager = TranscribeManager.getInstance(this.cacheDir);\n\t\tthis.ttsManager = TTSManager.getInstance(this.cacheDir);\n\n\t\t// Only create StudioLM and Ollama manager instances if enabled in environment\n\t\tif (process.env.USE_STUDIOLM_TEXT_MODELS === \"true\") {\n\t\t\tlogger.info(\n\t\t\t\t\"Creating StudioLM manager instance (enabled in environment)\",\n\t\t\t);\n\t\t\tthis.studioLMManager = StudioLMManager.getInstance();\n\t\t} else {\n\t\t\tlogger.info(\n\t\t\t\t\"StudioLM manager instance not created (disabled in environment)\",\n\t\t\t);\n\t\t}\n\n\t\tif (process.env.USE_OLLAMA_TEXT_MODELS === \"true\") {\n\t\t\tlogger.info(\"Creating Ollama manager instance (enabled in environment)\");\n\t\t\tthis.ollamaManager = OllamaManager.getInstance();\n\t\t} else {\n\t\t\tlogger.info(\n\t\t\t\t\"Ollama manager instance not created (disabled in environment)\",\n\t\t\t);\n\t\t}\n\n\t\t// Initialize environment\n\t\tthis.initializeEnvironment().catch((error) => {\n\t\t\tlogger.error(\"Environment initialization failed:\", error);\n\t\t\tthrow error;\n\t\t});\n\n\t\t// Add platform capabilities check in constructor\n\t\tthis.checkPlatformCapabilities().catch((error) => {\n\t\t\tlogger.warn(\"Platform capabilities check failed:\", error);\n\t\t});\n\n\t\t// Add embedding initialization\n\t\tthis.initializeEmbedding().catch((error) => {\n\t\t\tlogger.warn(\"Embedding initialization failed:\", error);\n\t\t});\n\n\t\t// Initialize models sequentially to avoid conflicts\n\t\tlogger.info(\"Starting model initialization sequence\");\n\n\t\t// First initialize the small model\n\t\tthis.initialize(ModelTypes.TEXT_SMALL)\n\t\t\t.then(() => {\n\t\t\t\tlogger.info(\n\t\t\t\t\t\"Small model initialization complete, starting large model initialization\",\n\t\t\t\t);\n\t\t\t\t// Then initialize the large model only after small model is done\n\t\t\t\treturn this.initialize(ModelTypes.TEXT_LARGE);\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tlogger.warn(\"Models initialization failed:\", {\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t});\n\n\t\t// Initialize other services in parallel\n\t\tconst servicePromises = [\n\t\t\t// Add vision initialization using a public method\n\t\t\tthis.initializeVision().catch((error) => {\n\t\t\t\tlogger.warn(\"Vision initialization failed:\", error);\n\t\t\t\treturn null; // Prevent Promise.all from failing completely\n\t\t\t}),\n\t\t\t// Add transcription initialization with better error handling\n\t\t\tthis.initializeTranscription().catch((error) => {\n\t\t\t\tlogger.warn(\"Transcription initialization failed:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t});\n\t\t\t\treturn null; // Prevent Promise.all from failing completely\n\t\t\t}),\n\t\t\t// Add TTS initialization\n\t\t\tthis.initializeTTS().catch((error) => {\n\t\t\t\tlogger.warn(\"TTS initialization failed:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t});\n\t\t\t\treturn null; // Prevent Promise.all from failing completely\n\t\t\t}),\n\t\t];\n\n\t\t// Only initialize StudioLM if enabled in environment and manager exists\n\t\tif (\n\t\t\tprocess.env.USE_STUDIOLM_TEXT_MODELS === \"true\" &&\n\t\t\tthis.studioLMManager\n\t\t) {\n\t\t\tlogger.info(\n\t\t\t\t\"StudioLM initialization enabled by environment configuration\",\n\t\t\t);\n\t\t\tservicePromises.push(\n\t\t\t\tthis.initializeStudioLM()\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tthis.studioLMInitialized = true;\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error) => {\n\t\t\t\t\t\tlogger.warn(\"StudioLM initialization failed:\", {\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn null; // Prevent Promise.all from failing completely\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tlogger.info(\n\t\t\t\t\"StudioLM initialization skipped (disabled in environment configuration or manager not created)\",\n\t\t\t);\n\t\t}\n\n\t\t// Only initialize Ollama if enabled in environment and manager exists\n\t\tif (process.env.USE_OLLAMA_TEXT_MODELS === \"true\" && this.ollamaManager) {\n\t\t\tlogger.info(\"Ollama initialization enabled by environment configuration\");\n\t\t\tservicePromises.push(\n\t\t\t\tthis.initializeOllama()\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tthis.ollamaInitialized = true;\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error) => {\n\t\t\t\t\t\tlogger.warn(\"Ollama initialization failed:\", {\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn null; // Prevent Promise.all from failing completely\n\t\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tlogger.info(\n\t\t\t\t\"Ollama initialization skipped (disabled in environment configuration or manager not created)\",\n\t\t\t);\n\t\t}\n\n\t\tPromise.all(servicePromises).catch((error) => {\n\t\t\tlogger.warn(\"Models initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves the singleton instance of LocalAIManager. If an instance does not already exist, a new one is created and returned.\n\t * @returns {LocalAIManager} The singleton instance of LocalAIManager\n\t */\n\tpublic static getInstance(): LocalAIManager {\n\t\tif (!LocalAIManager.instance) {\n\t\t\tLocalAIManager.instance = new LocalAIManager();\n\t\t}\n\t\treturn LocalAIManager.instance;\n\t}\n\n\t/**\n\t * Initializes the environment by validating the configuration and setting the environment variables with the validated values.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves once the environment has been successfully initialized.\n\t */\n\tprivate async initializeEnvironment(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Validating environment configuration...\");\n\n\t\t\t// Create initial config from current env vars\n\t\t\tconst config = {\n\t\t\t\tUSE_LOCAL_AI: process.env.USE_LOCAL_AI,\n\t\t\t\tUSE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n\t\t\t\tUSE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS,\n\t\t\t};\n\n\t\t\t// Validate configuration\n\t\t\tconst validatedConfig = await validateConfig(config);\n\n\t\t\t// Log the validated configuration\n\t\t\t// logger.info(\"Environment configuration validated:\", validatedConfig);\n\t\t\tlogger.info(\"Environment configuration validated\");\n\n\t\t\t// Ensure environment variables are set with validated values\n\t\t\tprocess.env.USE_LOCAL_AI = String(validatedConfig.USE_LOCAL_AI);\n\t\t\tprocess.env.USE_STUDIOLM_TEXT_MODELS = String(\n\t\t\t\tvalidatedConfig.USE_STUDIOLM_TEXT_MODELS,\n\t\t\t);\n\t\t\tprocess.env.USE_OLLAMA_TEXT_MODELS = String(\n\t\t\t\tvalidatedConfig.USE_OLLAMA_TEXT_MODELS,\n\t\t\t);\n\n\t\t\t// logger.info(\"Environment variables updated with validated values:\", {\n\t\t\t// USE_LOCAL_AI: process.env.USE_LOCAL_AI,\n\t\t\t// USE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n\t\t\t// USE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS\n\t\t\t// });\n\n\t\t\tlogger.success(\"Environment initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Environment validation failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the Ollama model.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when the initialization is complete.\n\t * @throws {Error} If the Ollama manager is not created, or if initialization of Ollama models fails.\n\t */\n\tprivate async initializeOllama(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing Ollama models...\");\n\n\t\t\t// Check if Ollama manager exists\n\t\t\tif (!this.ollamaManager) {\n\t\t\t\tthrow new Error(\"Ollama manager not created - cannot initialize\");\n\t\t\t}\n\n\t\t\t// Initialize and test models\n\t\t\tawait this.ollamaManager.initialize();\n\n\t\t\tif (!this.ollamaManager.isInitialized()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Ollama initialization failed - models not properly loaded\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlogger.success(\"Ollama initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Ollama initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Initializes StudioLM model with error handling.\n\t * @returns A Promise that resolves when the initialization is complete.\n\t * @throws {Error} If StudioLM manager is not created, initialization fails, or models are not properly loaded.\n\t */\n\tprivate async initializeStudioLM(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing StudioLM models...\");\n\n\t\t\t// Check if StudioLM manager exists\n\t\t\tif (!this.studioLMManager) {\n\t\t\t\tthrow new Error(\"StudioLM manager not created - cannot initialize\");\n\t\t\t}\n\n\t\t\t// Initialize and test models\n\t\t\tawait this.studioLMManager.initialize();\n\n\t\t\tif (!this.studioLMManager.isInitialized()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"StudioLM initialization failed - models not properly loaded\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.studioLMInitialized = true;\n\t\t\tlogger.success(\"StudioLM initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"StudioLM initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the transcription model by performing the following steps:\n\t * 1. Ensuring FFmpeg availability.\n\t * 2. Defining sample file path and AWS URL.\n\t * 3. Downloading the sample file if it doesn't exist in the cache.\n\t * 4. Verifying the existence of the sample file and loading it.\n\t * 5. Generating transcription result using the transcribeAudio method.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when the initialization process is complete or rejects with an error.\n\t */\n\tprivate async initializeTranscription(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing transcription model...\");\n\n\t\t\t// First ensure FFmpeg is available\n\t\t\tconst ffmpegAvailable = await this.transcribeManager.ensureFFmpeg();\n\t\t\tif (!ffmpegAvailable) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cannot initialize transcription without FFmpeg. Please install FFmpeg and try again.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// logger.info(\"FFmpeg initialized successfully:\", {\n\t\t\t// version: this.transcribeManager.getFFmpegVersion(),\n\t\t\t// available: this.transcribeManager.isFFmpegAvailable(),\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\n\t\t\t// Define sample file path and AWS URL\n\t\t\tconst samplePath = path.join(this.cacheDir, \"sample1.wav\");\n\t\t\tconst awsSampleUrl =\n\t\t\t\t\"https://d2908q01vomqb2.cloudfront.net/artifacts/DBSBlogs/ML-15311/sample1.wav?_=1\";\n\t\t\t// Download sample file if it doesn't exist\n\t\t\tif (!fs.existsSync(samplePath)) {\n\t\t\t\tlogger.info(\n\t\t\t\t\t\"Sample WAV file not found in cache, downloading from AWS...\",\n\t\t\t\t);\n\t\t\t\ttry {\n\t\t\t\t\tawait this.downloadManager.downloadFromUrl(awsSampleUrl, samplePath);\n\t\t\t\t\tlogger.success(\"Sample WAV file downloaded successfully\");\n\t\t\t\t} catch (downloadError) {\n\t\t\t\t\tlogger.error(\"Failed to download sample WAV file:\", {\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\tdownloadError instanceof Error\n\t\t\t\t\t\t\t\t? downloadError.message\n\t\t\t\t\t\t\t\t: String(downloadError),\n\t\t\t\t\t\turl: awsSampleUrl,\n\t\t\t\t\t\tdestination: samplePath,\n\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t});\n\t\t\t\t\tthrow downloadError;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger.info(\"Sample WAV file already exists in cache\");\n\t\t\t}\n\n\t\t\t// Verify file exists and load it\n\t\t\tif (!fs.existsSync(samplePath)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Sample audio file not found at: ${samplePath} after download attempt`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst testAudioBuffer = fs.readFileSync(samplePath);\n\t\t\t// logger.info(\"Sample audio file loaded:\", {\n\t\t\t// size: testAudioBuffer.length,\n\t\t\t// path: samplePath,\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\n\t\t\t// Use our existing transcribeAudio method which uses transcribeManager\n\t\t\tconst result = await this.transcribeAudio(testAudioBuffer);\n\t\t\tlogger.info(\"Test transcription result:\", {\n\t\t\t\ttext: result,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\tlogger.success(\"Transcription model initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Transcription initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the vision by downloading a test image from AWS, processing it, and describing the image.\n\t *\n\t * @returns A Promise that resolves when the vision is successfully initialized\n\t */\n\tprivate async initializeVision(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing vision model...\");\n\n\t\t\t// AWS test image URL\n\t\t\tconst awsImageUrl =\n\t\t\t\t\"https://d1.awsstatic.com/product-marketing/Rekognition/Image%20for%20facial%20analysis.3fcc22e8451b4a238540128cb5510b8cbe22da51.jpg\";\n\t\t\tconst imagePath = path.join(this.cacheDir, \"test_image.jpg\");\n\n\t\t\t// Download the test image if it doesn't exist\n\t\t\tif (!fs.existsSync(imagePath)) {\n\t\t\t\tlogger.info(\"Downloading test image from AWS...\");\n\t\t\t\ttry {\n\t\t\t\t\tawait this.downloadManager.downloadFromUrl(awsImageUrl, imagePath);\n\t\t\t\t\tlogger.success(\"Test image downloaded successfully\");\n\t\t\t\t} catch (downloadError) {\n\t\t\t\t\tlogger.error(\"Failed to download test image:\", {\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\tdownloadError instanceof Error\n\t\t\t\t\t\t\t\t? downloadError.message\n\t\t\t\t\t\t\t\t: String(downloadError),\n\t\t\t\t\t\turl: awsImageUrl,\n\t\t\t\t\t\tdestination: imagePath,\n\t\t\t\t\t});\n\t\t\t\t\tthrow downloadError;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger.info(\"Test image already exists in cache\");\n\t\t\t}\n\n\t\t\t// Verify file exists and load it\n\t\t\tif (!fs.existsSync(imagePath)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Test image not found at: ${imagePath} after download attempt`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst imageBuffer = fs.readFileSync(imagePath);\n\n\t\t\t// Process the test image\n\t\t\tconst result = await this.describeImage(imageBuffer, \"image/jpeg\");\n\t\t\tlogger.info(\"Test image description:\", result);\n\n\t\t\tlogger.success(\"Vision model initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Vision initialization failed:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the Text-to-Speech (TTS) model by testing TTS with sample text,\n\t * generating speech, and verifying the audio stream readability.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when the TTS model initialization is complete.\n\t */\n\tprivate async initializeTTS(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing TTS model...\");\n\n\t\t\t// Test text for TTS\n\t\t\tconst testText = \"ElizaOS is yours\";\n\n\t\t\t// Generate speech from test text\n\t\t\tlogger.info(\"Testing TTS with sample text:\", { text: testText });\n\t\t\tconst audioStream = await this.ttsManager.generateSpeech(testText);\n\n\t\t\t// Verify the stream is readable\n\t\t\tif (!(audioStream instanceof Readable)) {\n\t\t\t\tthrow new Error(\"TTS did not return a valid audio stream\");\n\t\t\t}\n\n\t\t\t// Test stream readability\n\t\t\tlet dataReceived = false;\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\taudioStream.on(\"data\", () => {\n\t\t\t\t\tif (!dataReceived) {\n\t\t\t\t\t\tdataReceived = true;\n\t\t\t\t\t\tlogger.info(\"TTS audio stream is producing data\");\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\taudioStream.on(\"end\", () => {\n\t\t\t\t\tif (!dataReceived) {\n\t\t\t\t\t\treject(new Error(\"No audio data received from TTS stream\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\taudioStream.on(\"error\", (err) => {\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tlogger.success(\"TTS model initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"TTS initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Downloads the model based on the modelPath provided.\n\t * Determines whether to download a large or small model based on the current modelPath.\n\t *\n\t * @returns A Promise that resolves to a boolean indicating whether the model download was successful.\n\t */\n\tprivate async downloadModel(): Promise<boolean> {\n\t\ttry {\n\t\t\t// Determine which model to download based on current modelPath\n\t\t\tconst isLargeModel = this.modelPath === this.mediumModelPath;\n\t\t\tconst modelSpec = isLargeModel ? MODEL_SPECS.medium : MODEL_SPECS.small;\n\t\t\treturn await this.downloadManager.downloadModel(\n\t\t\t\tmodelSpec,\n\t\t\t\tthis.modelPath,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Model download failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tmodelPath: this.modelPath,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously checks the platform capabilities.\n\t *\n\t * @returns {Promise<void>} A promise that resolves once the platform capabilities have been checked.\n\t */\n\tpublic async checkPlatformCapabilities(): Promise<void> {\n\t\ttry {\n\t\t\tconst platformManager = getPlatformManager();\n\t\t\tawait platformManager.initialize();\n\t\t\tconst capabilities = platformManager.getCapabilities();\n\n\t\t\tlogger.info(\"Platform capabilities detected:\", {\n\t\t\t\tplatform: capabilities.platform,\n\t\t\t\tgpu: capabilities.gpu?.type || \"none\",\n\t\t\t\trecommendedModel: capabilities.recommendedModelSize,\n\t\t\t\tsupportedBackends: capabilities.supportedBackends,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlogger.warn(\"Platform detection failed:\", error);\n\t\t}\n\t}\n\n\t/**\n\t * Initializes the LocalAI Manager for a given model type.\n\t *\n\t * @param {ModelType} modelType - The type of model to initialize (default: ModelTypes.TEXT_SMALL)\n\t * @returns {Promise<void>} A promise that resolves when initialization is complete or rejects if an error occurs\n\t */\n\tasync initialize(\n\t\tmodelType: ModelType = ModelTypes.TEXT_SMALL,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing LocalAI Manager for model class:\", modelType);\n\n\t\t\t// Set the correct model path based on the model class\n\t\t\tif (modelType === ModelTypes.TEXT_LARGE) {\n\t\t\t\tthis.modelPath = this.mediumModelPath;\n\t\t\t\tlogger.info(\"Using medium model path:\", this.modelPath);\n\t\t\t} else {\n\t\t\t\t// Ensure we're using the small model path for small model\n\t\t\t\tthis.modelPath = path.join(this.modelsDir, MODEL_SPECS.small.name);\n\t\t\t\tlogger.info(\"Using small model path:\", this.modelPath);\n\t\t\t}\n\n\t\t\t// Download the model and check if it was newly downloaded\n\t\t\tconst wasNewlyDownloaded = await this.downloadModel();\n\n\t\t\t// Add a delay to ensure file system operations are complete if the model was newly downloaded\n\t\t\tif (wasNewlyDownloaded) {\n\t\t\t\tif (modelType === ModelTypes.TEXT_LARGE) {\n\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\"Adding delay before loading large model to ensure download is complete...\",\n\t\t\t\t\t);\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10000)); // 60 second delay for large model\n\t\t\t\t} else {\n\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\"Adding delay before loading small model to ensure download is complete...\",\n\t\t\t\t\t);\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10000)); // 15 second delay for small model\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Verify the model file exists before trying to load it\n\t\t\tif (!fs.existsSync(this.modelPath)) {\n\t\t\t\tthrow new Error(`Model file not found at path: ${this.modelPath}`);\n\t\t\t}\n\n\t\t\tthis.llama = await getLlama();\n\n\t\t\t// Initialize the appropriate model\n\t\t\tif (modelType === ModelTypes.TEXT_LARGE) {\n\t\t\t\tthis.activeModelConfig = MODEL_SPECS.medium;\n\t\t\t\tlogger.info(\"Loading large model from:\", this.modelPath);\n\t\t\t\tthis.mediumModel = await this.llama.loadModel({\n\t\t\t\t\tmodelPath: this.modelPath,\n\t\t\t\t});\n\t\t\t\tthis.ctx = await this.mediumModel.createContext({\n\t\t\t\t\tcontextSize: MODEL_SPECS.medium.contextSize,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.activeModelConfig = MODEL_SPECS.small;\n\t\t\t\tlogger.info(\"Loading small model from:\", this.modelPath);\n\t\t\t\tthis.smallModel = await this.llama.loadModel({\n\t\t\t\t\tmodelPath: this.modelPath,\n\t\t\t\t});\n\t\t\t\tthis.ctx = await this.smallModel.createContext({\n\t\t\t\t\tcontextSize: MODEL_SPECS.small.contextSize,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!this.ctx) {\n\t\t\t\tthrow new Error(\"Failed to create prompt\");\n\t\t\t}\n\n\t\t\tthis.sequence = this.ctx.getSequence();\n\t\t\tlogger.success(\n\t\t\t\t`Model initialization complete for ${modelType === ModelTypes.TEXT_LARGE ? \"large\" : \"small\"} model`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Initialization failed:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the embedding model.\n\t *\n\t * @returns {Promise<void>} A promise that resolves once the initialization is complete.\n\t */\n\tpublic async initializeEmbedding(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing embedding model...\");\n\t\t\tlogger.info(\"Models directory:\", this.modelsDir);\n\n\t\t\t// Ensure models directory exists\n\t\t\tif (!fs.existsSync(this.modelsDir)) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"Models directory does not exist, creating it:\",\n\t\t\t\t\tthis.modelsDir,\n\t\t\t\t);\n\t\t\t\tfs.mkdirSync(this.modelsDir, { recursive: true });\n\t\t\t}\n\n\t\t\tif (!this.embeddingModel) {\n\t\t\t\tlogger.info(\n\t\t\t\t\t\"Creating new FlagEmbedding instance with BGESmallENV15 model\",\n\t\t\t\t);\n\t\t\t\t// logger.info(\"Embedding model download details:\", {\n\t\t\t\t// model: EmbeddingModel.BGESmallENV15,\n\t\t\t\t// modelsDir: this.modelsDir,\n\t\t\t\t// maxLength: 512,\n\t\t\t\t// timestamp: new Date().toISOString()\n\t\t\t\t// });\n\n\t\t\t\t// Display initial progress bar\n\t\t\t\tconst barLength = 30;\n\t\t\t\tconst emptyBar = \"▱\".repeat(barLength);\n\t\t\t\tlogger.info(`Downloading embedding model: ${emptyBar} 0%`);\n\n\t\t\t\t// Disable built-in progress bar and initialize the model\n\t\t\t\tthis.embeddingModel = await FlagEmbedding.init({\n\t\t\t\t\tcacheDir: this.modelsDir,\n\t\t\t\t\tmodel: EmbeddingModel.BGESmallENV15,\n\t\t\t\t\tmaxLength: 512,\n\t\t\t\t\tshowDownloadProgress: false,\n\t\t\t\t});\n\n\t\t\t\t// Display completed progress bar\n\t\t\t\tconst completedBar = \"▰\".repeat(barLength);\n\t\t\t\tlogger.info(`Downloading embedding model: ${completedBar} 100%`);\n\t\t\t\tlogger.success(\"FlagEmbedding instance created successfully\");\n\t\t\t}\n\n\t\t\t// Verify the model is working with a test embedding\n\t\t\tlogger.info(\"Testing embedding model with sample text...\");\n\t\t\tconst testEmbed = await this.embeddingModel.queryEmbed(\"test\");\n\t\t\tlogger.info(\n\t\t\t\t\"Test embedding generated successfully, dimensions:\",\n\t\t\t\ttestEmbed.length,\n\t\t\t);\n\n\t\t\tlogger.success(\"Embedding model initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Embedding initialization failed with details:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t\tmodel: EmbeddingModel.BGESmallENV15,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously generates text using either StudioLM or Ollama models based on the specified parameters.\n\t *\n\t * @param {GenerateTextParams} params - The parameters for generating the text.\n\t * @returns {Promise<string>} - A promise that resolves to the generated text.\n\t */\n\tasync generateTextOllamaStudio(params: GenerateTextParams): Promise<string> {\n\t\ttry {\n\t\t\tconst modelConfig = this.getTextModelSource();\n\t\t\tlogger.info(\"generateTextOllamaStudio called with:\", {\n\t\t\t\tmodelSource: modelConfig.source,\n\t\t\t\tmodelType: params.modelType,\n\t\t\t\tstudioLMInitialized: this.studioLMInitialized,\n\t\t\t\tollamaInitialized: this.ollamaInitialized,\n\t\t\t\tstudioLMEnabled: process.env.USE_STUDIOLM_TEXT_MODELS === \"true\",\n\t\t\t\tollamaEnabled: process.env.USE_OLLAMA_TEXT_MODELS === \"true\",\n\t\t\t});\n\n\t\t\tif (modelConfig.source === \"studiolm\") {\n\t\t\t\t// Check if StudioLM is enabled in environment\n\t\t\t\tif (process.env.USE_STUDIOLM_TEXT_MODELS !== \"true\") {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"StudioLM requested but disabled in environment, falling back to local models\",\n\t\t\t\t\t);\n\t\t\t\t\treturn this.generateText(params);\n\t\t\t\t}\n\n\t\t\t\t// Check if StudioLM manager exists\n\t\t\t\tif (!this.studioLMManager) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"StudioLM manager not initialized, falling back to local models\",\n\t\t\t\t\t);\n\t\t\t\t\treturn this.generateText(params);\n\t\t\t\t}\n\n\t\t\t\t// Only initialize if not already initialized\n\t\t\t\tif (!this.studioLMInitialized) {\n\t\t\t\t\tlogger.info(\"StudioLM not initialized, initializing now...\");\n\t\t\t\t\tawait this.initializeStudioLM();\n\t\t\t\t}\n\n\t\t\t\t// Pass initialization flag to generateText\n\t\t\t\treturn await this.studioLMManager.generateText(\n\t\t\t\t\tparams,\n\t\t\t\t\tthis.studioLMInitialized,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (modelConfig.source === \"ollama\") {\n\t\t\t\t// Check if Ollama is enabled in environment\n\t\t\t\tif (process.env.USE_OLLAMA_TEXT_MODELS !== \"true\") {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"Ollama requested but disabled in environment, falling back to local models\",\n\t\t\t\t\t);\n\t\t\t\t\treturn this.generateText(params);\n\t\t\t\t}\n\n\t\t\t\t// Check if Ollama manager exists\n\t\t\t\tif (!this.ollamaManager) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"Ollama manager not initialized, falling back to local models\",\n\t\t\t\t\t);\n\t\t\t\t\treturn this.generateText(params);\n\t\t\t\t}\n\n\t\t\t\t// Only initialize if not already initialized\n\t\t\t\tif (!this.ollamaInitialized && !this.ollamaManager.isInitialized()) {\n\t\t\t\t\tlogger.info(\"Initializing Ollama in generateTextOllamaStudio\");\n\t\t\t\t\tawait this.ollamaManager.initialize();\n\t\t\t\t\tthis.ollamaInitialized = true;\n\t\t\t\t}\n\n\t\t\t\t// Pass initialization flag to generateText\n\t\t\t\treturn await this.ollamaManager.generateText(\n\t\t\t\t\tparams,\n\t\t\t\t\tthis.ollamaInitialized,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Fallback to local models if something goes wrong\n\t\t\treturn this.generateText(params);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Text generation with Ollama/StudioLM failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tmodelSource: this.getTextModelSource().source,\n\t\t\t});\n\t\t\t// Fallback to local models\n\t\t\treturn this.generateText(params);\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously generates text based on the provided parameters.\n\t *\n\t * @param {GenerateTextParams} params - The parameters for text generation.\n\t * @returns {Promise<string>} The generated text as a string.\n\t */\n\tasync generateText(params: GenerateTextParams): Promise<string> {\n\t\ttry {\n\t\t\t// Initialize with the appropriate model class if not initialized\n\t\t\tif (\n\t\t\t\t!this.sequence ||\n\t\t\t\t!this.smallModel ||\n\t\t\t\t(params.modelType === ModelTypes.TEXT_LARGE && !this.mediumModel)\n\t\t\t) {\n\t\t\t\tawait this.initialize(params.modelType);\n\t\t\t}\n\n\t\t\t// Select the appropriate model based on the model class\n\t\t\tlet activeModel: LlamaModel;\n\t\t\tif (params.modelType === ModelTypes.TEXT_LARGE) {\n\t\t\t\tif (!this.mediumModel) {\n\t\t\t\t\tthrow new Error(\"Medium model not initialized\");\n\t\t\t\t}\n\t\t\t\tthis.activeModelConfig = MODEL_SPECS.medium;\n\t\t\t\tactiveModel = this.mediumModel;\n\t\t\t\t// QUICK TEST FIX: Always create fresh prompt\n\t\t\t\tthis.ctx = await activeModel.createContext({\n\t\t\t\t\tcontextSize: MODEL_SPECS.medium.contextSize,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (!this.smallModel) {\n\t\t\t\t\tthrow new Error(\"Small model not initialized\");\n\t\t\t\t}\n\t\t\t\tthis.activeModelConfig = MODEL_SPECS.small;\n\t\t\t\tactiveModel = this.smallModel;\n\t\t\t\t// QUICK TEST FIX: Always create fresh prompt\n\t\t\t\tthis.ctx = await activeModel.createContext({\n\t\t\t\t\tcontextSize: MODEL_SPECS.small.contextSize,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!this.ctx) {\n\t\t\t\tthrow new Error(\"Failed to create prompt\");\n\t\t\t}\n\n\t\t\t// QUICK TEST FIX: Always get fresh sequence\n\t\t\tthis.sequence = this.ctx.getSequence();\n\n\t\t\t// QUICK TEST FIX: Create new session each time without maintaining state\n\t\t\t// Only use valid options for LlamaChatSession\n\t\t\tthis.chatSession = new LlamaChatSession({\n\t\t\t\tcontextSequence: this.sequence,\n\t\t\t});\n\n\t\t\tif (!this.chatSession) {\n\t\t\t\tthrow new Error(\"Failed to create chat session\");\n\t\t\t}\n\t\t\tlogger.info(\"Created new chat session for model:\", params.modelType);\n\t\t\t// Log incoming prompt for debugging\n\t\t\tlogger.info(\"Incoming prompt structure:\", {\n\t\t\t\tcontextLength: params.prompt.length,\n\t\t\t\thasAction: params.prompt.includes(\"action\"),\n\t\t\t\truntime: !!params.runtime,\n\t\t\t\tstopSequences: params.stopSequences,\n\t\t\t});\n\n\t\t\tconst tokens = await this.tokenizerManager.encode(\n\t\t\t\tparams.prompt,\n\t\t\t\tthis.activeModelConfig,\n\t\t\t);\n\t\t\tlogger.info(\"Input tokens:\", { count: tokens.length });\n\n\t\t\t// QUICK TEST FIX: Add system message to reset prompt\n\t\t\tconst systemMessage =\n\t\t\t\t\"You are a helpful AI assistant. Respond to the current request only.\";\n\t\t\tawait this.chatSession.prompt(systemMessage, {\n\t\t\t\tmaxTokens: 1, // Minimal tokens for system message\n\t\t\t\ttemperature: 0.0,\n\t\t\t});\n\n\t\t\tlet response = await this.chatSession.prompt(params.prompt, {\n\t\t\t\tmaxTokens: 8192,\n\t\t\t\ttemperature: 0.7,\n\t\t\t\ttopP: 0.9,\n\t\t\t\trepeatPenalty: {\n\t\t\t\t\tpunishTokensFilter: () =>\n\t\t\t\t\t\tactiveModel.tokenize(wordsToPunish.join(\" \")),\n\t\t\t\t\tpenalty: 1.2,\n\t\t\t\t\tfrequencyPenalty: 0.7,\n\t\t\t\t\tpresencePenalty: 0.7,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Log raw response for debugging\n\t\t\tlogger.info(\"Raw response structure:\", {\n\t\t\t\tresponseLength: response.length,\n\t\t\t\thasAction: response.includes(\"action\"),\n\t\t\t\thasThinkTag: response.includes(\"<think>\"),\n\t\t\t});\n\n\t\t\t// Clean think tags if present\n\t\t\tif (response.includes(\"<think>\")) {\n\t\t\t\tlogger.info(\"Cleaning think tags from response\");\n\t\t\t\tresponse = response.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, \"\");\n\t\t\t\tlogger.info(\"Think tags removed from response\");\n\t\t\t}\n\n\t\t\t// Return the raw response and let the framework handle JSON parsing and action validation\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Text generation failed:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously generates an embedding for the provided text.\n\t *\n\t * @param {string} text - The input text for which to generate the embedding\n\t * @returns {Promise<number[]>} The generated embedding as an array of numbers\n\t * @throws {Error} If the input text is null or undefined, or if there is an issue generating the embedding\n\t */\n\tasync generateEmbedding(text: string): Promise<number[]> {\n\t\ttry {\n\t\t\tlogger.info(\"Generating embedding...\");\n\t\t\t// Add null check\n\t\t\tif (!text) {\n\t\t\t\tthrow new Error(\"Input text cannot be null or undefined\");\n\t\t\t}\n\t\t\tlogger.debug(\"Input text length:\", text.length);\n\n\t\t\tif (!this.embeddingModel) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Embedding model not initialized, attempting to initialize...\",\n\t\t\t\t);\n\t\t\t\tawait this.initializeEmbedding();\n\t\t\t}\n\n\t\t\tif (!this.embeddingModel) {\n\t\t\t\tthrow new Error(\"Failed to initialize embedding model\");\n\t\t\t}\n\n\t\t\tlogger.info(\"Generating query embedding...\");\n\t\t\tconst embedding = await this.embeddingModel.queryEmbed(text);\n\t\t\tconst dimensions = embedding.length;\n\t\t\tlogger.info(\"Embedding generation complete\", { dimensions });\n\n\t\t\treturn Array.from(embedding);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Embedding generation failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t// Only access text.length if text exists\n\t\t\t\ttextLength: text?.length ?? \"text is null\",\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously describes the image based on the provided image data and MIME type.\n\t * Converts the image data buffer to a data URL, then passes the URL to the VisionManager for processing.\n\t *\n\t * @param {Buffer} imageData The image data buffer to describe.\n\t * @param {string} mimeType The MIME type of the image data.\n\t * @returns {Promise<{ title: string; description: string }>} A Promise that resolves to an object containing the title and description of the described image.\n\t * @throws {Error} If an error occurs during image description process.\n\t */\n\n\tpublic async describeImage(\n\t\timageData: Buffer,\n\t\tmimeType: string,\n\t): Promise<{ title: string; description: string }> {\n\t\ttry {\n\t\t\t// Convert buffer to data URL\n\t\t\tconst base64 = imageData.toString(\"base64\");\n\t\t\tconst dataUrl = `data:${mimeType};base64,${base64}`;\n\t\t\treturn await this.visionManager.processImage(dataUrl);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Image description failed:\", error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Transcribe audio data from a Buffer.\n\t *\n\t * @param {Buffer} audioBuffer The audio data to transcribe\n\t * @returns {Promise<string>} The transcribed text\n\t * @throws {Error} If the audio transcription fails\n\t */\n\tpublic async transcribeAudio(audioBuffer: Buffer): Promise<string> {\n\t\ttry {\n\t\t\tconst result = await this.transcribeManager.transcribe(audioBuffer);\n\t\t\treturn result.text;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Audio transcription failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tbufferSize: audioBuffer.length,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously generates speech for the given text using the TTS manager.\n\t *\n\t * @param {string} text - The text for which speech needs to be generated.\n\t * @returns {Promise<Readable>} A Promise that resolves to a Readable stream containing the generated speech.\n\t * @throws {Error} If speech generation fails, an error is thrown with details logged using the logger.\n\t */\n\tpublic async generateSpeech(text: string): Promise<Readable> {\n\t\ttry {\n\t\t\treturn await this.ttsManager.generateSpeech(text);\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Speech generation failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\ttextLength: text.length,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// Add public accessor methods\n\t/**\n\t * Returns the TokenizerManager associated with this object.\n\t *\n\t * @returns {TokenizerManager} The TokenizerManager object.\n\t */\n\tpublic getTokenizerManager(): TokenizerManager {\n\t\treturn this.tokenizerManager;\n\t}\n\n\t/**\n\t * Returns the active model configuration.\n\t * @returns {ModelSpec} The active model configuration.\n\t */\n\tpublic getActiveModelConfig(): ModelSpec {\n\t\treturn this.activeModelConfig;\n\t}\n\n\t/**\n\t * Retrieves the source configuration for the text model based on environment variables and manager existence.\n\t * @returns {TextModelConfig} The configuration object containing the text model source and type.\n\t */\n\tpublic getTextModelSource(): TextModelConfig {\n\t\ttry {\n\t\t\t// Default configuration\n\t\t\tconst config: TextModelConfig = {\n\t\t\t\tsource: \"local\",\n\t\t\t\tmodelType: ModelTypes.TEXT_SMALL,\n\t\t\t};\n\n\t\t\t// Check environment configuration and manager existence\n\t\t\tif (\n\t\t\t\tprocess.env.USE_STUDIOLM_TEXT_MODELS === \"true\" &&\n\t\t\t\tthis.studioLMManager\n\t\t\t) {\n\t\t\t\tconfig.source = \"studiolm\";\n\t\t\t} else if (\n\t\t\t\tprocess.env.USE_OLLAMA_TEXT_MODELS === \"true\" &&\n\t\t\t\tthis.ollamaManager\n\t\t\t) {\n\t\t\t\tconfig.source = \"ollama\";\n\t\t\t}\n\n\t\t\tlogger.info(\"Selected text model source:\", config);\n\t\t\treturn config;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Error determining text model source:\", error);\n\t\t\t// Fallback to local models\n\t\t\treturn { source: \"local\", modelType: ModelTypes.TEXT_SMALL };\n\t\t}\n\t}\n}\n\n// Create manager instance\nconst localAIManager = LocalAIManager.getInstance();\n\n/**\n * Plugin that provides functionality for local AI using LLaMA models.\n * @type {Plugin}\n */\nexport const localAIPlugin: Plugin = {\n\tname: \"local-ai\",\n\tdescription: \"Local AI plugin using LLaMA models\",\n\n\tasync init(config: Record<string, string>) {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing local-ai plugin...\");\n\t\t\tconst validatedConfig = await validateConfig(config);\n\n\t\t\t// Set environment variables\n\t\t\tfor (const [key, value] of Object.entries(validatedConfig)) {\n\t\t\t\tprocess.env[key] = String(value); // Convert boolean to string\n\t\t\t\tlogger.debug(`Set ${key}=${value}`);\n\t\t\t}\n\n\t\t\tlogger.success(\"Local AI plugin configuration validated and initialized\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Plugin initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t},\n\n\tmodels: {\n\t\t[ModelTypes.TEXT_SMALL]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\t{ prompt, stopSequences = [] }: GenerateTextParams,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst modelConfig = localAIManager.getTextModelSource();\n\n\t\t\t\tif (modelConfig.source !== \"local\") {\n\t\t\t\t\treturn await localAIManager.generateTextOllamaStudio({\n\t\t\t\t\t\tprompt,\n\t\t\t\t\t\tstopSequences,\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tmodelType: ModelTypes.TEXT_SMALL,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn await localAIManager.generateText({\n\t\t\t\t\tprompt,\n\t\t\t\t\tstopSequences,\n\t\t\t\t\truntime,\n\t\t\t\t\tmodelType: ModelTypes.TEXT_SMALL,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_SMALL handler:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TEXT_LARGE]: async (\n\t\t\truntime: IAgentRuntime,\n\t\t\t{ prompt, stopSequences = [] }: GenerateTextParams,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst modelConfig = localAIManager.getTextModelSource();\n\n\t\t\t\tif (modelConfig.source !== \"local\") {\n\t\t\t\t\treturn await localAIManager.generateTextOllamaStudio({\n\t\t\t\t\t\tprompt,\n\t\t\t\t\t\tstopSequences,\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tmodelType: ModelTypes.TEXT_LARGE,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn await localAIManager.generateText({\n\t\t\t\t\tprompt,\n\t\t\t\t\tstopSequences,\n\t\t\t\t\truntime,\n\t\t\t\t\tmodelType: ModelTypes.TEXT_LARGE,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_LARGE handler:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TEXT_EMBEDDING]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\ttext: string | null,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\t// Add detailed logging of the input text and its structure\n\t\t\t\tlogger.info(\"TEXT_EMBEDDING handler - Initial input:\", {\n\t\t\t\t\ttext,\n\t\t\t\t\t// type: typeof text,\n\t\t\t\t\t// isString: typeof text === 'string',\n\t\t\t\t\t// isObject: typeof text === 'object',\n\t\t\t\t\t// hasThinkTag: typeof text === 'string' && text.includes('<think>'),\n\t\t\t\t\tlength: text?.length,\n\t\t\t\t\trawText: text, // Log the complete raw text\n\t\t\t\t});\n\n\t\t\t\t// If text is an object, log its structure\n\t\t\t\tif (typeof text === \"object\" && text !== null) {\n\t\t\t\t\tlogger.info(\"TEXT_EMBEDDING handler - Object structure:\", {\n\t\t\t\t\t\tkeys: Object.keys(text),\n\t\t\t\t\t\tstringified: JSON.stringify(text, null, 2),\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Handle null/undefined/empty text\n\t\t\t\tif (!text) {\n\t\t\t\t\tlogger.warn(\"Null or empty text input for embedding\");\n\t\t\t\t\treturn new Array(384).fill(0);\n\t\t\t\t}\n\n\t\t\t\t// Pass the raw text directly to the framework without any manipulation\n\t\t\t\treturn await localAIManager.generateEmbedding(text);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_EMBEDDING handler:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tfullText: text,\n\t\t\t\t\ttextType: typeof text,\n\t\t\t\t\ttextStructure: text !== null ? JSON.stringify(text, null, 2) : \"null\",\n\t\t\t\t});\n\t\t\t\treturn new Array(384).fill(0);\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TEXT_TOKENIZER_ENCODE]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\t{ text }: { text: string },\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst manager = localAIManager.getTokenizerManager();\n\t\t\t\tconst config = localAIManager.getActiveModelConfig();\n\t\t\t\treturn await manager.encode(text, config);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_TOKENIZER_ENCODE handler:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TEXT_TOKENIZER_DECODE]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\t{ tokens }: { tokens: number[] },\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst manager = localAIManager.getTokenizerManager();\n\t\t\t\tconst config = localAIManager.getActiveModelConfig();\n\t\t\t\treturn await manager.decode(tokens, config);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_TOKENIZER_DECODE handler:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.IMAGE_DESCRIPTION]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\timageUrl: string,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\"Processing image from URL:\", imageUrl);\n\n\t\t\t\t// Fetch the image from URL\n\t\t\t\tconst response = await fetch(imageUrl);\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow new Error(`Failed to fetch image: ${response.statusText}`);\n\t\t\t\t}\n\n\t\t\t\tconst buffer = Buffer.from(await response.arrayBuffer());\n\t\t\t\tconst mimeType = response.headers.get(\"content-type\") || \"image/jpeg\";\n\n\t\t\t\treturn await localAIManager.describeImage(buffer, mimeType);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in IMAGE_DESCRIPTION handler:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\timageUrl,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TRANSCRIPTION]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\taudioBuffer: Buffer,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tlogger.info(\"Processing audio transcription:\", {\n\t\t\t\t\tbufferSize: audioBuffer.length,\n\t\t\t\t});\n\n\t\t\t\treturn await localAIManager.transcribeAudio(audioBuffer);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TRANSCRIPTION handler:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tbufferSize: audioBuffer.length,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\n\t\t[ModelTypes.TEXT_TO_SPEECH]: async (\n\t\t\t_runtime: IAgentRuntime,\n\t\t\ttext: string,\n\t\t) => {\n\t\t\ttry {\n\t\t\t\treturn await localAIManager.generateSpeech(text);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Error in TEXT_TO_SPEECH handler:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\ttextLength: text.length,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t},\n\ttests: [\n\t\t{\n\t\t\tname: \"local_ai_plugin_tests\",\n\t\t\ttests: [\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_initialization\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting initialization test\");\n\n\t\t\t\t\t\t\t// Test TEXT_SMALL model initialization\n\t\t\t\t\t\t\tconst result = await runtime.useModel(ModelTypes.TEXT_SMALL, {\n\t\t\t\t\t\t\t\tprompt:\n\t\t\t\t\t\t\t\t\t\"Debug Mode: Test initialization. Respond with 'Initialization successful' if you can read this.\",\n\t\t\t\t\t\t\t\tstopSequences: [],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tlogger.info(\"Model response:\", result);\n\n\t\t\t\t\t\t\tif (!result || typeof result !== \"string\") {\n\t\t\t\t\t\t\t\tthrow new Error(\"Invalid response from model\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!result.includes(\"successful\")) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Model response does not indicate success\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\"Initialization test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"Initialization test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_text_large\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TEXT_LARGE model test\");\n\n\t\t\t\t\t\t\tconst result = await runtime.useModel(ModelTypes.TEXT_LARGE, {\n\t\t\t\t\t\t\t\tprompt:\n\t\t\t\t\t\t\t\t\t\"Debug Mode: Generate a one-sentence response about artificial intelligence.\",\n\t\t\t\t\t\t\t\tstopSequences: [],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tlogger.info(\"Large model response:\", result);\n\n\t\t\t\t\t\t\tif (!result || typeof result !== \"string\") {\n\t\t\t\t\t\t\t\tthrow new Error(\"Invalid response from large model\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (result.length < 10) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Response too short, possible model failure\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\"TEXT_LARGE test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TEXT_LARGE test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_text_embedding\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TEXT_EMBEDDING test\");\n\n\t\t\t\t\t\t\t// Test with normal text\n\t\t\t\t\t\t\tconst embedding = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_EMBEDDING,\n\t\t\t\t\t\t\t\t\"Test embedding generation\",\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\"Embedding generated with dimensions:\",\n\t\t\t\t\t\t\t\tembedding.length,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (!Array.isArray(embedding)) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Embedding is not an array\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (embedding.length === 0) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Embedding array is empty\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (embedding.some((val) => typeof val !== \"number\")) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Embedding contains non-numeric values\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Test with null input (should return zero vector)\n\t\t\t\t\t\t\tconst nullEmbedding = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_EMBEDDING,\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!Array.isArray(nullEmbedding) ||\n\t\t\t\t\t\t\t\tnullEmbedding.some((val) => val !== 0)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Null input did not return zero vector\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\"TEXT_EMBEDDING test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TEXT_EMBEDDING test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_tokenizer_encode\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TEXT_TOKENIZER_ENCODE test\");\n\t\t\t\t\t\t\tconst text = \"Hello tokenizer test!\";\n\n\t\t\t\t\t\t\tconst tokens = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_TOKENIZER_ENCODE,\n\t\t\t\t\t\t\t\t{ text },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlogger.info(\"Encoded tokens:\", { count: tokens.length });\n\n\t\t\t\t\t\t\tif (!Array.isArray(tokens)) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Tokens output is not an array\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (tokens.length === 0) {\n\t\t\t\t\t\t\t\tthrow new Error(\"No tokens generated\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (tokens.some((token) => !Number.isInteger(token))) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Tokens contain non-integer values\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\n\t\t\t\t\t\t\t\t\"TEXT_TOKENIZER_ENCODE test completed successfully\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TEXT_TOKENIZER_ENCODE test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_tokenizer_decode\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TEXT_TOKENIZER_DECODE test\");\n\n\t\t\t\t\t\t\t// First encode some text\n\t\t\t\t\t\t\tconst originalText = \"Hello tokenizer test!\";\n\t\t\t\t\t\t\tconst tokens = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_TOKENIZER_ENCODE,\n\t\t\t\t\t\t\t\t{ text: originalText },\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// Then decode it back\n\t\t\t\t\t\t\tconst decodedText = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_TOKENIZER_DECODE,\n\t\t\t\t\t\t\t\t{ tokens },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlogger.info(\"Round trip tokenization:\", {\n\t\t\t\t\t\t\t\toriginal: originalText,\n\t\t\t\t\t\t\t\tdecoded: decodedText,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (typeof decodedText !== \"string\") {\n\t\t\t\t\t\t\t\tthrow new Error(\"Decoded output is not a string\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\n\t\t\t\t\t\t\t\t\"TEXT_TOKENIZER_DECODE test completed successfully\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TEXT_TOKENIZER_DECODE test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_image_description\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting IMAGE_DESCRIPTION test\");\n\n\t\t\t\t\t\t\tconst imageUrl =\n\t\t\t\t\t\t\t\t\"https://raw.githubusercontent.com/microsoft/FLAML/main/website/static/img/flaml.png\";\n\t\t\t\t\t\t\tconst result = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.IMAGE_DESCRIPTION,\n\t\t\t\t\t\t\t\timageUrl,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tlogger.info(\"Image description result:\", result);\n\n\t\t\t\t\t\t\tif (!result || typeof result !== \"object\") {\n\t\t\t\t\t\t\t\tthrow new Error(\"Invalid response format\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!result.title || !result.description) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Missing title or description in response\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\ttypeof result.title !== \"string\" ||\n\t\t\t\t\t\t\t\ttypeof result.description !== \"string\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Title or description is not a string\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\"IMAGE_DESCRIPTION test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"IMAGE_DESCRIPTION test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_transcription\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TRANSCRIPTION test\");\n\n\t\t\t\t\t\t\t// Create a simple audio buffer for testing\n\t\t\t\t\t\t\tconst audioData = new Uint8Array([\n\t\t\t\t\t\t\t\t0x52,\n\t\t\t\t\t\t\t\t0x49,\n\t\t\t\t\t\t\t\t0x46,\n\t\t\t\t\t\t\t\t0x46, // \"RIFF\"\n\t\t\t\t\t\t\t\t0x24,\n\t\t\t\t\t\t\t\t0x00,\n\t\t\t\t\t\t\t\t0x00,\n\t\t\t\t\t\t\t\t0x00, // Chunk size\n\t\t\t\t\t\t\t\t0x57,\n\t\t\t\t\t\t\t\t0x41,\n\t\t\t\t\t\t\t\t0x56,\n\t\t\t\t\t\t\t\t0x45, // \"WAVE\"\n\t\t\t\t\t\t\t\t0x66,\n\t\t\t\t\t\t\t\t0x6d,\n\t\t\t\t\t\t\t\t0x74,\n\t\t\t\t\t\t\t\t0x20, // \"fmt \"\n\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\tconst audioBuffer = Buffer.from(audioData);\n\n\t\t\t\t\t\t\tconst transcription = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TRANSCRIPTION,\n\t\t\t\t\t\t\t\taudioBuffer,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlogger.info(\"Transcription result:\", transcription);\n\n\t\t\t\t\t\t\tif (typeof transcription !== \"string\") {\n\t\t\t\t\t\t\t\tthrow new Error(\"Transcription result is not a string\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlogger.success(\"TRANSCRIPTION test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TRANSCRIPTION test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"local_ai_test_text_to_speech\",\n\t\t\t\t\tfn: async (runtime) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlogger.info(\"Starting TEXT_TO_SPEECH test\");\n\n\t\t\t\t\t\t\tconst testText = \"This is a test of the text to speech system.\";\n\t\t\t\t\t\t\tconst audioStream = await runtime.useModel(\n\t\t\t\t\t\t\t\tModelTypes.TEXT_TO_SPEECH,\n\t\t\t\t\t\t\t\ttestText,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (!(audioStream instanceof Readable)) {\n\t\t\t\t\t\t\t\tthrow new Error(\"TTS output is not a readable stream\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Test stream readability\n\t\t\t\t\t\t\tlet dataReceived = false;\n\t\t\t\t\t\t\taudioStream.on(\"data\", () => {\n\t\t\t\t\t\t\t\tdataReceived = true;\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait new Promise((resolve, reject) => {\n\t\t\t\t\t\t\t\taudioStream.on(\"end\", () => {\n\t\t\t\t\t\t\t\t\tif (!dataReceived) {\n\t\t\t\t\t\t\t\t\t\treject(new Error(\"No audio data received from stream\"));\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\taudioStream.on(\"error\", reject);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tlogger.success(\"TEXT_TO_SPEECH test completed successfully\");\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tlogger.error(\"TEXT_TO_SPEECH test failed:\", {\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n};\n\nexport default localAIPlugin;\n","import type { IAgentRuntime } from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\nimport { z } from \"zod\";\n\n// Configuration schema with text model source flags\n/**\n * Configuration schema for different AI models and their settings.\n * This schema includes:\n * - Flags for enabling/disabling various AI models\n * - Ollama configurations including server URL, models, and embedding models\n * - StudioLM configurations including server URL, models, and embedding models\n */\nexport const configSchema = z.object({\n\tUSE_LOCAL_AI: z.boolean().default(true),\n\tUSE_STUDIOLM_TEXT_MODELS: z.boolean().default(false),\n\tUSE_OLLAMA_TEXT_MODELS: z.boolean().default(false),\n\n\t// Ollama Configuration\n\tOLLAMA_SERVER_URL: z.string().default(\"http://localhost:11434\"),\n\tOLLAMA_MODEL: z.string().default(\"deepseek-r1-distill-qwen-7b\"),\n\tUSE_OLLAMA_EMBEDDING: z.boolean().default(false),\n\tOLLAMA_EMBEDDING_MODEL: z.string().default(\"\"),\n\tSMALL_OLLAMA_MODEL: z.string().default(\"deepseek-r1:1.5b\"),\n\tMEDIUM_OLLAMA_MODEL: z.string().default(\"deepseek-r1:7b\"),\n\tLARGE_OLLAMA_MODEL: z.string().default(\"deepseek-r1:7b\"),\n\n\t// StudioLM Configuration\n\tSTUDIOLM_SERVER_URL: z.string().default(\"http://localhost:1234\"),\n\tSTUDIOLM_SMALL_MODEL: z\n\t\t.string()\n\t\t.default(\"lmstudio-community/deepseek-r1-distill-qwen-1.5b\"),\n\tSTUDIOLM_MEDIUM_MODEL: z.string().default(\"deepseek-r1-distill-qwen-7b\"),\n\tSTUDIOLM_EMBEDDING_MODEL: z.union([z.boolean(), z.string()]).default(false),\n});\n\n/**\n * Export type representing the inferred type of the 'configSchema'.\n */\nexport type Config = z.infer<typeof configSchema>;\n\n/**\n * Validates the model configuration object.\n *\n * @param {Record<string, boolean>} config - The model configuration object containing boolean values.\n * @returns {void}\n */\nfunction validateModelConfig(config: Record<string, boolean>): void {\n\t// Log raw values before validation\n\tlogger.info(\"Validating model configuration with values:\", {\n\t\tUSE_LOCAL_AI: config.USE_LOCAL_AI,\n\t\tUSE_STUDIOLM_TEXT_MODELS: config.USE_STUDIOLM_TEXT_MODELS,\n\t\tUSE_OLLAMA_TEXT_MODELS: config.USE_OLLAMA_TEXT_MODELS,\n\t});\n\n\t// Ensure USE_LOCAL_AI is always true\n\tif (!config.USE_LOCAL_AI) {\n\t\tconfig.USE_LOCAL_AI = true;\n\t\tlogger.info(\"Setting USE_LOCAL_AI to true as it's required\");\n\t}\n\n\t// Only validate that StudioLM and Ollama are not both enabled\n\tif (config.USE_STUDIOLM_TEXT_MODELS && config.USE_OLLAMA_TEXT_MODELS) {\n\t\tthrow new Error(\n\t\t\t\"StudioLM and Ollama text models cannot be enabled simultaneously\",\n\t\t);\n\t}\n\n\tlogger.info(\"Configuration is valid\");\n}\n\n/**\n * Validates and parses the configuration provided as a record of string key-value pairs.\n * This function performs boolean conversion on specific configuration values and sets default values for missing keys.\n * @param {Record<string, string>} config - The configuration to validate and parse.\n * @returns {Promise<Config>} The validated and parsed configuration object.\n */\nexport async function validateConfig(\n\tconfig: Record<string, string>,\n): Promise<Config> {\n\ttry {\n\t\t// Log raw environment variables\n\t\t// logger.info(\"Raw environment variables:\", {\n\t\t// USE_LOCAL_AI: process.env.USE_LOCAL_AI,\n\t\t// USE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n\t\t// USE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS,\n\t\t// OLLAMA_SERVER_URL: process.env.OLLAMA_SERVER_URL,\n\t\t// STUDIOLM_SERVER_URL: process.env.STUDIOLM_SERVER_URL\n\t\t// });\n\n\t\t// Parse environment variables with proper boolean conversion\n\t\tconst booleanConfig = {\n\t\t\tUSE_LOCAL_AI: true, // Always true\n\t\t\tUSE_STUDIOLM_TEXT_MODELS: config.USE_STUDIOLM_TEXT_MODELS === \"true\",\n\t\t\tUSE_OLLAMA_TEXT_MODELS: config.USE_OLLAMA_TEXT_MODELS === \"true\",\n\t\t\tUSE_OLLAMA_EMBEDDING: config.USE_OLLAMA_EMBEDDING === \"true\",\n\t\t};\n\n\t\t// logger.info(\"Parsed boolean configuration:\", booleanConfig);\n\n\t\t// Validate text model source configuration\n\t\tvalidateModelConfig(booleanConfig);\n\n\t\t// Create full config with all values\n\t\tconst fullConfig = {\n\t\t\t...booleanConfig,\n\t\t\tOLLAMA_SERVER_URL: config.OLLAMA_SERVER_URL || \"http://localhost:11434\",\n\t\t\tOLLAMA_MODEL: config.OLLAMA_MODEL || \"deepseek-r1-distill-qwen-7b\",\n\t\t\tOLLAMA_EMBEDDING_MODEL: config.OLLAMA_EMBEDDING_MODEL || \"\",\n\t\t\tSMALL_OLLAMA_MODEL: config.SMALL_OLLAMA_MODEL || \"deepseek-r1:1.5b\",\n\t\t\tMEDIUM_OLLAMA_MODEL: config.MEDIUM_OLLAMA_MODEL || \"deepseek-r1:7b\",\n\t\t\tLARGE_OLLAMA_MODEL: config.LARGE_OLLAMA_MODEL || \"deepseek-r1:7b\",\n\t\t\tSTUDIOLM_SERVER_URL:\n\t\t\t\tconfig.STUDIOLM_SERVER_URL || \"http://localhost:1234\",\n\t\t\tSTUDIOLM_SMALL_MODEL:\n\t\t\t\tconfig.STUDIOLM_SMALL_MODEL ||\n\t\t\t\t\"lmstudio-community/deepseek-r1-distill-qwen-1.5b\",\n\t\t\tSTUDIOLM_MEDIUM_MODEL:\n\t\t\t\tconfig.STUDIOLM_MEDIUM_MODEL || \"deepseek-r1-distill-qwen-7b\",\n\t\t\tSTUDIOLM_EMBEDDING_MODEL: config.STUDIOLM_EMBEDDING_MODEL || false,\n\t\t};\n\n\t\tconst validatedConfig = configSchema.parse(fullConfig);\n\n\t\t// logger.info(\"Final validated configuration:\", validatedConfig);\n\n\t\treturn validatedConfig;\n\t} catch (error) {\n\t\tif (error instanceof z.ZodError) {\n\t\t\tconst errorMessages = error.errors\n\t\t\t\t.map((err) => `${err.path.join(\".\")}: ${err.message}`)\n\t\t\t\t.join(\"\\n\");\n\t\t\tlogger.error(\"Zod validation failed:\", errorMessages);\n\t\t\tthrow new Error(`Configuration validation failed:\\n${errorMessages}`);\n\t\t}\n\t\tlogger.error(\"Configuration validation failed:\", {\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t});\n\t\tthrow error;\n\t}\n}\n","// Model specifications and configurations\n/**\n * Interface representing a Tokenizer configuration.\n * @property {string} name - The name of the tokenizer.\n * @property {string} type - The type of the tokenizer.\n */\nexport interface TokenizerConfig {\n\tname: string;\n\ttype: string;\n}\n\n/**\n * Interface representing the specification of a model.\n * @typedef {Object} ModelSpec\n * @property {string} name - The name of the model.\n * @property {string} repo - The repository of the model.\n * @property {string} size - The size of the model.\n * @property {string} quantization - The quantization of the model.\n * @property {number} contextSize - The context size of the model.\n * @property {TokenizerConfig} tokenizer - The configuration for the tokenizer used by the model.\n */\nexport interface ModelSpec {\n\tname: string;\n\trepo: string;\n\tsize: string;\n\tquantization: string;\n\tcontextSize: number;\n\ttokenizer: TokenizerConfig;\n}\n\n/**\n * Interface representing a specification for a vision model.\n * @typedef {object} VisionModelSpec\n * @property {string} name - The name of the vision model.\n * @property {string} repo - The repository of the vision model.\n * @property {string} size - The size of the vision model.\n * @property {string} modelId - The ID of the vision model.\n * @property {number} contextSize - The context size of the vision model.\n * @property {number} maxTokens - The maximum tokens of the vision model.\n * @property {Array.<string>} tasks - The tasks performed by the vision model.\n */\nexport interface VisionModelSpec {\n\tname: string;\n\trepo: string;\n\tsize: string;\n\tmodelId: string;\n\tcontextSize: number;\n\tmaxTokens: number;\n\ttasks: string[];\n}\n\n/**\n * Interface representing the specification for a TTS model.\n * @typedef { Object } TTSModelSpec\n * @property { string } name - The name of the model.\n * @property { string } repo - The repository where the model is stored.\n * @property { string } size - The size of the model.\n * @property { string } quantization - The quantization method used for the model.\n * @property {string[]} speakers - An array of speakers the model can mimic.\n * @property {string[]} languages - An array of languages the model can speak in.\n * @property {string[]} features - An array of features supported by the model.\n * @property { number } maxInputLength - The maximum input length accepted by the model.\n * @property { number } sampleRate - The sample rate used by the model.\n * @property { number } contextSize - The context size used by the model.\n * @property { TokenizerConfig } tokenizer - The configuration for the tokenizer used by the model.\n */\nexport interface TTSModelSpec {\n\tname: string;\n\trepo: string;\n\tsize: string;\n\tquantization: string;\n\tspeakers: string[];\n\tlanguages: string[];\n\tfeatures: string[];\n\tmaxInputLength: number;\n\tsampleRate: number;\n\tcontextSize: number;\n\ttokenizer: TokenizerConfig;\n}\n\n// Model specifications mapping\n/**\n * Interface for specifying different models for a project.\n * @interface ModelSpecs\n * @property {ModelSpec} small - Specifications for a small model\n * @property {ModelSpec} medium - Specifications for a medium model\n * @property {VisionModelSpec} vision - Specifications for a vision model\n * @property {VisionModelSpec} visionvl - Specifications for a vision model with vision loss\n * @property {Object} tts - Specifications for text-to-speech models\n * @property {TTSModelSpec} tts.base - Specifications for the base text-to-speech model\n * @property {TTSModelSpec} tts.medium - Specifications for a medium text-to-speech model\n * @property {TTSModelSpec} tts.large - Specifications for a large text-to-speech model\n */\nexport interface ModelSpecs {\n\tsmall: ModelSpec;\n\tmedium: ModelSpec;\n\tvision: VisionModelSpec;\n\tvisionvl: VisionModelSpec;\n\ttts: {\n\t\tbase: TTSModelSpec;\n\t\tmedium: TTSModelSpec;\n\t\tlarge: TTSModelSpec;\n\t};\n}\n\n// Export MODEL_SPECS constant type\n/**\n * Model specifications containing information about various models such as name, repository, size, quantization, context size, tokenizer details, tasks, speakers, languages, features, max input length, sample rate, and other relevant information.\n */\nexport const MODEL_SPECS: ModelSpecs = {\n\tsmall: {\n\t\tname: \"DeepSeek-R1-Distill-Qwen-1.5B-Q8_0.gguf\",\n\t\trepo: \"unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF\",\n\t\tsize: \"1.5B\",\n\t\tquantization: \"Q8_0\",\n\t\tcontextSize: 8192,\n\t\ttokenizer: {\n\t\t\tname: \"deepseek-ai/deepseek-llm-7b-base\",\n\t\t\ttype: \"llama\",\n\t\t},\n\t},\n\tmedium: {\n\t\tname: \"DeepSeek-R1-Distill-Qwen-7B-Q8_0.gguf\",\n\t\trepo: \"bartowski/DeepSeek-R1-Distill-Qwen-7B-GGUF\",\n\t\tsize: \"7B\",\n\t\tquantization: \"Q8_0\",\n\t\tcontextSize: 8192,\n\t\ttokenizer: {\n\t\t\tname: \"deepseek-ai/deepseek-llm-7b-base\",\n\t\t\ttype: \"llama\",\n\t\t},\n\t},\n\tvision: {\n\t\tname: \"Florence-2-base-ft\",\n\t\trepo: \"onnx-community/Florence-2-base-ft\",\n\t\tsize: \"0.23B\",\n\t\tmodelId: \"onnx-community/Florence-2-base-ft\",\n\t\tcontextSize: 1024,\n\t\tmaxTokens: 256,\n\t\ttasks: [\n\t\t\t\"CAPTION\",\n\t\t\t\"DETAILED_CAPTION\",\n\t\t\t\"MORE_DETAILED_CAPTION\",\n\t\t\t\"CAPTION_TO_PHRASE_GROUNDING\",\n\t\t\t\"OD\",\n\t\t\t\"DENSE_REGION_CAPTION\",\n\t\t\t\"REGION_PROPOSAL\",\n\t\t\t\"OCR\",\n\t\t\t\"OCR_WITH_REGION\",\n\t\t],\n\t},\n\tvisionvl: {\n\t\tname: \"Qwen2.5-VL-3B-Instruct\",\n\t\trepo: \"Qwen/Qwen2.5-VL-3B-Instruct\",\n\t\tsize: \"3B\",\n\t\tmodelId: \"Qwen/Qwen2.5-VL-3B-Instruct\",\n\t\tcontextSize: 32768,\n\t\tmaxTokens: 1024,\n\t\ttasks: [\n\t\t\t\"CAPTION\",\n\t\t\t\"DETAILED_CAPTION\",\n\t\t\t\"IMAGE_UNDERSTANDING\",\n\t\t\t\"VISUAL_QUESTION_ANSWERING\",\n\t\t\t\"OCR\",\n\t\t\t\"VISUAL_LOCALIZATION\",\n\t\t\t\"REGION_ANALYSIS\",\n\t\t],\n\t},\n\ttts: {\n\t\tbase: {\n\t\t\tname: \"OuteTTS-0.2-500M-Q8_0.gguf\",\n\t\t\trepo: \"OuteAI/OuteTTS-0.2-500M-GGUF\",\n\t\t\tsize: \"500M\",\n\t\t\tquantization: \"Q8_0\",\n\t\t\tspeakers: [\"male_1\", \"male_2\", \"female_1\", \"female_2\"],\n\t\t\tlanguages: [\"en\"],\n\t\t\tfeatures: [\n\t\t\t\t\"MULTI_SPEAKER\",\n\t\t\t\t\"VOICE_CLONING\",\n\t\t\t\t\"EMOTION_CONTROL\",\n\t\t\t\t\"SPEED_CONTROL\",\n\t\t\t],\n\t\t\tmaxInputLength: 4096,\n\t\t\tsampleRate: 24000,\n\t\t\tcontextSize: 2048,\n\t\t\ttokenizer: {\n\t\t\t\tname: \"OuteAI/OuteTTS-0.2-500M\",\n\t\t\t\ttype: \"llama\",\n\t\t\t},\n\t\t},\n\t\tmedium: {\n\t\t\tname: \"OuteTTS-0.3-1B.gguf\",\n\t\t\trepo: \"OuteAI/OuteTTS-0.3-1B-GGUF\",\n\t\t\tsize: \"1B\",\n\t\t\tquantization: \"Q8_0\",\n\t\t\tspeakers: [\n\t\t\t\t\"male_1\",\n\t\t\t\t\"male_2\",\n\t\t\t\t\"male_3\",\n\t\t\t\t\"female_1\",\n\t\t\t\t\"female_2\",\n\t\t\t\t\"female_3\",\n\t\t\t],\n\t\t\tlanguages: [\"en\", \"es\", \"fr\", \"de\", \"it\"],\n\t\t\tfeatures: [\n\t\t\t\t\"MULTI_SPEAKER\",\n\t\t\t\t\"VOICE_CLONING\",\n\t\t\t\t\"EMOTION_CONTROL\",\n\t\t\t\t\"SPEED_CONTROL\",\n\t\t\t\t\"MULTILINGUAL\",\n\t\t\t\t\"ACCENT_CONTROL\",\n\t\t\t],\n\t\t\tmaxInputLength: 8192,\n\t\t\tsampleRate: 32000,\n\t\t\tcontextSize: 4096,\n\t\t\ttokenizer: {\n\t\t\t\tname: \"OuteAI/OuteTTS-0.3-1B\",\n\t\t\t\ttype: \"llama\",\n\t\t\t},\n\t\t},\n\t\tlarge: {\n\t\t\tname: \"OuteTTS-0.3-3B.gguf\",\n\t\t\trepo: \"OuteAI/OuteTTS-0.3-3B-GGUF\",\n\t\t\tsize: \"3B\",\n\t\t\tquantization: \"Q8_0\",\n\t\t\tspeakers: [\n\t\t\t\t\"male_1\",\n\t\t\t\t\"male_2\",\n\t\t\t\t\"male_3\",\n\t\t\t\t\"male_4\",\n\t\t\t\t\"female_1\",\n\t\t\t\t\"female_2\",\n\t\t\t\t\"female_3\",\n\t\t\t\t\"female_4\",\n\t\t\t],\n\t\t\tlanguages: [\n\t\t\t\t\"en\",\n\t\t\t\t\"es\",\n\t\t\t\t\"fr\",\n\t\t\t\t\"de\",\n\t\t\t\t\"it\",\n\t\t\t\t\"pt\",\n\t\t\t\t\"nl\",\n\t\t\t\t\"pl\",\n\t\t\t\t\"ru\",\n\t\t\t\t\"ja\",\n\t\t\t\t\"ko\",\n\t\t\t\t\"zh\",\n\t\t\t],\n\t\t\tfeatures: [\n\t\t\t\t\"MULTI_SPEAKER\",\n\t\t\t\t\"VOICE_CLONING\",\n\t\t\t\t\"EMOTION_CONTROL\",\n\t\t\t\t\"SPEED_CONTROL\",\n\t\t\t\t\"MULTILINGUAL\",\n\t\t\t\t\"ACCENT_CONTROL\",\n\t\t\t\t\"STYLE_TRANSFER\",\n\t\t\t\t\"PROSODY_CONTROL\",\n\t\t\t],\n\t\t\tmaxInputLength: 16384,\n\t\t\tsampleRate: 48000,\n\t\t\tcontextSize: 8192,\n\t\t\ttokenizer: {\n\t\t\t\tname: \"OuteAI/OuteTTS-0.3-3B\",\n\t\t\t\ttype: \"llama\",\n\t\t\t},\n\t\t},\n\t},\n};\n","import fs from \"node:fs\";\nimport https from \"node:https\";\nimport path from \"node:path\";\nimport { logger } from \"@elizaos/core\";\nimport type { ModelSpec } from \"../types\";\n\n/**\n * Class representing a Download Manager.\n */\nexport class DownloadManager {\n\tprivate static instance: DownloadManager | null = null;\n\tprivate cacheDir: string;\n\tprivate modelsDir: string;\n\t// Track active downloads to prevent duplicates\n\tprivate activeDownloads: Map<string, Promise<void>> = new Map();\n\n\t/**\n\t * Creates a new instance of CacheManager.\n\t *\n\t * @param {string} cacheDir - The directory path for caching data.\n\t * @param {string} modelsDir - The directory path for model files.\n\t */\n\tprivate constructor(cacheDir: string, modelsDir: string) {\n\t\tthis.cacheDir = cacheDir;\n\t\tthis.modelsDir = modelsDir;\n\t\tthis.ensureCacheDirectory();\n\t\tthis.ensureModelsDirectory();\n\t}\n\n\t/**\n\t * Returns the singleton instance of the DownloadManager class.\n\t * If an instance does not already exist, it creates a new one using the provided cache directory and models directory.\n\t *\n\t * @param {string} cacheDir - The directory where downloaded files are stored.\n\t * @param {string} modelsDir - The directory where model files are stored.\n\t * @returns {DownloadManager} The singleton instance of the DownloadManager class.\n\t */\n\tpublic static getInstance(\n\t\tcacheDir: string,\n\t\tmodelsDir: string,\n\t): DownloadManager {\n\t\tif (!DownloadManager.instance) {\n\t\t\tDownloadManager.instance = new DownloadManager(cacheDir, modelsDir);\n\t\t}\n\t\treturn DownloadManager.instance;\n\t}\n\n\t/**\n\t * Ensure that the cache directory exists.\n\t */\n\tprivate ensureCacheDirectory(): void {\n\t\tlogger.info(\"Ensuring cache directory exists:\", this.cacheDir);\n\t\tif (!fs.existsSync(this.cacheDir)) {\n\t\t\tfs.mkdirSync(this.cacheDir, { recursive: true });\n\t\t\tlogger.info(\"Created cache directory\");\n\t\t}\n\t}\n\n\t/**\n\t * Ensure that the models directory exists. If it does not exist, create it.\n\t */\n\tprivate ensureModelsDirectory(): void {\n\t\tlogger.info(\"Ensuring models directory exists:\", this.modelsDir);\n\t\tif (!fs.existsSync(this.modelsDir)) {\n\t\t\tfs.mkdirSync(this.modelsDir, { recursive: true });\n\t\t\tlogger.info(\"Created models directory\");\n\t\t}\n\t}\n\n\t/**\n\t * Downloads a file from a given URL to a specified destination path asynchronously.\n\t *\n\t * @param {string} url - The URL from which to download the file.\n\t * @param {string} destPath - The destination path where the downloaded file will be saved.\n\t * @returns {Promise<void>} A Promise that resolves when the file download is completed successfully or rejects if an error occurs.\n\t */\n\tprivate async downloadFileInternal(\n\t\turl: string,\n\t\tdestPath: string,\n\t): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlogger.info(`Starting download to: ${destPath}`);\n\n\t\t\t// Create a temporary file path in the same directory as destPath\n\t\t\tconst tempPath = `${destPath}.tmp`;\n\n\t\t\t// Check if temp file already exists and remove it to avoid conflicts\n\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\ttry {\n\t\t\t\t\tlogger.warn(`Removing existing temporary file: ${tempPath}`);\n\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t`Failed to remove existing temporary file: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst request = https.get(\n\t\t\t\turl,\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\":\n\t\t\t\t\t\t\t\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36\",\n\t\t\t\t\t},\n\t\t\t\t\ttimeout: 300000, // Increase timeout to 5 minutes\n\t\t\t\t},\n\t\t\t\t(response) => {\n\t\t\t\t\tif (response.statusCode === 301 || response.statusCode === 302) {\n\t\t\t\t\t\tconst redirectUrl = response.headers.location;\n\t\t\t\t\t\tif (!redirectUrl) {\n\t\t\t\t\t\t\treject(new Error(\"Redirect location not found\"));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// logger.info(`Following redirect to: ${redirectUrl}`);\n\t\t\t\t\t\t// Remove the current download from tracking before starting a new one\n\t\t\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\t\t\tthis.downloadFile(redirectUrl, destPath)\n\t\t\t\t\t\t\t.then(resolve)\n\t\t\t\t\t\t\t.catch(reject);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (response.statusCode !== 200) {\n\t\t\t\t\t\treject(new Error(`Failed to download: ${response.statusCode}`));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst totalSize = Number.parseInt(\n\t\t\t\t\t\tresponse.headers[\"content-length\"] || \"0\",\n\t\t\t\t\t\t10,\n\t\t\t\t\t);\n\t\t\t\t\tlet downloadedSize = 0;\n\t\t\t\t\tlet lastLoggedPercent = 0;\n\t\t\t\t\tconst barLength = 30;\n\n\t\t\t\t\t// Log initial progress bar\n\t\t\t\t\tconst fileName = path.basename(destPath);\n\t\t\t\t\tlogger.info(`Downloading ${fileName}: ${\"▱\".repeat(barLength)} 0%`);\n\n\t\t\t\t\tconst file = fs.createWriteStream(tempPath);\n\n\t\t\t\t\tresponse.on(\"data\", (chunk) => {\n\t\t\t\t\t\tdownloadedSize += chunk.length;\n\t\t\t\t\t\tconst percent = Math.round((downloadedSize / totalSize) * 100);\n\n\t\t\t\t\t\t// Only update progress bar when percentage changes significantly (every 5%)\n\t\t\t\t\t\tif (percent >= lastLoggedPercent + 5) {\n\t\t\t\t\t\t\tconst filledLength = Math.floor(\n\t\t\t\t\t\t\t\t(downloadedSize / totalSize) * barLength,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst progressBar =\n\t\t\t\t\t\t\t\t\"▰\".repeat(filledLength) + \"▱\".repeat(barLength - filledLength);\n\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t`Downloading ${fileName}: ${progressBar} ${percent}%`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tlastLoggedPercent = percent;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tresponse.pipe(file);\n\n\t\t\t\t\tfile.on(\"finish\", () => {\n\t\t\t\t\t\tfile.close(() => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// Show completed progress bar\n\t\t\t\t\t\t\t\tconst completedBar = \"▰\".repeat(barLength);\n\t\t\t\t\t\t\t\tlogger.info(`Downloading ${fileName}: ${completedBar} 100%`);\n\n\t\t\t\t\t\t\t\t// Ensure the destination directory exists\n\t\t\t\t\t\t\t\tconst destDir = path.dirname(destPath);\n\t\t\t\t\t\t\t\tif (!fs.existsSync(destDir)) {\n\t\t\t\t\t\t\t\t\tfs.mkdirSync(destDir, { recursive: true });\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check if temp file exists before proceeding\n\t\t\t\t\t\t\t\tif (!fs.existsSync(tempPath)) {\n\t\t\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\t\t\tnew Error(`Temporary file ${tempPath} does not exist`),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Only delete the existing file if the temp file is ready\n\t\t\t\t\t\t\t\tif (fs.existsSync(destPath)) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t// Create a backup of the existing file before deleting it\n\t\t\t\t\t\t\t\t\t\tconst backupPath = `${destPath}.bak`;\n\t\t\t\t\t\t\t\t\t\tfs.renameSync(destPath, backupPath);\n\t\t\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t\t\t`Created backup of existing file: ${backupPath}`,\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Move temp file to destination\n\t\t\t\t\t\t\t\t\t\tfs.renameSync(tempPath, destPath);\n\n\t\t\t\t\t\t\t\t\t\t// If successful, remove the backup\n\t\t\t\t\t\t\t\t\t\tif (fs.existsSync(backupPath)) {\n\t\t\t\t\t\t\t\t\t\t\tfs.unlinkSync(backupPath);\n\t\t\t\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t\t\t\t`Removed backup file after successful update: ${backupPath}`,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} catch (moveErr) {\n\t\t\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t\t\t`Error replacing file: ${moveErr instanceof Error ? moveErr.message : String(moveErr)}`,\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Try to restore from backup if the move failed\n\t\t\t\t\t\t\t\t\t\tconst backupPath = `${destPath}.bak`;\n\t\t\t\t\t\t\t\t\t\tif (fs.existsSync(backupPath)) {\n\t\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\t\tfs.renameSync(backupPath, destPath);\n\t\t\t\t\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Restored from backup after failed update: ${backupPath}`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t} catch (restoreErr) {\n\t\t\t\t\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to restore from backup: ${restoreErr instanceof Error ? restoreErr.message : String(restoreErr)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Clean up temp file\n\t\t\t\t\t\t\t\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t\t\t\t\t\t\t\t} catch (unlinkErr) {\n\t\t\t\t\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Failed to clean up temp file: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\treject(moveErr);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// No existing file, just move the temp file\n\t\t\t\t\t\t\t\t\tfs.renameSync(tempPath, destPath);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tlogger.success(\n\t\t\t\t\t\t\t\t\t`Download of ${fileName} completed successfully`,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Remove from active downloads\n\t\t\t\t\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t`Error finalizing download: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t// Clean up temp file if it exists\n\t\t\t\t\t\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t\t\t\t\t\t} catch (unlinkErr) {\n\t\t\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t\t\t`Failed to clean up temp file: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Remove from active downloads\n\t\t\t\t\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\n\t\t\t\t\tfile.on(\"error\", (err) => {\n\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t`File write error: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfile.close(() => {\n\t\t\t\t\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t\t\t\t\t} catch (unlinkErr) {\n\t\t\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\t\t\t`Failed to clean up temp file after error: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Remove from active downloads\n\t\t\t\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\n\t\t\trequest.on(\"error\", (err) => {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Request error: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t\t);\n\t\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t\t} catch (unlinkErr) {\n\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t`Failed to clean up temp file after request error: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Remove from active downloads\n\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\trequest.on(\"timeout\", () => {\n\t\t\t\tlogger.error(\"Download timeout occurred\");\n\t\t\t\trequest.destroy();\n\t\t\t\tif (fs.existsSync(tempPath)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfs.unlinkSync(tempPath);\n\t\t\t\t\t} catch (unlinkErr) {\n\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t`Failed to clean up temp file after timeout: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Remove from active downloads\n\t\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\t\treject(new Error(\"Download timeout\"));\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Asynchronously downloads a file from the specified URL to the destination path.\n\t *\n\t * @param {string} url - The URL of the file to download.\n\t * @param {string} destPath - The destination path to save the downloaded file.\n\t * @returns {Promise<void>} A Promise that resolves once the file has been successfully downloaded.\n\t */\n\tpublic async downloadFile(url: string, destPath: string): Promise<void> {\n\t\t// Check if this file is already being downloaded\n\t\tif (this.activeDownloads.has(destPath)) {\n\t\t\tlogger.info(\n\t\t\t\t`Download for ${destPath} already in progress, waiting for it to complete...`,\n\t\t\t);\n\t\t\tconst existingDownload = this.activeDownloads.get(destPath);\n\t\t\tif (existingDownload) {\n\t\t\t\treturn existingDownload;\n\t\t\t}\n\t\t\t// If somehow the download was removed from the map but the key still exists\n\t\t\tlogger.warn(\n\t\t\t\t`Download for ${destPath} was marked as in progress but not found in tracking map`,\n\t\t\t);\n\t\t}\n\n\t\t// Start a new download and track it\n\t\tconst downloadPromise = this.downloadFileInternal(url, destPath);\n\t\tthis.activeDownloads.set(destPath, downloadPromise);\n\n\t\ttry {\n\t\t\treturn await downloadPromise;\n\t\t} catch (error) {\n\t\t\t// Make sure to remove from active downloads in case of error\n\t\t\tthis.activeDownloads.delete(destPath);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Downloads a model specified by the modelSpec and saves it to the provided modelPath.\n\t * If the model is successfully downloaded, returns true, otherwise returns false.\n\t *\n\t * @param {ModelSpec} modelSpec - The model specification containing repo and name.\n\t * @param {string} modelPath - The path where the model will be saved.\n\t * @returns {Promise<boolean>} - Indicates if the model was successfully downloaded or not.\n\t */\n\tpublic async downloadModel(\n\t\tmodelSpec: ModelSpec,\n\t\tmodelPath: string,\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\tlogger.info(\"Starting local model download...\");\n\n\t\t\t// Ensure model directory exists\n\t\t\tconst modelDir = path.dirname(modelPath);\n\t\t\tif (!fs.existsSync(modelDir)) {\n\t\t\t\tlogger.info(\"Creating model directory:\", modelDir);\n\t\t\t\tfs.mkdirSync(modelDir, { recursive: true });\n\t\t\t}\n\n\t\t\tif (!fs.existsSync(modelPath)) {\n\t\t\t\t// Try different URL patterns in sequence, similar to TTS manager approach\n\t\t\t\tconst attempts = [\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: \"LFS URL with GGUF suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}?download=true`,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: \"LFS URL without GGUF suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo.replace(\"-GGUF\", \"\")}/resolve/main/${modelSpec.name}?download=true`,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: \"Standard URL with GGUF suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}`,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdescription: \"Standard URL without GGUF suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo.replace(\"-GGUF\", \"\")}/resolve/main/${modelSpec.name}`,\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\t// logger.info(\"Model download details:\", {\n\t\t\t\t// modelName: modelSpec.name,\n\t\t\t\t// repo: modelSpec.repo,\n\t\t\t\t// modelPath: modelPath,\n\t\t\t\t// attemptUrls: attempts.map(a => ({ description: a.description, url: a.url })),\n\t\t\t\t// timestamp: new Date().toISOString()\n\t\t\t\t// });\n\n\t\t\t\tlet lastError = null;\n\t\t\t\tlet downloadSuccess = false;\n\n\t\t\t\tfor (const attempt of attempts) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlogger.info(\"Attempting model download:\", {\n\t\t\t\t\t\t\tdescription: attempt.description,\n\t\t\t\t\t\t\turl: attempt.url,\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// The downloadFile method now handles the progress bar display\n\t\t\t\t\t\tawait this.downloadFile(attempt.url, modelPath);\n\n\t\t\t\t\t\tlogger.success(\n\t\t\t\t\t\t\t`Model download complete: ${modelSpec.name} using ${attempt.description}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdownloadSuccess = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tlastError = error;\n\t\t\t\t\t\tlogger.warn(\"Model download attempt failed:\", {\n\t\t\t\t\t\t\tdescription: attempt.description,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!downloadSuccess) {\n\t\t\t\t\tthrow lastError || new Error(\"All download attempts failed\");\n\t\t\t\t}\n\n\t\t\t\t// Return true to indicate the model was newly downloaded\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// Model already exists\n\t\t\tlogger.info(\"Model already exists at:\", modelPath);\n\t\t\t// Return false to indicate the model already existed\n\t\t\treturn false;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Model download failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tmodelPath: modelPath,\n\t\t\t\tmodel: modelSpec.name,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the cache directory path.\n\t *\n\t * @returns {string} The path of the cache directory.\n\t */\n\n\tpublic getCacheDir(): string {\n\t\treturn this.cacheDir;\n\t}\n\n\t/**\n\t * Downloads a file from a given URL to a specified destination path.\n\t *\n\t * @param {string} url - The URL of the file to download.\n\t * @param {string} destPath - The destination path where the file should be saved.\n\t * @returns {Promise<void>} A Promise that resolves once the file has been downloaded.\n\t */\n\tpublic async downloadFromUrl(url: string, destPath: string): Promise<void> {\n\t\treturn this.downloadFile(url, destPath);\n\t}\n\n\t/**\n\t * Ensures that the specified directory exists. If it does not exist, it will be created.\n\t * @param {string} dirPath - The path of the directory to ensure existence of.\n\t * @returns {void}\n\t */\n\tpublic ensureDirectoryExists(dirPath: string): void {\n\t\tif (!fs.existsSync(dirPath)) {\n\t\t\tfs.mkdirSync(dirPath, { recursive: true });\n\t\t\tlogger.info(`Created directory: ${dirPath}`);\n\t\t}\n\t}\n}\n","import { type GenerateTextParams, ModelTypes, logger } from \"@elizaos/core\";\n\nimport fetch from \"node-fetch\";\n\n/**\n * Interface representing the structure of an Ollama model.\n * @typedef {Object} OllamaModel\n * @property {string} name - The name of the Ollama model.\n * @property {string} id - The unique identifier of the Ollama model.\n * @property {string} size - The size of the Ollama model.\n * @property {string} modified - The date when the Ollama model was last modified.\n */\ninterface OllamaModel {\n\tname: string;\n\tid: string;\n\tsize: string;\n\tmodified: string;\n}\n\n/**\n * Interface representing a response from the Ollama API.\n * @property {string} model - The model used for generating the response.\n * @property {string} response - The actual response generated by the model.\n * @property {boolean} done - Indicates whether the response generation is complete.\n * @property {number[]} [prompt] - Optional array of prompt values used in generating the response.\n * @property {number} [total_duration] - Optional total duration of the response generation process.\n * @property {number} [load_duration] - Optional load duration of the model used.\n * @property {number} [prompt_eval_duration] - Optional evaluation duration for the prompt values.\n * @property {number} [eval_duration] - Optional evaluation duration for the response generation.\n */\ninterface OllamaResponse {\n\tmodel: string;\n\tresponse: string;\n\tdone: boolean;\n\tprompt?: number[];\n\ttotal_duration?: number;\n\tload_duration?: number;\n\tprompt_eval_duration?: number;\n\teval_duration?: number;\n}\n\n/**\n * Manages interactions with the Ollama API, including server status checks, fetching available models,\n * testing models, initializing the manager, generating text, and more.\n */\nexport class OllamaManager {\n\tprivate static instance: OllamaManager | null = null;\n\tprivate serverUrl: string;\n\tprivate initialized = false;\n\tprivate availableModels: OllamaModel[] = [];\n\tprivate configuredModels = {\n\t\tsmall: process.env.SMALL_OLLAMA_MODEL || \"deepseek-r1:1.5b\",\n\t\tmedium: process.env.MEDIUM_OLLAMA_MODEL || \"deepseek-r1:7b\",\n\t};\n\n\t/**\n\t * Private constructor for initializing OllamaManager.\n\t */\n\tprivate constructor() {\n\t\tthis.serverUrl = process.env.OLLAMA_SERVER_URL || \"http://localhost:11434\";\n\t\tlogger.info(\"OllamaManager initialized with configuration:\", {\n\t\t\tserverUrl: this.serverUrl,\n\t\t\tconfiguredModels: this.configuredModels,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\t}\n\n\t/**\n\t * Returns an instance of the OllamaManager class.\n\t * If an instance does not already exist, a new instance is created and returned.\n\t * @returns {OllamaManager} The instance of the OllamaManager class.\n\t */\n\tpublic static getInstance(): OllamaManager {\n\t\tif (!OllamaManager.instance) {\n\t\t\tOllamaManager.instance = new OllamaManager();\n\t\t}\n\t\treturn OllamaManager.instance;\n\t}\n\n\t/**\n\t * Asynchronously checks the status of the server by attempting to fetch the \"/api/tags\" endpoint.\n\t * @returns A Promise that resolves to a boolean indicating if the server is reachable and responding with a successful status.\n\t */\n\tprivate async checkServerStatus(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst response = await fetch(`${this.serverUrl}/api/tags`);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Server responded with status: ${response.status}`);\n\t\t\t}\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Ollama server check failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tserverUrl: this.serverUrl,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Fetches the available Ollama models from the specified server URL.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when the available models are successfully fetched.\n\t */\n\tprivate async fetchAvailableModels(): Promise<void> {\n\t\ttry {\n\t\t\tconst response = await fetch(`${this.serverUrl}/api/tags`);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch models: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as { models: OllamaModel[] };\n\t\t\tthis.availableModels = data.models;\n\n\t\t\tlogger.info(\"Ollama available models:\", {\n\t\t\t\tcount: this.availableModels.length,\n\t\t\t\tmodels: this.availableModels.map((m) => m.name),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to fetch Ollama models:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tserverUrl: this.serverUrl,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously tests a model specified by the given modelId.\n\t *\n\t * @param {string} modelId - The ID of the model to be tested.\n\t * @returns {Promise<boolean>} - A promise that resolves to true if the model test is successful, false otherwise.\n\t */\n\tprivate async testModel(modelId: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst testRequest = {\n\t\t\t\tmodel: modelId,\n\t\t\t\tprompt:\n\t\t\t\t\t\"Debug Mode: Test initialization. Respond with 'Initialization successful' if you can read this.\",\n\t\t\t\tstream: false,\n\t\t\t\toptions: {\n\t\t\t\t\ttemperature: 0.7,\n\t\t\t\t\tnum_predict: 100,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tlogger.info(`Testing model ${modelId}...`);\n\n\t\t\tconst response = await fetch(`${this.serverUrl}/api/generate`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(testRequest),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Model test failed with status: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst result = (await response.json()) as OllamaResponse;\n\n\t\t\tif (!result.response) {\n\t\t\t\tthrow new Error(\"No valid response content received\");\n\t\t\t}\n\n\t\t\tlogger.info(`Model ${modelId} test response:`, {\n\t\t\t\tcontent: result.response,\n\t\t\t\tmodel: result.model,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tlogger.error(`Model ${modelId} test failed:`, {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously tests the configured text models to ensure they are working properly.\n\t * Logs the test results for each model and outputs a warning if any models fail the test.\n\t * @returns {Promise<void>} A Promise that resolves when all configured models have been tested.\n\t */\n\tprivate async testTextModels(): Promise<void> {\n\t\tlogger.info(\"Testing configured text models...\");\n\n\t\tconst results = await Promise.all([\n\t\t\tthis.testModel(this.configuredModels.small),\n\t\t\tthis.testModel(this.configuredModels.medium),\n\t\t]);\n\n\t\tconst [smallWorking, mediumWorking] = results;\n\n\t\tif (!smallWorking || !mediumWorking) {\n\t\t\tconst failedModels = [];\n\t\t\tif (!smallWorking) failedModels.push(\"small\");\n\t\t\tif (!mediumWorking) failedModels.push(\"medium\");\n\n\t\t\tlogger.warn(\"Some models failed the test:\", {\n\t\t\t\tfailedModels,\n\t\t\t\tsmall: this.configuredModels.small,\n\t\t\t\tmedium: this.configuredModels.medium,\n\t\t\t});\n\t\t} else {\n\t\t\tlogger.success(\"All configured models passed the test\");\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the Ollama service by checking server status,\n\t * fetching available models, and testing text models.\n\t *\n\t * @returns A Promise that resolves when initialization is complete\n\t */\n\tpublic async initialize(): Promise<void> {\n\t\ttry {\n\t\t\tif (this.initialized) {\n\t\t\t\tlogger.info(\"Ollama already initialized, skipping initialization\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlogger.info(\"Starting Ollama initialization...\");\n\t\t\tconst serverAvailable = await this.checkServerStatus();\n\n\t\t\tif (!serverAvailable) {\n\t\t\t\tthrow new Error(\"Ollama server is not available\");\n\t\t\t}\n\n\t\t\tawait this.fetchAvailableModels();\n\t\t\tawait this.testTextModels();\n\n\t\t\tthis.initialized = true;\n\t\t\tlogger.success(\"Ollama initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Ollama initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the available Ollama models.\n\t *\n\t * @returns {OllamaModel[]} An array of OllamaModel objects representing the available models.\n\t */\n\tpublic getAvailableModels(): OllamaModel[] {\n\t\treturn this.availableModels;\n\t}\n\n\t/**\n\t * Check if the object is initialized.\n\t * @returns {boolean} True if the object is initialized, false otherwise.\n\t */\n\tpublic isInitialized(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\t/**\n\t * Generates text using the Ollama AI model.\n\t *\n\t * @param {GenerateTextParams} params - The parameters for generating text.\n\t * @param {boolean} [isInitialized=false] - Flag indicating if Ollama is already initialized.\n\t * @returns {Promise<string>} - A promise that resolves with the generated text.\n\t */\n\tpublic async generateText(\n\t\tparams: GenerateTextParams,\n\t\tisInitialized = false,\n\t): Promise<string> {\n\t\ttry {\n\t\t\t// Log entry point with all parameters\n\t\t\tlogger.info(\"Ollama generateText entry:\", {\n\t\t\t\tisInitialized,\n\t\t\t\tcurrentInitState: this.initialized,\n\t\t\t\tmanagerInitState: this.isInitialized(),\n\t\t\t\tmodelType: params.modelType,\n\t\t\t\tcontextLength: params.prompt?.length,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\t// Only initialize if not already initialized and not marked as initialized\n\t\t\tif (!this.initialized && !isInitialized) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Ollama not initialized. Please initialize before generating text.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlogger.info(\"Ollama preparing request:\", {\n\t\t\t\tmodel:\n\t\t\t\t\tparams.modelType === ModelTypes.TEXT_LARGE\n\t\t\t\t\t\t? this.configuredModels.medium\n\t\t\t\t\t\t: this.configuredModels.small,\n\t\t\t\tcontextLength: params.prompt.length,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\tconst request = {\n\t\t\t\tmodel:\n\t\t\t\t\tparams.modelType === ModelTypes.TEXT_LARGE\n\t\t\t\t\t\t? this.configuredModels.medium\n\t\t\t\t\t\t: this.configuredModels.small,\n\t\t\t\tprompt: params.prompt,\n\t\t\t\tstream: false,\n\t\t\t\toptions: {\n\t\t\t\t\ttemperature: 0.7,\n\t\t\t\t\ttop_p: 0.9,\n\t\t\t\t\tnum_predict: 8192,\n\t\t\t\t\trepeat_penalty: 1.2,\n\t\t\t\t\tfrequency_penalty: 0.7,\n\t\t\t\t\tpresence_penalty: 0.7,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst response = await fetch(`${this.serverUrl}/api/generate`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(request),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Ollama request failed: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst result = (await response.json()) as OllamaResponse;\n\n\t\t\tif (!result.response) {\n\t\t\t\tthrow new Error(\"No valid response content received from Ollama\");\n\t\t\t}\n\n\t\t\tlet responseText = result.response;\n\n\t\t\t// Log raw response for debugging\n\t\t\tlogger.info(\"Raw response structure:\", {\n\t\t\t\tresponseLength: responseText.length,\n\t\t\t\thasAction: responseText.includes(\"action\"),\n\t\t\t\thasThinkTag: responseText.includes(\"<think>\"),\n\t\t\t});\n\n\t\t\t// Clean think tags if present\n\t\t\tif (responseText.includes(\"<think>\")) {\n\t\t\t\tlogger.info(\"Cleaning think tags from response\");\n\t\t\t\tresponseText = responseText.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, \"\");\n\t\t\t\tlogger.info(\"Think tags removed from response\");\n\t\t\t}\n\n\t\t\tlogger.info(\"Ollama request completed successfully:\", {\n\t\t\t\tresponseLength: responseText.length,\n\t\t\t\thasThinkTags: responseText.includes(\"<think>\"),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\treturn responseText;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Ollama text generation error:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tphase: \"text generation\",\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n","/**\n * Index.js\n *\n * a request API compatible with window.fetch\n *\n * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.\n */\n\nimport http from 'node:http';\nimport https from 'node:https';\nimport zlib from 'node:zlib';\nimport Stream, {PassThrough, pipeline as pump} from 'node:stream';\nimport {Buffer} from 'node:buffer';\n\nimport dataUriToBuffer from 'data-uri-to-buffer';\n\nimport {writeToStream, clone} from './body.js';\nimport Response from './response.js';\nimport Headers, {fromRawHeaders} from './headers.js';\nimport Request, {getNodeRequestOptions} from './request.js';\nimport {FetchError} from './errors/fetch-error.js';\nimport {AbortError} from './errors/abort-error.js';\nimport {isRedirect} from './utils/is-redirect.js';\nimport {FormData} from 'formdata-polyfill/esm.min.js';\nimport {isDomainOrSubdomain, isSameProtocol} from './utils/is.js';\nimport {parseReferrerPolicyFromHeader} from './utils/referrer.js';\nimport {\n\tBlob,\n\tFile,\n\tfileFromSync,\n\tfileFrom,\n\tblobFromSync,\n\tblobFrom\n} from 'fetch-blob/from.js';\n\nexport {FormData, Headers, Request, Response, FetchError, AbortError, isRedirect};\nexport {Blob, File, fileFromSync, fileFrom, blobFromSync, blobFrom};\n\nconst supportedSchemas = new Set(['data:', 'http:', 'https:']);\n\n/**\n * Fetch function\n *\n * @param {string | URL | import('./request').default} url - Absolute url or Request instance\n * @param {*} [options_] - Fetch options\n * @return {Promise<import('./response').default>}\n */\nexport default async function fetch(url, options_) {\n\treturn new Promise((resolve, reject) => {\n\t\t// Build request object\n\t\tconst request = new Request(url, options_);\n\t\tconst {parsedURL, options} = getNodeRequestOptions(request);\n\t\tif (!supportedSchemas.has(parsedURL.protocol)) {\n\t\t\tthrow new TypeError(`node-fetch cannot load ${url}. URL scheme \"${parsedURL.protocol.replace(/:$/, '')}\" is not supported.`);\n\t\t}\n\n\t\tif (parsedURL.protocol === 'data:') {\n\t\t\tconst data = dataUriToBuffer(request.url);\n\t\t\tconst response = new Response(data, {headers: {'Content-Type': data.typeFull}});\n\t\t\tresolve(response);\n\t\t\treturn;\n\t\t}\n\n\t\t// Wrap http.request into fetch\n\t\tconst send = (parsedURL.protocol === 'https:' ? https : http).request;\n\t\tconst {signal} = request;\n\t\tlet response = null;\n\n\t\tconst abort = () => {\n\t\t\tconst error = new AbortError('The operation was aborted.');\n\t\t\treject(error);\n\t\t\tif (request.body && request.body instanceof Stream.Readable) {\n\t\t\t\trequest.body.destroy(error);\n\t\t\t}\n\n\t\t\tif (!response || !response.body) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tresponse.body.emit('error', error);\n\t\t};\n\n\t\tif (signal && signal.aborted) {\n\t\t\tabort();\n\t\t\treturn;\n\t\t}\n\n\t\tconst abortAndFinalize = () => {\n\t\t\tabort();\n\t\t\tfinalize();\n\t\t};\n\n\t\t// Send request\n\t\tconst request_ = send(parsedURL.toString(), options);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', abortAndFinalize);\n\t\t}\n\n\t\tconst finalize = () => {\n\t\t\trequest_.abort();\n\t\t\tif (signal) {\n\t\t\t\tsignal.removeEventListener('abort', abortAndFinalize);\n\t\t\t}\n\t\t};\n\n\t\trequest_.on('error', error => {\n\t\t\treject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));\n\t\t\tfinalize();\n\t\t});\n\n\t\tfixResponseChunkedTransferBadEnding(request_, error => {\n\t\t\tif (response && response.body) {\n\t\t\t\tresponse.body.destroy(error);\n\t\t\t}\n\t\t});\n\n\t\t/* c8 ignore next 18 */\n\t\tif (process.version < 'v14') {\n\t\t\t// Before Node.js 14, pipeline() does not fully support async iterators and does not always\n\t\t\t// properly handle when the socket close/end events are out of order.\n\t\t\trequest_.on('socket', s => {\n\t\t\t\tlet endedWithEventsCount;\n\t\t\t\ts.prependListener('end', () => {\n\t\t\t\t\tendedWithEventsCount = s._eventsCount;\n\t\t\t\t});\n\t\t\t\ts.prependListener('close', hadError => {\n\t\t\t\t\t// if end happened before close but the socket didn't emit an error, do it now\n\t\t\t\t\tif (response && endedWithEventsCount < s._eventsCount && !hadError) {\n\t\t\t\t\t\tconst error = new Error('Premature close');\n\t\t\t\t\t\terror.code = 'ERR_STREAM_PREMATURE_CLOSE';\n\t\t\t\t\t\tresponse.body.emit('error', error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\trequest_.on('response', response_ => {\n\t\t\trequest_.setTimeout(0);\n\t\t\tconst headers = fromRawHeaders(response_.rawHeaders);\n\n\t\t\t// HTTP fetch step 5\n\t\t\tif (isRedirect(response_.statusCode)) {\n\t\t\t\t// HTTP fetch step 5.2\n\t\t\t\tconst location = headers.get('Location');\n\n\t\t\t\t// HTTP fetch step 5.3\n\t\t\t\tlet locationURL = null;\n\t\t\t\ttry {\n\t\t\t\t\tlocationURL = location === null ? null : new URL(location, request.url);\n\t\t\t\t} catch {\n\t\t\t\t\t// error here can only be invalid URL in Location: header\n\t\t\t\t\t// do not throw when options.redirect == manual\n\t\t\t\t\t// let the user extract the errorneous redirect URL\n\t\t\t\t\tif (request.redirect !== 'manual') {\n\t\t\t\t\t\treject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// HTTP fetch step 5.5\n\t\t\t\tswitch (request.redirect) {\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\treject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 'manual':\n\t\t\t\t\t\t// Nothing to do\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'follow': {\n\t\t\t\t\t\t// HTTP-redirect fetch step 2\n\t\t\t\t\t\tif (locationURL === null) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 5\n\t\t\t\t\t\tif (request.counter >= request.follow) {\n\t\t\t\t\t\t\treject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 6 (counter increment)\n\t\t\t\t\t\t// Create a new Request object.\n\t\t\t\t\t\tconst requestOptions = {\n\t\t\t\t\t\t\theaders: new Headers(request.headers),\n\t\t\t\t\t\t\tfollow: request.follow,\n\t\t\t\t\t\t\tcounter: request.counter + 1,\n\t\t\t\t\t\t\tagent: request.agent,\n\t\t\t\t\t\t\tcompress: request.compress,\n\t\t\t\t\t\t\tmethod: request.method,\n\t\t\t\t\t\t\tbody: clone(request),\n\t\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t\t\tsize: request.size,\n\t\t\t\t\t\t\treferrer: request.referrer,\n\t\t\t\t\t\t\treferrerPolicy: request.referrerPolicy\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// when forwarding sensitive headers like \"Authorization\",\n\t\t\t\t\t\t// \"WWW-Authenticate\", and \"Cookie\" to untrusted targets,\n\t\t\t\t\t\t// headers will be ignored when following a redirect to a domain\n\t\t\t\t\t\t// that is not a subdomain match or exact match of the initial domain.\n\t\t\t\t\t\t// For example, a redirect from \"foo.com\" to either \"foo.com\" or \"sub.foo.com\"\n\t\t\t\t\t\t// will forward the sensitive headers, but a redirect to \"bar.com\" will not.\n\t\t\t\t\t\t// headers will also be ignored when following a redirect to a domain using\n\t\t\t\t\t\t// a different protocol. For example, a redirect from \"https://foo.com\" to \"http://foo.com\"\n\t\t\t\t\t\t// will not forward the sensitive headers\n\t\t\t\t\t\tif (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) {\n\t\t\t\t\t\t\tfor (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) {\n\t\t\t\t\t\t\t\trequestOptions.headers.delete(name);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 9\n\t\t\t\t\t\tif (response_.statusCode !== 303 && request.body && options_.body instanceof Stream.Readable) {\n\t\t\t\t\t\t\treject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 11\n\t\t\t\t\t\tif (response_.statusCode === 303 || ((response_.statusCode === 301 || response_.statusCode === 302) && request.method === 'POST')) {\n\t\t\t\t\t\t\trequestOptions.method = 'GET';\n\t\t\t\t\t\t\trequestOptions.body = undefined;\n\t\t\t\t\t\t\trequestOptions.headers.delete('content-length');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 14\n\t\t\t\t\t\tconst responseReferrerPolicy = parseReferrerPolicyFromHeader(headers);\n\t\t\t\t\t\tif (responseReferrerPolicy) {\n\t\t\t\t\t\t\trequestOptions.referrerPolicy = responseReferrerPolicy;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 15\n\t\t\t\t\t\tresolve(fetch(new Request(locationURL, requestOptions)));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn reject(new TypeError(`Redirect option '${request.redirect}' is not a valid value of RequestRedirect`));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Prepare response\n\t\t\tif (signal) {\n\t\t\t\tresponse_.once('end', () => {\n\t\t\t\t\tsignal.removeEventListener('abort', abortAndFinalize);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlet body = pump(response_, new PassThrough(), error => {\n\t\t\t\tif (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\t\t\t});\n\t\t\t// see https://github.com/nodejs/node/pull/29376\n\t\t\t/* c8 ignore next 3 */\n\t\t\tif (process.version < 'v12.10') {\n\t\t\t\tresponse_.on('aborted', abortAndFinalize);\n\t\t\t}\n\n\t\t\tconst responseOptions = {\n\t\t\t\turl: request.url,\n\t\t\t\tstatus: response_.statusCode,\n\t\t\t\tstatusText: response_.statusMessage,\n\t\t\t\theaders,\n\t\t\t\tsize: request.size,\n\t\t\t\tcounter: request.counter,\n\t\t\t\thighWaterMark: request.highWaterMark\n\t\t\t};\n\n\t\t\t// HTTP-network fetch step 12.1.1.3\n\t\t\tconst codings = headers.get('Content-Encoding');\n\n\t\t\t// HTTP-network fetch step 12.1.1.4: handle content codings\n\n\t\t\t// in following scenarios we ignore compression support\n\t\t\t// 1. compression support is disabled\n\t\t\t// 2. HEAD request\n\t\t\t// 3. no Content-Encoding header\n\t\t\t// 4. no content response (204)\n\t\t\t// 5. content not modified response (304)\n\t\t\tif (!request.compress || request.method === 'HEAD' || codings === null || response_.statusCode === 204 || response_.statusCode === 304) {\n\t\t\t\tresponse = new Response(body, responseOptions);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For Node v6+\n\t\t\t// Be less strict when decoding compressed responses, since sometimes\n\t\t\t// servers send slightly invalid responses that are still accepted\n\t\t\t// by common browsers.\n\t\t\t// Always using Z_SYNC_FLUSH is what cURL does.\n\t\t\tconst zlibOptions = {\n\t\t\t\tflush: zlib.Z_SYNC_FLUSH,\n\t\t\t\tfinishFlush: zlib.Z_SYNC_FLUSH\n\t\t\t};\n\n\t\t\t// For gzip\n\t\t\tif (codings === 'gzip' || codings === 'x-gzip') {\n\t\t\t\tbody = pump(body, zlib.createGunzip(zlibOptions), error => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresponse = new Response(body, responseOptions);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For deflate\n\t\t\tif (codings === 'deflate' || codings === 'x-deflate') {\n\t\t\t\t// Handle the infamous raw deflate response from old servers\n\t\t\t\t// a hack for old IIS and Apache servers\n\t\t\t\tconst raw = pump(response_, new PassThrough(), error => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\traw.once('data', chunk => {\n\t\t\t\t\t// See http://stackoverflow.com/questions/37519828\n\t\t\t\t\tif ((chunk[0] & 0x0F) === 0x08) {\n\t\t\t\t\t\tbody = pump(body, zlib.createInflate(), error => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbody = pump(body, zlib.createInflateRaw(), error => {\n\t\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tresponse = new Response(body, responseOptions);\n\t\t\t\t\tresolve(response);\n\t\t\t\t});\n\t\t\t\traw.once('end', () => {\n\t\t\t\t\t// Some old IIS servers return zero-length OK deflate responses, so\n\t\t\t\t\t// 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903\n\t\t\t\t\tif (!response) {\n\t\t\t\t\t\tresponse = new Response(body, responseOptions);\n\t\t\t\t\t\tresolve(response);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For br\n\t\t\tif (codings === 'br') {\n\t\t\t\tbody = pump(body, zlib.createBrotliDecompress(), error => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresponse = new Response(body, responseOptions);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Otherwise, use response as-is\n\t\t\tresponse = new Response(body, responseOptions);\n\t\t\tresolve(response);\n\t\t});\n\n\t\t// eslint-disable-next-line promise/prefer-await-to-then\n\t\twriteToStream(request_, request).catch(reject);\n\t});\n}\n\nfunction fixResponseChunkedTransferBadEnding(request, errorCallback) {\n\tconst LAST_CHUNK = Buffer.from('0\\r\\n\\r\\n');\n\n\tlet isChunkedTransfer = false;\n\tlet properLastChunkReceived = false;\n\tlet previousChunk;\n\n\trequest.on('response', response => {\n\t\tconst {headers} = response;\n\t\tisChunkedTransfer = headers['transfer-encoding'] === 'chunked' && !headers['content-length'];\n\t});\n\n\trequest.on('socket', socket => {\n\t\tconst onSocketClose = () => {\n\t\t\tif (isChunkedTransfer && !properLastChunkReceived) {\n\t\t\t\tconst error = new Error('Premature close');\n\t\t\t\terror.code = 'ERR_STREAM_PREMATURE_CLOSE';\n\t\t\t\terrorCallback(error);\n\t\t\t}\n\t\t};\n\n\t\tconst onData = buf => {\n\t\t\tproperLastChunkReceived = Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0;\n\n\t\t\t// Sometimes final 0-length chunk and end of message code are in separate packets\n\t\t\tif (!properLastChunkReceived && previousChunk) {\n\t\t\t\tproperLastChunkReceived = (\n\t\t\t\t\tBuffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 &&\n\t\t\t\t\tBuffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpreviousChunk = buf;\n\t\t};\n\n\t\tsocket.prependListener('close', onSocketClose);\n\t\tsocket.on('data', onData);\n\n\t\trequest.on('close', () => {\n\t\t\tsocket.removeListener('close', onSocketClose);\n\t\t\tsocket.removeListener('data', onData);\n\t\t});\n\t});\n}\n","export interface MimeBuffer extends Buffer {\n\ttype: string;\n\ttypeFull: string;\n\tcharset: string;\n}\n\n/**\n * Returns a `Buffer` instance from the given data URI `uri`.\n *\n * @param {String} uri Data URI to turn into a Buffer instance\n * @returns {Buffer} Buffer instance from Data URI\n * @api public\n */\nexport function dataUriToBuffer(uri: string): MimeBuffer {\n\tif (!/^data:/i.test(uri)) {\n\t\tthrow new TypeError(\n\t\t\t'`uri` does not appear to be a Data URI (must begin with \"data:\")'\n\t\t);\n\t}\n\n\t// strip newlines\n\turi = uri.replace(/\\r?\\n/g, '');\n\n\t// split the URI up into the \"metadata\" and the \"data\" portions\n\tconst firstComma = uri.indexOf(',');\n\tif (firstComma === -1 || firstComma <= 4) {\n\t\tthrow new TypeError('malformed data: URI');\n\t}\n\n\t// remove the \"data:\" scheme and parse the metadata\n\tconst meta = uri.substring(5, firstComma).split(';');\n\n\tlet charset = '';\n\tlet base64 = false;\n\tconst type = meta[0] || 'text/plain';\n\tlet typeFull = type;\n\tfor (let i = 1; i < meta.length; i++) {\n\t\tif (meta[i] === 'base64') {\n\t\t\tbase64 = true;\n\t\t} else if(meta[i]) {\n\t\t\ttypeFull += `;${ meta[i]}`;\n\t\t\tif (meta[i].indexOf('charset=') === 0) {\n\t\t\t\tcharset = meta[i].substring(8);\n\t\t\t}\n\t\t}\n\t}\n\t// defaults to US-ASCII only if type is not provided\n\tif (!meta[0] && !charset.length) {\n\t\ttypeFull += ';charset=US-ASCII';\n\t\tcharset = 'US-ASCII';\n\t}\n\n\t// get the encoded data portion and decode URI-encoded chars\n\tconst encoding = base64 ? 'base64' : 'ascii';\n\tconst data = unescape(uri.substring(firstComma + 1));\n\tconst buffer = Buffer.from(data, encoding) as MimeBuffer;\n\n\t// set `.type` and `.typeFull` properties to MIME type\n\tbuffer.type = type;\n\tbuffer.typeFull = typeFull;\n\n\t// set the `.charset` property\n\tbuffer.charset = charset;\n\n\treturn buffer;\n}\n\nexport default dataUriToBuffer;\n","\n/**\n * Body.js\n *\n * Body interface provides common methods for Request and Response\n */\n\nimport Stream, {PassThrough} from 'node:stream';\nimport {types, deprecate, promisify} from 'node:util';\nimport {Buffer} from 'node:buffer';\n\nimport Blob from 'fetch-blob';\nimport {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';\n\nimport {FetchError} from './errors/fetch-error.js';\nimport {FetchBaseError} from './errors/base.js';\nimport {isBlob, isURLSearchParameters} from './utils/is.js';\n\nconst pipeline = promisify(Stream.pipeline);\nconst INTERNALS = Symbol('Body internals');\n\n/**\n * Body mixin\n *\n * Ref: https://fetch.spec.whatwg.org/#body\n *\n * @param Stream body Readable stream\n * @param Object opts Response options\n * @return Void\n */\nexport default class Body {\n\tconstructor(body, {\n\t\tsize = 0\n\t} = {}) {\n\t\tlet boundary = null;\n\n\t\tif (body === null) {\n\t\t\t// Body is undefined or null\n\t\t\tbody = null;\n\t\t} else if (isURLSearchParameters(body)) {\n\t\t\t// Body is a URLSearchParams\n\t\t\tbody = Buffer.from(body.toString());\n\t\t} else if (isBlob(body)) {\n\t\t\t// Body is blob\n\t\t} else if (Buffer.isBuffer(body)) {\n\t\t\t// Body is Buffer\n\t\t} else if (types.isAnyArrayBuffer(body)) {\n\t\t\t// Body is ArrayBuffer\n\t\t\tbody = Buffer.from(body);\n\t\t} else if (ArrayBuffer.isView(body)) {\n\t\t\t// Body is ArrayBufferView\n\t\t\tbody = Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n\t\t} else if (body instanceof Stream) {\n\t\t\t// Body is stream\n\t\t} else if (body instanceof FormData) {\n\t\t\t// Body is FormData\n\t\t\tbody = formDataToBlob(body);\n\t\t\tboundary = body.type.split('=')[1];\n\t\t} else {\n\t\t\t// None of the above\n\t\t\t// coerce to string then buffer\n\t\t\tbody = Buffer.from(String(body));\n\t\t}\n\n\t\tlet stream = body;\n\n\t\tif (Buffer.isBuffer(body)) {\n\t\t\tstream = Stream.Readable.from(body);\n\t\t} else if (isBlob(body)) {\n\t\t\tstream = Stream.Readable.from(body.stream());\n\t\t}\n\n\t\tthis[INTERNALS] = {\n\t\t\tbody,\n\t\t\tstream,\n\t\t\tboundary,\n\t\t\tdisturbed: false,\n\t\t\terror: null\n\t\t};\n\t\tthis.size = size;\n\n\t\tif (body instanceof Stream) {\n\t\t\tbody.on('error', error_ => {\n\t\t\t\tconst error = error_ instanceof FetchBaseError ?\n\t\t\t\t\terror_ :\n\t\t\t\t\tnew FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_);\n\t\t\t\tthis[INTERNALS].error = error;\n\t\t\t});\n\t\t}\n\t}\n\n\tget body() {\n\t\treturn this[INTERNALS].stream;\n\t}\n\n\tget bodyUsed() {\n\t\treturn this[INTERNALS].disturbed;\n\t}\n\n\t/**\n\t * Decode response as ArrayBuffer\n\t *\n\t * @return Promise\n\t */\n\tasync arrayBuffer() {\n\t\tconst {buffer, byteOffset, byteLength} = await consumeBody(this);\n\t\treturn buffer.slice(byteOffset, byteOffset + byteLength);\n\t}\n\n\tasync formData() {\n\t\tconst ct = this.headers.get('content-type');\n\n\t\tif (ct.startsWith('application/x-www-form-urlencoded')) {\n\t\t\tconst formData = new FormData();\n\t\t\tconst parameters = new URLSearchParams(await this.text());\n\n\t\t\tfor (const [name, value] of parameters) {\n\t\t\t\tformData.append(name, value);\n\t\t\t}\n\n\t\t\treturn formData;\n\t\t}\n\n\t\tconst {toFormData} = await import('./utils/multipart-parser.js');\n\t\treturn toFormData(this.body, ct);\n\t}\n\n\t/**\n\t * Return raw response as Blob\n\t *\n\t * @return Promise\n\t */\n\tasync blob() {\n\t\tconst ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS].body && this[INTERNALS].body.type) || '';\n\t\tconst buf = await this.arrayBuffer();\n\n\t\treturn new Blob([buf], {\n\t\t\ttype: ct\n\t\t});\n\t}\n\n\t/**\n\t * Decode response as json\n\t *\n\t * @return Promise\n\t */\n\tasync json() {\n\t\tconst text = await this.text();\n\t\treturn JSON.parse(text);\n\t}\n\n\t/**\n\t * Decode response as text\n\t *\n\t * @return Promise\n\t */\n\tasync text() {\n\t\tconst buffer = await consumeBody(this);\n\t\treturn new TextDecoder().decode(buffer);\n\t}\n\n\t/**\n\t * Decode response as buffer (non-spec api)\n\t *\n\t * @return Promise\n\t */\n\tbuffer() {\n\t\treturn consumeBody(this);\n\t}\n}\n\nBody.prototype.buffer = deprecate(Body.prototype.buffer, 'Please use \\'response.arrayBuffer()\\' instead of \\'response.buffer()\\'', 'node-fetch#buffer');\n\n// In browsers, all properties are enumerable.\nObject.defineProperties(Body.prototype, {\n\tbody: {enumerable: true},\n\tbodyUsed: {enumerable: true},\n\tarrayBuffer: {enumerable: true},\n\tblob: {enumerable: true},\n\tjson: {enumerable: true},\n\ttext: {enumerable: true},\n\tdata: {get: deprecate(() => {},\n\t\t'data doesn\\'t exist, use json(), text(), arrayBuffer(), or body instead',\n\t\t'https://github.com/node-fetch/node-fetch/issues/1000 (response)')}\n});\n\n/**\n * Consume and convert an entire Body to a Buffer.\n *\n * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body\n *\n * @return Promise\n */\nasync function consumeBody(data) {\n\tif (data[INTERNALS].disturbed) {\n\t\tthrow new TypeError(`body used already for: ${data.url}`);\n\t}\n\n\tdata[INTERNALS].disturbed = true;\n\n\tif (data[INTERNALS].error) {\n\t\tthrow data[INTERNALS].error;\n\t}\n\n\tconst {body} = data;\n\n\t// Body is null\n\tif (body === null) {\n\t\treturn Buffer.alloc(0);\n\t}\n\n\t/* c8 ignore next 3 */\n\tif (!(body instanceof Stream)) {\n\t\treturn Buffer.alloc(0);\n\t}\n\n\t// Body is stream\n\t// get ready to actually consume the body\n\tconst accum = [];\n\tlet accumBytes = 0;\n\n\ttry {\n\t\tfor await (const chunk of body) {\n\t\t\tif (data.size > 0 && accumBytes + chunk.length > data.size) {\n\t\t\t\tconst error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, 'max-size');\n\t\t\t\tbody.destroy(error);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\taccumBytes += chunk.length;\n\t\t\taccum.push(chunk);\n\t\t}\n\t} catch (error) {\n\t\tconst error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error);\n\t\tthrow error_;\n\t}\n\n\tif (body.readableEnded === true || body._readableState.ended === true) {\n\t\ttry {\n\t\t\tif (accum.every(c => typeof c === 'string')) {\n\t\t\t\treturn Buffer.from(accum.join(''));\n\t\t\t}\n\n\t\t\treturn Buffer.concat(accum, accumBytes);\n\t\t} catch (error) {\n\t\t\tthrow new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error);\n\t\t}\n\t} else {\n\t\tthrow new FetchError(`Premature close of server response while trying to fetch ${data.url}`);\n\t}\n}\n\n/**\n * Clone body given Res/Req instance\n *\n * @param Mixed instance Response or Request instance\n * @param String highWaterMark highWaterMark for both PassThrough body streams\n * @return Mixed\n */\nexport const clone = (instance, highWaterMark) => {\n\tlet p1;\n\tlet p2;\n\tlet {body} = instance[INTERNALS];\n\n\t// Don't allow cloning a used body\n\tif (instance.bodyUsed) {\n\t\tthrow new Error('cannot clone body after it is used');\n\t}\n\n\t// Check that body is a stream and not form-data object\n\t// note: we can't clone the form-data object without having it as a dependency\n\tif ((body instanceof Stream) && (typeof body.getBoundary !== 'function')) {\n\t\t// Tee instance body\n\t\tp1 = new PassThrough({highWaterMark});\n\t\tp2 = new PassThrough({highWaterMark});\n\t\tbody.pipe(p1);\n\t\tbody.pipe(p2);\n\t\t// Set instance body to teed body and return the other teed body\n\t\tinstance[INTERNALS].stream = p1;\n\t\tbody = p2;\n\t}\n\n\treturn body;\n};\n\nconst getNonSpecFormDataBoundary = deprecate(\n\tbody => body.getBoundary(),\n\t'form-data doesn\\'t follow the spec and requires special treatment. Use alternative package',\n\t'https://github.com/node-fetch/node-fetch/issues/1167'\n);\n\n/**\n * Performs the operation \"extract a `Content-Type` value from |object|\" as\n * specified in the specification:\n * https://fetch.spec.whatwg.org/#concept-bodyinit-extract\n *\n * This function assumes that instance.body is present.\n *\n * @param {any} body Any options.body input\n * @returns {string | null}\n */\nexport const extractContentType = (body, request) => {\n\t// Body is null or undefined\n\tif (body === null) {\n\t\treturn null;\n\t}\n\n\t// Body is string\n\tif (typeof body === 'string') {\n\t\treturn 'text/plain;charset=UTF-8';\n\t}\n\n\t// Body is a URLSearchParams\n\tif (isURLSearchParameters(body)) {\n\t\treturn 'application/x-www-form-urlencoded;charset=UTF-8';\n\t}\n\n\t// Body is blob\n\tif (isBlob(body)) {\n\t\treturn body.type || null;\n\t}\n\n\t// Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView)\n\tif (Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {\n\t\treturn null;\n\t}\n\n\tif (body instanceof FormData) {\n\t\treturn `multipart/form-data; boundary=${request[INTERNALS].boundary}`;\n\t}\n\n\t// Detect form data input from form-data module\n\tif (body && typeof body.getBoundary === 'function') {\n\t\treturn `multipart/form-data;boundary=${getNonSpecFormDataBoundary(body)}`;\n\t}\n\n\t// Body is stream - can't really do much about this\n\tif (body instanceof Stream) {\n\t\treturn null;\n\t}\n\n\t// Body constructor defaults other things to string\n\treturn 'text/plain;charset=UTF-8';\n};\n\n/**\n * The Fetch Standard treats this as if \"total bytes\" is a property on the body.\n * For us, we have to explicitly get it with a function.\n *\n * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes\n *\n * @param {any} obj.body Body object from the Body instance.\n * @returns {number | null}\n */\nexport const getTotalBytes = request => {\n\tconst {body} = request[INTERNALS];\n\n\t// Body is null or undefined\n\tif (body === null) {\n\t\treturn 0;\n\t}\n\n\t// Body is Blob\n\tif (isBlob(body)) {\n\t\treturn body.size;\n\t}\n\n\t// Body is Buffer\n\tif (Buffer.isBuffer(body)) {\n\t\treturn body.length;\n\t}\n\n\t// Detect form data input from form-data module\n\tif (body && typeof body.getLengthSync === 'function') {\n\t\treturn body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null;\n\t}\n\n\t// Body is stream\n\treturn null;\n};\n\n/**\n * Write a Body to a Node.js WritableStream (e.g. http.Request) object.\n *\n * @param {Stream.Writable} dest The stream to write to.\n * @param obj.body Body object from the Body instance.\n * @returns {Promise<void>}\n */\nexport const writeToStream = async (dest, {body}) => {\n\tif (body === null) {\n\t\t// Body is null\n\t\tdest.end();\n\t} else {\n\t\t// Body is stream\n\t\tawait pipeline(body, dest);\n\t}\n};\n","export class FetchBaseError extends Error {\n\tconstructor(message, type) {\n\t\tsuper(message);\n\t\t// Hide custom error implementation details from end-users\n\t\tError.captureStackTrace(this, this.constructor);\n\n\t\tthis.type = type;\n\t}\n\n\tget name() {\n\t\treturn this.constructor.name;\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn this.constructor.name;\n\t}\n}\n","\nimport {FetchBaseError} from './base.js';\n\n/**\n * @typedef {{ address?: string, code: string, dest?: string, errno: number, info?: object, message: string, path?: string, port?: number, syscall: string}} SystemError\n*/\n\n/**\n * FetchError interface for operational errors\n */\nexport class FetchError extends FetchBaseError {\n\t/**\n\t * @param {string} message - Error message for human\n\t * @param {string} [type] - Error type for machine\n\t * @param {SystemError} [systemError] - For Node.js system error\n\t */\n\tconstructor(message, type, systemError) {\n\t\tsuper(message, type);\n\t\t// When err.type is `system`, err.erroredSysCall contains system error and err.code contains system error code\n\t\tif (systemError) {\n\t\t\t// eslint-disable-next-line no-multi-assign\n\t\t\tthis.code = this.errno = systemError.code;\n\t\t\tthis.erroredSysCall = systemError.syscall;\n\t\t}\n\t}\n}\n","/**\n * Is.js\n *\n * Object type checks.\n */\n\nconst NAME = Symbol.toStringTag;\n\n/**\n * Check if `obj` is a URLSearchParams object\n * ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-307598143\n * @param {*} object - Object to check for\n * @return {boolean}\n */\nexport const isURLSearchParameters = object => {\n\treturn (\n\t\ttypeof object === 'object' &&\n\t\ttypeof object.append === 'function' &&\n\t\ttypeof object.delete === 'function' &&\n\t\ttypeof object.get === 'function' &&\n\t\ttypeof object.getAll === 'function' &&\n\t\ttypeof object.has === 'function' &&\n\t\ttypeof object.set === 'function' &&\n\t\ttypeof object.sort === 'function' &&\n\t\tobject[NAME] === 'URLSearchParams'\n\t);\n};\n\n/**\n * Check if `object` is a W3C `Blob` object (which `File` inherits from)\n * @param {*} object - Object to check for\n * @return {boolean}\n */\nexport const isBlob = object => {\n\treturn (\n\t\tobject &&\n\t\ttypeof object === 'object' &&\n\t\ttypeof object.arrayBuffer === 'function' &&\n\t\ttypeof object.type === 'string' &&\n\t\ttypeof object.stream === 'function' &&\n\t\ttypeof object.constructor === 'function' &&\n\t\t/^(Blob|File)$/.test(object[NAME])\n\t);\n};\n\n/**\n * Check if `obj` is an instance of AbortSignal.\n * @param {*} object - Object to check for\n * @return {boolean}\n */\nexport const isAbortSignal = object => {\n\treturn (\n\t\ttypeof object === 'object' && (\n\t\t\tobject[NAME] === 'AbortSignal' ||\n\t\t\tobject[NAME] === 'EventTarget'\n\t\t)\n\t);\n};\n\n/**\n * isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of\n * the parent domain.\n *\n * Both domains must already be in canonical form.\n * @param {string|URL} original\n * @param {string|URL} destination\n */\nexport const isDomainOrSubdomain = (destination, original) => {\n\tconst orig = new URL(original).hostname;\n\tconst dest = new URL(destination).hostname;\n\n\treturn orig === dest || orig.endsWith(`.${dest}`);\n};\n\n/**\n * isSameProtocol reports whether the two provided URLs use the same protocol.\n *\n * Both domains must already be in canonical form.\n * @param {string|URL} original\n * @param {string|URL} destination\n */\nexport const isSameProtocol = (destination, original) => {\n\tconst orig = new URL(original).protocol;\n\tconst dest = new URL(destination).protocol;\n\n\treturn orig === dest;\n};\n","/**\n * Headers.js\n *\n * Headers class offers convenient helpers\n */\n\nimport {types} from 'node:util';\nimport http from 'node:http';\n\n/* c8 ignore next 9 */\nconst validateHeaderName = typeof http.validateHeaderName === 'function' ?\n\thttp.validateHeaderName :\n\tname => {\n\t\tif (!/^[\\^`\\-\\w!#$%&'*+.|~]+$/.test(name)) {\n\t\t\tconst error = new TypeError(`Header name must be a valid HTTP token [${name}]`);\n\t\t\tObject.defineProperty(error, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'});\n\t\t\tthrow error;\n\t\t}\n\t};\n\n/* c8 ignore next 9 */\nconst validateHeaderValue = typeof http.validateHeaderValue === 'function' ?\n\thttp.validateHeaderValue :\n\t(name, value) => {\n\t\tif (/[^\\t\\u0020-\\u007E\\u0080-\\u00FF]/.test(value)) {\n\t\t\tconst error = new TypeError(`Invalid character in header content [\"${name}\"]`);\n\t\t\tObject.defineProperty(error, 'code', {value: 'ERR_INVALID_CHAR'});\n\t\t\tthrow error;\n\t\t}\n\t};\n\n/**\n * @typedef {Headers | Record<string, string> | Iterable<readonly [string, string]> | Iterable<Iterable<string>>} HeadersInit\n */\n\n/**\n * This Fetch API interface allows you to perform various actions on HTTP request and response headers.\n * These actions include retrieving, setting, adding to, and removing.\n * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.\n * You can add to this using methods like append() (see Examples.)\n * In all methods of this interface, header names are matched by case-insensitive byte sequence.\n *\n */\nexport default class Headers extends URLSearchParams {\n\t/**\n\t * Headers class\n\t *\n\t * @constructor\n\t * @param {HeadersInit} [init] - Response headers\n\t */\n\tconstructor(init) {\n\t\t// Validate and normalize init object in [name, value(s)][]\n\t\t/** @type {string[][]} */\n\t\tlet result = [];\n\t\tif (init instanceof Headers) {\n\t\t\tconst raw = init.raw();\n\t\t\tfor (const [name, values] of Object.entries(raw)) {\n\t\t\t\tresult.push(...values.map(value => [name, value]));\n\t\t\t}\n\t\t} else if (init == null) { // eslint-disable-line no-eq-null, eqeqeq\n\t\t\t// No op\n\t\t} else if (typeof init === 'object' && !types.isBoxedPrimitive(init)) {\n\t\t\tconst method = init[Symbol.iterator];\n\t\t\t// eslint-disable-next-line no-eq-null, eqeqeq\n\t\t\tif (method == null) {\n\t\t\t\t// Record<ByteString, ByteString>\n\t\t\t\tresult.push(...Object.entries(init));\n\t\t\t} else {\n\t\t\t\tif (typeof method !== 'function') {\n\t\t\t\t\tthrow new TypeError('Header pairs must be iterable');\n\t\t\t\t}\n\n\t\t\t\t// Sequence<sequence<ByteString>>\n\t\t\t\t// Note: per spec we have to first exhaust the lists then process them\n\t\t\t\tresult = [...init]\n\t\t\t\t\t.map(pair => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\ttypeof pair !== 'object' || types.isBoxedPrimitive(pair)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new TypeError('Each header pair must be an iterable object');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn [...pair];\n\t\t\t\t\t}).map(pair => {\n\t\t\t\t\t\tif (pair.length !== 2) {\n\t\t\t\t\t\t\tthrow new TypeError('Each header pair must be a name/value tuple');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn [...pair];\n\t\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new TypeError('Failed to construct \\'Headers\\': The provided value is not of type \\'(sequence<sequence<ByteString>> or record<ByteString, ByteString>)');\n\t\t}\n\n\t\t// Validate and lowercase\n\t\tresult =\n\t\t\tresult.length > 0 ?\n\t\t\t\tresult.map(([name, value]) => {\n\t\t\t\t\tvalidateHeaderName(name);\n\t\t\t\t\tvalidateHeaderValue(name, String(value));\n\t\t\t\t\treturn [String(name).toLowerCase(), String(value)];\n\t\t\t\t}) :\n\t\t\t\tundefined;\n\n\t\tsuper(result);\n\n\t\t// Returning a Proxy that will lowercase key names, validate parameters and sort keys\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn new Proxy(this, {\n\t\t\tget(target, p, receiver) {\n\t\t\t\tswitch (p) {\n\t\t\t\t\tcase 'append':\n\t\t\t\t\tcase 'set':\n\t\t\t\t\t\treturn (name, value) => {\n\t\t\t\t\t\t\tvalidateHeaderName(name);\n\t\t\t\t\t\t\tvalidateHeaderValue(name, String(value));\n\t\t\t\t\t\t\treturn URLSearchParams.prototype[p].call(\n\t\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\t\tString(name).toLowerCase(),\n\t\t\t\t\t\t\t\tString(value)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t};\n\n\t\t\t\t\tcase 'delete':\n\t\t\t\t\tcase 'has':\n\t\t\t\t\tcase 'getAll':\n\t\t\t\t\t\treturn name => {\n\t\t\t\t\t\t\tvalidateHeaderName(name);\n\t\t\t\t\t\t\treturn URLSearchParams.prototype[p].call(\n\t\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\t\tString(name).toLowerCase()\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t};\n\n\t\t\t\t\tcase 'keys':\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\ttarget.sort();\n\t\t\t\t\t\t\treturn new Set(URLSearchParams.prototype.keys.call(target)).keys();\n\t\t\t\t\t\t};\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn Reflect.get(target, p, receiver);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t/* c8 ignore next */\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn this.constructor.name;\n\t}\n\n\ttoString() {\n\t\treturn Object.prototype.toString.call(this);\n\t}\n\n\tget(name) {\n\t\tconst values = this.getAll(name);\n\t\tif (values.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet value = values.join(', ');\n\t\tif (/^content-encoding$/i.test(name)) {\n\t\t\tvalue = value.toLowerCase();\n\t\t}\n\n\t\treturn value;\n\t}\n\n\tforEach(callback, thisArg = undefined) {\n\t\tfor (const name of this.keys()) {\n\t\t\tReflect.apply(callback, thisArg, [this.get(name), name, this]);\n\t\t}\n\t}\n\n\t* values() {\n\t\tfor (const name of this.keys()) {\n\t\t\tyield this.get(name);\n\t\t}\n\t}\n\n\t/**\n\t * @type {() => IterableIterator<[string, string]>}\n\t */\n\t* entries() {\n\t\tfor (const name of this.keys()) {\n\t\t\tyield [name, this.get(name)];\n\t\t}\n\t}\n\n\t[Symbol.iterator]() {\n\t\treturn this.entries();\n\t}\n\n\t/**\n\t * Node-fetch non-spec method\n\t * returning all headers and their values as array\n\t * @returns {Record<string, string[]>}\n\t */\n\traw() {\n\t\treturn [...this.keys()].reduce((result, key) => {\n\t\t\tresult[key] = this.getAll(key);\n\t\t\treturn result;\n\t\t}, {});\n\t}\n\n\t/**\n\t * For better console.log(headers) and also to convert Headers into Node.js Request compatible format\n\t */\n\t[Symbol.for('nodejs.util.inspect.custom')]() {\n\t\treturn [...this.keys()].reduce((result, key) => {\n\t\t\tconst values = this.getAll(key);\n\t\t\t// Http.request() only supports string as Host header.\n\t\t\t// This hack makes specifying custom Host header possible.\n\t\t\tif (key === 'host') {\n\t\t\t\tresult[key] = values[0];\n\t\t\t} else {\n\t\t\t\tresult[key] = values.length > 1 ? values : values[0];\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}, {});\n\t}\n}\n\n/**\n * Re-shaping object for Web IDL tests\n * Only need to do it for overridden methods\n */\nObject.defineProperties(\n\tHeaders.prototype,\n\t['get', 'entries', 'forEach', 'values'].reduce((result, property) => {\n\t\tresult[property] = {enumerable: true};\n\t\treturn result;\n\t}, {})\n);\n\n/**\n * Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do\n * not conform to HTTP grammar productions.\n * @param {import('http').IncomingMessage['rawHeaders']} headers\n */\nexport function fromRawHeaders(headers = []) {\n\treturn new Headers(\n\t\theaders\n\t\t\t// Split into pairs\n\t\t\t.reduce((result, value, index, array) => {\n\t\t\t\tif (index % 2 === 0) {\n\t\t\t\t\tresult.push(array.slice(index, index + 2));\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t}, [])\n\t\t\t.filter(([name, value]) => {\n\t\t\t\ttry {\n\t\t\t\t\tvalidateHeaderName(name);\n\t\t\t\t\tvalidateHeaderValue(name, String(value));\n\t\t\t\t\treturn true;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t})\n\n\t);\n}\n","const redirectStatus = new Set([301, 302, 303, 307, 308]);\n\n/**\n * Redirect code matching\n *\n * @param {number} code - Status code\n * @return {boolean}\n */\nexport const isRedirect = code => {\n\treturn redirectStatus.has(code);\n};\n","/**\n * Response.js\n *\n * Response class provides content decoding\n */\n\nimport Headers from './headers.js';\nimport Body, {clone, extractContentType} from './body.js';\nimport {isRedirect} from './utils/is-redirect.js';\n\nconst INTERNALS = Symbol('Response internals');\n\n/**\n * Response class\n *\n * Ref: https://fetch.spec.whatwg.org/#response-class\n *\n * @param Stream body Readable stream\n * @param Object opts Response options\n * @return Void\n */\nexport default class Response extends Body {\n\tconstructor(body = null, options = {}) {\n\t\tsuper(body, options);\n\n\t\t// eslint-disable-next-line no-eq-null, eqeqeq, no-negated-condition\n\t\tconst status = options.status != null ? options.status : 200;\n\n\t\tconst headers = new Headers(options.headers);\n\n\t\tif (body !== null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(body, this);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tthis[INTERNALS] = {\n\t\t\ttype: 'default',\n\t\t\turl: options.url,\n\t\t\tstatus,\n\t\t\tstatusText: options.statusText || '',\n\t\t\theaders,\n\t\t\tcounter: options.counter,\n\t\t\thighWaterMark: options.highWaterMark\n\t\t};\n\t}\n\n\tget type() {\n\t\treturn this[INTERNALS].type;\n\t}\n\n\tget url() {\n\t\treturn this[INTERNALS].url || '';\n\t}\n\n\tget status() {\n\t\treturn this[INTERNALS].status;\n\t}\n\n\t/**\n\t * Convenience property representing if the request ended normally\n\t */\n\tget ok() {\n\t\treturn this[INTERNALS].status >= 200 && this[INTERNALS].status < 300;\n\t}\n\n\tget redirected() {\n\t\treturn this[INTERNALS].counter > 0;\n\t}\n\n\tget statusText() {\n\t\treturn this[INTERNALS].statusText;\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS].headers;\n\t}\n\n\tget highWaterMark() {\n\t\treturn this[INTERNALS].highWaterMark;\n\t}\n\n\t/**\n\t * Clone this response\n\t *\n\t * @return Response\n\t */\n\tclone() {\n\t\treturn new Response(clone(this, this.highWaterMark), {\n\t\t\ttype: this.type,\n\t\t\turl: this.url,\n\t\t\tstatus: this.status,\n\t\t\tstatusText: this.statusText,\n\t\t\theaders: this.headers,\n\t\t\tok: this.ok,\n\t\t\tredirected: this.redirected,\n\t\t\tsize: this.size,\n\t\t\thighWaterMark: this.highWaterMark\n\t\t});\n\t}\n\n\t/**\n\t * @param {string} url The URL that the new response is to originate from.\n\t * @param {number} status An optional status code for the response (e.g., 302.)\n\t * @returns {Response} A Response object.\n\t */\n\tstatic redirect(url, status = 302) {\n\t\tif (!isRedirect(status)) {\n\t\t\tthrow new RangeError('Failed to execute \"redirect\" on \"response\": Invalid status code');\n\t\t}\n\n\t\treturn new Response(null, {\n\t\t\theaders: {\n\t\t\t\tlocation: new URL(url).toString()\n\t\t\t},\n\t\t\tstatus\n\t\t});\n\t}\n\n\tstatic error() {\n\t\tconst response = new Response(null, {status: 0, statusText: ''});\n\t\tresponse[INTERNALS].type = 'error';\n\t\treturn response;\n\t}\n\n\tstatic json(data = undefined, init = {}) {\n\t\tconst body = JSON.stringify(data);\n\n\t\tif (body === undefined) {\n\t\t\tthrow new TypeError('data is not JSON serializable');\n\t\t}\n\n\t\tconst headers = new Headers(init && init.headers);\n\n\t\tif (!headers.has('content-type')) {\n\t\t\theaders.set('content-type', 'application/json');\n\t\t}\n\n\t\treturn new Response(body, {\n\t\t\t...init,\n\t\t\theaders\n\t\t});\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Response';\n\t}\n}\n\nObject.defineProperties(Response.prototype, {\n\ttype: {enumerable: true},\n\turl: {enumerable: true},\n\tstatus: {enumerable: true},\n\tok: {enumerable: true},\n\tredirected: {enumerable: true},\n\tstatusText: {enumerable: true},\n\theaders: {enumerable: true},\n\tclone: {enumerable: true}\n});\n","/**\n * Request.js\n *\n * Request class contains server only options\n *\n * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.\n */\n\nimport {format as formatUrl} from 'node:url';\nimport {deprecate} from 'node:util';\nimport Headers from './headers.js';\nimport Body, {clone, extractContentType, getTotalBytes} from './body.js';\nimport {isAbortSignal} from './utils/is.js';\nimport {getSearch} from './utils/get-search.js';\nimport {\n\tvalidateReferrerPolicy, determineRequestsReferrer, DEFAULT_REFERRER_POLICY\n} from './utils/referrer.js';\n\nconst INTERNALS = Symbol('Request internals');\n\n/**\n * Check if `obj` is an instance of Request.\n *\n * @param {*} object\n * @return {boolean}\n */\nconst isRequest = object => {\n\treturn (\n\t\ttypeof object === 'object' &&\n\t\ttypeof object[INTERNALS] === 'object'\n\t);\n};\n\nconst doBadDataWarn = deprecate(() => {},\n\t'.data is not a valid RequestInit property, use .body instead',\n\t'https://github.com/node-fetch/node-fetch/issues/1000 (request)');\n\n/**\n * Request class\n *\n * Ref: https://fetch.spec.whatwg.org/#request-class\n *\n * @param Mixed input Url or Request instance\n * @param Object init Custom options\n * @return Void\n */\nexport default class Request extends Body {\n\tconstructor(input, init = {}) {\n\t\tlet parsedURL;\n\n\t\t// Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245)\n\t\tif (isRequest(input)) {\n\t\t\tparsedURL = new URL(input.url);\n\t\t} else {\n\t\t\tparsedURL = new URL(input);\n\t\t\tinput = {};\n\t\t}\n\n\t\tif (parsedURL.username !== '' || parsedURL.password !== '') {\n\t\t\tthrow new TypeError(`${parsedURL} is an url with embedded credentials.`);\n\t\t}\n\n\t\tlet method = init.method || input.method || 'GET';\n\t\tif (/^(delete|get|head|options|post|put)$/i.test(method)) {\n\t\t\tmethod = method.toUpperCase();\n\t\t}\n\n\t\tif (!isRequest(init) && 'data' in init) {\n\t\t\tdoBadDataWarn();\n\t\t}\n\n\t\t// eslint-disable-next-line no-eq-null, eqeqeq\n\t\tif ((init.body != null || (isRequest(input) && input.body !== null)) &&\n\t\t\t(method === 'GET' || method === 'HEAD')) {\n\t\t\tthrow new TypeError('Request with GET/HEAD method cannot have body');\n\t\t}\n\n\t\tconst inputBody = init.body ?\n\t\t\tinit.body :\n\t\t\t(isRequest(input) && input.body !== null ?\n\t\t\t\tclone(input) :\n\t\t\t\tnull);\n\n\t\tsuper(inputBody, {\n\t\t\tsize: init.size || input.size || 0\n\t\t});\n\n\t\tconst headers = new Headers(init.headers || input.headers || {});\n\n\t\tif (inputBody !== null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(inputBody, this);\n\t\t\tif (contentType) {\n\t\t\t\theaders.set('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tlet signal = isRequest(input) ?\n\t\t\tinput.signal :\n\t\t\tnull;\n\t\tif ('signal' in init) {\n\t\t\tsignal = init.signal;\n\t\t}\n\n\t\t// eslint-disable-next-line no-eq-null, eqeqeq\n\t\tif (signal != null && !isAbortSignal(signal)) {\n\t\t\tthrow new TypeError('Expected signal to be an instanceof AbortSignal or EventTarget');\n\t\t}\n\n\t\t// §5.4, Request constructor steps, step 15.1\n\t\t// eslint-disable-next-line no-eq-null, eqeqeq\n\t\tlet referrer = init.referrer == null ? input.referrer : init.referrer;\n\t\tif (referrer === '') {\n\t\t\t// §5.4, Request constructor steps, step 15.2\n\t\t\treferrer = 'no-referrer';\n\t\t} else if (referrer) {\n\t\t\t// §5.4, Request constructor steps, step 15.3.1, 15.3.2\n\t\t\tconst parsedReferrer = new URL(referrer);\n\t\t\t// §5.4, Request constructor steps, step 15.3.3, 15.3.4\n\t\t\treferrer = /^about:(\\/\\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer;\n\t\t} else {\n\t\t\treferrer = undefined;\n\t\t}\n\n\t\tthis[INTERNALS] = {\n\t\t\tmethod,\n\t\t\tredirect: init.redirect || input.redirect || 'follow',\n\t\t\theaders,\n\t\t\tparsedURL,\n\t\t\tsignal,\n\t\t\treferrer\n\t\t};\n\n\t\t// Node-fetch-only options\n\t\tthis.follow = init.follow === undefined ? (input.follow === undefined ? 20 : input.follow) : init.follow;\n\t\tthis.compress = init.compress === undefined ? (input.compress === undefined ? true : input.compress) : init.compress;\n\t\tthis.counter = init.counter || input.counter || 0;\n\t\tthis.agent = init.agent || input.agent;\n\t\tthis.highWaterMark = init.highWaterMark || input.highWaterMark || 16384;\n\t\tthis.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false;\n\n\t\t// §5.4, Request constructor steps, step 16.\n\t\t// Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy\n\t\tthis.referrerPolicy = init.referrerPolicy || input.referrerPolicy || '';\n\t}\n\n\t/** @returns {string} */\n\tget method() {\n\t\treturn this[INTERNALS].method;\n\t}\n\n\t/** @returns {string} */\n\tget url() {\n\t\treturn formatUrl(this[INTERNALS].parsedURL);\n\t}\n\n\t/** @returns {Headers} */\n\tget headers() {\n\t\treturn this[INTERNALS].headers;\n\t}\n\n\tget redirect() {\n\t\treturn this[INTERNALS].redirect;\n\t}\n\n\t/** @returns {AbortSignal} */\n\tget signal() {\n\t\treturn this[INTERNALS].signal;\n\t}\n\n\t// https://fetch.spec.whatwg.org/#dom-request-referrer\n\tget referrer() {\n\t\tif (this[INTERNALS].referrer === 'no-referrer') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (this[INTERNALS].referrer === 'client') {\n\t\t\treturn 'about:client';\n\t\t}\n\n\t\tif (this[INTERNALS].referrer) {\n\t\t\treturn this[INTERNALS].referrer.toString();\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tget referrerPolicy() {\n\t\treturn this[INTERNALS].referrerPolicy;\n\t}\n\n\tset referrerPolicy(referrerPolicy) {\n\t\tthis[INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy);\n\t}\n\n\t/**\n\t * Clone this request\n\t *\n\t * @return Request\n\t */\n\tclone() {\n\t\treturn new Request(this);\n\t}\n\n\tget [Symbol.toStringTag]() {\n\t\treturn 'Request';\n\t}\n}\n\nObject.defineProperties(Request.prototype, {\n\tmethod: {enumerable: true},\n\turl: {enumerable: true},\n\theaders: {enumerable: true},\n\tredirect: {enumerable: true},\n\tclone: {enumerable: true},\n\tsignal: {enumerable: true},\n\treferrer: {enumerable: true},\n\treferrerPolicy: {enumerable: true}\n});\n\n/**\n * Convert a Request to Node.js http request options.\n *\n * @param {Request} request - A Request instance\n * @return The options object to be passed to http.request\n */\nexport const getNodeRequestOptions = request => {\n\tconst {parsedURL} = request[INTERNALS];\n\tconst headers = new Headers(request[INTERNALS].headers);\n\n\t// Fetch step 1.3\n\tif (!headers.has('Accept')) {\n\t\theaders.set('Accept', '*/*');\n\t}\n\n\t// HTTP-network-or-cache fetch steps 2.4-2.7\n\tlet contentLengthValue = null;\n\tif (request.body === null && /^(post|put)$/i.test(request.method)) {\n\t\tcontentLengthValue = '0';\n\t}\n\n\tif (request.body !== null) {\n\t\tconst totalBytes = getTotalBytes(request);\n\t\t// Set Content-Length if totalBytes is a number (that is not NaN)\n\t\tif (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) {\n\t\t\tcontentLengthValue = String(totalBytes);\n\t\t}\n\t}\n\n\tif (contentLengthValue) {\n\t\theaders.set('Content-Length', contentLengthValue);\n\t}\n\n\t// 4.1. Main fetch, step 2.6\n\t// > If request's referrer policy is the empty string, then set request's referrer policy to the\n\t// > default referrer policy.\n\tif (request.referrerPolicy === '') {\n\t\trequest.referrerPolicy = DEFAULT_REFERRER_POLICY;\n\t}\n\n\t// 4.1. Main fetch, step 2.7\n\t// > If request's referrer is not \"no-referrer\", set request's referrer to the result of invoking\n\t// > determine request's referrer.\n\tif (request.referrer && request.referrer !== 'no-referrer') {\n\t\trequest[INTERNALS].referrer = determineRequestsReferrer(request);\n\t} else {\n\t\trequest[INTERNALS].referrer = 'no-referrer';\n\t}\n\n\t// 4.5. HTTP-network-or-cache fetch, step 6.9\n\t// > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized\n\t// > and isomorphic encoded, to httpRequest's header list.\n\tif (request[INTERNALS].referrer instanceof URL) {\n\t\theaders.set('Referer', request.referrer);\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.11\n\tif (!headers.has('User-Agent')) {\n\t\theaders.set('User-Agent', 'node-fetch');\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.15\n\tif (request.compress && !headers.has('Accept-Encoding')) {\n\t\theaders.set('Accept-Encoding', 'gzip, deflate, br');\n\t}\n\n\tlet {agent} = request;\n\tif (typeof agent === 'function') {\n\t\tagent = agent(parsedURL);\n\t}\n\n\t// HTTP-network fetch step 4.2\n\t// chunked encoding is handled by Node.js\n\n\tconst search = getSearch(parsedURL);\n\n\t// Pass the full URL directly to request(), but overwrite the following\n\t// options:\n\tconst options = {\n\t\t// Overwrite search to retain trailing ? (issue #776)\n\t\tpath: parsedURL.pathname + search,\n\t\t// The following options are not expressed in the URL\n\t\tmethod: request.method,\n\t\theaders: headers[Symbol.for('nodejs.util.inspect.custom')](),\n\t\tinsecureHTTPParser: request.insecureHTTPParser,\n\t\tagent\n\t};\n\n\treturn {\n\t\t/** @type {URL} */\n\t\tparsedURL,\n\t\toptions\n\t};\n};\n","export const getSearch = parsedURL => {\n\tif (parsedURL.search) {\n\t\treturn parsedURL.search;\n\t}\n\n\tconst lastOffset = parsedURL.href.length - 1;\n\tconst hash = parsedURL.hash || (parsedURL.href[lastOffset] === '#' ? '#' : '');\n\treturn parsedURL.href[lastOffset - hash.length] === '?' ? '?' : '';\n};\n","import {isIP} from 'node:net';\n\n/**\n * @external URL\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/URL|URL}\n */\n\n/**\n * @module utils/referrer\n * @private\n */\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#strip-url|Referrer Policy §8.4. Strip url for use as a referrer}\n * @param {string} URL\n * @param {boolean} [originOnly=false]\n */\nexport function stripURLForUseAsAReferrer(url, originOnly = false) {\n\t// 1. If url is null, return no referrer.\n\tif (url == null) { // eslint-disable-line no-eq-null, eqeqeq\n\t\treturn 'no-referrer';\n\t}\n\n\turl = new URL(url);\n\n\t// 2. If url's scheme is a local scheme, then return no referrer.\n\tif (/^(about|blob|data):$/.test(url.protocol)) {\n\t\treturn 'no-referrer';\n\t}\n\n\t// 3. Set url's username to the empty string.\n\turl.username = '';\n\n\t// 4. Set url's password to null.\n\t// Note: `null` appears to be a mistake as this actually results in the password being `\"null\"`.\n\turl.password = '';\n\n\t// 5. Set url's fragment to null.\n\t// Note: `null` appears to be a mistake as this actually results in the fragment being `\"#null\"`.\n\turl.hash = '';\n\n\t// 6. If the origin-only flag is true, then:\n\tif (originOnly) {\n\t\t// 6.1. Set url's path to null.\n\t\t// Note: `null` appears to be a mistake as this actually results in the path being `\"/null\"`.\n\t\turl.pathname = '';\n\n\t\t// 6.2. Set url's query to null.\n\t\t// Note: `null` appears to be a mistake as this actually results in the query being `\"?null\"`.\n\t\turl.search = '';\n\t}\n\n\t// 7. Return url.\n\treturn url;\n}\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#enumdef-referrerpolicy|enum ReferrerPolicy}\n */\nexport const ReferrerPolicy = new Set([\n\t'',\n\t'no-referrer',\n\t'no-referrer-when-downgrade',\n\t'same-origin',\n\t'origin',\n\t'strict-origin',\n\t'origin-when-cross-origin',\n\t'strict-origin-when-cross-origin',\n\t'unsafe-url'\n]);\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy|default referrer policy}\n */\nexport const DEFAULT_REFERRER_POLICY = 'strict-origin-when-cross-origin';\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#referrer-policies|Referrer Policy §3. Referrer Policies}\n * @param {string} referrerPolicy\n * @returns {string} referrerPolicy\n */\nexport function validateReferrerPolicy(referrerPolicy) {\n\tif (!ReferrerPolicy.has(referrerPolicy)) {\n\t\tthrow new TypeError(`Invalid referrerPolicy: ${referrerPolicy}`);\n\t}\n\n\treturn referrerPolicy;\n}\n\n/**\n * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy|Referrer Policy §3.2. Is origin potentially trustworthy?}\n * @param {external:URL} url\n * @returns `true`: \"Potentially Trustworthy\", `false`: \"Not Trustworthy\"\n */\nexport function isOriginPotentiallyTrustworthy(url) {\n\t// 1. If origin is an opaque origin, return \"Not Trustworthy\".\n\t// Not applicable\n\n\t// 2. Assert: origin is a tuple origin.\n\t// Not for implementations\n\n\t// 3. If origin's scheme is either \"https\" or \"wss\", return \"Potentially Trustworthy\".\n\tif (/^(http|ws)s:$/.test(url.protocol)) {\n\t\treturn true;\n\t}\n\n\t// 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return \"Potentially Trustworthy\".\n\tconst hostIp = url.host.replace(/(^\\[)|(]$)/g, '');\n\tconst hostIPVersion = isIP(hostIp);\n\n\tif (hostIPVersion === 4 && /^127\\./.test(hostIp)) {\n\t\treturn true;\n\t}\n\n\tif (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) {\n\t\treturn true;\n\t}\n\n\t// 5. If origin's host component is \"localhost\" or falls within \".localhost\", and the user agent conforms to the name resolution rules in [let-localhost-be-localhost], return \"Potentially Trustworthy\".\n\t// We are returning FALSE here because we cannot ensure conformance to\n\t// let-localhost-be-loalhost (https://tools.ietf.org/html/draft-west-let-localhost-be-localhost)\n\tif (url.host === 'localhost' || url.host.endsWith('.localhost')) {\n\t\treturn false;\n\t}\n\n\t// 6. If origin's scheme component is file, return \"Potentially Trustworthy\".\n\tif (url.protocol === 'file:') {\n\t\treturn true;\n\t}\n\n\t// 7. If origin's scheme component is one which the user agent considers to be authenticated, return \"Potentially Trustworthy\".\n\t// Not supported\n\n\t// 8. If origin has been configured as a trustworthy origin, return \"Potentially Trustworthy\".\n\t// Not supported\n\n\t// 9. Return \"Not Trustworthy\".\n\treturn false;\n}\n\n/**\n * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-url-trustworthy|Referrer Policy §3.3. Is url potentially trustworthy?}\n * @param {external:URL} url\n * @returns `true`: \"Potentially Trustworthy\", `false`: \"Not Trustworthy\"\n */\nexport function isUrlPotentiallyTrustworthy(url) {\n\t// 1. If url is \"about:blank\" or \"about:srcdoc\", return \"Potentially Trustworthy\".\n\tif (/^about:(blank|srcdoc)$/.test(url)) {\n\t\treturn true;\n\t}\n\n\t// 2. If url's scheme is \"data\", return \"Potentially Trustworthy\".\n\tif (url.protocol === 'data:') {\n\t\treturn true;\n\t}\n\n\t// Note: The origin of blob: and filesystem: URLs is the origin of the context in which they were\n\t// created. Therefore, blobs created in a trustworthy origin will themselves be potentially\n\t// trustworthy.\n\tif (/^(blob|filesystem):$/.test(url.protocol)) {\n\t\treturn true;\n\t}\n\n\t// 3. Return the result of executing §3.2 Is origin potentially trustworthy? on url's origin.\n\treturn isOriginPotentiallyTrustworthy(url);\n}\n\n/**\n * Modifies the referrerURL to enforce any extra security policy considerations.\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7\n * @callback module:utils/referrer~referrerURLCallback\n * @param {external:URL} referrerURL\n * @returns {external:URL} modified referrerURL\n */\n\n/**\n * Modifies the referrerOrigin to enforce any extra security policy considerations.\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7\n * @callback module:utils/referrer~referrerOriginCallback\n * @param {external:URL} referrerOrigin\n * @returns {external:URL} modified referrerOrigin\n */\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}\n * @param {Request} request\n * @param {object} o\n * @param {module:utils/referrer~referrerURLCallback} o.referrerURLCallback\n * @param {module:utils/referrer~referrerOriginCallback} o.referrerOriginCallback\n * @returns {external:URL} Request's referrer\n */\nexport function determineRequestsReferrer(request, {referrerURLCallback, referrerOriginCallback} = {}) {\n\t// There are 2 notes in the specification about invalid pre-conditions. We return null, here, for\n\t// these cases:\n\t// > Note: If request's referrer is \"no-referrer\", Fetch will not call into this algorithm.\n\t// > Note: If request's referrer policy is the empty string, Fetch will not call into this\n\t// > algorithm.\n\tif (request.referrer === 'no-referrer' || request.referrerPolicy === '') {\n\t\treturn null;\n\t}\n\n\t// 1. Let policy be request's associated referrer policy.\n\tconst policy = request.referrerPolicy;\n\n\t// 2. Let environment be request's client.\n\t// not applicable to node.js\n\n\t// 3. Switch on request's referrer:\n\tif (request.referrer === 'about:client') {\n\t\treturn 'no-referrer';\n\t}\n\n\t// \"a URL\": Let referrerSource be request's referrer.\n\tconst referrerSource = request.referrer;\n\n\t// 4. Let request's referrerURL be the result of stripping referrerSource for use as a referrer.\n\tlet referrerURL = stripURLForUseAsAReferrer(referrerSource);\n\n\t// 5. Let referrerOrigin be the result of stripping referrerSource for use as a referrer, with the\n\t// origin-only flag set to true.\n\tlet referrerOrigin = stripURLForUseAsAReferrer(referrerSource, true);\n\n\t// 6. If the result of serializing referrerURL is a string whose length is greater than 4096, set\n\t// referrerURL to referrerOrigin.\n\tif (referrerURL.toString().length > 4096) {\n\t\treferrerURL = referrerOrigin;\n\t}\n\n\t// 7. The user agent MAY alter referrerURL or referrerOrigin at this point to enforce arbitrary\n\t// policy considerations in the interests of minimizing data leakage. For example, the user\n\t// agent could strip the URL down to an origin, modify its host, replace it with an empty\n\t// string, etc.\n\tif (referrerURLCallback) {\n\t\treferrerURL = referrerURLCallback(referrerURL);\n\t}\n\n\tif (referrerOriginCallback) {\n\t\treferrerOrigin = referrerOriginCallback(referrerOrigin);\n\t}\n\n\t// 8.Execute the statements corresponding to the value of policy:\n\tconst currentURL = new URL(request.url);\n\n\tswitch (policy) {\n\t\tcase 'no-referrer':\n\t\t\treturn 'no-referrer';\n\n\t\tcase 'origin':\n\t\t\treturn referrerOrigin;\n\n\t\tcase 'unsafe-url':\n\t\t\treturn referrerURL;\n\n\t\tcase 'strict-origin':\n\t\t\t// 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a\n\t\t\t// potentially trustworthy URL, then return no referrer.\n\t\t\tif (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {\n\t\t\t\treturn 'no-referrer';\n\t\t\t}\n\n\t\t\t// 2. Return referrerOrigin.\n\t\t\treturn referrerOrigin.toString();\n\n\t\tcase 'strict-origin-when-cross-origin':\n\t\t\t// 1. If the origin of referrerURL and the origin of request's current URL are the same, then\n\t\t\t// return referrerURL.\n\t\t\tif (referrerURL.origin === currentURL.origin) {\n\t\t\t\treturn referrerURL;\n\t\t\t}\n\n\t\t\t// 2. If referrerURL is a potentially trustworthy URL and request's current URL is not a\n\t\t\t// potentially trustworthy URL, then return no referrer.\n\t\t\tif (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {\n\t\t\t\treturn 'no-referrer';\n\t\t\t}\n\n\t\t\t// 3. Return referrerOrigin.\n\t\t\treturn referrerOrigin;\n\n\t\tcase 'same-origin':\n\t\t\t// 1. If the origin of referrerURL and the origin of request's current URL are the same, then\n\t\t\t// return referrerURL.\n\t\t\tif (referrerURL.origin === currentURL.origin) {\n\t\t\t\treturn referrerURL;\n\t\t\t}\n\n\t\t\t// 2. Return no referrer.\n\t\t\treturn 'no-referrer';\n\n\t\tcase 'origin-when-cross-origin':\n\t\t\t// 1. If the origin of referrerURL and the origin of request's current URL are the same, then\n\t\t\t// return referrerURL.\n\t\t\tif (referrerURL.origin === currentURL.origin) {\n\t\t\t\treturn referrerURL;\n\t\t\t}\n\n\t\t\t// Return referrerOrigin.\n\t\t\treturn referrerOrigin;\n\n\t\tcase 'no-referrer-when-downgrade':\n\t\t\t// 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a\n\t\t\t// potentially trustworthy URL, then return no referrer.\n\t\t\tif (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {\n\t\t\t\treturn 'no-referrer';\n\t\t\t}\n\n\t\t\t// 2. Return referrerURL.\n\t\t\treturn referrerURL;\n\n\t\tdefault:\n\t\t\tthrow new TypeError(`Invalid referrerPolicy: ${policy}`);\n\t}\n}\n\n/**\n * @see {@link https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header|Referrer Policy §8.1. Parse a referrer policy from a Referrer-Policy header}\n * @param {Headers} headers Response headers\n * @returns {string} policy\n */\nexport function parseReferrerPolicyFromHeader(headers) {\n\t// 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy`\n\t// and response’s header list.\n\tconst policyTokens = (headers.get('referrer-policy') || '').split(/[,\\s]+/);\n\n\t// 2. Let policy be the empty string.\n\tlet policy = '';\n\n\t// 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty\n\t// string, then set policy to token.\n\t// Note: This algorithm loops over multiple policy values to allow deployment of new policy\n\t// values with fallbacks for older user agents, as described in § 11.1 Unknown Policy Values.\n\tfor (const token of policyTokens) {\n\t\tif (token && ReferrerPolicy.has(token)) {\n\t\t\tpolicy = token;\n\t\t}\n\t}\n\n\t// 4. Return policy.\n\treturn policy;\n}\n","import {FetchBaseError} from './base.js';\n\n/**\n * AbortError interface for cancelled requests\n */\nexport class AbortError extends FetchBaseError {\n\tconstructor(message, type = 'aborted') {\n\t\tsuper(message, type);\n\t}\n}\n","import { exec } from \"node:child_process\";\nimport os from \"node:os\";\nimport { promisify } from \"node:util\";\nimport { logger } from \"@elizaos/core\";\n\nconst execAsync = promisify(exec);\n\n/**\n * Represents the configuration of a system GPU.\n * @typedef {Object} SystemGPU\n * @property {string} name - The name of the GPU.\n * @property {number} [memory] - The memory size of the GPU. (Optional)\n * @property {\"cuda\" | \"metal\" | \"directml\" | \"none\"} type - The type of GPU.\n * @property {string} [version] - The version of the GPU. (Optional)\n * @property {boolean} [isAppleSilicon] - Indicates if the GPU is Apple Silicon. (Optional)\n */\nexport interface SystemGPU {\n\tname: string;\n\tmemory?: number;\n\ttype: \"cuda\" | \"metal\" | \"directml\" | \"none\";\n\tversion?: string;\n\tisAppleSilicon?: boolean;\n}\n\n/**\n * Interface representing the system CPU information.\n * @typedef {Object} SystemCPU\n * @property {string} model - The model of the CPU.\n * @property {number} cores - The number of cores in the CPU.\n * @property {number} speed - The speed of the CPU.\n * @property {string} architecture - The architecture of the CPU.\n * @property {Object} memory - Object containing memory information.\n * @property {number} memory.total - The total memory available.\n * @property {number} memory.free - The free memory available.\n */\nexport interface SystemCPU {\n\tmodel: string;\n\tcores: number;\n\tspeed: number;\n\tarchitecture: string;\n\tmemory: {\n\t\ttotal: number;\n\t\tfree: number;\n\t};\n}\n\n/**\n * Interface representing the capabilities of a system.\n *\n * @typedef {Object} SystemCapabilities\n * @property {NodeJS.Platform} platform - The platform of the system.\n * @property {SystemCPU} cpu - The CPU information of the system.\n * @property {SystemGPU | null} gpu - The GPU information of the system, can be null if no GPU is present.\n * @property {\"small\" | \"medium\" | \"large\"} recommendedModelSize - The recommended model size for the system.\n * @property {Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">} supportedBackends - An array of supported backends for the system.\n */\nexport interface SystemCapabilities {\n\tplatform: NodeJS.Platform;\n\tcpu: SystemCPU;\n\tgpu: SystemGPU | null;\n\trecommendedModelSize: \"small\" | \"medium\" | \"large\";\n\tsupportedBackends: Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">;\n}\n\n/**\n * Class representing a Platform Manager.\n *\n * @class\n */\n\nexport class PlatformManager {\n\tprivate static instance: PlatformManager;\n\tprivate capabilities: SystemCapabilities | null = null;\n\n\t/**\n\t * Private constructor method.\n\t */\n\tprivate constructor() {}\n\n\t/**\n\t * Get the singleton instance of the PlatformManager class\n\t * @returns {PlatformManager} The instance of PlatformManager\n\t */\n\tstatic getInstance(): PlatformManager {\n\t\tif (!PlatformManager.instance) {\n\t\t\tPlatformManager.instance = new PlatformManager();\n\t\t}\n\t\treturn PlatformManager.instance;\n\t}\n\n\t/**\n\t * Asynchronous method to initialize platform detection.\n\t *\n\t * @returns {Promise<void>} Promise that resolves once platform detection is completed.\n\t */\n\tasync initialize(): Promise<void> {\n\t\ttry {\n\t\t\tlogger.info(\"Initializing platform detection...\");\n\t\t\tthis.capabilities = await this.detectSystemCapabilities();\n\t\t\t// logger.info(\"Platform detection completed\", {\n\t\t\t// platform: this.capabilities.platform,\n\t\t\t// gpu: this.capabilities.gpu?.type || \"none\",\n\t\t\t// recommendedModel: this.capabilities.recommendedModelSize,\n\t\t\t// });\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Platform detection failed\", { error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Detects the system capabilities including platform, CPU information, GPU information,\n\t * supported backends, and recommended model size.\n\t *\n\t * @returns {Promise<SystemCapabilities>} Details of the system capabilities including platform, CPU info, GPU info,\n\t * recommended model size, and supported backends.\n\t */\n\tprivate async detectSystemCapabilities(): Promise<SystemCapabilities> {\n\t\tconst platform = process.platform;\n\t\tconst cpuInfo = this.getCPUInfo();\n\t\tconst gpu = await this.detectGPU();\n\t\tconst supportedBackends = await this.getSupportedBackends(platform, gpu);\n\t\tconst recommendedModelSize = this.getRecommendedModelSize(cpuInfo, gpu);\n\n\t\treturn {\n\t\t\tplatform,\n\t\t\tcpu: cpuInfo,\n\t\t\tgpu,\n\t\t\trecommendedModelSize,\n\t\t\tsupportedBackends,\n\t\t};\n\t}\n\n\t/**\n\t * Returns information about the CPU and memory of the system.\n\t * @returns {SystemCPU} The CPU information including model, number of cores, speed, architecture, and memory details.\n\t */\n\tprivate getCPUInfo(): SystemCPU {\n\t\tconst cpus = os.cpus();\n\t\tconst totalMemory = os.totalmem();\n\t\tconst freeMemory = os.freemem();\n\n\t\treturn {\n\t\t\tmodel: cpus[0].model,\n\t\t\tcores: cpus.length,\n\t\t\tspeed: cpus[0].speed,\n\t\t\tarchitecture: process.arch,\n\t\t\tmemory: {\n\t\t\t\ttotal: totalMemory,\n\t\t\t\tfree: freeMemory,\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Asynchronously detects the GPU information based on the current platform.\n\t * @returns A promise that resolves with the GPU information if detection is successful, otherwise null.\n\t */\n\tprivate async detectGPU(): Promise<SystemGPU | null> {\n\t\tconst platform = process.platform;\n\n\t\ttry {\n\t\t\tswitch (platform) {\n\t\t\t\tcase \"darwin\":\n\t\t\t\t\treturn await this.detectMacGPU();\n\t\t\t\tcase \"win32\":\n\t\t\t\t\treturn await this.detectWindowsGPU();\n\t\t\t\tcase \"linux\":\n\t\t\t\t\treturn await this.detectLinuxGPU();\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.error(\"GPU detection failed\", { error });\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously detects the GPU of a Mac system.\n\t * @returns {Promise<SystemGPU>} A promise that resolves to an object representing the detected GPU.\n\t */\n\tprivate async detectMacGPU(): Promise<SystemGPU> {\n\t\ttry {\n\t\t\tconst { stdout } = await execAsync(\"sysctl -n machdep.cpu.brand_string\");\n\t\t\tconst isAppleSilicon = stdout.toLowerCase().includes(\"apple\");\n\n\t\t\tif (isAppleSilicon) {\n\t\t\t\treturn {\n\t\t\t\t\tname: \"Apple Silicon\",\n\t\t\t\t\ttype: \"metal\",\n\t\t\t\t\tisAppleSilicon: true,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// For Intel Macs with discrete GPU\n\t\t\tconst { stdout: gpuInfo } = await execAsync(\n\t\t\t\t\"system_profiler SPDisplaysDataType\",\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tname:\n\t\t\t\t\tgpuInfo.split(\"Chipset Model:\")[1]?.split(\"\\n\")[0]?.trim() ||\n\t\t\t\t\t\"Unknown GPU\",\n\t\t\t\ttype: \"metal\",\n\t\t\t\tisAppleSilicon: false,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Mac GPU detection failed\", { error });\n\t\t\treturn {\n\t\t\t\tname: \"Unknown Mac GPU\",\n\t\t\t\ttype: \"metal\",\n\t\t\t\tisAppleSilicon: false,\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Detects the GPU in a Windows system and returns information about it.\n\t *\n\t * @returns {Promise<SystemGPU | null>} A promise that resolves with the detected GPU information or null if detection fails.\n\t */\n\tprivate async detectWindowsGPU(): Promise<SystemGPU | null> {\n\t\ttry {\n\t\t\tconst { stdout } = await execAsync(\n\t\t\t\t\"wmic path win32_VideoController get name\",\n\t\t\t);\n\t\t\tconst gpuName = stdout.split(\"\\n\")[1].trim();\n\n\t\t\t// Check for NVIDIA GPU\n\t\t\tif (gpuName.toLowerCase().includes(\"nvidia\")) {\n\t\t\t\tconst { stdout: nvidiaInfo } = await execAsync(\n\t\t\t\t\t\"nvidia-smi --query-gpu=name,memory.total --format=csv,noheader\",\n\t\t\t\t);\n\t\t\t\tconst [name, memoryStr] = nvidiaInfo.split(\",\").map((s) => s.trim());\n\t\t\t\tconst memory = Number.parseInt(memoryStr);\n\n\t\t\t\treturn {\n\t\t\t\t\tname,\n\t\t\t\t\tmemory,\n\t\t\t\t\ttype: \"cuda\",\n\t\t\t\t\tversion: await this.getNvidiaDriverVersion(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Default to DirectML for other GPUs\n\t\t\treturn {\n\t\t\t\tname: gpuName,\n\t\t\t\ttype: \"directml\",\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Windows GPU detection failed\", { error });\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously detects the GPU information for Linux systems.\n\t * Tries to detect NVIDIA GPU first using 'nvidia-smi' command and if successful,\n\t * returns the GPU name, memory size, type as 'cuda', and NVIDIA driver version.\n\t * If NVIDIA detection fails, it falls back to checking for other GPUs using 'lspci | grep -i vga' command.\n\t * If no GPU is detected, it returns null.\n\t *\n\t * @returns {Promise<SystemGPU | null>} The detected GPU information or null if detection fails.\n\t */\n\tprivate async detectLinuxGPU(): Promise<SystemGPU | null> {\n\t\ttry {\n\t\t\t// Try NVIDIA first\n\t\t\tconst { stdout } = await execAsync(\n\t\t\t\t\"nvidia-smi --query-gpu=name,memory.total --format=csv,noheader\",\n\t\t\t);\n\t\t\tif (stdout) {\n\t\t\t\tconst [name, memoryStr] = stdout.split(\",\").map((s) => s.trim());\n\t\t\t\tconst memory = Number.parseInt(memoryStr);\n\n\t\t\t\treturn {\n\t\t\t\t\tname,\n\t\t\t\t\tmemory,\n\t\t\t\t\ttype: \"cuda\",\n\t\t\t\t\tversion: await this.getNvidiaDriverVersion(),\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\t// If nvidia-smi fails, check for other GPUs\n\t\t\ttry {\n\t\t\t\tconst { stdout } = await execAsync(\"lspci | grep -i vga\");\n\t\t\t\treturn {\n\t\t\t\t\tname: stdout.split(\":\").pop()?.trim() || \"Unknown GPU\",\n\t\t\t\t\ttype: \"none\",\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Linux GPU detection failed\", { error });\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Asynchronously retrieves the driver version of the Nvidia GPU using the 'nvidia-smi' command.\n\t *\n\t * @returns A promise that resolves with the driver version as a string, or 'unknown' if an error occurs.\n\t */\n\tprivate async getNvidiaDriverVersion(): Promise<string> {\n\t\ttry {\n\t\t\tconst { stdout } = await execAsync(\n\t\t\t\t\"nvidia-smi --query-gpu=driver_version --format=csv,noheader\",\n\t\t\t);\n\t\t\treturn stdout.trim();\n\t\t} catch {\n\t\t\treturn \"unknown\";\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the supported backends based on the platform and GPU type.\n\t * @param {NodeJS.Platform} platform - The platform on which the code is running.\n\t * @param {SystemGPU | null} gpu - The GPU information, if available.\n\t * @returns {Promise<Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">>} - An array of supported backends including 'cuda', 'metal', 'directml', and 'cpu'.\n\t */\n\tprivate async getSupportedBackends(\n\t\tplatform: NodeJS.Platform,\n\t\tgpu: SystemGPU | null,\n\t): Promise<Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">> {\n\t\tconst backends: Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\"> = [\"cpu\"];\n\n\t\tif (gpu) {\n\t\t\tswitch (platform) {\n\t\t\t\tcase \"darwin\":\n\t\t\t\t\tbackends.push(\"metal\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"win32\":\n\t\t\t\t\tif (gpu.type === \"cuda\") {\n\t\t\t\t\t\tbackends.push(\"cuda\");\n\t\t\t\t\t}\n\t\t\t\t\tbackends.push(\"directml\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"linux\":\n\t\t\t\t\tif (gpu.type === \"cuda\") {\n\t\t\t\t\t\tbackends.push(\"cuda\");\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn backends;\n\t}\n\n\t/**\n\t * Determines the recommended model size based on the system's CPU and GPU.\n\t * @param {SystemCPU} cpu - The system's CPU.\n\t * @param {SystemGPU | null} gpu - The system's GPU, if available.\n\t * @returns {\"small\" | \"medium\" | \"large\"} - The recommended model size (\"small\", \"medium\", or \"large\").\n\t */\n\tprivate getRecommendedModelSize(\n\t\tcpu: SystemCPU,\n\t\tgpu: SystemGPU | null,\n\t): \"small\" | \"medium\" | \"large\" {\n\t\t// For Apple Silicon\n\t\tif (gpu?.isAppleSilicon) {\n\t\t\treturn cpu.memory.total > 16 * 1024 * 1024 * 1024 ? \"medium\" : \"small\";\n\t\t}\n\n\t\t// For NVIDIA GPUs\n\t\tif (gpu?.type === \"cuda\") {\n\t\t\tconst gpuMemGB = (gpu.memory || 0) / 1024;\n\t\t\tif (gpuMemGB >= 16) return \"large\";\n\t\t\tif (gpuMemGB >= 8) return \"medium\";\n\t\t}\n\n\t\t// For systems with significant RAM but no powerful GPU\n\t\tif (cpu.memory.total > 32 * 1024 * 1024 * 1024) return \"medium\";\n\n\t\t// Default to small model\n\t\treturn \"small\";\n\t}\n\n\t/**\n\t * Returns the SystemCapabilities of the PlatformManager.\n\t *\n\t * @returns {SystemCapabilities} The SystemCapabilities of the PlatformManager.\n\t * @throws {Error} if PlatformManager is not initialized.\n\t */\n\tgetCapabilities(): SystemCapabilities {\n\t\tif (!this.capabilities) {\n\t\t\tthrow new Error(\"PlatformManager not initialized\");\n\t\t}\n\t\treturn this.capabilities;\n\t}\n\n\t/**\n\t * Checks if the device's GPU is Apple Silicon.\n\t * @returns {boolean} True if the GPU is Apple Silicon, false otherwise.\n\t */\n\tisAppleSilicon(): boolean {\n\t\treturn !!this.capabilities?.gpu?.isAppleSilicon;\n\t}\n\n\t/**\n\t * Checks if the current device has GPU support.\n\t * @returns {boolean} - Returns true if the device has GPU support, false otherwise.\n\t */\n\thasGPUSupport(): boolean {\n\t\treturn !!this.capabilities?.gpu;\n\t}\n\n\t/**\n\t * Checks if the system supports CUDA GPU for processing.\n\t *\n\t * @returns {boolean} True if the system supports CUDA, false otherwise.\n\t */\n\tsupportsCUDA(): boolean {\n\t\treturn this.capabilities?.gpu?.type === \"cuda\";\n\t}\n\n\t/**\n\t * Check if the device supports Metal API for rendering graphics.\n\t * @returns {boolean} True if the device supports Metal, false otherwise.\n\t */\n\tsupportsMetal(): boolean {\n\t\treturn this.capabilities?.gpu?.type === \"metal\";\n\t}\n\n\t/**\n\t * Check if the device supports DirectML for GPU acceleration.\n\t *\n\t * @returns {boolean} True if the device supports DirectML, false otherwise.\n\t */\n\tsupportsDirectML(): boolean {\n\t\treturn this.capabilities?.gpu?.type === \"directml\";\n\t}\n\n\t/**\n\t * Get the recommended backend for computation based on the available capabilities.\n\t * @returns {\"cuda\" | \"metal\" | \"directml\" | \"cpu\"} The recommended backend for computation.\n\t * @throws {Error} Throws an error if PlatformManager is not initialized.\n\t */\n\tgetRecommendedBackend(): \"cuda\" | \"metal\" | \"directml\" | \"cpu\" {\n\t\tif (!this.capabilities) {\n\t\t\tthrow new Error(\"PlatformManager not initialized\");\n\t\t}\n\n\t\tconst { gpu, supportedBackends } = this.capabilities;\n\n\t\tif (gpu?.type === \"cuda\") return \"cuda\";\n\t\tif (gpu?.type === \"metal\") return \"metal\";\n\t\tif (supportedBackends.includes(\"directml\")) return \"directml\";\n\t\treturn \"cpu\";\n\t}\n}\n\n// Export a helper function to get the singleton instance\nexport const getPlatformManager = (): PlatformManager => {\n\treturn PlatformManager.getInstance();\n};\n","import { type GenerateTextParams, ModelTypes, logger } from \"@elizaos/core\";\nimport fetch from \"node-fetch\";\n\n/**\n * Represents a StudioLMModel object with the following properties:\n * - id: string\n * - object: string\n * - created: number\n * - owned_by: string\n */\ninterface StudioLMModel {\n\tid: string;\n\tobject: string;\n\tcreated: number;\n\towned_by: string;\n}\n\n/**\n * Interface representing a chat message.\n * @property {string} role - The role of the sender, can be \"system\", \"user\", or \"assistant\".\n * @property {string} content - The content of the message.\n */\ninterface ChatMessage {\n\trole: \"system\" | \"user\" | \"assistant\";\n\tcontent: string;\n}\n\n/**\n * Interface representing a chat completion request.\n * @property {string} model - The model to be used for generating chat completions.\n * @property {ChatMessage[]} messages - An array of chat messages to provide context for the completion.\n * @property {number} [temperature] - The temperature parameter to control the randomness of the generated completions.\n * @property {number} [max_tokens] - The maximum number of tokens to generate in the completion.\n * @property {boolean} [stream] - Whether to generate completions in a streaming fashion.\n */\n\ninterface ChatCompletionRequest {\n\tmodel: string;\n\tmessages: ChatMessage[];\n\ttemperature?: number;\n\tmax_tokens?: number;\n\tstream?: boolean;\n}\n\n/**\n * Represents a response object for completing a chat session.\n * @typedef {Object} ChatCompletionResponse\n * @property {string} id - The unique identifier for the completion response.\n * @property {string} object - The type of object being returned.\n * @property {number} created - The timestamp of when the completion response was created.\n * @property {string} model - The type of model associated with the completion response.\n * @property {Object[]} choices - An array of choices made during the chat session.\n * @property {number} choices.index - The index of the choice within the array.\n * @property {ChatMessage} choices.message - The message associated with the choice.\n * @property {string} choices.finish_reason - The reason for finishing the chat session.\n */\ninterface ChatCompletionResponse {\n\tid: string;\n\tobject: string;\n\tcreated: number;\n\tmodel: string;\n\tchoices: {\n\t\tindex: number;\n\t\tmessage: ChatMessage;\n\t\tfinish_reason: string;\n\t}[];\n}\n\n/**\n * Class representing a Studio Language Model Manager.\n */\n\nexport class StudioLMManager {\n\tprivate static instance: StudioLMManager | null = null;\n\tprivate serverUrl: string;\n\tprivate initialized = false;\n\tprivate availableModels: StudioLMModel[] = [];\n\tprivate configuredModels = {\n\t\tsmall:\n\t\t\tprocess.env.STUDIOLM_SMALL_MODEL ||\n\t\t\t\"lmstudio-community/deepseek-r1-distill-qwen-1.5b\",\n\t\tmedium: process.env.STUDIOLM_MEDIUM_MODEL || \"deepseek-r1-distill-qwen-7b\",\n\t};\n\n\t/**\n\t * Private constructor for StudioLMManager.\n\t * Initializes with default serverUrl if not provided in environment variables.\n\t * Logs initialization information including serverUrl, configuredModels, and timestamp.\n\t */\n\tprivate constructor() {\n\t\tthis.serverUrl = process.env.STUDIOLM_SERVER_URL || \"http://localhost:1234\";\n\t\tlogger.info(\"StudioLMManager initialized with configuration:\", {\n\t\t\tserverUrl: this.serverUrl,\n\t\t\tconfiguredModels: this.configuredModels,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\t}\n\n\t/**\n\t * Returns an instance of StudioLMManager. If an instance already exists, it returns the existing instance.\n\t * @returns {StudioLMManager} The instance of StudioLMManager\n\t */\n\tpublic static getInstance(): StudioLMManager {\n\t\tif (!StudioLMManager.instance) {\n\t\t\tStudioLMManager.instance = new StudioLMManager();\n\t\t}\n\t\treturn StudioLMManager.instance;\n\t}\n\n\t/**\n\t * Check the status of the server by sending a request to the /v1/models endpoint.\n\t * @returns {Promise<boolean>} A Promise that resolves to true if the server responds with success status, false otherwise.\n\t */\n\tprivate async checkServerStatus(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst response = await fetch(`${this.serverUrl}/v1/models`);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Server responded with status: ${response.status}`);\n\t\t\t}\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"LM Studio server check failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tserverUrl: this.serverUrl,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Fetches the available models from the server and stores them in the 'availableModels' property.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when the models are fetched successfully or rejects with an error.\n\t */\n\tprivate async fetchAvailableModels(): Promise<void> {\n\t\ttry {\n\t\t\tconst response = await fetch(`${this.serverUrl}/v1/models`);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch models: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as { data: StudioLMModel[] };\n\t\t\tthis.availableModels = data.data;\n\n\t\t\tlogger.info(\"LM Studio available models:\", {\n\t\t\t\tcount: this.availableModels.length,\n\t\t\t\tmodels: this.availableModels.map((m) => m.id),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to fetch LM Studio models:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tserverUrl: this.serverUrl,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously tests the specified model with a chat completion request.\n\t * @param {string} modelId - The ID of the model to test.\n\t * @returns {Promise<boolean>} - A promise that resolves to true if the model test was successful, false otherwise.\n\t */\n\tprivate async testModel(modelId: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst testRequest: ChatCompletionRequest = {\n\t\t\t\tmodel: modelId,\n\t\t\t\tmessages: [\n\t\t\t\t\t{\n\t\t\t\t\t\trole: \"system\",\n\t\t\t\t\t\tcontent: \"Always answer in rhymes. Today is Thursday\",\n\t\t\t\t\t},\n\t\t\t\t\t{ role: \"user\", content: \"What day is it today?\" },\n\t\t\t\t],\n\t\t\t\ttemperature: 0.7,\n\t\t\t\tmax_tokens: -1,\n\t\t\t\tstream: false,\n\t\t\t};\n\n\t\t\tlogger.info(`Testing model ${modelId}...`);\n\n\t\t\tconst response = await fetch(`${this.serverUrl}/v1/chat/completions`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(testRequest),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Model test failed with status: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst result = (await response.json()) as ChatCompletionResponse;\n\n\t\t\tif (!result.choices?.[0]?.message?.content) {\n\t\t\t\tthrow new Error(\"No valid response content received\");\n\t\t\t}\n\n\t\t\tlogger.info(`Model ${modelId} test response:`, {\n\t\t\t\tcontent: result.choices[0].message.content,\n\t\t\t\tmodel: result.model,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tlogger.error(`Model ${modelId} test failed:`, {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Tests the configured text models to ensure they are working properly.\n\t * Logs the results of the test and any failed models.\n\t * @returns {Promise<void>} A promise that resolves when the test is complete.\n\t */\n\tprivate async testTextModels(): Promise<void> {\n\t\tlogger.info(\"Testing configured text models...\");\n\n\t\tconst results = await Promise.all([\n\t\t\tthis.testModel(this.configuredModels.small),\n\t\t\tthis.testModel(this.configuredModels.medium),\n\t\t]);\n\n\t\tconst [smallWorking, mediumWorking] = results;\n\n\t\tif (!smallWorking || !mediumWorking) {\n\t\t\tconst failedModels = [];\n\t\t\tif (!smallWorking) failedModels.push(\"small\");\n\t\t\tif (!mediumWorking) failedModels.push(\"medium\");\n\n\t\t\tlogger.warn(\"Some models failed the test:\", {\n\t\t\t\tfailedModels,\n\t\t\t\tsmall: this.configuredModels.small,\n\t\t\t\tmedium: this.configuredModels.medium,\n\t\t\t});\n\t\t} else {\n\t\t\tlogger.success(\"All configured models passed the test\");\n\t\t}\n\t}\n\n\t/**\n\t * Initializes StudioLM by checking server status, fetching available models,\n\t * and testing text models.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves when initialization is complete\n\t */\n\tpublic async initialize(): Promise<void> {\n\t\ttry {\n\t\t\tif (this.initialized) {\n\t\t\t\tlogger.info(\"StudioLM already initialized, skipping initialization\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlogger.info(\"Starting StudioLM initialization...\");\n\t\t\tconst serverAvailable = await this.checkServerStatus();\n\n\t\t\tif (!serverAvailable) {\n\t\t\t\tthrow new Error(\"LM Studio server is not available\");\n\t\t\t}\n\n\t\t\tawait this.fetchAvailableModels();\n\t\t\tawait this.testTextModels();\n\n\t\t\tthis.initialized = true;\n\t\t\tlogger.success(\"StudioLM initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"StudioLM initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the available models in the studio.\n\t *\n\t * @returns {StudioLMModel[]} An array of StudioLMModel objects representing the available models.\n\t */\n\tpublic getAvailableModels(): StudioLMModel[] {\n\t\treturn this.availableModels;\n\t}\n\n\t/**\n\t * Check if the object is initialized.\n\t *\n\t * @returns {boolean} Returns true if the object is initialized, otherwise false.\n\t */\n\tpublic isInitialized(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\t/**\n\t * Asynchronously generates text using StudioLM based on provided parameters.\n\t *\n\t * @param {GenerateTextParams} params - The parameters for generating text.\n\t * @param {boolean} [isInitialized=false] - Flag to indicate if the model is already initialized.\n\t * @returns {Promise<string>} The generated text as a Promise.\n\t */\n\tpublic async generateText(\n\t\tparams: GenerateTextParams,\n\t\tisInitialized = false,\n\t): Promise<string> {\n\t\ttry {\n\t\t\t// Log entry point with all parameters\n\t\t\tlogger.info(\"StudioLM generateText entry:\", {\n\t\t\t\tisInitialized,\n\t\t\t\tcurrentInitState: this.initialized,\n\t\t\t\tmanagerInitState: this.isInitialized(),\n\t\t\t\tmodelType: params.modelType,\n\t\t\t\tcontextLength: params.prompt?.length,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\t// Only initialize if not already initialized and not marked as initialized\n\t\t\tif (!this.initialized && !isInitialized) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"StudioLM not initialized. Please initialize before generating text.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst messages: ChatMessage[] = [\n\t\t\t\t{\n\t\t\t\t\trole: \"system\",\n\t\t\t\t\tcontent:\n\t\t\t\t\t\t\"You are a helpful AI assistant. Respond to the current request only.\",\n\t\t\t\t},\n\t\t\t\t{ role: \"user\", content: params.prompt },\n\t\t\t];\n\n\t\t\tlogger.info(\"StudioLM preparing request:\", {\n\t\t\t\tmodel:\n\t\t\t\t\tparams.modelType === ModelTypes.TEXT_LARGE\n\t\t\t\t\t\t? this.configuredModels.medium\n\t\t\t\t\t\t: this.configuredModels.small,\n\t\t\t\tmessageCount: messages.length,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\tlogger.info(\"Incoming context structure:\", {\n\t\t\t\tcontextLength: params.prompt.length,\n\t\t\t\thasAction: params.prompt.includes(\"action\"),\n\t\t\t\truntime: !!params.runtime,\n\t\t\t\tstopSequences: params.stopSequences,\n\t\t\t});\n\n\t\t\tconst request: ChatCompletionRequest = {\n\t\t\t\tmodel:\n\t\t\t\t\tparams.modelType === ModelTypes.TEXT_LARGE\n\t\t\t\t\t\t? this.configuredModels.medium\n\t\t\t\t\t\t: this.configuredModels.small,\n\t\t\t\tmessages,\n\t\t\t\ttemperature: 0.7,\n\t\t\t\tmax_tokens: 8192,\n\t\t\t\tstream: false,\n\t\t\t};\n\n\t\t\tconst response = await fetch(`${this.serverUrl}/v1/chat/completions`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(request),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`StudioLM request failed: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst result = (await response.json()) as ChatCompletionResponse;\n\n\t\t\tif (!result.choices?.[0]?.message?.content) {\n\t\t\t\tthrow new Error(\"No valid response content received from StudioLM\");\n\t\t\t}\n\n\t\t\tlet responseText = result.choices[0].message.content;\n\n\t\t\t// Log raw response for debugging\n\t\t\tlogger.info(\"Raw response structure:\", {\n\t\t\t\tresponseLength: responseText.length,\n\t\t\t\thasAction: responseText.includes(\"action\"),\n\t\t\t\thasThinkTag: responseText.includes(\"<think>\"),\n\t\t\t});\n\n\t\t\t// Clean think tags if present\n\t\t\tif (responseText.includes(\"<think>\")) {\n\t\t\t\tlogger.info(\"Cleaning think tags from response\");\n\t\t\t\tresponseText = responseText.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, \"\");\n\t\t\t\tlogger.info(\"Think tags removed from response\");\n\t\t\t}\n\n\t\t\tlogger.info(\"StudioLM request completed successfully:\", {\n\t\t\t\tresponseLength: responseText.length,\n\t\t\t\thasThinkTags: responseText.includes(\"<think>\"),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\treturn responseText;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"StudioLM text generation error:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tphase: \"text generation\",\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n","import { logger } from \"@elizaos/core\";\nimport {\n\tAutoTokenizer,\n\ttype PreTrainedTokenizer,\n} from \"@huggingface/transformers\";\n\n// Import the MODEL_SPECS type from a new types file we'll create later\nimport type { ModelSpec } from \"../types\";\n\n/**\n * Represents a Tokenizer Manager which manages tokenizers for different models.\n * * @class TokenizerManager\n */\nexport class TokenizerManager {\n\tprivate static instance: TokenizerManager | null = null;\n\tprivate tokenizers: Map<string, PreTrainedTokenizer>;\n\tprivate cacheDir: string;\n\tprivate modelsDir: string;\n\n\t/**\n\t * Constructor for creating a new instance of the class.\n\t *\n\t * @param {string} cacheDir - The directory for caching data.\n\t * @param {string} modelsDir - The directory for storing models.\n\t */\n\tprivate constructor(cacheDir: string, modelsDir: string) {\n\t\tthis.tokenizers = new Map();\n\t\tthis.cacheDir = cacheDir;\n\t\tthis.modelsDir = modelsDir;\n\t}\n\n\t/**\n\t * Get the singleton instance of TokenizerManager class. If the instance does not exist, it will create a new one.\n\t *\n\t * @param {string} cacheDir - The directory to cache the tokenizer models.\n\t * @param {string} modelsDir - The directory where tokenizer models are stored.\n\t * @returns {TokenizerManager} The singleton instance of TokenizerManager.\n\t */\n\tstatic getInstance(cacheDir: string, modelsDir: string): TokenizerManager {\n\t\tif (!TokenizerManager.instance) {\n\t\t\tTokenizerManager.instance = new TokenizerManager(cacheDir, modelsDir);\n\t\t}\n\t\treturn TokenizerManager.instance;\n\t}\n\n\t/**\n\t * Asynchronously loads a tokenizer based on the provided ModelSpec configuration.\n\t *\n\t * @param {ModelSpec} modelConfig - The configuration object for the model to load the tokenizer for.\n\t * @returns {Promise<PreTrainedTokenizer>} - A promise that resolves to the loaded tokenizer.\n\t */\n\tasync loadTokenizer(modelConfig: ModelSpec): Promise<PreTrainedTokenizer> {\n\t\ttry {\n\t\t\tconst tokenizerKey = `${modelConfig.tokenizer.type}-${modelConfig.tokenizer.name}`;\n\t\t\tlogger.info(\"Loading tokenizer:\", {\n\t\t\t\tkey: tokenizerKey,\n\t\t\t\tname: modelConfig.tokenizer.name,\n\t\t\t\ttype: modelConfig.tokenizer.type,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t\tcacheDir: this.cacheDir,\n\t\t\t});\n\n\t\t\tif (this.tokenizers.has(tokenizerKey)) {\n\t\t\t\tlogger.info(\"Using cached tokenizer:\", { key: tokenizerKey });\n\t\t\t\tconst cachedTokenizer = this.tokenizers.get(tokenizerKey);\n\t\t\t\tif (!cachedTokenizer) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Tokenizer ${tokenizerKey} exists in map but returned undefined`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn cachedTokenizer;\n\t\t\t}\n\n\t\t\t// Check if models directory exists\n\t\t\tconst fs = await import(\"node:fs\");\n\t\t\tif (!fs.existsSync(this.modelsDir)) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"Models directory does not exist, creating it:\",\n\t\t\t\t\tthis.modelsDir,\n\t\t\t\t);\n\t\t\t\tfs.mkdirSync(this.modelsDir, { recursive: true });\n\t\t\t}\n\n\t\t\tlogger.info(\n\t\t\t\t\"Initializing new tokenizer from HuggingFace with models directory:\",\n\t\t\t\tthis.modelsDir,\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst tokenizer = await AutoTokenizer.from_pretrained(\n\t\t\t\t\tmodelConfig.tokenizer.name,\n\t\t\t\t\t{\n\t\t\t\t\t\tcache_dir: this.modelsDir,\n\t\t\t\t\t\tlocal_files_only: false,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tthis.tokenizers.set(tokenizerKey, tokenizer);\n\t\t\t\tlogger.success(\"Tokenizer loaded successfully:\", { key: tokenizerKey });\n\t\t\t\treturn tokenizer;\n\t\t\t} catch (tokenizeError) {\n\t\t\t\tlogger.error(\"Failed to load tokenizer from HuggingFace:\", {\n\t\t\t\t\terror:\n\t\t\t\t\t\ttokenizeError instanceof Error\n\t\t\t\t\t\t\t? tokenizeError.message\n\t\t\t\t\t\t\t: String(tokenizeError),\n\t\t\t\t\tstack:\n\t\t\t\t\t\ttokenizeError instanceof Error ? tokenizeError.stack : undefined,\n\t\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t\t});\n\n\t\t\t\t// Try again with local_files_only set to false and a longer timeout\n\t\t\t\tlogger.info(\"Retrying tokenizer loading...\");\n\t\t\t\tconst tokenizer = await AutoTokenizer.from_pretrained(\n\t\t\t\t\tmodelConfig.tokenizer.name,\n\t\t\t\t\t{\n\t\t\t\t\t\tcache_dir: this.modelsDir,\n\t\t\t\t\t\tlocal_files_only: false,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tthis.tokenizers.set(tokenizerKey, tokenizer);\n\t\t\t\tlogger.success(\"Tokenizer loaded successfully on retry:\", {\n\t\t\t\t\tkey: tokenizerKey,\n\t\t\t\t});\n\t\t\t\treturn tokenizer;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to load tokenizer:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tmodel: modelConfig.name,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Encodes the given text using the specified tokenizer model configuration.\n\t *\n\t * @param {string} text - The text to encode.\n\t * @param {ModelSpec} modelConfig - The configuration for the model tokenizer.\n\t * @returns {Promise<number[]>} - An array of integers representing the encoded text.\n\t * @throws {Error} - If the text encoding fails, an error is thrown.\n\t */\n\tasync encode(text: string, modelConfig: ModelSpec): Promise<number[]> {\n\t\ttry {\n\t\t\tlogger.info(\"Encoding text with tokenizer:\", {\n\t\t\t\tlength: text.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t});\n\n\t\t\tconst tokenizer = await this.loadTokenizer(modelConfig);\n\n\t\t\tlogger.info(\"Tokenizer loaded, encoding text...\");\n\t\t\tconst encoded = await tokenizer.encode(text, {\n\t\t\t\tadd_special_tokens: true,\n\t\t\t\treturn_token_type_ids: false,\n\t\t\t});\n\n\t\t\tlogger.info(\"Text encoded successfully:\", {\n\t\t\t\ttokenCount: encoded.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t});\n\t\t\treturn encoded;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Text encoding failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttextLength: text.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously decodes an array of tokens using a tokenizer based on the provided ModelSpec.\n\t *\n\t * @param {number[]} tokens - The array of tokens to be decoded.\n\t * @param {ModelSpec} modelConfig - The ModelSpec object containing information about the model and tokenizer to be used.\n\t * @returns {Promise<string>} - A Promise that resolves with the decoded text.\n\t * @throws {Error} - If an error occurs during token decoding.\n\t */\n\tasync decode(tokens: number[], modelConfig: ModelSpec): Promise<string> {\n\t\ttry {\n\t\t\tlogger.info(\"Decoding tokens with tokenizer:\", {\n\t\t\t\tcount: tokens.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t});\n\n\t\t\tconst tokenizer = await this.loadTokenizer(modelConfig);\n\n\t\t\tlogger.info(\"Tokenizer loaded, decoding tokens...\");\n\t\t\tconst decoded = await tokenizer.decode(tokens, {\n\t\t\t\tskip_special_tokens: true,\n\t\t\t\tclean_up_tokenization_spaces: true,\n\t\t\t});\n\n\t\t\tlogger.info(\"Tokens decoded successfully:\", {\n\t\t\t\ttextLength: decoded.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t});\n\t\t\treturn decoded;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Token decoding failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttokenCount: tokens.length,\n\t\t\t\ttokenizer: modelConfig.tokenizer.name,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n","import { exec } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { logger } from \"@elizaos/core\";\nimport { nodewhisper } from \"nodejs-whisper\";\n\nconst execAsync = promisify(exec);\n\n/**\n * Interface representing the result of a transcription process.\n * @interface\n * @property {string} text - The transcribed text.\n */\ninterface TranscriptionResult {\n\ttext: string;\n}\n\n/**\n * Class representing a TranscribeManager.\n *\n * @property {TranscribeManager | null} instance - The singleton instance of the TranscribeManager class.\n * @property {string} cacheDir - The directory path for caching transcribed files.\n * @property {boolean} ffmpegAvailable - Flag indicating if ffmpeg is available for audio processing.\n * @property {string | null} ffmpegVersion - The version of ffmpeg if available.\n * @property {string | null} ffmpegPath - The path to the ffmpeg executable.\n * @property {boolean} ffmpegInitialized - Flag indicating if ffmpeg has been initialized.\n *\n * @constructor\n * Creates an instance of TranscribeManager with the specified cache directory.\n */\nexport class TranscribeManager {\n\tprivate static instance: TranscribeManager | null = null;\n\tprivate cacheDir: string;\n\tprivate ffmpegAvailable = false;\n\tprivate ffmpegVersion: string | null = null;\n\tprivate ffmpegPath: string | null = null;\n\tprivate ffmpegInitialized = false;\n\n\t/**\n\t * Constructor for TranscribeManager class.\n\t *\n\t * @param {string} cacheDir - The directory path for storing cached files.\n\t */\n\tprivate constructor(cacheDir: string) {\n\t\tthis.cacheDir = path.join(cacheDir, \"whisper\");\n\t\tlogger.info(\"Initializing TranscribeManager\", {\n\t\t\tcacheDir: this.cacheDir,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t});\n\t\tthis.ensureCacheDirectory();\n\t}\n\n\t/**\n\t * Ensures that FFmpeg is initialized and available for use.\n\t * @returns {Promise<boolean>} A promise that resolves to a boolean value indicating if FFmpeg is available.\n\t */\n\tpublic async ensureFFmpeg(): Promise<boolean> {\n\t\tif (!this.ffmpegInitialized) {\n\t\t\ttry {\n\t\t\t\tawait this.initializeFFmpeg();\n\t\t\t\tthis.ffmpegInitialized = true;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"FFmpeg initialization failed:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn this.ffmpegAvailable;\n\t}\n\n\t/**\n\t * Checks if FFmpeg is available.\n\t * @returns {boolean} True if FFmpeg is available, false otherwise.\n\t */\n\tpublic isFFmpegAvailable(): boolean {\n\t\treturn this.ffmpegAvailable;\n\t}\n\n\t/**\n\t * Asynchronously retrieves the FFmpeg version if it hasn't been fetched yet.\n\t * If the FFmpeg version has already been fetched, it will return the stored version.\n\t * @returns A Promise that resolves with the FFmpeg version as a string, or null if the version is not available.\n\t */\n\tpublic async getFFmpegVersion(): Promise<string | null> {\n\t\tif (!this.ffmpegVersion) {\n\t\t\tawait this.fetchFFmpegVersion();\n\t\t}\n\t\treturn this.ffmpegVersion;\n\t}\n\n\t/**\n\t * Fetches the FFmpeg version by executing the command \"ffmpeg -version\".\n\t * Updates the class property ffmpegVersion with the retrieved version.\n\t * Logs the FFmpeg version information or error message.\n\t * @returns {Promise<void>} A Promise that resolves once the FFmpeg version is fetched and logged.\n\t */\n\tprivate async fetchFFmpegVersion(): Promise<void> {\n\t\ttry {\n\t\t\tconst { stdout } = await execAsync(\"ffmpeg -version\");\n\t\t\tthis.ffmpegVersion = stdout.split(\"\\n\")[0];\n\t\t\tlogger.info(\"FFmpeg version:\", {\n\t\t\t\tversion: this.ffmpegVersion,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.ffmpegVersion = null;\n\t\t\tlogger.error(\"Failed to get FFmpeg version:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Initializes FFmpeg by performing the following steps:\n\t * 1. Checks for FFmpeg availability in PATH\n\t * 2. Retrieves FFmpeg version information\n\t * 3. Verifies FFmpeg capabilities\n\t *\n\t * If FFmpeg is available, logs a success message with version, path, and timestamp.\n\t * If FFmpeg is not available, logs installation instructions.\n\t *\n\t * @returns A Promise that resolves once FFmpeg has been successfully initialized\n\t */\n\tprivate async initializeFFmpeg(): Promise<void> {\n\t\ttry {\n\t\t\t// First check if ffmpeg exists in PATH\n\t\t\tawait this.checkFFmpegAvailability();\n\n\t\t\tif (this.ffmpegAvailable) {\n\t\t\t\t// Get FFmpeg version info\n\t\t\t\tawait this.fetchFFmpegVersion();\n\n\t\t\t\t// Verify FFmpeg capabilities\n\t\t\t\tawait this.verifyFFmpegCapabilities();\n\n\t\t\t\t// logger.success(\"FFmpeg initialized successfully\", {\n\t\t\t\t// version: this.ffmpegVersion,\n\t\t\t\t// path: this.ffmpegPath,\n\t\t\t\t// timestamp: new Date().toISOString()\n\t\t\t\t// });\n\t\t\t} else {\n\t\t\t\tthis.logFFmpegInstallInstructions();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.ffmpegAvailable = false;\n\t\t\tlogger.error(\"FFmpeg initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthis.logFFmpegInstallInstructions();\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously checks for the availability of FFmpeg in the system by executing a command to find the FFmpeg location.\n\t * Updates the class properties `ffmpegPath` and `ffmpegAvailable` accordingly.\n\t * Logs relevant information such as FFmpeg location and potential errors using the logger.\n\t *\n\t * @returns A Promise that resolves with no value upon completion.\n\t */\n\tprivate async checkFFmpegAvailability(): Promise<void> {\n\t\ttry {\n\t\t\tconst { stdout, stderr } = await execAsync(\n\t\t\t\t\"which ffmpeg || where ffmpeg\",\n\t\t\t);\n\t\t\tthis.ffmpegPath = stdout.trim();\n\t\t\tthis.ffmpegAvailable = true;\n\t\t\tlogger.info(\"FFmpeg found at:\", {\n\t\t\t\tpath: this.ffmpegPath,\n\t\t\t\tstderr: stderr ? stderr.trim() : undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.ffmpegAvailable = false;\n\t\t\tthis.ffmpegPath = null;\n\t\t\tlogger.error(\"FFmpeg not found in PATH:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstderr:\n\t\t\t\t\terror instanceof Error && \"stderr\" in error\n\t\t\t\t\t\t? error.stderr\n\t\t\t\t\t\t: undefined,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Verifies the FFmpeg capabilities by checking if FFmpeg supports the required codecs and formats.\n\t *\n\t * @returns {Promise<void>} A Promise that resolves if FFmpeg has the required codecs, otherwise rejects with an error message.\n\t */\n\tprivate async verifyFFmpegCapabilities(): Promise<void> {\n\t\ttry {\n\t\t\t// Check if FFmpeg supports required codecs and formats\n\t\t\tconst { stdout } = await execAsync(\"ffmpeg -codecs\");\n\t\t\tconst hasRequiredCodecs =\n\t\t\t\tstdout.includes(\"pcm_s16le\") && stdout.includes(\"wav\");\n\n\t\t\tif (!hasRequiredCodecs) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"FFmpeg installation missing required codecs (pcm_s16le, wav)\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// logger.info(\"FFmpeg capabilities verified\", {\n\t\t\t// hasRequiredCodecs,\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\t\t} catch (error) {\n\t\t\tlogger.error(\"FFmpeg capabilities verification failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Logs instructions on how to install FFmpeg if it is not properly installed.\n\t */\n\tprivate logFFmpegInstallInstructions(): void {\n\t\tlogger.warn(\n\t\t\t\"FFmpeg is required but not properly installed. Please install FFmpeg:\",\n\t\t\t{\n\t\t\t\tinstructions: {\n\t\t\t\t\tmac: \"brew install ffmpeg\",\n\t\t\t\t\tubuntu: \"sudo apt-get install ffmpeg\",\n\t\t\t\t\twindows: \"choco install ffmpeg\",\n\t\t\t\t\tmanual: \"Download from https://ffmpeg.org/download.html\",\n\t\t\t\t},\n\t\t\t\trequiredVersion: \"4.0 or later\",\n\t\t\t\trequiredCodecs: [\"pcm_s16le\", \"wav\"],\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Gets the singleton instance of TranscribeManager, creates a new instance if it doesn't exist.\n\t *\n\t * @param {string} cacheDir - The directory path for caching transcriptions.\n\t * @returns {TranscribeManager} The singleton instance of TranscribeManager.\n\t */\n\tpublic static getInstance(cacheDir: string): TranscribeManager {\n\t\tif (!TranscribeManager.instance) {\n\t\t\tTranscribeManager.instance = new TranscribeManager(cacheDir);\n\t\t}\n\t\treturn TranscribeManager.instance;\n\t}\n\n\t/**\n\t * Ensures that the cache directory exists. If it doesn't exist,\n\t * creates the directory using fs.mkdirSync with recursive set to true.\n\t * @returns {void}\n\t */\n\tprivate ensureCacheDirectory(): void {\n\t\tif (!fs.existsSync(this.cacheDir)) {\n\t\t\tfs.mkdirSync(this.cacheDir, { recursive: true });\n\t\t\t// logger.info(\"Created whisper cache directory:\", this.cacheDir);\n\t\t}\n\t}\n\n\t/**\n\t * Converts an audio file to WAV format using FFmpeg.\n\t *\n\t * @param {string} inputPath - The input path of the audio file to convert.\n\t * @param {string} outputPath - The output path where the converted WAV file will be saved.\n\t * @returns {Promise<void>} A Promise that resolves when the conversion is completed.\n\t * @throws {Error} If FFmpeg is not installed or not properly configured, or if the audio conversion fails.\n\t */\n\tprivate async convertToWav(\n\t\tinputPath: string,\n\t\toutputPath: string,\n\t): Promise<void> {\n\t\tif (!this.ffmpegAvailable) {\n\t\t\tthrow new Error(\n\t\t\t\t\"FFmpeg is not installed or not properly configured. Please install FFmpeg to use audio transcription.\",\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\t// Add -loglevel error to suppress FFmpeg output unless there's an error\n\t\t\tconst { stderr } = await execAsync(\n\t\t\t\t`ffmpeg -y -loglevel error -i \"${inputPath}\" -acodec pcm_s16le -ar 16000 -ac 1 \"${outputPath}\"`,\n\t\t\t);\n\n\t\t\tif (stderr) {\n\t\t\t\tlogger.warn(\"FFmpeg conversion error:\", {\n\t\t\t\t\tstderr,\n\t\t\t\t\tinputPath,\n\t\t\t\t\toutputPath,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!fs.existsSync(outputPath)) {\n\t\t\t\tthrow new Error(\"WAV file was not created successfully\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Audio conversion failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tcommand: `ffmpeg -y -loglevel error -i \"${inputPath}\" -acodec pcm_s16le -ar 16000 -ac 1 \"${outputPath}\"`,\n\t\t\t\tffmpegAvailable: this.ffmpegAvailable,\n\t\t\t\tffmpegVersion: this.ffmpegVersion,\n\t\t\t\tffmpegPath: this.ffmpegPath,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to convert audio to WAV format: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously preprocesses the audio by converting the provided audio buffer into a WAV file.\n\t * If FFmpeg is not installed, an error is thrown.\n\t *\n\t * @param {Buffer} audioBuffer The audio buffer to preprocess\n\t * @returns {Promise<string>} The path to the preprocessed WAV file\n\t * @throws {Error} If FFmpeg is not installed or if audio preprocessing fails\n\t */\n\tprivate async preprocessAudio(audioBuffer: Buffer): Promise<string> {\n\t\tif (!this.ffmpegAvailable) {\n\t\t\tthrow new Error(\n\t\t\t\t\"FFmpeg is not installed. Please install FFmpeg to use audio transcription.\",\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst tempInputFile = path.join(\n\t\t\t\tthis.cacheDir,\n\t\t\t\t`temp_input_${Date.now()}`,\n\t\t\t);\n\t\t\tconst tempWavFile = path.join(this.cacheDir, `temp_${Date.now()}.wav`);\n\n\t\t\t// logger.info(\"Creating temporary files\", {\n\t\t\t// inputFile: tempInputFile,\n\t\t\t// wavFile: tempWavFile,\n\t\t\t// bufferSize: audioBuffer.length,\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\n\t\t\t// Write buffer to temporary file\n\t\t\tfs.writeFileSync(tempInputFile, audioBuffer);\n\t\t\t// logger.info(\"Temporary input file created\", {\n\t\t\t// path: tempInputFile,\n\t\t\t// size: audioBuffer.length,\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\n\t\t\t// Convert to WAV format\n\t\t\tawait this.convertToWav(tempInputFile, tempWavFile);\n\n\t\t\t// Clean up the input file\n\t\t\tif (fs.existsSync(tempInputFile)) {\n\t\t\t\tfs.unlinkSync(tempInputFile);\n\t\t\t\t// logger.info(\"Temporary input file cleaned up\", {\n\t\t\t\t// path: tempInputFile,\n\t\t\t\t// timestamp: new Date().toISOString()\n\t\t\t\t// });\n\t\t\t}\n\n\t\t\treturn tempWavFile;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Audio preprocessing failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tffmpegAvailable: this.ffmpegAvailable,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to preprocess audio: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Transcribes the audio buffer to text using whisper.\n\t *\n\t * @param {Buffer} audioBuffer The audio buffer to transcribe.\n\t * @returns {Promise<TranscriptionResult>} A promise that resolves with the transcription result.\n\t * @throws {Error} If FFmpeg is not installed or properly configured.\n\t */\n\n\tpublic async transcribe(audioBuffer: Buffer): Promise<TranscriptionResult> {\n\t\tawait this.ensureFFmpeg();\n\n\t\tif (!this.ffmpegAvailable) {\n\t\t\tthrow new Error(\n\t\t\t\t\"FFmpeg is not installed or not properly configured. Please install FFmpeg to use audio transcription.\",\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\t// Preprocess audio to WAV format\n\t\t\tconst wavFile = await this.preprocessAudio(audioBuffer);\n\n\t\t\tlogger.info(\"Starting transcription with whisper...\");\n\n\t\t\t// Save original stdout and stderr write functions\n\t\t\tconst originalStdoutWrite = process.stdout.write;\n\t\t\tconst originalStderrWrite = process.stderr.write;\n\n\t\t\t// Create a no-op function to suppress output\n\t\t\tconst noopWrite = () => true;\n\n\t\t\t// Redirect stdout and stderr to suppress whisper output\n\t\t\tprocess.stdout.write = noopWrite;\n\t\t\tprocess.stderr.write = noopWrite;\n\n\t\t\tlet output: string;\n\t\t\ttry {\n\t\t\t\t// Transcribe using whisper with output suppressed\n\t\t\t\toutput = await nodewhisper(wavFile, {\n\t\t\t\t\tmodelName: \"base.en\",\n\t\t\t\t\tautoDownloadModelName: \"base.en\",\n\t\t\t\t\tverbose: false,\n\t\t\t\t\twhisperOptions: {\n\t\t\t\t\t\toutputInText: true,\n\t\t\t\t\t\tlanguage: \"en\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\t// Restore original stdout and stderr\n\t\t\t\tprocess.stdout.write = originalStdoutWrite;\n\t\t\t\tprocess.stderr.write = originalStderrWrite;\n\t\t\t}\n\n\t\t\t// Clean up temporary WAV file\n\t\t\tif (fs.existsSync(wavFile)) {\n\t\t\t\tfs.unlinkSync(wavFile);\n\t\t\t\tlogger.info(\"Temporary WAV file cleaned up\");\n\t\t\t}\n\n\t\t\t// Extract just the text content without timestamps\n\t\t\tconst cleanText = output\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.map((line) => {\n\t\t\t\t\t// Remove timestamps if present [00:00:00.000 --> 00:00:00.000]\n\t\t\t\t\tconst textMatch = line.match(/](.+)$/);\n\t\t\t\t\treturn textMatch ? textMatch[1].trim() : line.trim();\n\t\t\t\t})\n\t\t\t\t.filter((line) => line) // Remove empty lines\n\t\t\t\t.join(\" \");\n\n\t\t\tlogger.success(\"Transcription complete:\", {\n\t\t\t\ttextLength: cleanText.length,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\n\t\t\treturn { text: cleanText };\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Transcription failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tffmpegAvailable: this.ffmpegAvailable,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { logger } from \"@elizaos/core\";\nimport {\n\ttype LlamaContext,\n\ttype LlamaContextSequence,\n\ttype LlamaModel,\n\ttype Token,\n\tgetLlama,\n} from \"node-llama-cpp\";\nimport { MODEL_SPECS } from \"../types\";\nimport { prependWavHeader } from \"./audioUtils\";\nimport { DownloadManager } from \"./downloadManager\";\n\n/**\n * Interface representing the response from a Text-to-Speech (TTS) service.\n * @typedef { Object } TTSResponse\n * @property {number[]} tokens - The array of token ids representing the text to be converted to speech.\n * @property { Float32Array } [audio] - Optional Float32Array representing the audio data output from the TTS service.\n */\ninterface TTSResponse {\n\ttokens: number[];\n\taudio?: Float32Array;\n}\n\n/**\n * Class representing a Text-to-Speech Manager\n */\nexport class TTSManager {\n\tprivate static instance: TTSManager | null = null;\n\tprivate cacheDir: string;\n\tprivate model: LlamaModel | null = null;\n\tprivate ctx: LlamaContext | null = null;\n\tprivate sequence: LlamaContextSequence | null = null;\n\tprivate initialized = false;\n\tprivate downloadManager: DownloadManager;\n\tprivate modelsDir: string;\n\n\t/**\n\t * Creates a new instance of TTSManager with the provided cache directory.\n\t *\n\t * @param {string} cacheDir - The directory where cached data will be stored.\n\t */\n\tprivate constructor(cacheDir: string) {\n\t\tthis.cacheDir = path.join(cacheDir, \"tts\");\n\t\tthis.modelsDir = process.env.LLAMALOCAL_PATH?.trim()\n\t\t\t? path.resolve(process.env.LLAMALOCAL_PATH.trim())\n\t\t\t: path.join(process.cwd(), \"models\");\n\t\tthis.downloadManager = DownloadManager.getInstance(\n\t\t\tthis.cacheDir,\n\t\t\tthis.modelsDir,\n\t\t);\n\t\tthis.ensureCacheDirectory();\n\t\tlogger.info(\"TTSManager initialized\");\n\t\t// Add a variable to deactivate the logging of the configuration\n\t\t// logger.info(\"TTSManager initialized with configuration:\", {\n\t\t// cacheDir: this.cacheDir,\n\t\t// modelsDir: this.modelsDir,\n\t\t// timestamp: new Date().toISOString()\n\t\t// });\n\t}\n\n\t/**\n\t * Returns an instance of TTSManager, creating a new one if none exist.\n\t *\n\t * @param {string} cacheDir - The directory path to store cached audio files.\n\t * @returns {TTSManager} An instance of TTSManager.\n\t */\n\tpublic static getInstance(cacheDir: string): TTSManager {\n\t\tif (!TTSManager.instance) {\n\t\t\tTTSManager.instance = new TTSManager(cacheDir);\n\t\t}\n\t\treturn TTSManager.instance;\n\t}\n\n\t/**\n\t * Ensures that the cache directory exists. If it does not exist, the directory will be created.\n\t */\n\tprivate ensureCacheDirectory(): void {\n\t\tif (!fs.existsSync(this.cacheDir)) {\n\t\t\tfs.mkdirSync(this.cacheDir, { recursive: true });\n\t\t\tlogger.info(\"Created TTS cache directory:\", this.cacheDir);\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously initializes the TTS module with GGUF backend.\n\t * If already initialized or missing necessary components (model and context), it returns early.\n\t * Handles model download using different URL patterns as fallback if model not found locally.\n\t * Initializes the TTS model, creates context, and sets the sequence for TTS generation.\n\t * Logs detailed steps and final output of initialization.\n\t *\n\t * @returns {Promise<void>} A promise that resolves once the TTS module is fully initialized.\n\t */\n\tprivate async initialize(): Promise<void> {\n\t\ttry {\n\t\t\tif (this.initialized && this.model && this.ctx) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlogger.info(\"Initializing TTS with GGUF backend...\");\n\n\t\t\tconst modelSpec = MODEL_SPECS.tts.base;\n\t\t\tconst modelPath = path.join(this.modelsDir, modelSpec.name);\n\n\t\t\t// Log detailed model configuration and paths\n\t\t\t// logger.info(\"TTS model configuration:\", {\n\t\t\t// name: modelSpec.name,\n\t\t\t// repo: modelSpec.repo,\n\t\t\t// modelPath,\n\t\t\t// timestamp: new Date().toISOString()\n\t\t\t// });\n\n\t\t\tif (!fs.existsSync(modelPath)) {\n\t\t\t\t// Try different URL patterns in sequence\n\t\t\t\tconst attempts = [\n\t\t\t\t\t{\n\t\t\t\t\t\tspec: { ...modelSpec },\n\t\t\t\t\t\tdescription: \"Standard URL with GGUF\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}?download=true`,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tspec: { ...modelSpec, repo: modelSpec.repo.replace(\"-GGUF\", \"\") },\n\t\t\t\t\t\tdescription: \"URL without GGUF suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo.replace(\"-GGUF\", \"\")}/resolve/main/${modelSpec.name}?download=true`,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tspec: { ...modelSpec, name: modelSpec.name.replace(\"-Q8_0\", \"\") },\n\t\t\t\t\t\tdescription: \"URL without quantization suffix\",\n\t\t\t\t\t\turl: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name.replace(\"-Q8_0\", \"\")}.gguf?download=true`,\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\tlet lastError = null;\n\t\t\t\tfor (const attempt of attempts) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlogger.info(\"Attempting TTS model download:\", {\n\t\t\t\t\t\t\tdescription: attempt.description,\n\t\t\t\t\t\t\trepo: attempt.spec.repo,\n\t\t\t\t\t\t\tname: attempt.spec.name,\n\t\t\t\t\t\t\turl: attempt.url,\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst barLength = 30;\n\t\t\t\t\t\tconst emptyBar = \"▱\".repeat(barLength);\n\t\t\t\t\t\tlogger.info(`Downloading TTS model: ${emptyBar} 0%`);\n\n\t\t\t\t\t\tawait this.downloadManager.downloadFromUrl(attempt.url, modelPath);\n\n\t\t\t\t\t\tconst completedBar = \"▰\".repeat(barLength);\n\t\t\t\t\t\tlogger.info(`Downloading TTS model: ${completedBar} 100%`);\n\t\t\t\t\t\tlogger.success(\n\t\t\t\t\t\t\t\"TTS model download successful with:\",\n\t\t\t\t\t\t\tattempt.description,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tlastError = error;\n\t\t\t\t\t\tlogger.warn(\"TTS model download attempt failed:\", {\n\t\t\t\t\t\t\tdescription: attempt.description,\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!fs.existsSync(modelPath)) {\n\t\t\t\t\tthrow lastError || new Error(\"All download attempts failed\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.info(\"Loading TTS model...\");\n\t\t\tconst llama = await getLlama();\n\t\t\tthis.model = await llama.loadModel({\n\t\t\t\tmodelPath,\n\t\t\t\tgpuLayers: 0, // Force CPU for now until we add GPU support\n\t\t\t});\n\n\t\t\tthis.ctx = await this.model.createContext({\n\t\t\t\tcontextSize: modelSpec.contextSize,\n\t\t\t});\n\n\t\t\tthis.sequence = this.ctx.getSequence();\n\n\t\t\tlogger.success(\"TTS initialization complete\", {\n\t\t\t\tmodelPath,\n\t\t\t\tcontextSize: modelSpec.contextSize,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthis.initialized = true;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"TTS initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tmodel: MODEL_SPECS.tts.base.name,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Asynchronously generates speech from a given text using the initialized TTS model.\n\t * @param {string} text - The text to generate speech from.\n\t * @returns {Promise<Readable>} A promise that resolves to a Readable stream containing the generated audio data.\n\t * @throws {Error} If the TTS model is not initialized or if no audio tokens are generated.\n\t */\n\tpublic async generateSpeech(text: string): Promise<Readable> {\n\t\ttry {\n\t\t\tawait this.initialize();\n\n\t\t\tif (!this.model || !this.ctx || !this.sequence) {\n\t\t\t\tthrow new Error(\"TTS model not initialized\");\n\t\t\t}\n\n\t\t\tlogger.info(\"Starting speech generation for text:\", { text });\n\n\t\t\t// Format prompt for TTS generation\n\t\t\tconst prompt = `[SPEAKER=female_1][LANGUAGE=en]${text}`;\n\t\t\tlogger.info(\"Formatted prompt:\", { prompt });\n\n\t\t\t// Tokenize input\n\t\t\tlogger.info(\"Tokenizing input...\");\n\t\t\tconst inputTokens = this.model.tokenize(prompt);\n\t\t\tlogger.info(\"Input tokenized:\", { tokenCount: inputTokens.length });\n\n\t\t\t// Generate audio tokens with optimized limit (2x input)\n\t\t\tconst maxTokens = inputTokens.length * 2;\n\t\t\tlogger.info(\"Starting token generation with optimized limit:\", {\n\t\t\t\tmaxTokens,\n\t\t\t});\n\t\t\tconst responseTokens: Token[] = [];\n\t\t\tconst _startTime = Date.now();\n\n\t\t\ttry {\n\t\t\t\tfor await (const token of this.sequence.evaluate(inputTokens, {\n\t\t\t\t\ttemperature: 0.1,\n\t\t\t\t})) {\n\t\t\t\t\tresponseTokens.push(token);\n\n\t\t\t\t\t// Update progress bar\n\t\t\t\t\tconst percent = Math.round((responseTokens.length / maxTokens) * 100);\n\t\t\t\t\tconst barLength = 30;\n\t\t\t\t\tconst filledLength = Math.floor(\n\t\t\t\t\t\t(responseTokens.length / maxTokens) * barLength,\n\t\t\t\t\t);\n\t\t\t\t\tconst progressBar =\n\t\t\t\t\t\t\"▰\".repeat(filledLength) + \"▱\".repeat(barLength - filledLength);\n\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t`Token generation: ${progressBar} ${percent}% (${responseTokens.length}/${maxTokens})`,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Stop if we hit our token limit\n\t\t\t\t\tif (responseTokens.length >= maxTokens) {\n\t\t\t\t\t\tlogger.info(\"Token generation complete\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Token generation error:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// logger.info(\"Token generation stats:\", {\n\t\t\t// inputTokens: inputTokens.length,\n\t\t\t// outputTokens: responseTokens.length,\n\t\t\t// timeMs: Date.now() - startTime\n\t\t\t// });\n\n\t\t\tif (responseTokens.length === 0) {\n\t\t\t\tthrow new Error(\"No audio tokens generated\");\n\t\t\t}\n\n\t\t\t// Convert tokens to audio data\n\t\t\tlogger.info(\"Converting tokens to audio data...\");\n\t\t\tconst audioData = this.processAudioResponse({\n\t\t\t\ttokens: responseTokens.map((t) =>\n\t\t\t\t\tNumber.parseInt(this.model.detokenize([t]), 10),\n\t\t\t\t),\n\t\t\t});\n\n\t\t\tlogger.info(\"Audio data generated:\", {\n\t\t\t\tbyteLength: audioData.length,\n\t\t\t\tsampleRate: MODEL_SPECS.tts.base.sampleRate,\n\t\t\t});\n\n\t\t\t// Create WAV format\n\t\t\tconst audioStream = prependWavHeader(\n\t\t\t\tReadable.from(audioData),\n\t\t\t\taudioData.length,\n\t\t\t\tMODEL_SPECS.tts.base.sampleRate,\n\t\t\t\t1,\n\t\t\t\t16,\n\t\t\t);\n\n\t\t\tlogger.success(\"Speech generation complete\");\n\t\t\treturn audioStream;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Speech generation failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\ttext,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Processes the audio response from the TTS service by converting\n\t * the data to 16-bit PCM format.\n\t * If the response contains direct audio data, it converts Float32Array\n\t * to 16-bit PCM. If the response only contains tokens, it converts\n\t * them to PCM data. The actual conversion process may vary depending\n\t * on the model used.\n\t *\n\t * @param {TTSResponse} response - The response object from the TTS service\n\t * @returns {Buffer} The processed audio data in 16-bit PCM format\n\t */\n\tprivate processAudioResponse(response: TTSResponse): Buffer {\n\t\tif (response.audio) {\n\t\t\t// If we have direct audio data, convert Float32Array to 16-bit PCM\n\t\t\tconst pcmData = new Int16Array(response.audio.length);\n\t\t\tfor (let i = 0; i < response.audio.length; i++) {\n\t\t\t\t// Convert float to 16-bit PCM\n\t\t\t\tconst s = Math.max(-1, Math.min(1, response.audio[i]));\n\t\t\t\tpcmData[i] = s < 0 ? s * 0x8000 : s * 0x7fff;\n\t\t\t}\n\t\t\treturn Buffer.from(pcmData.buffer);\n\t\t}\n\n\t\t// If we only have tokens, convert them to PCM data\n\t\t// This is a placeholder implementation - actual conversion depends on model\n\t\tconst pcmData = new Int16Array(response.tokens.length * 2);\n\t\tfor (let i = 0; i < response.tokens.length; i++) {\n\t\t\t// Simple conversion for testing - replace with actual model-specific conversion\n\t\t\tpcmData[i * 2] = response.tokens[i] & 0xffff;\n\t\t\tpcmData[i * 2 + 1] = (response.tokens[i] >> 16) & 0xffff;\n\t\t}\n\t\treturn Buffer.from(pcmData.buffer);\n\t}\n}\n","import { PassThrough, type Readable } from \"node:stream\";\n\n/**\n * Generates a WAV header for audio data based on the input parameters.\n *\n * @param {number} audioLength - The length of the audio data in bytes.\n * @param {number} sampleRate - The sample rate of the audio data.\n * @param {number} [channelCount=1] - The number of audio channels (default is 1).\n * @param {number} [bitsPerSample=16] - The number of bits per audio sample (default is 16).\n * @returns {Buffer} - The WAV header as a Buffer.\n */\nexport function getWavHeader(\n\taudioLength: number,\n\tsampleRate: number,\n\tchannelCount = 1,\n\tbitsPerSample = 16,\n): Buffer {\n\tconst wavHeader = Buffer.alloc(44);\n\twavHeader.write(\"RIFF\", 0);\n\twavHeader.writeUInt32LE(36 + audioLength, 4); // Length of entire file in bytes minus 8\n\twavHeader.write(\"WAVE\", 8);\n\twavHeader.write(\"fmt \", 12);\n\twavHeader.writeUInt32LE(16, 16); // Length of format data\n\twavHeader.writeUInt16LE(1, 20); // Type of format (1 is PCM)\n\twavHeader.writeUInt16LE(channelCount, 22); // Number of channels\n\twavHeader.writeUInt32LE(sampleRate, 24); // Sample rate\n\twavHeader.writeUInt32LE((sampleRate * bitsPerSample * channelCount) / 8, 28); // Byte rate\n\twavHeader.writeUInt16LE((bitsPerSample * channelCount) / 8, 32); // Block align\n\twavHeader.writeUInt16LE(bitsPerSample, 34); // Bits per sample\n\twavHeader.write(\"data\", 36); // Data chunk header\n\twavHeader.writeUInt32LE(audioLength, 40); // Data chunk size\n\treturn wavHeader;\n}\n\n/**\n * Prepends a WAV header to an audio stream.\n *\n * @param {Readable} readable - The readable stream of audio data.\n * @param {number} audioLength - The length of the audio in seconds.\n * @param {number} sampleRate - The sample rate of the audio.\n * @param {number} [channelCount=1] - The number of audio channels. Default is 1.\n * @param {number} [bitsPerSample=16] - The number of bits per sample. Default is 16.\n * @returns {Readable} - A readable stream with the WAV header prepended to the audio data.\n */\nexport function prependWavHeader(\n\treadable: Readable,\n\taudioLength: number,\n\tsampleRate: number,\n\tchannelCount = 1,\n\tbitsPerSample = 16,\n): Readable {\n\tconst wavHeader = getWavHeader(\n\t\taudioLength,\n\t\tsampleRate,\n\t\tchannelCount,\n\t\tbitsPerSample,\n\t);\n\tlet pushedHeader = false;\n\tconst passThrough = new PassThrough();\n\treadable.on(\"data\", (data) => {\n\t\tif (!pushedHeader) {\n\t\t\tpassThrough.push(wavHeader);\n\t\t\tpushedHeader = true;\n\t\t}\n\t\tpassThrough.push(data);\n\t});\n\treadable.on(\"end\", () => {\n\t\tpassThrough.end();\n\t});\n\treturn passThrough;\n}\n","import { existsSync } from \"node:fs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { logger } from \"@elizaos/core\";\nimport {\n\tAutoProcessor,\n\tAutoTokenizer,\n\tFlorence2ForConditionalGeneration,\n\ttype Florence2Processor,\n\ttype PreTrainedModel,\n\ttype PreTrainedTokenizer,\n\ttype ProgressCallback,\n\ttype ProgressInfo,\n\tRawImage,\n\ttype Tensor,\n\tenv,\n} from \"@huggingface/transformers\";\nimport { MODEL_SPECS } from \"../types\";\nimport { DownloadManager } from \"./downloadManager\";\n\n// Define valid types based on HF transformers types\n/**\n * Defines the type 'DeviceType' which can take one of the three string values: 'cpu', 'gpu', or 'auto'\n */\ntype DeviceType = \"cpu\" | \"gpu\" | \"auto\";\n/**\n * Represents the available data types options.\n */\ntype DTypeType = \"fp32\" | \"fp16\" | \"auto\";\n\n/**\n * Interface for platform configuration options.\n * @typedef {Object} PlatformConfig\n * @property {DeviceType} device - The type of device to use.\n * @property {DTypeType} dtype - The data type to use.\n * @property {boolean} useOnnx - Flag indicating whether to use ONNX for processing.\n */\ninterface PlatformConfig {\n\tdevice: DeviceType;\n\tdtype: DTypeType;\n\tuseOnnx: boolean;\n}\n\n/**\n * Represents a model component with a name, type, and optionally a data type.\n * @interface ModelComponent\n * @property { string } name - The name of the model component.\n * @property { string } type - The type of the model component.\n * @property { DTypeType } [dtype] - The data type of the model component (optional).\n */\ninterface ModelComponent {\n\tname: string;\n\ttype: string;\n\tdtype?: DTypeType;\n}\n\n/**\n * Class representing a VisionManager.\n * @property {VisionManager | null} instance - The static instance of VisionManager.\n * @property {Florence2ForConditionalGeneration | null} model - The model for conditional generation.\n * @property {Florence2Processor | null} processor - The processor for Florence2.\n * @property {PreTrainedTokenizer | null} tokenizer - The pre-trained tokenizer.\n * @property {string} modelsDir - The directory for models.\n * @property {string} cacheDir - The directory for caching.\n * @property {boolean} initialized - Flag indicating if the VisionManager has been initialized.\n * @property {DownloadManager} downloadManager - The manager for downloading.\n */\nexport class VisionManager {\n\tprivate static instance: VisionManager | null = null;\n\tprivate model: Florence2ForConditionalGeneration | null = null;\n\tprivate processor: Florence2Processor | null = null;\n\tprivate tokenizer: PreTrainedTokenizer | null = null;\n\tprivate modelsDir: string;\n\tprivate cacheDir: string;\n\tprivate initialized = false;\n\tprivate downloadManager: DownloadManager;\n\tprivate modelDownloaded = false;\n\tprivate tokenizerDownloaded = false;\n\tprivate processorDownloaded = false;\n\tprivate platformConfig: PlatformConfig;\n\tprivate modelComponents: ModelComponent[] = [\n\t\t{ name: \"embed_tokens\", type: \"embeddings\" },\n\t\t{ name: \"vision_encoder\", type: \"encoder\" },\n\t\t{ name: \"decoder_model_merged\", type: \"decoder\" },\n\t\t{ name: \"encoder_model\", type: \"encoder\" },\n\t];\n\n\t/**\n\t * Constructor for VisionManager class.\n\t *\n\t * @param {string} cacheDir - The directory path for caching vision models.\n\t */\n\tprivate constructor(cacheDir: string) {\n\t\tthis.modelsDir = path.join(path.dirname(cacheDir), \"models\", \"vision\");\n\t\tthis.cacheDir = cacheDir;\n\t\tthis.ensureModelsDirExists();\n\t\tthis.downloadManager = DownloadManager.getInstance(\n\t\t\tthis.cacheDir,\n\t\t\tthis.modelsDir,\n\t\t);\n\t\tthis.platformConfig = this.getPlatformConfig();\n\t\tlogger.info(\"VisionManager initialized\");\n\t\t// logger.info(\"VisionManager initialized with configuration:\", {\n\t\t// modelsDir: this.modelsDir,\n\t\t// exists: existsSync(this.modelsDir),\n\t\t// platform: this.platformConfig\n\t\t// });\n\t}\n\n\t/**\n\t * Retrieves the platform configuration based on the operating system and architecture.\n\t * @returns {PlatformConfig} The platform configuration object with device, dtype, and useOnnx properties.\n\t */\n\tprivate getPlatformConfig(): PlatformConfig {\n\t\tconst platform = os.platform();\n\t\tconst arch = os.arch();\n\n\t\t// Default configuration\n\t\tlet config: PlatformConfig = {\n\t\t\tdevice: \"cpu\",\n\t\t\tdtype: \"fp32\",\n\t\t\tuseOnnx: true,\n\t\t};\n\n\t\tif (platform === \"darwin\" && (arch === \"arm64\" || arch === \"aarch64\")) {\n\t\t\t// Apple Silicon\n\t\t\tconfig = {\n\t\t\t\tdevice: \"gpu\",\n\t\t\t\tdtype: \"fp16\",\n\t\t\t\tuseOnnx: true,\n\t\t\t};\n\t\t} else if (platform === \"win32\" || platform === \"linux\") {\n\t\t\t// Windows or Linux with CUDA\n\t\t\tconst hasCuda = process.env.CUDA_VISIBLE_DEVICES !== undefined;\n\t\t\tif (hasCuda) {\n\t\t\t\tconfig = {\n\t\t\t\t\tdevice: \"gpu\",\n\t\t\t\t\tdtype: \"fp16\",\n\t\t\t\t\tuseOnnx: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlogger.info(\"Platform configuration detected:\", {\n\t\t\tplatform,\n\t\t\tarch,\n\t\t\tconfig,\n\t\t});\n\n\t\treturn config;\n\t}\n\n\t/**\n\t * Ensures that the models directory exists. If it does not exist, it creates the directory.\n\t */\n\tprivate ensureModelsDirExists(): void {\n\t\tif (!existsSync(this.modelsDir)) {\n\t\t\tlogger.info(`Creating models directory at: ${this.modelsDir}`);\n\t\t\tfs.mkdirSync(this.modelsDir, { recursive: true });\n\t\t}\n\t}\n\n\t/**\n\t * Returns the singleton instance of VisionManager.\n\t * If an instance does not already exist, a new instance is created with the specified cache directory.\n\t *\n\t * @param {string} cacheDir - The directory where cache files will be stored.\n\t *\n\t * @returns {VisionManager} The singleton instance of VisionManager.\n\t */\n\tpublic static getInstance(cacheDir: string): VisionManager {\n\t\tif (!VisionManager.instance) {\n\t\t\tVisionManager.instance = new VisionManager(cacheDir);\n\t\t}\n\t\treturn VisionManager.instance;\n\t}\n\n\t/**\n\t * Check if the cache exists for the specified model or tokenizer or processor.\n\t * @param {string} modelId - The ID of the model.\n\t * @param {\"model\" | \"tokenizer\" | \"processor\"} type - The type of the cache (\"model\", \"tokenizer\", or \"processor\").\n\t * @returns {boolean} - Returns true if cache exists, otherwise returns false.\n\t */\n\tprivate checkCacheExists(\n\t\tmodelId: string,\n\t\ttype: \"model\" | \"tokenizer\" | \"processor\",\n\t): boolean {\n\t\tconst modelPath = path.join(\n\t\t\tthis.modelsDir,\n\t\t\tmodelId.replace(\"/\", \"--\"),\n\t\t\ttype,\n\t\t);\n\t\tif (existsSync(modelPath)) {\n\t\t\tlogger.info(`${type} found at: ${modelPath}`);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Configures the model components based on the platform and architecture.\n\t * Sets the default data type (dtype) for components based on platform capabilities.\n\t * Updates all component dtypes to match the default dtype.\n\t */\n\tprivate configureModelComponents(): void {\n\t\tconst platform = os.platform();\n\t\tconst arch = os.arch();\n\n\t\t// Set dtype based on platform capabilities\n\t\tlet defaultDtype: DTypeType = \"fp32\";\n\n\t\tif (platform === \"darwin\" && (arch === \"arm64\" || arch === \"aarch64\")) {\n\t\t\t// Apple Silicon can handle fp16\n\t\t\tdefaultDtype = \"fp16\";\n\t\t} else if (\n\t\t\t(platform === \"win32\" || platform === \"linux\") &&\n\t\t\tprocess.env.CUDA_VISIBLE_DEVICES !== undefined\n\t\t) {\n\t\t\t// CUDA-enabled systems can handle fp16\n\t\t\tdefaultDtype = \"fp16\";\n\t\t}\n\n\t\t// Update all component dtypes\n\t\tthis.modelComponents = this.modelComponents.map((component) => ({\n\t\t\t...component,\n\t\t\tdtype: defaultDtype,\n\t\t}));\n\n\t\tlogger.info(\"Model components configured with dtype:\", {\n\t\t\tplatform,\n\t\t\tarch,\n\t\t\tdefaultDtype,\n\t\t\tcomponents: this.modelComponents.map((c) => `${c.name}: ${c.dtype}`),\n\t\t});\n\t}\n\n\t/**\n\t * Get the model configuration based on the input component name.\n\t * @param {string} componentName - The name of the component to retrieve the configuration for.\n\t * @returns {object} The model configuration object containing device, dtype, and cache_dir.\n\t */\n\tprivate getModelConfig(componentName: string) {\n\t\tconst component = this.modelComponents.find(\n\t\t\t(c) => c.name === componentName,\n\t\t);\n\t\treturn {\n\t\t\tdevice: this.platformConfig.device,\n\t\t\tdtype: component?.dtype || \"fp32\",\n\t\t\tcache_dir: this.modelsDir,\n\t\t};\n\t}\n\n\t/**\n\t * Asynchronous method to initialize the vision model by loading Florence2 model, vision tokenizer, and vision processor.\n\t *\n\t * @returns {Promise<void>} - Promise that resolves once the initialization process is completed.\n\t * @throws {Error} - If there is an error during the initialization process.\n\t */\n\tprivate async initialize() {\n\t\ttry {\n\t\t\tif (this.initialized) {\n\t\t\t\tlogger.info(\n\t\t\t\t\t\"Vision model already initialized, skipping initialization\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlogger.info(\"Starting vision model initialization...\");\n\t\t\tconst modelSpec = MODEL_SPECS.vision;\n\n\t\t\t// Configure environment\n\t\t\tlogger.info(\"Configuring environment for vision model...\");\n\t\t\tenv.allowLocalModels = true;\n\t\t\tenv.allowRemoteModels = true;\n\n\t\t\t// Configure ONNX backend\n\t\t\tif (this.platformConfig.useOnnx) {\n\t\t\t\tenv.backends.onnx.enabled = true;\n\t\t\t\tenv.backends.onnx.logLevel = \"info\";\n\t\t\t}\n\n\t\t\t// logger.info(\"Vision model configuration:\", {\n\t\t\t// modelId: modelSpec.modelId,\n\t\t\t// modelsDir: this.modelsDir,\n\t\t\t// allowLocalModels: env.allowLocalModels,\n\t\t\t// allowRemoteModels: env.allowRemoteModels,\n\t\t\t// platform: this.platformConfig\n\t\t\t// });\n\n\t\t\t// Initialize model with detailed logging\n\t\t\tlogger.info(\"Loading Florence2 model...\");\n\t\t\ttry {\n\t\t\t\tlet lastProgress = -1;\n\t\t\t\tconst modelCached = this.checkCacheExists(modelSpec.modelId, \"model\");\n\n\t\t\t\tconst model = await Florence2ForConditionalGeneration.from_pretrained(\n\t\t\t\t\tmodelSpec.modelId,\n\t\t\t\t\t{\n\t\t\t\t\t\tdevice: \"cpu\",\n\t\t\t\t\t\tcache_dir: this.modelsDir,\n\t\t\t\t\t\tlocal_files_only: modelCached,\n\t\t\t\t\t\trevision: \"main\",\n\t\t\t\t\t\tprogress_callback: ((progressInfo: ProgressInfo) => {\n\t\t\t\t\t\t\tif (modelCached || this.modelDownloaded) return;\n\t\t\t\t\t\t\tconst progress =\n\t\t\t\t\t\t\t\t\"progress\" in progressInfo\n\t\t\t\t\t\t\t\t\t? Math.max(0, Math.min(1, progressInfo.progress))\n\t\t\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t\t\tconst currentProgress = Math.round(progress * 100);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tcurrentProgress > lastProgress + 9 ||\n\t\t\t\t\t\t\t\tcurrentProgress === 100\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tlastProgress = currentProgress;\n\t\t\t\t\t\t\t\tconst barLength = 30;\n\t\t\t\t\t\t\t\tconst filledLength = Math.floor(\n\t\t\t\t\t\t\t\t\t(currentProgress / 100) * barLength,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst progressBar =\n\t\t\t\t\t\t\t\t\t\"▰\".repeat(filledLength) +\n\t\t\t\t\t\t\t\t\t\"▱\".repeat(barLength - filledLength);\n\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t`Downloading vision model: ${progressBar} ${currentProgress}%`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (currentProgress === 100) this.modelDownloaded = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}) as ProgressCallback,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tthis.model = model as unknown as Florence2ForConditionalGeneration;\n\t\t\t\tlogger.success(\"Florence2 model loaded successfully\");\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to load Florence2 model:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\tmodelId: modelSpec.modelId,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// Initialize tokenizer with detailed logging\n\t\t\tlogger.info(\"Loading vision tokenizer...\");\n\t\t\ttry {\n\t\t\t\tconst tokenizerCached = this.checkCacheExists(\n\t\t\t\t\tmodelSpec.modelId,\n\t\t\t\t\t\"tokenizer\",\n\t\t\t\t);\n\t\t\t\tlet tokenizerProgress = -1;\n\n\t\t\t\tthis.tokenizer = await AutoTokenizer.from_pretrained(\n\t\t\t\t\tmodelSpec.modelId,\n\t\t\t\t\t{\n\t\t\t\t\t\tcache_dir: this.modelsDir,\n\t\t\t\t\t\tlocal_files_only: tokenizerCached,\n\t\t\t\t\t\tprogress_callback: ((progressInfo: ProgressInfo) => {\n\t\t\t\t\t\t\tif (tokenizerCached || this.tokenizerDownloaded) return;\n\t\t\t\t\t\t\tconst progress =\n\t\t\t\t\t\t\t\t\"progress\" in progressInfo\n\t\t\t\t\t\t\t\t\t? Math.max(0, Math.min(1, progressInfo.progress))\n\t\t\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t\t\tconst currentProgress = Math.round(progress * 100);\n\t\t\t\t\t\t\tif (currentProgress !== tokenizerProgress) {\n\t\t\t\t\t\t\t\ttokenizerProgress = currentProgress;\n\t\t\t\t\t\t\t\tconst barLength = 30;\n\t\t\t\t\t\t\t\tconst filledLength = Math.floor(\n\t\t\t\t\t\t\t\t\t(currentProgress / 100) * barLength,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst progressBar =\n\t\t\t\t\t\t\t\t\t\"▰\".repeat(filledLength) +\n\t\t\t\t\t\t\t\t\t\"▱\".repeat(barLength - filledLength);\n\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t`Downloading vision tokenizer: ${progressBar} ${currentProgress}%`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (currentProgress === 100) this.tokenizerDownloaded = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}) as ProgressCallback,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tlogger.success(\"Vision tokenizer loaded successfully\");\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to load tokenizer:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\tmodelId: modelSpec.modelId,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// Initialize processor with detailed logging\n\t\t\tlogger.info(\"Loading vision processor...\");\n\t\t\ttry {\n\t\t\t\tconst processorCached = this.checkCacheExists(\n\t\t\t\t\tmodelSpec.modelId,\n\t\t\t\t\t\"processor\",\n\t\t\t\t);\n\t\t\t\tlet processorProgress = -1;\n\n\t\t\t\tthis.processor = (await AutoProcessor.from_pretrained(\n\t\t\t\t\tmodelSpec.modelId,\n\t\t\t\t\t{\n\t\t\t\t\t\tdevice: \"cpu\",\n\t\t\t\t\t\tcache_dir: this.modelsDir,\n\t\t\t\t\t\tlocal_files_only: processorCached,\n\t\t\t\t\t\tprogress_callback: ((progressInfo: ProgressInfo) => {\n\t\t\t\t\t\t\tif (processorCached || this.processorDownloaded) return;\n\t\t\t\t\t\t\tconst progress =\n\t\t\t\t\t\t\t\t\"progress\" in progressInfo\n\t\t\t\t\t\t\t\t\t? Math.max(0, Math.min(1, progressInfo.progress))\n\t\t\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t\t\tconst currentProgress = Math.round(progress * 100);\n\t\t\t\t\t\t\tif (currentProgress !== processorProgress) {\n\t\t\t\t\t\t\t\tprocessorProgress = currentProgress;\n\t\t\t\t\t\t\t\tconst barLength = 30;\n\t\t\t\t\t\t\t\tconst filledLength = Math.floor(\n\t\t\t\t\t\t\t\t\t(currentProgress / 100) * barLength,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconst progressBar =\n\t\t\t\t\t\t\t\t\t\"▰\".repeat(filledLength) +\n\t\t\t\t\t\t\t\t\t\"▱\".repeat(barLength - filledLength);\n\t\t\t\t\t\t\t\tlogger.info(\n\t\t\t\t\t\t\t\t\t`Downloading vision processor: ${progressBar} ${currentProgress}%`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (currentProgress === 100) this.processorDownloaded = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}) as ProgressCallback,\n\t\t\t\t\t},\n\t\t\t\t)) as Florence2Processor;\n\t\t\t\tlogger.success(\"Vision processor loaded successfully\");\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to load vision processor:\", {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\t\tmodelId: modelSpec.modelId,\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tthis.initialized = true;\n\t\t\tlogger.success(\"Vision model initialization complete\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Vision model initialization failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\tmodelsDir: this.modelsDir,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Fetches an image from a given URL and returns the image data as a Buffer along with its MIME type.\n\t *\n\t * @param {string} url - The URL of the image to fetch.\n\t * @returns {Promise<{ buffer: Buffer; mimeType: string }>} Object containing the image data as a Buffer and its MIME type.\n\t */\n\tprivate async fetchImage(\n\t\turl: string,\n\t): Promise<{ buffer: Buffer; mimeType: string }> {\n\t\ttry {\n\t\t\tlogger.info(`Fetching image from URL: ${url.slice(0, 100)}...`);\n\n\t\t\t// Handle data URLs differently\n\t\t\tif (url.startsWith(\"data:\")) {\n\t\t\t\tlogger.info(\"Processing data URL...\");\n\t\t\t\tconst [header, base64Data] = url.split(\",\");\n\t\t\t\tconst mimeType = header.split(\";\")[0].split(\":\")[1];\n\t\t\t\tconst buffer = Buffer.from(base64Data, \"base64\");\n\t\t\t\tlogger.info(\"Data URL processed successfully\");\n\t\t\t\t// logger.info(\"Data URL processed successfully:\", {\n\t\t\t\t// mimeType,\n\t\t\t\t// bufferSize: buffer.length\n\t\t\t\t// });\n\t\t\t\treturn { buffer, mimeType };\n\t\t\t}\n\n\t\t\t// Handle regular URLs\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch image: ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = Buffer.from(await response.arrayBuffer());\n\t\t\tconst mimeType = response.headers.get(\"content-type\") || \"image/jpeg\";\n\n\t\t\tlogger.info(\"Image fetched successfully:\", {\n\t\t\t\tmimeType,\n\t\t\t\tbufferSize: buffer.length,\n\t\t\t\tstatus: response.status,\n\t\t\t});\n\n\t\t\treturn { buffer, mimeType };\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to fetch image:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\turl,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Processes the image from the provided URL using the initialized vision model components.\n\t * @param {string} imageUrl - The URL of the image to process.\n\t * @returns {Promise<{ title: string; description: string }>} An object containing the title and description of the processed image.\n\t */\n\tpublic async processImage(\n\t\timageUrl: string,\n\t): Promise<{ title: string; description: string }> {\n\t\ttry {\n\t\t\tlogger.info(\"Starting image processing...\");\n\n\t\t\t// Ensure model is initialized\n\t\t\tif (!this.initialized) {\n\t\t\t\tlogger.info(\"Vision model not initialized, initializing now...\");\n\t\t\t\tawait this.initialize();\n\t\t\t}\n\n\t\t\tif (!this.model || !this.processor || !this.tokenizer) {\n\t\t\t\tthrow new Error(\"Vision model components not properly initialized\");\n\t\t\t}\n\n\t\t\t// Fetch and process image\n\t\t\tlogger.info(\"Fetching image...\");\n\t\t\tconst { buffer, mimeType } = await this.fetchImage(imageUrl);\n\n\t\t\t// Process image\n\t\t\tlogger.info(\"Creating image blob...\");\n\t\t\tconst blob = new Blob([buffer], { type: mimeType });\n\t\t\tlogger.info(\"Converting blob to RawImage...\");\n\t\t\t// @ts-ignore - RawImage.fromBlob expects web Blob but works with node Blob\n\t\t\tconst image = await RawImage.fromBlob(blob);\n\n\t\t\tlogger.info(\"Processing image with vision processor...\");\n\t\t\tconst visionInputs = await this.processor(image);\n\t\t\tlogger.info(\"Constructing prompts...\");\n\t\t\tconst prompts = this.processor.construct_prompts(\"<DETAILED_CAPTION>\");\n\t\t\tlogger.info(\"Tokenizing prompts...\");\n\t\t\tconst textInputs = this.tokenizer(prompts);\n\n\t\t\t// Generate description\n\t\t\tlogger.info(\"Generating image description...\");\n\t\t\tconst generatedIds = (await this.model.generate({\n\t\t\t\t...textInputs,\n\t\t\t\t...visionInputs,\n\t\t\t\tmax_new_tokens: MODEL_SPECS.vision.maxTokens,\n\t\t\t})) as Tensor;\n\n\t\t\tlogger.info(\"Decoding generated text...\");\n\t\t\tconst generatedText = this.tokenizer.batch_decode(generatedIds, {\n\t\t\t\tskip_special_tokens: false,\n\t\t\t})[0];\n\n\t\t\tlogger.info(\"Post-processing generation...\");\n\t\t\tconst result = this.processor.post_process_generation(\n\t\t\t\tgeneratedText,\n\t\t\t\t\"<DETAILED_CAPTION>\",\n\t\t\t\timage.size,\n\t\t\t);\n\n\t\t\tconst detailedCaption = result[\"<DETAILED_CAPTION>\"] as string;\n\t\t\tconst response = {\n\t\t\t\ttitle: `${detailedCaption.split(\".\")[0]}.`,\n\t\t\t\tdescription: detailedCaption,\n\t\t\t};\n\n\t\t\tlogger.success(\"Image processing complete:\", {\n\t\t\t\ttitleLength: response.title.length,\n\t\t\t\tdescriptionLength: response.description.length,\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Image processing failed:\", {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t\timageUrl,\n\t\t\t\tmodelInitialized: this.initialized,\n\t\t\t\thasModel: !!this.model,\n\t\t\t\thasProcessor: !!this.processor,\n\t\t\t\thasTokenizer: !!this.tokenizer,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"],"mappings":"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","names":["fs","path","Readable","ModelTypes","logger","getLlama","logger","logger","http","https","Stream","PassThrough","Buffer","Buffer","Buffer","types","INTERNALS","deprecate","INTERNALS","deprecate","fetch","response","https","http","Stream","PassThrough","Buffer","logger","fetch","promisify","logger","ModelTypes","logger","logger","fetch","ModelTypes","logger","fs","exec","fs","path","promisify","logger","execAsync","fs","path","logger","PassThrough","path","logger","fs","pcmData","fs","os","path","process","logger","AutoTokenizer","path","logger","os","process","fs","AutoTokenizer","mimeType","buffer","path","logger","ModelTypes","fs","Readable","getLlama"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/environment.ts","../src/types.ts","../src/utils/downloadManager.ts","../src/utils/ollamaManager.ts","../src/utils/platform.ts","../src/utils/studiolmManager.ts","../src/utils/tokenizerManager.ts","../src/utils/transcribeManager.ts","../src/utils/ttsManager.ts","../src/utils/audioUtils.ts","../src/utils/visionManager.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { fileURLToPath } from 'node:url';\nimport type {\n GenerateTextParams,\n ModelTypeName,\n TextEmbeddingParams,\n ObjectGenerationParams,\n} from '@elizaos/core';\nimport { type IAgentRuntime, ModelType, type Plugin, logger } from '@elizaos/core';\nimport { EmbeddingModel, FlagEmbedding } from 'fastembed';\nimport {\n type Llama,\n LlamaChatSession,\n type LlamaContext,\n type LlamaContextSequence,\n type LlamaModel,\n getLlama,\n} from 'node-llama-cpp';\nimport { validateConfig } from './environment';\nimport { MODEL_SPECS, type ModelSpec } from './types';\nimport { DownloadManager } from './utils/downloadManager';\nimport { OllamaManager } from './utils/ollamaManager';\nimport { getPlatformManager } from './utils/platform';\nimport { StudioLMManager } from './utils/studiolmManager';\nimport { TokenizerManager } from './utils/tokenizerManager';\nimport { TranscribeManager } from './utils/transcribeManager';\nimport { TTSManager } from './utils/ttsManager';\nimport { VisionManager } from './utils/visionManager';\n\n// const execAsync = promisify(exec);\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Words to punish in LLM responses\n/**\n * Array containing words that should trigger a punishment when used in a message.\n * This array includes words like \"please\", \"feel\", \"free\", punctuation marks, and various topic-related words.\n * @type {string[]}\n */\nconst wordsToPunish = [\n ' please',\n ' feel',\n ' free',\n '!',\n '–',\n '—',\n '?',\n '.',\n ',',\n '; ',\n ' cosmos',\n ' tapestry',\n ' tapestries',\n ' glitch',\n ' matrix',\n ' cyberspace',\n ' troll',\n ' questions',\n ' topics',\n ' discuss',\n ' basically',\n ' simulation',\n ' simulate',\n ' universe',\n ' like',\n ' debug',\n ' debugging',\n ' wild',\n ' existential',\n ' juicy',\n ' circuits',\n ' help',\n ' ask',\n ' happy',\n ' just',\n ' cosmic',\n ' cool',\n ' joke',\n ' punchline',\n ' fancy',\n ' glad',\n ' assist',\n ' algorithm',\n ' Indeed',\n ' Furthermore',\n ' However',\n ' Notably',\n ' Therefore',\n];\n\n// Add type definitions for model source selection\n/**\n * Represents the available sources for a text model: \"local\", \"studiolm\", or \"ollama\".\n */\ntype TextModelSource = 'local' | 'studiolm' | 'ollama';\n\n/**\n * Interface representing the configuration for a text model.\n *\n * @property {TextModelSource} source - The source of the text model.\n * @property {ModelTypeName} modelType - The type of the model.\n */\ninterface TextModelConfig {\n source: TextModelSource;\n modelType: ModelTypeName;\n}\n\n/**\n * Class representing a LocalAIManager.\n * @property {LocalAIManager | null} instance - The static instance of LocalAIManager.\n * @property {Llama | undefined} llama - The llama object.\n * @property {LlamaModel | undefined} smallModel - The small LlamaModel object.\n * @property {LlamaModel | undefined} mediumModel - The medium LlamaModel object.\n * @property {LlamaContext | undefined} ctx - The LlamaContext object.\n * @property {LlamaContextSequence | undefined} sequence - The LlamaContextSequence object.\n * @property {LlamaChatSession | undefined} chatSession - The LlamaChatSession object.\n * @property {string} modelPath - The path to the model.\n */\nclass LocalAIManager {\n private static instance: LocalAIManager | null = null;\n private llama: Llama | undefined;\n private smallModel: LlamaModel | undefined;\n private mediumModel: LlamaModel | undefined;\n private ctx: LlamaContext | undefined;\n private sequence: LlamaContextSequence | undefined;\n private chatSession: LlamaChatSession | undefined;\n private modelPath: string;\n private mediumModelPath: string;\n private cacheDir: string;\n private embeddingModel: FlagEmbedding | null = null;\n private tokenizerManager: TokenizerManager;\n private downloadManager: DownloadManager;\n private visionManager: VisionManager;\n private activeModelConfig: ModelSpec;\n private transcribeManager: TranscribeManager;\n private ttsManager: TTSManager;\n private studioLMManager: StudioLMManager;\n private ollamaManager: OllamaManager;\n\n // Initialization state flags\n private ollamaInitialized = false;\n private studioLMInitialized = false;\n private smallModelInitialized = false;\n private mediumModelInitialized = false;\n private embeddingInitialized = false;\n private visionInitialized = false;\n private transcriptionInitialized = false;\n private ttsInitialized = false;\n\n // Initialization promises to prevent duplicate initialization\n private smallModelInitializingPromise: Promise<void> | null = null;\n private mediumModelInitializingPromise: Promise<void> | null = null;\n private embeddingInitializingPromise: Promise<void> | null = null;\n private visionInitializingPromise: Promise<void> | null = null;\n private transcriptionInitializingPromise: Promise<void> | null = null;\n private ttsInitializingPromise: Promise<void> | null = null;\n private ollamaInitializingPromise: Promise<void> | null = null;\n private studioLMInitializingPromise: Promise<void> | null = null;\n\n private modelsDir: string;\n\n /**\n * Private constructor function to initialize base managers and paths.\n * This now only sets up the basic infrastructure without loading any models.\n */\n private constructor() {\n // Set up models directory consistently, similar to cacheDir\n const modelsDir = path.join(process.cwd(), 'models');\n\n // Check if LLAMALOCAL_PATH is set\n if (process.env.LLAMALOCAL_PATH?.trim()) {\n this.modelsDir = path.resolve(process.env.LLAMALOCAL_PATH.trim());\n } else {\n // Ensure models directory exists\n if (!fs.existsSync(modelsDir)) {\n fs.mkdirSync(modelsDir, { recursive: true });\n logger.debug('Created models directory');\n }\n this.modelsDir = modelsDir;\n }\n\n // Set paths for models\n this.modelPath = path.join(this.modelsDir, 'DeepHermes-3-Llama-3-3B-Preview-q4.gguf');\n\n this.mediumModelPath = path.join(this.modelsDir, 'DeepHermes-3-Llama-3-8B-q4.gguf');\n\n // Set up cache directory\n const cacheDirEnv = process.env.CACHE_DIR?.trim();\n if (cacheDirEnv) {\n this.cacheDir = path.resolve(cacheDirEnv);\n } else {\n const cacheDir = path.join(process.cwd(), 'cache');\n // Ensure cache directory exists\n if (!fs.existsSync(cacheDir)) {\n fs.mkdirSync(cacheDir, { recursive: true });\n logger.debug('Ensuring cache directory exists:', cacheDir);\n }\n this.cacheDir = cacheDir;\n }\n\n // Initialize the download manager\n this.downloadManager = DownloadManager.getInstance(this.cacheDir, this.modelsDir);\n\n // Initialize tokenizer manager\n this.tokenizerManager = TokenizerManager.getInstance(this.cacheDir, this.modelsDir);\n\n // Initialize vision manager\n this.visionManager = VisionManager.getInstance(this.cacheDir);\n\n // Initialize transcribe manager\n this.transcribeManager = TranscribeManager.getInstance(this.cacheDir);\n\n // Initialize TTS manager\n this.ttsManager = TTSManager.getInstance(this.cacheDir);\n\n // Initialize StudioLM manager if enabled\n if (process.env.USE_STUDIOLM_TEXT_MODELS === 'true') {\n this.studioLMManager = StudioLMManager.getInstance();\n }\n\n // Initialize Ollama manager if enabled\n if (process.env.USE_OLLAMA_TEXT_MODELS === 'true') {\n this.ollamaManager = OllamaManager.getInstance();\n }\n\n // Initialize active model config\n this.activeModelConfig = MODEL_SPECS.small;\n }\n\n /**\n * Retrieves the singleton instance of LocalAIManager. If an instance does not already exist, a new one is created and returned.\n * @returns {LocalAIManager} The singleton instance of LocalAIManager\n */\n public static getInstance(): LocalAIManager {\n if (!LocalAIManager.instance) {\n LocalAIManager.instance = new LocalAIManager();\n }\n return LocalAIManager.instance;\n }\n\n /**\n * Initializes the environment by validating the configuration and setting the environment variables with the validated values.\n *\n * @returns {Promise<void>} A Promise that resolves once the environment has been successfully initialized.\n */\n private async initializeEnvironment(): Promise<void> {\n try {\n logger.info('Validating environment configuration...');\n\n // Create initial config from current env vars\n const config = {\n USE_LOCAL_AI: process.env.USE_LOCAL_AI,\n USE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n USE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS,\n };\n\n // Validate configuration\n const validatedConfig = await validateConfig(config);\n\n // Log the validated configuration\n // logger.info(\"Environment configuration validated:\", validatedConfig);\n logger.info('Environment configuration validated');\n\n // Ensure environment variables are set with validated values\n process.env.USE_LOCAL_AI = String(validatedConfig.USE_LOCAL_AI);\n process.env.USE_STUDIOLM_TEXT_MODELS = String(validatedConfig.USE_STUDIOLM_TEXT_MODELS);\n process.env.USE_OLLAMA_TEXT_MODELS = String(validatedConfig.USE_OLLAMA_TEXT_MODELS);\n\n // logger.info(\"Environment variables updated with validated values:\", {\n // USE_LOCAL_AI: process.env.USE_LOCAL_AI,\n // USE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n // USE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS\n // });\n\n logger.success('Environment initialization complete');\n } catch (error) {\n logger.error('Environment validation failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously initializes the Ollama model.\n *\n * @returns {Promise<void>} A Promise that resolves when the initialization is complete.\n * @throws {Error} If the Ollama manager is not created, or if initialization of Ollama models fails.\n */\n private async initializeOllama(): Promise<void> {\n try {\n logger.info('Initializing Ollama models...');\n\n // Check if Ollama manager exists\n if (!this.ollamaManager) {\n throw new Error('Ollama manager not created - cannot initialize');\n }\n\n // Initialize and test models\n await this.ollamaManager.initialize();\n\n if (!this.ollamaManager.isInitialized()) {\n throw new Error('Ollama initialization failed - models not properly loaded');\n }\n\n logger.success('Ollama initialization complete');\n } catch (error) {\n logger.error('Ollama initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Initializes StudioLM model with error handling.\n * @returns A Promise that resolves when the initialization is complete.\n * @throws {Error} If StudioLM manager is not created, initialization fails, or models are not properly loaded.\n */\n private async initializeStudioLM(): Promise<void> {\n try {\n logger.info('Initializing StudioLM models...');\n\n // Check if StudioLM manager exists\n if (!this.studioLMManager) {\n throw new Error('StudioLM manager not created - cannot initialize');\n }\n\n // Initialize and test models\n await this.studioLMManager.initialize();\n\n if (!this.studioLMManager.isInitialized()) {\n throw new Error('StudioLM initialization failed - models not properly loaded');\n }\n\n this.studioLMInitialized = true;\n logger.success('StudioLM initialization complete');\n } catch (error) {\n logger.error('StudioLM initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Downloads the model based on the modelPath provided.\n * Determines whether to download a large or small model based on the current modelPath.\n *\n * @returns A Promise that resolves to a boolean indicating whether the model download was successful.\n */\n private async downloadModel(modelType: ModelTypeName): Promise<boolean> {\n const modelSpec = modelType === ModelType.TEXT_LARGE ? MODEL_SPECS.medium : MODEL_SPECS.small;\n const modelPath = modelType === ModelType.TEXT_LARGE ? this.mediumModelPath : this.modelPath;\n try {\n return await this.downloadManager.downloadModel(modelSpec, modelPath);\n } catch (error) {\n logger.error('Model download failed:', {\n error: error instanceof Error ? error.message : String(error),\n modelPath,\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously checks the platform capabilities.\n *\n * @returns {Promise<void>} A promise that resolves once the platform capabilities have been checked.\n */\n public async checkPlatformCapabilities(): Promise<void> {\n try {\n const platformManager = getPlatformManager();\n await platformManager.initialize();\n const capabilities = platformManager.getCapabilities();\n\n logger.info('Platform capabilities detected:', {\n platform: capabilities.platform,\n gpu: capabilities.gpu?.type || 'none',\n recommendedModel: capabilities.recommendedModelSize,\n supportedBackends: capabilities.supportedBackends,\n });\n } catch (error) {\n logger.warn('Platform detection failed:', error);\n }\n }\n\n /**\n * Initializes the LocalAI Manager for a given model type.\n *\n * @param {ModelTypeName} modelType - The type of model to initialize (default: ModelType.TEXT_SMALL)\n * @returns {Promise<void>} A promise that resolves when initialization is complete or rejects if an error occurs\n */\n async initialize(modelType: ModelTypeName = ModelType.TEXT_SMALL): Promise<void> {\n if (modelType === ModelType.TEXT_LARGE) {\n await this.lazyInitMediumModel();\n } else {\n await this.lazyInitSmallModel();\n }\n }\n\n /**\n * Asynchronously initializes the embedding model.\n *\n * @returns {Promise<void>} A promise that resolves once the initialization is complete.\n */\n public async initializeEmbedding(): Promise<void> {\n try {\n logger.info('Initializing embedding model...');\n logger.info('Models directory:', this.modelsDir);\n\n // Ensure models directory exists\n if (!fs.existsSync(this.modelsDir)) {\n logger.warn('Models directory does not exist, creating it:', this.modelsDir);\n fs.mkdirSync(this.modelsDir, { recursive: true });\n }\n\n if (!this.embeddingModel) {\n logger.info('Creating new FlagEmbedding instance with BGESmallENV15 model');\n // logger.info(\"Embedding model download details:\", {\n // model: EmbeddingModel.BGESmallENV15,\n // modelsDir: this.modelsDir,\n // maxLength: 512,\n // timestamp: new Date().toISOString()\n // });\n\n // Display initial progress bar\n const barLength = 30;\n const emptyBar = '▱'.repeat(barLength);\n logger.info(`Downloading embedding model: ${emptyBar} 0%`);\n\n // Disable built-in progress bar and initialize the model\n this.embeddingModel = await FlagEmbedding.init({\n cacheDir: this.modelsDir,\n model: EmbeddingModel.BGESmallENV15,\n maxLength: 512,\n showDownloadProgress: false,\n });\n\n // Display completed progress bar\n const completedBar = '▰'.repeat(barLength);\n logger.info(`Downloading embedding model: ${completedBar} 100%`);\n logger.success('FlagEmbedding instance created successfully');\n }\n } catch (error) {\n logger.error('Embedding initialization failed with details:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelsDir: this.modelsDir,\n model: EmbeddingModel.BGESmallENV15,\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously generates text using either StudioLM or Ollama models based on the specified parameters.\n *\n * @param {GenerateTextParams} params - The parameters for generating the text.\n * @returns {Promise<string>} - A promise that resolves to the generated text.\n */\n async generateTextOllamaStudio(params: GenerateTextParams): Promise<string> {\n try {\n const modelConfig = this.getTextModelSource();\n logger.info('generateTextOllamaStudio called with:', {\n modelSource: modelConfig.source,\n modelType: params.modelType,\n studioLMInitialized: this.studioLMInitialized,\n ollamaInitialized: this.ollamaInitialized,\n studioLMEnabled: process.env.USE_STUDIOLM_TEXT_MODELS === 'true',\n ollamaEnabled: process.env.USE_OLLAMA_TEXT_MODELS === 'true',\n });\n\n if (modelConfig.source === 'studiolm') {\n // Check if StudioLM is enabled in environment\n if (process.env.USE_STUDIOLM_TEXT_MODELS !== 'true') {\n logger.warn(\n 'StudioLM requested but disabled in environment, falling back to local models'\n );\n return this.generateText(params);\n }\n\n // Check if StudioLM manager exists\n if (!this.studioLMManager) {\n logger.warn('StudioLM manager not initialized, falling back to local models');\n return this.generateText(params);\n }\n\n // Only initialize if not already initialized\n if (!this.studioLMInitialized) {\n logger.info('StudioLM not initialized, initializing now...');\n await this.initializeStudioLM();\n }\n\n // Pass initialization flag to generateText\n return await this.studioLMManager.generateText(params, this.studioLMInitialized);\n }\n\n if (modelConfig.source === 'ollama') {\n // Check if Ollama is enabled in environment\n if (process.env.USE_OLLAMA_TEXT_MODELS !== 'true') {\n logger.warn('Ollama requested but disabled in environment, falling back to local models');\n return this.generateText(params);\n }\n\n // Check if Ollama manager exists\n if (!this.ollamaManager) {\n logger.warn('Ollama manager not initialized, falling back to local models');\n return this.generateText(params);\n }\n\n // Only initialize if not already initialized\n if (!this.ollamaInitialized && !this.ollamaManager.isInitialized()) {\n logger.info('Initializing Ollama in generateTextOllamaStudio');\n await this.ollamaManager.initialize();\n this.ollamaInitialized = true;\n }\n\n // Pass initialization flag to generateText\n return await this.ollamaManager.generateText(params, this.ollamaInitialized);\n }\n\n // Fallback to local models if something goes wrong\n return this.generateText(params);\n } catch (error) {\n logger.error('Text generation with Ollama/StudioLM failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelSource: this.getTextModelSource().source,\n });\n // Fallback to local models\n return this.generateText(params);\n }\n }\n\n /**\n * Asynchronously generates text based on the provided parameters.\n * Now uses lazy initialization for models\n */\n async generateText(params: GenerateTextParams): Promise<string> {\n try {\n // Lazy initialize the appropriate model\n if (params.modelType === ModelType.TEXT_LARGE) {\n await this.lazyInitMediumModel();\n\n if (!this.mediumModel) {\n throw new Error('Medium model initialization failed');\n }\n\n this.activeModelConfig = MODEL_SPECS.medium;\n const mediumModel = this.mediumModel;\n\n // Create fresh context\n this.ctx = await mediumModel.createContext({\n contextSize: MODEL_SPECS.medium.contextSize,\n });\n } else {\n await this.lazyInitSmallModel();\n\n if (!this.smallModel) {\n throw new Error('Small model initialization failed');\n }\n\n this.activeModelConfig = MODEL_SPECS.small;\n const smallModel = this.smallModel;\n\n // Create fresh context\n this.ctx = await smallModel.createContext({\n contextSize: MODEL_SPECS.small.contextSize,\n });\n }\n\n if (!this.ctx) {\n throw new Error('Failed to create prompt');\n }\n\n // QUICK TEST FIX: Always get fresh sequence\n this.sequence = this.ctx.getSequence();\n\n // QUICK TEST FIX: Create new session each time without maintaining state\n // Only use valid options for LlamaChatSession\n this.chatSession = new LlamaChatSession({\n contextSequence: this.sequence,\n });\n\n if (!this.chatSession) {\n throw new Error('Failed to create chat session');\n }\n logger.info('Created new chat session for model:', params.modelType);\n // Log incoming prompt for debugging\n logger.info('Incoming prompt structure:', {\n contextLength: params.prompt.length,\n hasAction: params.prompt.includes('action'),\n runtime: !!params.runtime,\n stopSequences: params.stopSequences,\n });\n\n const tokens = await this.tokenizerManager.encode(params.prompt, this.activeModelConfig);\n logger.info('Input tokens:', { count: tokens.length });\n\n // QUICK TEST FIX: Add system message to reset prompt\n const systemMessage = 'You are a helpful AI assistant. Respond to the current request only.';\n await this.chatSession.prompt(systemMessage, {\n maxTokens: 1, // Minimal tokens for system message\n temperature: 0.0,\n });\n\n let response = await this.chatSession.prompt(params.prompt, {\n maxTokens: 8192,\n temperature: 0.7,\n topP: 0.9,\n repeatPenalty: {\n punishTokensFilter: () => this.smallModel!.tokenize(wordsToPunish.join(' ')),\n penalty: 1.2,\n frequencyPenalty: 0.7,\n presencePenalty: 0.7,\n },\n });\n\n // Log raw response for debugging\n logger.info('Raw response structure:', {\n responseLength: response.length,\n hasAction: response.includes('action'),\n hasThinkTag: response.includes('<think>'),\n });\n\n // Clean think tags if present\n if (response.includes('<think>')) {\n logger.info('Cleaning think tags from response');\n response = response.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, '');\n logger.info('Think tags removed from response');\n }\n\n // Return the raw response and let the framework handle JSON parsing and action validation\n return response;\n } catch (error) {\n logger.error('Text generation failed:', error);\n throw error;\n }\n }\n\n /**\n * Generate embeddings - now with lazy initialization\n */\n async generateEmbedding(text: string): Promise<number[]> {\n try {\n // Lazy initialize embedding model\n await this.lazyInitEmbedding();\n\n if (!this.embeddingModel) {\n throw new Error('Failed to initialize embedding model');\n }\n\n logger.info('Generating query embedding...');\n const embedding = await this.embeddingModel.queryEmbed(text);\n const dimensions = embedding.length;\n logger.info('Embedding generation complete', { dimensions });\n\n return Array.from(embedding);\n } catch (error) {\n logger.error('Embedding generation failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n // Only access text.length if text exists\n textLength: text?.length ?? 'text is null',\n });\n throw error;\n }\n }\n\n /**\n * Describe image with lazy vision model initialization\n */\n public async describeImage(\n imageData: Buffer,\n mimeType: string\n ): Promise<{ title: string; description: string }> {\n try {\n // Lazy initialize vision model\n await this.lazyInitVision();\n\n // Convert buffer to data URL\n const base64 = imageData.toString('base64');\n const dataUrl = `data:${mimeType};base64,${base64}`;\n return await this.visionManager.processImage(dataUrl);\n } catch (error) {\n logger.error('Image description failed:', error);\n throw error;\n }\n }\n\n /**\n * Transcribe audio with lazy transcription model initialization\n */\n public async transcribeAudio(audioBuffer: Buffer): Promise<string> {\n try {\n // Lazy initialize transcription model\n await this.lazyInitTranscription();\n\n const result = await this.transcribeManager.transcribe(audioBuffer);\n return result.text;\n } catch (error) {\n logger.error('Audio transcription failed:', {\n error: error instanceof Error ? error.message : String(error),\n bufferSize: audioBuffer.length,\n });\n throw error;\n }\n }\n\n /**\n * Generate speech with lazy TTS model initialization\n */\n public async generateSpeech(text: string): Promise<Readable> {\n try {\n // Lazy initialize TTS model\n await this.lazyInitTTS();\n\n return await this.ttsManager.generateSpeech(text);\n } catch (error) {\n logger.error('Speech generation failed:', {\n error: error instanceof Error ? error.message : String(error),\n textLength: text.length,\n });\n throw error;\n }\n }\n\n // Add public accessor methods\n /**\n * Returns the TokenizerManager associated with this object.\n *\n * @returns {TokenizerManager} The TokenizerManager object.\n */\n public getTokenizerManager(): TokenizerManager {\n return this.tokenizerManager;\n }\n\n /**\n * Returns the active model configuration.\n * @returns {ModelSpec} The active model configuration.\n */\n public getActiveModelConfig(): ModelSpec {\n return this.activeModelConfig;\n }\n\n /**\n * Retrieves the source configuration for the text model based on environment variables and manager existence.\n * @returns {TextModelConfig} The configuration object containing the text model source and type.\n */\n public getTextModelSource(): TextModelConfig {\n try {\n // Default configuration\n const config: TextModelConfig = {\n source: 'local',\n modelType: ModelType.TEXT_SMALL,\n };\n\n // Check environment configuration and manager existence\n if (process.env.USE_STUDIOLM_TEXT_MODELS === 'true' && this.studioLMManager) {\n config.source = 'studiolm';\n } else if (process.env.USE_OLLAMA_TEXT_MODELS === 'true' && this.ollamaManager) {\n config.source = 'ollama';\n }\n\n logger.info('Selected text model source:', config);\n return config;\n } catch (error) {\n logger.error('Error determining text model source:', error);\n // Fallback to local models\n return { source: 'local', modelType: ModelType.TEXT_SMALL };\n }\n }\n\n /**\n * Generic lazy initialization handler for any model type\n */\n private async lazyInitialize<T>(\n modelType: string,\n isInitialized: boolean,\n initPromise: Promise<T> | null,\n initFunction: () => Promise<T>\n ): Promise<T> {\n // If already initialized, return immediately\n if (isInitialized) {\n return Promise.resolve(null) as Promise<T>;\n }\n\n // If currently initializing, wait for it to complete\n if (initPromise) {\n logger.info(`Waiting for ${modelType} initialization to complete...`);\n await initPromise;\n return Promise.resolve(null) as Promise<T>;\n }\n\n // Otherwise start initialization\n logger.info(`Lazy initializing ${modelType}...`);\n return initFunction();\n }\n\n /**\n * Lazy initialize the small text model\n */\n private async lazyInitSmallModel(): Promise<void> {\n if (this.smallModelInitialized) return;\n\n if (!this.smallModelInitializingPromise) {\n this.smallModelInitializingPromise = (async () => {\n await this.initializeEnvironment();\n await this.checkPlatformCapabilities();\n\n // Download model if needed\n await this.downloadModel(ModelType.TEXT_SMALL);\n\n // Initialize Llama and small model\n try {\n // Use getLlama helper instead of directly creating\n this.llama = await getLlama();\n\n const smallModel = await this.llama.loadModel({\n gpuLayers: 43,\n modelPath: this.modelPath,\n vocabOnly: false,\n });\n\n this.smallModel = smallModel;\n\n const ctx = await smallModel.createContext({\n contextSize: MODEL_SPECS.small.contextSize,\n });\n\n this.ctx = ctx;\n this.sequence = undefined; // Reset sequence to create a new one\n this.smallModelInitialized = true;\n logger.info('Small model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize small model:', error);\n this.smallModelInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.smallModelInitializingPromise;\n }\n\n /**\n * Lazy initialize the medium text model\n */\n private async lazyInitMediumModel(): Promise<void> {\n if (this.mediumModelInitialized) return;\n\n if (!this.mediumModelInitializingPromise) {\n this.mediumModelInitializingPromise = (async () => {\n // Make sure llama is initialized first\n if (!this.llama) {\n await this.lazyInitSmallModel();\n }\n\n await this.downloadModel(ModelType.TEXT_LARGE);\n\n // Initialize medium model\n try {\n const mediumModel = await this.llama!.loadModel({\n gpuLayers: 43,\n modelPath: this.mediumModelPath,\n vocabOnly: false,\n });\n\n this.mediumModel = mediumModel;\n this.mediumModelInitialized = true;\n logger.info('Medium model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize medium model:', error);\n this.mediumModelInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.mediumModelInitializingPromise;\n }\n\n /**\n * Lazy initialize the embedding model\n */\n private async lazyInitEmbedding(): Promise<void> {\n if (this.embeddingInitialized) return;\n\n if (!this.embeddingInitializingPromise) {\n this.embeddingInitializingPromise = (async () => {\n try {\n await this.initializeEmbedding();\n this.embeddingInitialized = true;\n logger.info('Embedding model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize embedding model:', error);\n this.embeddingInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.embeddingInitializingPromise;\n }\n\n /**\n * Lazy initialize the vision model\n */\n private async lazyInitVision(): Promise<void> {\n if (this.visionInitialized) return;\n\n if (!this.visionInitializingPromise) {\n this.visionInitializingPromise = (async () => {\n try {\n // Initialize vision model directly\n // Use existing initialization code from the file\n // ...\n this.visionInitialized = true;\n logger.info('Vision model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize vision model:', error);\n this.visionInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.visionInitializingPromise;\n }\n\n /**\n * Lazy initialize the transcription model\n */\n private async lazyInitTranscription(): Promise<void> {\n if (this.transcriptionInitialized) return;\n\n if (!this.transcriptionInitializingPromise) {\n this.transcriptionInitializingPromise = (async () => {\n try {\n // Initialize transcription model directly\n // Use existing initialization code from the file\n // ...\n this.transcriptionInitialized = true;\n logger.info('Transcription model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize transcription model:', error);\n this.transcriptionInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.transcriptionInitializingPromise;\n }\n\n /**\n * Lazy initialize the TTS model\n */\n private async lazyInitTTS(): Promise<void> {\n if (this.ttsInitialized) return;\n\n if (!this.ttsInitializingPromise) {\n this.ttsInitializingPromise = (async () => {\n try {\n // Initialize TTS model directly\n // Use existing initialization code from the file\n // ...\n this.ttsInitialized = true;\n logger.info('TTS model initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize TTS model:', error);\n this.ttsInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.ttsInitializingPromise;\n }\n\n /**\n * Lazy initialize the Ollama integration\n */\n private async lazyInitOllama(): Promise<void> {\n if (this.ollamaInitialized) return;\n\n if (!this.ollamaInitializingPromise) {\n this.ollamaInitializingPromise = (async () => {\n try {\n await this.initializeOllama();\n this.ollamaInitialized = true;\n logger.info('Ollama initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize Ollama:', error);\n this.ollamaInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.ollamaInitializingPromise;\n }\n\n /**\n * Lazy initialize the StudioLM integration\n */\n private async lazyInitStudioLM(): Promise<void> {\n if (this.studioLMInitialized) return;\n\n if (!this.studioLMInitializingPromise) {\n this.studioLMInitializingPromise = (async () => {\n try {\n await this.initializeStudioLM();\n this.studioLMInitialized = true;\n logger.info('StudioLM initialized successfully');\n } catch (error) {\n logger.error('Failed to initialize StudioLM:', error);\n this.studioLMInitializingPromise = null;\n throw error;\n }\n })();\n }\n\n await this.studioLMInitializingPromise;\n }\n}\n\n// Create manager instance\nconst localAIManager = LocalAIManager.getInstance();\n\n/**\n * Plugin that provides functionality for local AI using LLaMA models.\n * @type {Plugin}\n */\nexport const localAIPlugin: Plugin = {\n name: 'local-ai',\n description: 'Local AI plugin using LLaMA models',\n\n async init() {\n try {\n logger.debug('Initializing local-ai plugin...');\n // Only validate config - actual models will be lazy-loaded when needed\n logger.success('Local AI plugin configuration validated and initialized');\n } catch (error) {\n logger.error('Plugin initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n runtime: IAgentRuntime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n try {\n const modelConfig = localAIManager.getTextModelSource();\n\n if (modelConfig.source !== 'local') {\n return await localAIManager.generateTextOllamaStudio({\n prompt,\n stopSequences,\n runtime,\n modelType: ModelType.TEXT_SMALL,\n });\n }\n\n return await localAIManager.generateText({\n prompt,\n stopSequences,\n runtime,\n modelType: ModelType.TEXT_SMALL,\n });\n } catch (error) {\n logger.error('Error in TEXT_SMALL handler:', error);\n throw error;\n }\n },\n\n [ModelType.TEXT_LARGE]: async (\n runtime: IAgentRuntime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n try {\n const modelConfig = localAIManager.getTextModelSource();\n\n if (modelConfig.source !== 'local') {\n return await localAIManager.generateTextOllamaStudio({\n prompt,\n stopSequences,\n runtime,\n modelType: ModelType.TEXT_LARGE,\n });\n }\n\n return await localAIManager.generateText({\n prompt,\n stopSequences,\n runtime,\n modelType: ModelType.TEXT_LARGE,\n });\n } catch (error) {\n logger.error('Error in TEXT_LARGE handler:', error);\n throw error;\n }\n },\n\n [ModelType.TEXT_EMBEDDING]: async (_runtime: IAgentRuntime, params: TextEmbeddingParams) => {\n const text = params?.text;\n try {\n // Handle null/undefined/empty text\n if (!text) {\n logger.debug('Null or empty text input for embedding, returning zero vector');\n return new Array(384).fill(0);\n }\n\n // Pass the raw text directly to the framework without any manipulation\n return await localAIManager.generateEmbedding(text);\n } catch (error) {\n logger.error('Error in TEXT_EMBEDDING handler:', {\n error: error instanceof Error ? error.message : String(error),\n fullText: text,\n textType: typeof text,\n textStructure: text !== null ? JSON.stringify(text, null, 2) : 'null',\n });\n return new Array(384).fill(0);\n }\n },\n\n [ModelType.OBJECT_SMALL]: async (runtime: IAgentRuntime, params: ObjectGenerationParams) => {\n try {\n logger.info('OBJECT_SMALL handler - Processing request:', {\n prompt: params.prompt,\n hasSchema: !!params.schema,\n temperature: params.temperature,\n });\n\n // Enhance the prompt to request JSON output\n let jsonPrompt = params.prompt;\n if (!jsonPrompt.includes('```json') && !jsonPrompt.includes('respond with valid JSON')) {\n jsonPrompt +=\n '\\nPlease respond with valid JSON only, without any explanations, markdown formatting, or additional text.';\n }\n\n const modelConfig = localAIManager.getTextModelSource();\n\n // Generate text based on the configured model source\n let textResponse: string;\n if (modelConfig.source !== 'local') {\n textResponse = await localAIManager.generateTextOllamaStudio({\n prompt: jsonPrompt,\n stopSequences: params.stopSequences,\n runtime,\n modelType: ModelType.TEXT_SMALL,\n });\n } else {\n textResponse = await localAIManager.generateText({\n prompt: jsonPrompt,\n stopSequences: params.stopSequences,\n runtime,\n modelType: ModelType.TEXT_SMALL,\n });\n }\n\n // Extract and parse JSON from the text response\n try {\n // Function to extract JSON content from text\n const extractJSON = (text: string): string => {\n // Try to find content between JSON codeblocks or markdown blocks\n const jsonBlockRegex = /```(?:json)?\\s*([\\s\\S]*?)\\s*```/;\n const match = text.match(jsonBlockRegex);\n\n if (match && match[1]) {\n return match[1].trim();\n }\n\n // If no code blocks, try to find JSON-like content\n // This regex looks for content that starts with { and ends with }\n const jsonContentRegex = /\\s*(\\{[\\s\\S]*\\})\\s*$/;\n const contentMatch = text.match(jsonContentRegex);\n\n if (contentMatch && contentMatch[1]) {\n return contentMatch[1].trim();\n }\n\n // If no JSON-like content found, return the original text\n return text.trim();\n };\n\n const extractedJsonText = extractJSON(textResponse);\n logger.debug('Extracted JSON text:', extractedJsonText);\n\n let jsonObject;\n try {\n jsonObject = JSON.parse(extractedJsonText);\n } catch (parseError) {\n // Try fixing common JSON issues\n logger.debug('Initial JSON parse failed, attempting to fix common issues');\n\n // Replace any unescaped newlines in string values\n const fixedJson = extractedJsonText\n .replace(/:\\s*\"([^\"]*)(?:\\n)([^\"]*)\"/g, ': \"$1\\\\n$2\"')\n // Remove any non-JSON text that might have gotten mixed into string values\n .replace(/\"([^\"]*?)[^a-zA-Z0-9\\s\\.,;:\\-_\\(\\)\"'\\[\\]{}]([^\"]*?)\"/g, '\"$1$2\"')\n // Fix missing quotes around property names\n .replace(/(\\s*)(\\w+)(\\s*):/g, '$1\"$2\"$3:')\n // Fix trailing commas in arrays and objects\n .replace(/,(\\s*[\\]}])/g, '$1');\n\n try {\n jsonObject = JSON.parse(fixedJson);\n } catch (finalError) {\n logger.error('Failed to parse JSON after fixing:', finalError);\n throw new Error('Invalid JSON returned from model');\n }\n }\n\n // Validate against schema if provided\n if (params.schema) {\n try {\n // Simplistic schema validation - check if all required properties exist\n for (const key of Object.keys(params.schema)) {\n if (!(key in jsonObject)) {\n jsonObject[key] = null; // Add missing properties with null value\n }\n }\n } catch (schemaError) {\n logger.error('Schema validation failed:', schemaError);\n }\n }\n\n return jsonObject;\n } catch (parseError) {\n logger.error('Failed to parse JSON:', parseError);\n logger.error('Raw response:', textResponse);\n throw new Error('Invalid JSON returned from model');\n }\n } catch (error) {\n logger.error('Error in OBJECT_SMALL handler:', error);\n throw error;\n }\n },\n\n [ModelType.OBJECT_LARGE]: async (runtime: IAgentRuntime, params: ObjectGenerationParams) => {\n try {\n logger.info('OBJECT_LARGE handler - Processing request:', {\n prompt: params.prompt,\n hasSchema: !!params.schema,\n temperature: params.temperature,\n });\n\n // Enhance the prompt to request JSON output\n let jsonPrompt = params.prompt;\n if (!jsonPrompt.includes('```json') && !jsonPrompt.includes('respond with valid JSON')) {\n jsonPrompt +=\n '\\nPlease respond with valid JSON only, without any explanations, markdown formatting, or additional text.';\n }\n\n const modelConfig = localAIManager.getTextModelSource();\n\n // Generate text based on the configured model source\n let textResponse: string;\n if (modelConfig.source !== 'local') {\n textResponse = await localAIManager.generateTextOllamaStudio({\n prompt: jsonPrompt,\n stopSequences: params.stopSequences,\n runtime,\n modelType: ModelType.TEXT_LARGE,\n });\n } else {\n textResponse = await localAIManager.generateText({\n prompt: jsonPrompt,\n stopSequences: params.stopSequences,\n runtime,\n modelType: ModelType.TEXT_LARGE,\n });\n }\n\n // Extract and parse JSON from the text response\n try {\n // Function to extract JSON content from text\n const extractJSON = (text: string): string => {\n // Try to find content between JSON codeblocks or markdown blocks\n const jsonBlockRegex = /```(?:json)?\\s*([\\s\\S]*?)\\s*```/;\n const match = text.match(jsonBlockRegex);\n\n if (match && match[1]) {\n return match[1].trim();\n }\n\n // If no code blocks, try to find JSON-like content\n // This regex looks for content that starts with { and ends with }\n const jsonContentRegex = /\\s*(\\{[\\s\\S]*\\})\\s*$/;\n const contentMatch = text.match(jsonContentRegex);\n\n if (contentMatch && contentMatch[1]) {\n return contentMatch[1].trim();\n }\n\n // If no JSON-like content found, return the original text\n return text.trim();\n };\n\n // Clean up the extracted JSON to handle common formatting issues\n const cleanupJSON = (jsonText: string): string => {\n // Remove common logging/debugging patterns that might get mixed into the JSON\n return (\n jsonText\n // Remove any lines that look like log statements\n .replace(/\\[DEBUG\\].*?(\\n|$)/g, '\\n')\n .replace(/\\[LOG\\].*?(\\n|$)/g, '\\n')\n .replace(/console\\.log.*?(\\n|$)/g, '\\n')\n );\n };\n\n const extractedJsonText = extractJSON(textResponse);\n const cleanedJsonText = cleanupJSON(extractedJsonText);\n logger.debug('Extracted JSON text:', cleanedJsonText);\n\n let jsonObject;\n try {\n jsonObject = JSON.parse(cleanedJsonText);\n } catch (parseError) {\n // Try fixing common JSON issues\n logger.debug('Initial JSON parse failed, attempting to fix common issues');\n\n // Replace any unescaped newlines in string values\n const fixedJson = cleanedJsonText\n .replace(/:\\s*\"([^\"]*)(?:\\n)([^\"]*)\"/g, ': \"$1\\\\n$2\"')\n // Remove any non-JSON text that might have gotten mixed into string values\n .replace(/\"([^\"]*?)[^a-zA-Z0-9\\s\\.,;:\\-_\\(\\)\"'\\[\\]{}]([^\"]*?)\"/g, '\"$1$2\"')\n // Fix missing quotes around property names\n .replace(/(\\s*)(\\w+)(\\s*):/g, '$1\"$2\"$3:')\n // Fix trailing commas in arrays and objects\n .replace(/,(\\s*[\\]}])/g, '$1');\n\n try {\n jsonObject = JSON.parse(fixedJson);\n } catch (finalError) {\n logger.error('Failed to parse JSON after fixing:', finalError);\n throw new Error('Invalid JSON returned from model');\n }\n }\n\n // Validate against schema if provided\n if (params.schema) {\n try {\n // Simplistic schema validation - check if all required properties exist\n for (const key of Object.keys(params.schema)) {\n if (!(key in jsonObject)) {\n jsonObject[key] = null; // Add missing properties with null value\n }\n }\n } catch (schemaError) {\n logger.error('Schema validation failed:', schemaError);\n }\n }\n\n return jsonObject;\n } catch (parseError) {\n logger.error('Failed to parse JSON:', parseError);\n logger.error('Raw response:', textResponse);\n throw new Error('Invalid JSON returned from model');\n }\n } catch (error) {\n logger.error('Error in OBJECT_LARGE handler:', error);\n throw error;\n }\n },\n\n [ModelType.TEXT_TOKENIZER_ENCODE]: async (\n _runtime: IAgentRuntime,\n { text }: { text: string }\n ) => {\n try {\n const manager = localAIManager.getTokenizerManager();\n const config = localAIManager.getActiveModelConfig();\n return await manager.encode(text, config);\n } catch (error) {\n logger.error('Error in TEXT_TOKENIZER_ENCODE handler:', error);\n throw error;\n }\n },\n\n [ModelType.TEXT_TOKENIZER_DECODE]: async (\n _runtime: IAgentRuntime,\n { tokens }: { tokens: number[] }\n ) => {\n try {\n const manager = localAIManager.getTokenizerManager();\n const config = localAIManager.getActiveModelConfig();\n return await manager.decode(tokens, config);\n } catch (error) {\n logger.error('Error in TEXT_TOKENIZER_DECODE handler:', error);\n throw error;\n }\n },\n\n [ModelType.IMAGE_DESCRIPTION]: async (_runtime: IAgentRuntime, imageUrl: string) => {\n try {\n logger.info('Processing image from URL:', imageUrl);\n\n // Fetch the image from URL\n const response = await fetch(imageUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch image: ${response.statusText}`);\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n const mimeType = response.headers.get('content-type') || 'image/jpeg';\n\n return await localAIManager.describeImage(buffer, mimeType);\n } catch (error) {\n logger.error('Error in IMAGE_DESCRIPTION handler:', {\n error: error instanceof Error ? error.message : String(error),\n imageUrl,\n });\n throw error;\n }\n },\n\n [ModelType.TRANSCRIPTION]: async (_runtime: IAgentRuntime, audioBuffer: Buffer) => {\n try {\n logger.info('Processing audio transcription:', {\n bufferSize: audioBuffer.length,\n });\n\n return await localAIManager.transcribeAudio(audioBuffer);\n } catch (error) {\n logger.error('Error in TRANSCRIPTION handler:', {\n error: error instanceof Error ? error.message : String(error),\n bufferSize: audioBuffer.length,\n });\n throw error;\n }\n },\n\n [ModelType.TEXT_TO_SPEECH]: async (_runtime: IAgentRuntime, text: string) => {\n try {\n return await localAIManager.generateSpeech(text);\n } catch (error) {\n logger.error('Error in TEXT_TO_SPEECH handler:', {\n error: error instanceof Error ? error.message : String(error),\n textLength: text.length,\n });\n throw error;\n }\n },\n },\n tests: [\n {\n name: 'local_ai_plugin_tests',\n tests: [\n {\n name: 'local_ai_test_initialization',\n fn: async (runtime) => {\n try {\n logger.info('Starting initialization test');\n\n // Test TEXT_SMALL model initialization\n const result = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt:\n \"Debug Mode: Test initialization. Respond with 'Initialization successful' if you can read this.\",\n stopSequences: [],\n });\n\n logger.info('Model response:', result);\n\n if (!result || typeof result !== 'string') {\n throw new Error('Invalid response from model');\n }\n\n if (!result.includes('successful')) {\n throw new Error('Model response does not indicate success');\n }\n\n logger.success('Initialization test completed successfully');\n } catch (error) {\n logger.error('Initialization test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_text_large',\n fn: async (runtime) => {\n try {\n logger.info('Starting TEXT_LARGE model test');\n\n const result = await runtime.useModel(ModelType.TEXT_LARGE, {\n prompt:\n 'Debug Mode: Generate a one-sentence response about artificial intelligence.',\n stopSequences: [],\n });\n\n logger.info('Large model response:', result);\n\n if (!result || typeof result !== 'string') {\n throw new Error('Invalid response from large model');\n }\n\n if (result.length < 10) {\n throw new Error('Response too short, possible model failure');\n }\n\n logger.success('TEXT_LARGE test completed successfully');\n } catch (error) {\n logger.error('TEXT_LARGE test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_text_embedding',\n fn: async (runtime) => {\n try {\n logger.info('Starting TEXT_EMBEDDING test');\n\n // Test with normal text\n const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, {\n text: 'This is a test of the text embedding model.',\n });\n\n logger.info('Embedding generated with dimensions:', embedding.length);\n\n if (!Array.isArray(embedding)) {\n throw new Error('Embedding is not an array');\n }\n\n if (embedding.length === 0) {\n throw new Error('Embedding array is empty');\n }\n\n if (embedding.some((val) => typeof val !== 'number')) {\n throw new Error('Embedding contains non-numeric values');\n }\n\n // Test with null input (should return zero vector)\n const nullEmbedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, null);\n if (!Array.isArray(nullEmbedding) || nullEmbedding.some((val) => val !== 0)) {\n throw new Error('Null input did not return zero vector');\n }\n\n logger.success('TEXT_EMBEDDING test completed successfully');\n } catch (error) {\n logger.error('TEXT_EMBEDDING test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_tokenizer_encode',\n fn: async (runtime) => {\n try {\n logger.info('Starting TEXT_TOKENIZER_ENCODE test');\n const text = 'Hello tokenizer test!';\n\n const tokens = await runtime.useModel(ModelType.TEXT_TOKENIZER_ENCODE, { text });\n logger.info('Encoded tokens:', { count: tokens.length });\n\n if (!Array.isArray(tokens)) {\n throw new Error('Tokens output is not an array');\n }\n\n if (tokens.length === 0) {\n throw new Error('No tokens generated');\n }\n\n if (tokens.some((token) => !Number.isInteger(token))) {\n throw new Error('Tokens contain non-integer values');\n }\n\n logger.success('TEXT_TOKENIZER_ENCODE test completed successfully');\n } catch (error) {\n logger.error('TEXT_TOKENIZER_ENCODE test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_tokenizer_decode',\n fn: async (runtime) => {\n try {\n logger.info('Starting TEXT_TOKENIZER_DECODE test');\n\n // First encode some text\n const originalText = 'Hello tokenizer test!';\n const tokens = await runtime.useModel(ModelType.TEXT_TOKENIZER_ENCODE, {\n text: originalText,\n });\n\n // Then decode it back\n const decodedText = await runtime.useModel(ModelType.TEXT_TOKENIZER_DECODE, {\n tokens,\n });\n logger.info('Round trip tokenization:', {\n original: originalText,\n decoded: decodedText,\n });\n\n if (typeof decodedText !== 'string') {\n throw new Error('Decoded output is not a string');\n }\n\n logger.success('TEXT_TOKENIZER_DECODE test completed successfully');\n } catch (error) {\n logger.error('TEXT_TOKENIZER_DECODE test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_image_description',\n fn: async (runtime) => {\n try {\n logger.info('Starting IMAGE_DESCRIPTION test');\n\n const imageUrl =\n 'https://raw.githubusercontent.com/microsoft/FLAML/main/website/static/img/flaml.png';\n const result = await runtime.useModel(ModelType.IMAGE_DESCRIPTION, imageUrl);\n\n logger.info('Image description result:', result);\n\n if (!result || typeof result !== 'object') {\n throw new Error('Invalid response format');\n }\n\n if (!result.title || !result.description) {\n throw new Error('Missing title or description in response');\n }\n\n if (typeof result.title !== 'string' || typeof result.description !== 'string') {\n throw new Error('Title or description is not a string');\n }\n\n logger.success('IMAGE_DESCRIPTION test completed successfully');\n } catch (error) {\n logger.error('IMAGE_DESCRIPTION test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_transcription',\n fn: async (runtime) => {\n try {\n logger.info('Starting TRANSCRIPTION test');\n\n // Create a simple audio buffer for testing\n const audioData = new Uint8Array([\n 0x52,\n 0x49,\n 0x46,\n 0x46, // \"RIFF\"\n 0x24,\n 0x00,\n 0x00,\n 0x00, // Chunk size\n 0x57,\n 0x41,\n 0x56,\n 0x45, // \"WAVE\"\n 0x66,\n 0x6d,\n 0x74,\n 0x20, // \"fmt \"\n ]);\n const audioBuffer = Buffer.from(audioData);\n\n const transcription = await runtime.useModel(ModelType.TRANSCRIPTION, audioBuffer);\n logger.info('Transcription result:', transcription);\n\n if (typeof transcription !== 'string') {\n throw new Error('Transcription result is not a string');\n }\n\n logger.success('TRANSCRIPTION test completed successfully');\n } catch (error) {\n logger.error('TRANSCRIPTION test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n {\n name: 'local_ai_test_text_to_speech',\n fn: async (runtime) => {\n try {\n logger.info('Starting TEXT_TO_SPEECH test');\n\n const testText = 'This is a test of the text to speech system.';\n const audioStream = await runtime.useModel(ModelType.TEXT_TO_SPEECH, testText);\n\n if (!(audioStream instanceof Readable)) {\n throw new Error('TTS output is not a readable stream');\n }\n\n // Test stream readability\n let dataReceived = false;\n audioStream.on('data', () => {\n dataReceived = true;\n });\n\n await new Promise((resolve, reject) => {\n audioStream.on('end', () => {\n if (!dataReceived) {\n reject(new Error('No audio data received from stream'));\n } else {\n resolve(true);\n }\n });\n audioStream.on('error', reject);\n });\n\n logger.success('TEXT_TO_SPEECH test completed successfully');\n } catch (error) {\n logger.error('TEXT_TO_SPEECH test failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n },\n },\n ],\n },\n ],\n};\n\nexport default localAIPlugin;\n","import type { IAgentRuntime } from '@elizaos/core';\nimport { logger } from '@elizaos/core';\nimport { z } from 'zod';\n\n// Configuration schema with text model source flags\n/**\n * Configuration schema for different AI models and their settings.\n * This schema includes:\n * - Flags for enabling/disabling various AI models\n * - Ollama configurations including server URL, models, and embedding models\n * - StudioLM configurations including server URL, models, and embedding models\n */\nexport const configSchema = z.object({\n USE_LOCAL_AI: z.boolean().default(true),\n USE_STUDIOLM_TEXT_MODELS: z.boolean().default(false),\n USE_OLLAMA_TEXT_MODELS: z.boolean().default(false),\n\n // Ollama Configuration\n OLLAMA_SERVER_URL: z.string().default('http://localhost:11434'),\n OLLAMA_MODEL: z.string().default('deepseek-r1-distill-qwen-7b'),\n USE_OLLAMA_EMBEDDING: z.boolean().default(false),\n OLLAMA_EMBEDDING_MODEL: z.string().default(''),\n SMALL_OLLAMA_MODEL: z.string().default('deepseek-r1:1.5b'),\n MEDIUM_OLLAMA_MODEL: z.string().default('deepseek-r1:7b'),\n LARGE_OLLAMA_MODEL: z.string().default('deepseek-r1:7b'),\n\n // StudioLM Configuration\n STUDIOLM_SERVER_URL: z.string().default('http://localhost:1234'),\n STUDIOLM_SMALL_MODEL: z.string().default('lmstudio-community/deepseek-r1-distill-qwen-1.5b'),\n STUDIOLM_MEDIUM_MODEL: z.string().default('deepseek-r1-distill-qwen-7b'),\n STUDIOLM_EMBEDDING_MODEL: z.union([z.boolean(), z.string()]).default(false),\n});\n\n/**\n * Export type representing the inferred type of the 'configSchema'.\n */\nexport type Config = z.infer<typeof configSchema>;\n\n/**\n * Validates the model configuration object.\n *\n * @param {Record<string, boolean>} config - The model configuration object containing boolean values.\n * @returns {void}\n */\nfunction validateModelConfig(config: Record<string, boolean>): void {\n // Log raw values before validation\n logger.info('Validating model configuration with values:', {\n USE_LOCAL_AI: config.USE_LOCAL_AI,\n USE_STUDIOLM_TEXT_MODELS: config.USE_STUDIOLM_TEXT_MODELS,\n USE_OLLAMA_TEXT_MODELS: config.USE_OLLAMA_TEXT_MODELS,\n });\n\n // Ensure USE_LOCAL_AI is always true\n if (!config.USE_LOCAL_AI) {\n config.USE_LOCAL_AI = true;\n logger.info(\"Setting USE_LOCAL_AI to true as it's required\");\n }\n\n // Only validate that StudioLM and Ollama are not both enabled\n if (config.USE_STUDIOLM_TEXT_MODELS && config.USE_OLLAMA_TEXT_MODELS) {\n throw new Error('StudioLM and Ollama text models cannot be enabled simultaneously');\n }\n\n logger.info('Configuration is valid');\n}\n\n/**\n * Validates and parses the configuration provided as a record of string key-value pairs.\n * This function performs boolean conversion on specific configuration values and sets default values for missing keys.\n * @param {Record<string, string>} config - The configuration to validate and parse.\n * @returns {Promise<Config>} The validated and parsed configuration object.\n */\nexport async function validateConfig(config: Record<string, string>): Promise<Config> {\n try {\n // Log raw environment variables\n // logger.info(\"Raw environment variables:\", {\n // USE_LOCAL_AI: process.env.USE_LOCAL_AI,\n // USE_STUDIOLM_TEXT_MODELS: process.env.USE_STUDIOLM_TEXT_MODELS,\n // USE_OLLAMA_TEXT_MODELS: process.env.USE_OLLAMA_TEXT_MODELS,\n // OLLAMA_SERVER_URL: process.env.OLLAMA_SERVER_URL,\n // STUDIOLM_SERVER_URL: process.env.STUDIOLM_SERVER_URL\n // });\n\n // Parse environment variables with proper boolean conversion\n const booleanConfig = {\n USE_LOCAL_AI: true, // Always true\n USE_STUDIOLM_TEXT_MODELS: config.USE_STUDIOLM_TEXT_MODELS === 'true',\n USE_OLLAMA_TEXT_MODELS: config.USE_OLLAMA_TEXT_MODELS === 'true',\n USE_OLLAMA_EMBEDDING: config.USE_OLLAMA_EMBEDDING === 'true',\n };\n\n // logger.info(\"Parsed boolean configuration:\", booleanConfig);\n\n // Validate text model source configuration\n validateModelConfig(booleanConfig);\n\n // Create full config with all values\n const fullConfig = {\n ...booleanConfig,\n OLLAMA_SERVER_URL: config.OLLAMA_SERVER_URL || 'http://localhost:11434',\n OLLAMA_MODEL: config.OLLAMA_MODEL || 'deepseek-r1-distill-qwen-7b',\n OLLAMA_EMBEDDING_MODEL: config.OLLAMA_EMBEDDING_MODEL || '',\n SMALL_OLLAMA_MODEL: config.SMALL_OLLAMA_MODEL || 'deepseek-r1:1.5b',\n MEDIUM_OLLAMA_MODEL: config.MEDIUM_OLLAMA_MODEL || 'deepseek-r1:7b',\n LARGE_OLLAMA_MODEL: config.LARGE_OLLAMA_MODEL || 'deepseek-r1:7b',\n STUDIOLM_SERVER_URL: config.STUDIOLM_SERVER_URL || 'http://localhost:1234',\n STUDIOLM_SMALL_MODEL:\n config.STUDIOLM_SMALL_MODEL || 'lmstudio-community/deepseek-r1-distill-qwen-1.5b',\n STUDIOLM_MEDIUM_MODEL: config.STUDIOLM_MEDIUM_MODEL || 'deepseek-r1-distill-qwen-7b',\n STUDIOLM_EMBEDDING_MODEL: config.STUDIOLM_EMBEDDING_MODEL || false,\n };\n\n const validatedConfig = configSchema.parse(fullConfig);\n\n // logger.info(\"Final validated configuration:\", validatedConfig);\n\n return validatedConfig;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const errorMessages = error.errors\n .map((err) => `${err.path.join('.')}: ${err.message}`)\n .join('\\n');\n logger.error('Zod validation failed:', errorMessages);\n throw new Error(`Configuration validation failed:\\n${errorMessages}`);\n }\n logger.error('Configuration validation failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n}\n","// Model specifications and configurations\n/**\n * Interface representing a Tokenizer configuration.\n * @property {string} name - The name of the tokenizer.\n * @property {string} type - The type of the tokenizer.\n */\nexport interface TokenizerConfig {\n name: string;\n type: string;\n}\n\n/**\n * Interface representing the specification of a model.\n * @typedef {Object} ModelSpec\n * @property {string} name - The name of the model.\n * @property {string} repo - The repository of the model.\n * @property {string} size - The size of the model.\n * @property {string} quantization - The quantization of the model.\n * @property {number} contextSize - The context size of the model.\n * @property {TokenizerConfig} tokenizer - The configuration for the tokenizer used by the model.\n */\nexport interface ModelSpec {\n name: string;\n repo: string;\n size: string;\n quantization: string;\n contextSize: number;\n tokenizer: TokenizerConfig;\n}\n\n/**\n * Interface representing a specification for a vision model.\n * @typedef {object} VisionModelSpec\n * @property {string} name - The name of the vision model.\n * @property {string} repo - The repository of the vision model.\n * @property {string} size - The size of the vision model.\n * @property {string} modelId - The ID of the vision model.\n * @property {number} contextSize - The context size of the vision model.\n * @property {number} maxTokens - The maximum tokens of the vision model.\n * @property {Array.<string>} tasks - The tasks performed by the vision model.\n */\nexport interface VisionModelSpec {\n name: string;\n repo: string;\n size: string;\n modelId: string;\n contextSize: number;\n maxTokens: number;\n tasks: string[];\n}\n\n/**\n * Interface representing the specification for a TTS model.\n * @typedef { Object } TTSModelSpec\n * @property { string } name - The name of the model.\n * @property { string } repo - The repository where the model is stored.\n * @property { string } size - The size of the model.\n * @property { string } quantization - The quantization method used for the model.\n * @property {string[]} speakers - An array of speakers the model can mimic.\n * @property {string[]} languages - An array of languages the model can speak in.\n * @property {string[]} features - An array of features supported by the model.\n * @property { number } maxInputLength - The maximum input length accepted by the model.\n * @property { number } sampleRate - The sample rate used by the model.\n * @property { number } contextSize - The context size used by the model.\n * @property { TokenizerConfig } tokenizer - The configuration for the tokenizer used by the model.\n */\nexport interface TTSModelSpec {\n name: string;\n repo: string;\n size: string;\n quantization: string;\n speakers: string[];\n languages: string[];\n features: string[];\n maxInputLength: number;\n sampleRate: number;\n contextSize: number;\n tokenizer: TokenizerConfig;\n}\n\n// Model specifications mapping\n/**\n * Interface for specifying different models for a project.\n * @interface ModelSpecs\n * @property {ModelSpec} small - Specifications for a small model\n * @property {ModelSpec} medium - Specifications for a medium model\n * @property {VisionModelSpec} vision - Specifications for a vision model\n * @property {VisionModelSpec} visionvl - Specifications for a vision model with vision loss\n * @property {Object} tts - Specifications for text-to-speech models\n * @property {TTSModelSpec} tts.base - Specifications for the base text-to-speech model\n * @property {TTSModelSpec} tts.medium - Specifications for a medium text-to-speech model\n * @property {TTSModelSpec} tts.large - Specifications for a large text-to-speech model\n */\nexport interface ModelSpecs {\n small: ModelSpec;\n medium: ModelSpec;\n vision: VisionModelSpec;\n visionvl: VisionModelSpec;\n tts: {\n base: TTSModelSpec;\n medium: TTSModelSpec;\n large: TTSModelSpec;\n };\n}\n\n// Export MODEL_SPECS constant type\n/**\n * Model specifications containing information about various models such as name, repository, size, quantization, context size, tokenizer details, tasks, speakers, languages, features, max input length, sample rate, and other relevant information.\n */\nexport const MODEL_SPECS: ModelSpecs = {\n small: {\n name: 'DeepHermes-3-Llama-3-3B-Preview-q4.gguf',\n repo: 'NousResearch/DeepHermes-3-Llama-3-3B-Preview-GGUF',\n size: '3B',\n quantization: 'Q4_0',\n contextSize: 8192,\n tokenizer: {\n name: 'NousResearch/DeepHermes-3-Llama-3-3B-Preview',\n type: 'llama',\n },\n },\n medium: {\n name: 'DeepHermes-3-Llama-3-8B-q4.gguf',\n repo: 'NousResearch/DeepHermes-3-Llama-3-8B-Preview-GGUF',\n size: '8B',\n quantization: 'Q4_0',\n contextSize: 8192,\n tokenizer: {\n name: 'NousResearch/DeepHermes-3-Llama-3-8B-Preview',\n type: 'llama',\n },\n },\n vision: {\n name: 'Florence-2-base-ft',\n repo: 'onnx-community/Florence-2-base-ft',\n size: '0.23B',\n modelId: 'onnx-community/Florence-2-base-ft',\n contextSize: 1024,\n maxTokens: 256,\n tasks: [\n 'CAPTION',\n 'DETAILED_CAPTION',\n 'MORE_DETAILED_CAPTION',\n 'CAPTION_TO_PHRASE_GROUNDING',\n 'OD',\n 'DENSE_REGION_CAPTION',\n 'REGION_PROPOSAL',\n 'OCR',\n 'OCR_WITH_REGION',\n ],\n },\n visionvl: {\n name: 'Qwen2.5-VL-3B-Instruct',\n repo: 'Qwen/Qwen2.5-VL-3B-Instruct',\n size: '3B',\n modelId: 'Qwen/Qwen2.5-VL-3B-Instruct',\n contextSize: 32768,\n maxTokens: 1024,\n tasks: [\n 'CAPTION',\n 'DETAILED_CAPTION',\n 'IMAGE_UNDERSTANDING',\n 'VISUAL_QUESTION_ANSWERING',\n 'OCR',\n 'VISUAL_LOCALIZATION',\n 'REGION_ANALYSIS',\n ],\n },\n tts: {\n base: {\n name: 'OuteTTS-0.2-500M-Q8_0.gguf',\n repo: 'OuteAI/OuteTTS-0.2-500M-GGUF',\n size: '500M',\n quantization: 'Q8_0',\n speakers: ['male_1', 'male_2', 'female_1', 'female_2'],\n languages: ['en'],\n features: ['MULTI_SPEAKER', 'VOICE_CLONING', 'EMOTION_CONTROL', 'SPEED_CONTROL'],\n maxInputLength: 4096,\n sampleRate: 24000,\n contextSize: 2048,\n tokenizer: {\n name: 'OuteAI/OuteTTS-0.2-500M',\n type: 'llama',\n },\n },\n medium: {\n name: 'OuteTTS-0.3-1B.gguf',\n repo: 'OuteAI/OuteTTS-0.3-1B-GGUF',\n size: '1B',\n quantization: 'Q8_0',\n speakers: ['male_1', 'male_2', 'male_3', 'female_1', 'female_2', 'female_3'],\n languages: ['en', 'es', 'fr', 'de', 'it'],\n features: [\n 'MULTI_SPEAKER',\n 'VOICE_CLONING',\n 'EMOTION_CONTROL',\n 'SPEED_CONTROL',\n 'MULTILINGUAL',\n 'ACCENT_CONTROL',\n ],\n maxInputLength: 8192,\n sampleRate: 32000,\n contextSize: 4096,\n tokenizer: {\n name: 'OuteAI/OuteTTS-0.3-1B',\n type: 'llama',\n },\n },\n large: {\n name: 'OuteTTS-0.3-3B.gguf',\n repo: 'OuteAI/OuteTTS-0.3-3B-GGUF',\n size: '3B',\n quantization: 'Q8_0',\n speakers: [\n 'male_1',\n 'male_2',\n 'male_3',\n 'male_4',\n 'female_1',\n 'female_2',\n 'female_3',\n 'female_4',\n ],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'nl', 'pl', 'ru', 'ja', 'ko', 'zh'],\n features: [\n 'MULTI_SPEAKER',\n 'VOICE_CLONING',\n 'EMOTION_CONTROL',\n 'SPEED_CONTROL',\n 'MULTILINGUAL',\n 'ACCENT_CONTROL',\n 'STYLE_TRANSFER',\n 'PROSODY_CONTROL',\n ],\n maxInputLength: 16384,\n sampleRate: 48000,\n contextSize: 8192,\n tokenizer: {\n name: 'OuteAI/OuteTTS-0.3-3B',\n type: 'llama',\n },\n },\n },\n};\n","import fs from 'node:fs';\nimport https from 'node:https';\nimport path from 'node:path';\nimport { logger } from '@elizaos/core';\nimport type { ModelSpec } from '../types';\n\n/**\n * Class representing a Download Manager.\n */\nexport class DownloadManager {\n private static instance: DownloadManager | null = null;\n private cacheDir: string;\n private modelsDir: string;\n // Track active downloads to prevent duplicates\n private activeDownloads: Map<string, Promise<void>> = new Map();\n\n /**\n * Creates a new instance of CacheManager.\n *\n * @param {string} cacheDir - The directory path for caching data.\n * @param {string} modelsDir - The directory path for model files.\n */\n private constructor(cacheDir: string, modelsDir: string) {\n this.cacheDir = cacheDir;\n this.modelsDir = modelsDir;\n this.ensureCacheDirectory();\n this.ensureModelsDirectory();\n }\n\n /**\n * Returns the singleton instance of the DownloadManager class.\n * If an instance does not already exist, it creates a new one using the provided cache directory and models directory.\n *\n * @param {string} cacheDir - The directory where downloaded files are stored.\n * @param {string} modelsDir - The directory where model files are stored.\n * @returns {DownloadManager} The singleton instance of the DownloadManager class.\n */\n public static getInstance(cacheDir: string, modelsDir: string): DownloadManager {\n if (!DownloadManager.instance) {\n DownloadManager.instance = new DownloadManager(cacheDir, modelsDir);\n }\n return DownloadManager.instance;\n }\n\n /**\n * Ensure that the cache directory exists.\n */\n private ensureCacheDirectory(): void {\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n logger.debug('Created cache directory');\n }\n }\n\n /**\n * Ensure that the models directory exists. If it does not exist, create it.\n */\n private ensureModelsDirectory(): void {\n logger.debug('Ensuring models directory exists:', this.modelsDir);\n if (!fs.existsSync(this.modelsDir)) {\n fs.mkdirSync(this.modelsDir, { recursive: true });\n logger.debug('Created models directory');\n }\n }\n\n /**\n * Downloads a file from a given URL to a specified destination path asynchronously.\n *\n * @param {string} url - The URL from which to download the file.\n * @param {string} destPath - The destination path where the downloaded file will be saved.\n * @returns {Promise<void>} A Promise that resolves when the file download is completed successfully or rejects if an error occurs.\n */\n private async downloadFileInternal(url: string, destPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n logger.info(`Starting download to: ${destPath}`);\n\n // Create a temporary file path in the same directory as destPath\n const tempPath = `${destPath}.tmp`;\n\n // Check if temp file already exists and remove it to avoid conflicts\n if (fs.existsSync(tempPath)) {\n try {\n logger.warn(`Removing existing temporary file: ${tempPath}`);\n fs.unlinkSync(tempPath);\n } catch (err) {\n logger.error(\n `Failed to remove existing temporary file: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n const request = https.get(\n url,\n {\n headers: {\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n },\n timeout: 300000, // Increase timeout to 5 minutes\n },\n (response) => {\n if (response.statusCode === 301 || response.statusCode === 302) {\n const redirectUrl = response.headers.location;\n if (!redirectUrl) {\n reject(new Error('Redirect location not found'));\n return;\n }\n // logger.info(`Following redirect to: ${redirectUrl}`);\n // Remove the current download from tracking before starting a new one\n this.activeDownloads.delete(destPath);\n this.downloadFile(redirectUrl, destPath).then(resolve).catch(reject);\n return;\n }\n\n if (response.statusCode !== 200) {\n reject(new Error(`Failed to download: ${response.statusCode}`));\n return;\n }\n\n const totalSize = Number.parseInt(response.headers['content-length'] || '0', 10);\n let downloadedSize = 0;\n let lastLoggedPercent = 0;\n const barLength = 30;\n\n // Log initial progress bar\n const fileName = path.basename(destPath);\n logger.info(`Downloading ${fileName}: ${'▱'.repeat(barLength)} 0%`);\n\n const file = fs.createWriteStream(tempPath);\n\n response.on('data', (chunk) => {\n downloadedSize += chunk.length;\n const percent = Math.round((downloadedSize / totalSize) * 100);\n\n // Only update progress bar when percentage changes significantly (every 5%)\n if (percent >= lastLoggedPercent + 5) {\n const filledLength = Math.floor((downloadedSize / totalSize) * barLength);\n const progressBar = '▰'.repeat(filledLength) + '▱'.repeat(barLength - filledLength);\n logger.info(`Downloading ${fileName}: ${progressBar} ${percent}%`);\n lastLoggedPercent = percent;\n }\n });\n\n response.pipe(file);\n\n file.on('finish', () => {\n file.close(() => {\n try {\n // Show completed progress bar\n const completedBar = '▰'.repeat(barLength);\n logger.info(`Downloading ${fileName}: ${completedBar} 100%`);\n\n // Ensure the destination directory exists\n const destDir = path.dirname(destPath);\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n // Check if temp file exists before proceeding\n if (!fs.existsSync(tempPath)) {\n reject(new Error(`Temporary file ${tempPath} does not exist`));\n return;\n }\n\n // Only delete the existing file if the temp file is ready\n if (fs.existsSync(destPath)) {\n try {\n // Create a backup of the existing file before deleting it\n const backupPath = `${destPath}.bak`;\n fs.renameSync(destPath, backupPath);\n logger.info(`Created backup of existing file: ${backupPath}`);\n\n // Move temp file to destination\n fs.renameSync(tempPath, destPath);\n\n // If successful, remove the backup\n if (fs.existsSync(backupPath)) {\n fs.unlinkSync(backupPath);\n logger.info(`Removed backup file after successful update: ${backupPath}`);\n }\n } catch (moveErr) {\n logger.error(\n `Error replacing file: ${moveErr instanceof Error ? moveErr.message : String(moveErr)}`\n );\n\n // Try to restore from backup if the move failed\n const backupPath = `${destPath}.bak`;\n if (fs.existsSync(backupPath)) {\n try {\n fs.renameSync(backupPath, destPath);\n logger.info(`Restored from backup after failed update: ${backupPath}`);\n } catch (restoreErr) {\n logger.error(\n `Failed to restore from backup: ${restoreErr instanceof Error ? restoreErr.message : String(restoreErr)}`\n );\n }\n }\n\n // Clean up temp file\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (unlinkErr) {\n logger.error(\n `Failed to clean up temp file: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`\n );\n }\n }\n\n reject(moveErr);\n return;\n }\n } else {\n // No existing file, just move the temp file\n fs.renameSync(tempPath, destPath);\n }\n\n logger.success(`Download of ${fileName} completed successfully`);\n\n // Remove from active downloads\n this.activeDownloads.delete(destPath);\n resolve();\n } catch (err) {\n logger.error(\n `Error finalizing download: ${err instanceof Error ? err.message : String(err)}`\n );\n // Clean up temp file if it exists\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (unlinkErr) {\n logger.error(\n `Failed to clean up temp file: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`\n );\n }\n }\n // Remove from active downloads\n this.activeDownloads.delete(destPath);\n reject(err);\n }\n });\n });\n\n file.on('error', (err) => {\n logger.error(`File write error: ${err instanceof Error ? err.message : String(err)}`);\n file.close(() => {\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (unlinkErr) {\n logger.error(\n `Failed to clean up temp file after error: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`\n );\n }\n }\n // Remove from active downloads\n this.activeDownloads.delete(destPath);\n reject(err);\n });\n });\n }\n );\n\n request.on('error', (err) => {\n logger.error(`Request error: ${err instanceof Error ? err.message : String(err)}`);\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (unlinkErr) {\n logger.error(\n `Failed to clean up temp file after request error: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`\n );\n }\n }\n // Remove from active downloads\n this.activeDownloads.delete(destPath);\n reject(err);\n });\n\n request.on('timeout', () => {\n logger.error('Download timeout occurred');\n request.destroy();\n if (fs.existsSync(tempPath)) {\n try {\n fs.unlinkSync(tempPath);\n } catch (unlinkErr) {\n logger.error(\n `Failed to clean up temp file after timeout: ${unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr)}`\n );\n }\n }\n // Remove from active downloads\n this.activeDownloads.delete(destPath);\n reject(new Error('Download timeout'));\n });\n });\n }\n\n /**\n * Asynchronously downloads a file from the specified URL to the destination path.\n *\n * @param {string} url - The URL of the file to download.\n * @param {string} destPath - The destination path to save the downloaded file.\n * @returns {Promise<void>} A Promise that resolves once the file has been successfully downloaded.\n */\n public async downloadFile(url: string, destPath: string): Promise<void> {\n // Check if this file is already being downloaded\n if (this.activeDownloads.has(destPath)) {\n logger.info(`Download for ${destPath} already in progress, waiting for it to complete...`);\n const existingDownload = this.activeDownloads.get(destPath);\n if (existingDownload) {\n return existingDownload;\n }\n // If somehow the download was removed from the map but the key still exists\n logger.warn(\n `Download for ${destPath} was marked as in progress but not found in tracking map`\n );\n }\n\n // Start a new download and track it\n const downloadPromise = this.downloadFileInternal(url, destPath);\n this.activeDownloads.set(destPath, downloadPromise);\n\n try {\n return await downloadPromise;\n } catch (error) {\n // Make sure to remove from active downloads in case of error\n this.activeDownloads.delete(destPath);\n throw error;\n }\n }\n\n /**\n * Downloads a model specified by the modelSpec and saves it to the provided modelPath.\n * If the model is successfully downloaded, returns true, otherwise returns false.\n *\n * @param {ModelSpec} modelSpec - The model specification containing repo and name.\n * @param {string} modelPath - The path where the model will be saved.\n * @returns {Promise<boolean>} - Indicates if the model was successfully downloaded or not.\n */\n public async downloadModel(modelSpec: ModelSpec, modelPath: string): Promise<boolean> {\n try {\n logger.info('Starting local model download...');\n\n // Ensure model directory exists\n const modelDir = path.dirname(modelPath);\n if (!fs.existsSync(modelDir)) {\n logger.info('Creating model directory:', modelDir);\n fs.mkdirSync(modelDir, { recursive: true });\n }\n\n if (!fs.existsSync(modelPath)) {\n // Try different URL patterns in sequence, similar to TTS manager approach\n const attempts = [\n {\n description: 'LFS URL with GGUF suffix',\n url: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}?download=true`,\n },\n {\n description: 'LFS URL without GGUF suffix',\n url: `https://huggingface.co/${modelSpec.repo.replace('-GGUF', '')}/resolve/main/${modelSpec.name}?download=true`,\n },\n {\n description: 'Standard URL with GGUF suffix',\n url: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}`,\n },\n {\n description: 'Standard URL without GGUF suffix',\n url: `https://huggingface.co/${modelSpec.repo.replace('-GGUF', '')}/resolve/main/${modelSpec.name}`,\n },\n ];\n\n // logger.info(\"Model download details:\", {\n // modelName: modelSpec.name,\n // repo: modelSpec.repo,\n // modelPath: modelPath,\n // attemptUrls: attempts.map(a => ({ description: a.description, url: a.url })),\n // timestamp: new Date().toISOString()\n // });\n\n let lastError = null;\n let downloadSuccess = false;\n\n for (const attempt of attempts) {\n try {\n logger.info('Attempting model download:', {\n description: attempt.description,\n url: attempt.url,\n timestamp: new Date().toISOString(),\n });\n\n // The downloadFile method now handles the progress bar display\n await this.downloadFile(attempt.url, modelPath);\n\n logger.success(\n `Model download complete: ${modelSpec.name} using ${attempt.description}`\n );\n downloadSuccess = true;\n break;\n } catch (error) {\n lastError = error;\n logger.warn('Model download attempt failed:', {\n description: attempt.description,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n if (!downloadSuccess) {\n throw lastError || new Error('All download attempts failed');\n }\n\n // Return true to indicate the model was newly downloaded\n return true;\n }\n\n // Model already exists\n logger.info('Model already exists at:', modelPath);\n // Return false to indicate the model already existed\n return false;\n } catch (error) {\n logger.error('Model download failed:', {\n error: error instanceof Error ? error.message : String(error),\n modelPath: modelPath,\n model: modelSpec.name,\n });\n throw error;\n }\n }\n\n /**\n * Returns the cache directory path.\n *\n * @returns {string} The path of the cache directory.\n */\n\n public getCacheDir(): string {\n return this.cacheDir;\n }\n\n /**\n * Downloads a file from a given URL to a specified destination path.\n *\n * @param {string} url - The URL of the file to download.\n * @param {string} destPath - The destination path where the file should be saved.\n * @returns {Promise<void>} A Promise that resolves once the file has been downloaded.\n */\n public async downloadFromUrl(url: string, destPath: string): Promise<void> {\n return this.downloadFile(url, destPath);\n }\n\n /**\n * Ensures that the specified directory exists. If it does not exist, it will be created.\n * @param {string} dirPath - The path of the directory to ensure existence of.\n * @returns {void}\n */\n public ensureDirectoryExists(dirPath: string): void {\n if (!fs.existsSync(dirPath)) {\n fs.mkdirSync(dirPath, { recursive: true });\n logger.info(`Created directory: ${dirPath}`);\n }\n }\n}\n","import { type GenerateTextParams, ModelType, logger } from '@elizaos/core';\n\n/**\n * Interface representing the structure of an Ollama model.\n * @typedef {Object} OllamaModel\n * @property {string} name - The name of the Ollama model.\n * @property {string} id - The unique identifier of the Ollama model.\n * @property {string} size - The size of the Ollama model.\n * @property {string} modified - The date when the Ollama model was last modified.\n */\ninterface OllamaModel {\n name: string;\n id: string;\n size: string;\n modified: string;\n}\n\n/**\n * Interface representing a response from the Ollama API.\n * @property {string} model - The model used for generating the response.\n * @property {string} response - The actual response generated by the model.\n * @property {boolean} done - Indicates whether the response generation is complete.\n * @property {number[]} [prompt] - Optional array of prompt values used in generating the response.\n * @property {number} [total_duration] - Optional total duration of the response generation process.\n * @property {number} [load_duration] - Optional load duration of the model used.\n * @property {number} [prompt_eval_duration] - Optional evaluation duration for the prompt values.\n * @property {number} [eval_duration] - Optional evaluation duration for the response generation.\n */\ninterface OllamaResponse {\n model: string;\n response: string;\n done: boolean;\n prompt?: number[];\n total_duration?: number;\n load_duration?: number;\n prompt_eval_duration?: number;\n eval_duration?: number;\n}\n\n/**\n * Manages interactions with the Ollama API, including server status checks, fetching available models,\n * testing models, initializing the manager, generating text, and more.\n */\nexport class OllamaManager {\n private static instance: OllamaManager | null = null;\n private serverUrl: string;\n private initialized = false;\n private availableModels: OllamaModel[] = [];\n private configuredModels = {\n small: process.env.SMALL_OLLAMA_MODEL || 'deepseek-r1:1.5b',\n medium: process.env.MEDIUM_OLLAMA_MODEL || 'deepseek-r1:7b',\n };\n\n /**\n * Private constructor for initializing OllamaManager.\n */\n private constructor() {\n this.serverUrl = process.env.OLLAMA_SERVER_URL || 'http://localhost:11434';\n logger.info('OllamaManager initialized with configuration:', {\n serverUrl: this.serverUrl,\n configuredModels: this.configuredModels,\n timestamp: new Date().toISOString(),\n });\n }\n\n /**\n * Returns an instance of the OllamaManager class.\n * If an instance does not already exist, a new instance is created and returned.\n * @returns {OllamaManager} The instance of the OllamaManager class.\n */\n public static getInstance(): OllamaManager {\n if (!OllamaManager.instance) {\n OllamaManager.instance = new OllamaManager();\n }\n return OllamaManager.instance;\n }\n\n /**\n * Asynchronously checks the status of the server by attempting to fetch the \"/api/tags\" endpoint.\n * @returns A Promise that resolves to a boolean indicating if the server is reachable and responding with a successful status.\n */\n private async checkServerStatus(): Promise<boolean> {\n try {\n const response = await fetch(`${this.serverUrl}/api/tags`);\n if (!response.ok) {\n throw new Error(`Server responded with status: ${response.status}`);\n }\n return true;\n } catch (error) {\n logger.error('Ollama server check failed:', {\n error: error instanceof Error ? error.message : String(error),\n serverUrl: this.serverUrl,\n timestamp: new Date().toISOString(),\n });\n return false;\n }\n }\n\n /**\n * Fetches the available Ollama models from the specified server URL.\n *\n * @returns {Promise<void>} A Promise that resolves when the available models are successfully fetched.\n */\n private async fetchAvailableModels(): Promise<void> {\n try {\n const response = await fetch(`${this.serverUrl}/api/tags`);\n if (!response.ok) {\n throw new Error(`Failed to fetch models: ${response.status}`);\n }\n\n const data = (await response.json()) as { models: OllamaModel[] };\n this.availableModels = data.models;\n\n logger.info('Ollama available models:', {\n count: this.availableModels.length,\n models: this.availableModels.map((m) => m.name),\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n logger.error('Failed to fetch Ollama models:', {\n error: error instanceof Error ? error.message : String(error),\n serverUrl: this.serverUrl,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously tests a model specified by the given modelId.\n *\n * @param {string} modelId - The ID of the model to be tested.\n * @returns {Promise<boolean>} - A promise that resolves to true if the model test is successful, false otherwise.\n */\n private async testModel(modelId: string): Promise<boolean> {\n try {\n const testRequest = {\n model: modelId,\n prompt:\n \"Debug Mode: Test initialization. Respond with 'Initialization successful' if you can read this.\",\n stream: false,\n options: {\n temperature: 0.7,\n num_predict: 100,\n },\n };\n\n logger.info(`Testing model ${modelId}...`);\n\n const response = await fetch(`${this.serverUrl}/api/generate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(testRequest),\n });\n\n if (!response.ok) {\n throw new Error(`Model test failed with status: ${response.status}`);\n }\n\n const result = (await response.json()) as OllamaResponse;\n\n if (!result.response) {\n throw new Error('No valid response content received');\n }\n\n logger.info(`Model ${modelId} test response:`, {\n content: result.response,\n model: result.model,\n timestamp: new Date().toISOString(),\n });\n\n return true;\n } catch (error) {\n logger.error(`Model ${modelId} test failed:`, {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n return false;\n }\n }\n\n /**\n * Asynchronously tests the configured text models to ensure they are working properly.\n * Logs the test results for each model and outputs a warning if any models fail the test.\n * @returns {Promise<void>} A Promise that resolves when all configured models have been tested.\n */\n private async testTextModels(): Promise<void> {\n logger.info('Testing configured text models...');\n\n const results = await Promise.all([\n this.testModel(this.configuredModels.small),\n this.testModel(this.configuredModels.medium),\n ]);\n\n const [smallWorking, mediumWorking] = results;\n\n if (!smallWorking || !mediumWorking) {\n const failedModels = [];\n if (!smallWorking) failedModels.push('small');\n if (!mediumWorking) failedModels.push('medium');\n\n logger.warn('Some models failed the test:', {\n failedModels,\n small: this.configuredModels.small,\n medium: this.configuredModels.medium,\n });\n } else {\n logger.success('All configured models passed the test');\n }\n }\n\n /**\n * Asynchronously initializes the Ollama service by checking server status,\n * fetching available models, and testing text models.\n *\n * @returns A Promise that resolves when initialization is complete\n */\n public async initialize(): Promise<void> {\n try {\n if (this.initialized) {\n logger.info('Ollama already initialized, skipping initialization');\n return;\n }\n\n logger.info('Starting Ollama initialization...');\n const serverAvailable = await this.checkServerStatus();\n\n if (!serverAvailable) {\n throw new Error('Ollama server is not available');\n }\n\n await this.fetchAvailableModels();\n await this.testTextModels();\n\n this.initialized = true;\n logger.success('Ollama initialization complete');\n } catch (error) {\n logger.error('Ollama initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n }\n\n /**\n * Retrieves the available Ollama models.\n *\n * @returns {OllamaModel[]} An array of OllamaModel objects representing the available models.\n */\n public getAvailableModels(): OllamaModel[] {\n return this.availableModels;\n }\n\n /**\n * Check if the object is initialized.\n * @returns {boolean} True if the object is initialized, false otherwise.\n */\n public isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Generates text using the Ollama AI model.\n *\n * @param {GenerateTextParams} params - The parameters for generating text.\n * @param {boolean} [isInitialized=false] - Flag indicating if Ollama is already initialized.\n * @returns {Promise<string>} - A promise that resolves with the generated text.\n */\n public async generateText(params: GenerateTextParams, isInitialized = false): Promise<string> {\n try {\n // Log entry point with all parameters\n logger.info('Ollama generateText entry:', {\n isInitialized,\n currentInitState: this.initialized,\n managerInitState: this.isInitialized(),\n modelType: params.modelType,\n contextLength: params.prompt?.length,\n timestamp: new Date().toISOString(),\n });\n\n // Only initialize if not already initialized and not marked as initialized\n if (!this.initialized && !isInitialized) {\n throw new Error('Ollama not initialized. Please initialize before generating text.');\n }\n\n logger.info('Ollama preparing request:', {\n model:\n params.modelType === ModelType.TEXT_LARGE\n ? this.configuredModels.medium\n : this.configuredModels.small,\n contextLength: params.prompt.length,\n timestamp: new Date().toISOString(),\n });\n\n const request = {\n model:\n params.modelType === ModelType.TEXT_LARGE\n ? this.configuredModels.medium\n : this.configuredModels.small,\n prompt: params.prompt,\n stream: false,\n options: {\n temperature: 0.7,\n top_p: 0.9,\n num_predict: 8192,\n repeat_penalty: 1.2,\n frequency_penalty: 0.7,\n presence_penalty: 0.7,\n },\n };\n\n const response = await fetch(`${this.serverUrl}/api/generate`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`Ollama request failed: ${response.status}`);\n }\n\n const result = (await response.json()) as OllamaResponse;\n\n if (!result.response) {\n throw new Error('No valid response content received from Ollama');\n }\n\n let responseText = result.response;\n\n // Log raw response for debugging\n logger.info('Raw response structure:', {\n responseLength: responseText.length,\n hasAction: responseText.includes('action'),\n hasThinkTag: responseText.includes('<think>'),\n });\n\n // Clean think tags if present\n if (responseText.includes('<think>')) {\n logger.info('Cleaning think tags from response');\n responseText = responseText.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, '');\n logger.info('Think tags removed from response');\n }\n\n logger.info('Ollama request completed successfully:', {\n responseLength: responseText.length,\n hasThinkTags: responseText.includes('<think>'),\n timestamp: new Date().toISOString(),\n });\n\n return responseText;\n } catch (error) {\n logger.error('Ollama text generation error:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n phase: 'text generation',\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n}\n","import { exec } from 'node:child_process';\nimport os from 'node:os';\nimport { promisify } from 'node:util';\nimport { logger } from '@elizaos/core';\n\nconst execAsync = promisify(exec);\n\n/**\n * Represents the configuration of a system GPU.\n * @typedef {Object} SystemGPU\n * @property {string} name - The name of the GPU.\n * @property {number} [memory] - The memory size of the GPU. (Optional)\n * @property {\"cuda\" | \"metal\" | \"directml\" | \"none\"} type - The type of GPU.\n * @property {string} [version] - The version of the GPU. (Optional)\n * @property {boolean} [isAppleSilicon] - Indicates if the GPU is Apple Silicon. (Optional)\n */\nexport interface SystemGPU {\n name: string;\n memory?: number;\n type: 'cuda' | 'metal' | 'directml' | 'none';\n version?: string;\n isAppleSilicon?: boolean;\n}\n\n/**\n * Interface representing the system CPU information.\n * @typedef {Object} SystemCPU\n * @property {string} model - The model of the CPU.\n * @property {number} cores - The number of cores in the CPU.\n * @property {number} speed - The speed of the CPU.\n * @property {string} architecture - The architecture of the CPU.\n * @property {Object} memory - Object containing memory information.\n * @property {number} memory.total - The total memory available.\n * @property {number} memory.free - The free memory available.\n */\nexport interface SystemCPU {\n model: string;\n cores: number;\n speed: number;\n architecture: string;\n memory: {\n total: number;\n free: number;\n };\n}\n\n/**\n * Interface representing the capabilities of a system.\n *\n * @typedef {Object} SystemCapabilities\n * @property {NodeJS.Platform} platform - The platform of the system.\n * @property {SystemCPU} cpu - The CPU information of the system.\n * @property {SystemGPU | null} gpu - The GPU information of the system, can be null if no GPU is present.\n * @property {\"small\" | \"medium\" | \"large\"} recommendedModelSize - The recommended model size for the system.\n * @property {Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">} supportedBackends - An array of supported backends for the system.\n */\nexport interface SystemCapabilities {\n platform: NodeJS.Platform;\n cpu: SystemCPU;\n gpu: SystemGPU | null;\n recommendedModelSize: 'small' | 'medium' | 'large';\n supportedBackends: Array<'cuda' | 'metal' | 'directml' | 'cpu'>;\n}\n\n/**\n * Class representing a Platform Manager.\n *\n * @class\n */\n\nexport class PlatformManager {\n private static instance: PlatformManager;\n private capabilities: SystemCapabilities | null = null;\n\n /**\n * Private constructor method.\n */\n private constructor() {}\n\n /**\n * Get the singleton instance of the PlatformManager class\n * @returns {PlatformManager} The instance of PlatformManager\n */\n static getInstance(): PlatformManager {\n if (!PlatformManager.instance) {\n PlatformManager.instance = new PlatformManager();\n }\n return PlatformManager.instance;\n }\n\n /**\n * Asynchronous method to initialize platform detection.\n *\n * @returns {Promise<void>} Promise that resolves once platform detection is completed.\n */\n async initialize(): Promise<void> {\n try {\n logger.info('Initializing platform detection...');\n this.capabilities = await this.detectSystemCapabilities();\n // logger.info(\"Platform detection completed\", {\n // platform: this.capabilities.platform,\n // gpu: this.capabilities.gpu?.type || \"none\",\n // recommendedModel: this.capabilities.recommendedModelSize,\n // });\n } catch (error) {\n logger.error('Platform detection failed', { error });\n throw error;\n }\n }\n\n /**\n * Detects the system capabilities including platform, CPU information, GPU information,\n * supported backends, and recommended model size.\n *\n * @returns {Promise<SystemCapabilities>} Details of the system capabilities including platform, CPU info, GPU info,\n * recommended model size, and supported backends.\n */\n private async detectSystemCapabilities(): Promise<SystemCapabilities> {\n const platform = process.platform;\n const cpuInfo = this.getCPUInfo();\n const gpu = await this.detectGPU();\n const supportedBackends = await this.getSupportedBackends(platform, gpu);\n const recommendedModelSize = this.getRecommendedModelSize(cpuInfo, gpu);\n\n return {\n platform,\n cpu: cpuInfo,\n gpu,\n recommendedModelSize,\n supportedBackends,\n };\n }\n\n /**\n * Returns information about the CPU and memory of the system.\n * @returns {SystemCPU} The CPU information including model, number of cores, speed, architecture, and memory details.\n */\n private getCPUInfo(): SystemCPU {\n const cpus = os.cpus();\n const totalMemory = os.totalmem();\n const freeMemory = os.freemem();\n\n return {\n model: cpus[0].model,\n cores: cpus.length,\n speed: cpus[0].speed,\n architecture: process.arch,\n memory: {\n total: totalMemory,\n free: freeMemory,\n },\n };\n }\n\n /**\n * Asynchronously detects the GPU information based on the current platform.\n * @returns A promise that resolves with the GPU information if detection is successful, otherwise null.\n */\n private async detectGPU(): Promise<SystemGPU | null> {\n const platform = process.platform;\n\n try {\n switch (platform) {\n case 'darwin':\n return await this.detectMacGPU();\n case 'win32':\n return await this.detectWindowsGPU();\n case 'linux':\n return await this.detectLinuxGPU();\n default:\n return null;\n }\n } catch (error) {\n logger.error('GPU detection failed', { error });\n return null;\n }\n }\n\n /**\n * Asynchronously detects the GPU of a Mac system.\n * @returns {Promise<SystemGPU>} A promise that resolves to an object representing the detected GPU.\n */\n private async detectMacGPU(): Promise<SystemGPU> {\n try {\n const { stdout } = await execAsync('sysctl -n machdep.cpu.brand_string');\n const isAppleSilicon = stdout.toLowerCase().includes('apple');\n\n if (isAppleSilicon) {\n return {\n name: 'Apple Silicon',\n type: 'metal',\n isAppleSilicon: true,\n };\n }\n\n // For Intel Macs with discrete GPU\n const { stdout: gpuInfo } = await execAsync('system_profiler SPDisplaysDataType');\n return {\n name: gpuInfo.split('Chipset Model:')[1]?.split('\\n')[0]?.trim() || 'Unknown GPU',\n type: 'metal',\n isAppleSilicon: false,\n };\n } catch (error) {\n logger.error('Mac GPU detection failed', { error });\n return {\n name: 'Unknown Mac GPU',\n type: 'metal',\n isAppleSilicon: false,\n };\n }\n }\n\n /**\n * Detects the GPU in a Windows system and returns information about it.\n *\n * @returns {Promise<SystemGPU | null>} A promise that resolves with the detected GPU information or null if detection fails.\n */\n private async detectWindowsGPU(): Promise<SystemGPU | null> {\n try {\n const { stdout } = await execAsync('wmic path win32_VideoController get name');\n const gpuName = stdout.split('\\n')[1].trim();\n\n // Check for NVIDIA GPU\n if (gpuName.toLowerCase().includes('nvidia')) {\n const { stdout: nvidiaInfo } = await execAsync(\n 'nvidia-smi --query-gpu=name,memory.total --format=csv,noheader'\n );\n const [name, memoryStr] = nvidiaInfo.split(',').map((s) => s.trim());\n const memory = Number.parseInt(memoryStr);\n\n return {\n name,\n memory,\n type: 'cuda',\n version: await this.getNvidiaDriverVersion(),\n };\n }\n\n // Default to DirectML for other GPUs\n return {\n name: gpuName,\n type: 'directml',\n };\n } catch (error) {\n logger.error('Windows GPU detection failed', { error });\n return null;\n }\n }\n\n /**\n * Asynchronously detects the GPU information for Linux systems.\n * Tries to detect NVIDIA GPU first using 'nvidia-smi' command and if successful,\n * returns the GPU name, memory size, type as 'cuda', and NVIDIA driver version.\n * If NVIDIA detection fails, it falls back to checking for other GPUs using 'lspci | grep -i vga' command.\n * If no GPU is detected, it returns null.\n *\n * @returns {Promise<SystemGPU | null>} The detected GPU information or null if detection fails.\n */\n private async detectLinuxGPU(): Promise<SystemGPU | null> {\n try {\n // Try NVIDIA first\n const { stdout } = await execAsync(\n 'nvidia-smi --query-gpu=name,memory.total --format=csv,noheader'\n );\n if (stdout) {\n const [name, memoryStr] = stdout.split(',').map((s) => s.trim());\n const memory = Number.parseInt(memoryStr);\n\n return {\n name,\n memory,\n type: 'cuda',\n version: await this.getNvidiaDriverVersion(),\n };\n }\n } catch {\n // If nvidia-smi fails, check for other GPUs\n try {\n const { stdout } = await execAsync('lspci | grep -i vga');\n return {\n name: stdout.split(':').pop()?.trim() || 'Unknown GPU',\n type: 'none',\n };\n } catch (error) {\n logger.error('Linux GPU detection failed', { error });\n return null;\n }\n }\n return null;\n }\n\n /**\n * Asynchronously retrieves the driver version of the Nvidia GPU using the 'nvidia-smi' command.\n *\n * @returns A promise that resolves with the driver version as a string, or 'unknown' if an error occurs.\n */\n private async getNvidiaDriverVersion(): Promise<string> {\n try {\n const { stdout } = await execAsync(\n 'nvidia-smi --query-gpu=driver_version --format=csv,noheader'\n );\n return stdout.trim();\n } catch {\n return 'unknown';\n }\n }\n\n /**\n * Retrieves the supported backends based on the platform and GPU type.\n * @param {NodeJS.Platform} platform - The platform on which the code is running.\n * @param {SystemGPU | null} gpu - The GPU information, if available.\n * @returns {Promise<Array<\"cuda\" | \"metal\" | \"directml\" | \"cpu\">>} - An array of supported backends including 'cuda', 'metal', 'directml', and 'cpu'.\n */\n private async getSupportedBackends(\n platform: NodeJS.Platform,\n gpu: SystemGPU | null\n ): Promise<Array<'cuda' | 'metal' | 'directml' | 'cpu'>> {\n const backends: Array<'cuda' | 'metal' | 'directml' | 'cpu'> = ['cpu'];\n\n if (gpu) {\n switch (platform) {\n case 'darwin':\n backends.push('metal');\n break;\n case 'win32':\n if (gpu.type === 'cuda') {\n backends.push('cuda');\n }\n backends.push('directml');\n break;\n case 'linux':\n if (gpu.type === 'cuda') {\n backends.push('cuda');\n }\n break;\n }\n }\n\n return backends;\n }\n\n /**\n * Determines the recommended model size based on the system's CPU and GPU.\n * @param {SystemCPU} cpu - The system's CPU.\n * @param {SystemGPU | null} gpu - The system's GPU, if available.\n * @returns {\"small\" | \"medium\" | \"large\"} - The recommended model size (\"small\", \"medium\", or \"large\").\n */\n private getRecommendedModelSize(\n cpu: SystemCPU,\n gpu: SystemGPU | null\n ): 'small' | 'medium' | 'large' {\n // For Apple Silicon\n if (gpu?.isAppleSilicon) {\n return cpu.memory.total > 16 * 1024 * 1024 * 1024 ? 'medium' : 'small';\n }\n\n // For NVIDIA GPUs\n if (gpu?.type === 'cuda') {\n const gpuMemGB = (gpu.memory || 0) / 1024;\n if (gpuMemGB >= 16) return 'large';\n if (gpuMemGB >= 8) return 'medium';\n }\n\n // For systems with significant RAM but no powerful GPU\n if (cpu.memory.total > 32 * 1024 * 1024 * 1024) return 'medium';\n\n // Default to small model\n return 'small';\n }\n\n /**\n * Returns the SystemCapabilities of the PlatformManager.\n *\n * @returns {SystemCapabilities} The SystemCapabilities of the PlatformManager.\n * @throws {Error} if PlatformManager is not initialized.\n */\n getCapabilities(): SystemCapabilities {\n if (!this.capabilities) {\n throw new Error('PlatformManager not initialized');\n }\n return this.capabilities;\n }\n\n /**\n * Checks if the device's GPU is Apple Silicon.\n * @returns {boolean} True if the GPU is Apple Silicon, false otherwise.\n */\n isAppleSilicon(): boolean {\n return !!this.capabilities?.gpu?.isAppleSilicon;\n }\n\n /**\n * Checks if the current device has GPU support.\n * @returns {boolean} - Returns true if the device has GPU support, false otherwise.\n */\n hasGPUSupport(): boolean {\n return !!this.capabilities?.gpu;\n }\n\n /**\n * Checks if the system supports CUDA GPU for processing.\n *\n * @returns {boolean} True if the system supports CUDA, false otherwise.\n */\n supportsCUDA(): boolean {\n return this.capabilities?.gpu?.type === 'cuda';\n }\n\n /**\n * Check if the device supports Metal API for rendering graphics.\n * @returns {boolean} True if the device supports Metal, false otherwise.\n */\n supportsMetal(): boolean {\n return this.capabilities?.gpu?.type === 'metal';\n }\n\n /**\n * Check if the device supports DirectML for GPU acceleration.\n *\n * @returns {boolean} True if the device supports DirectML, false otherwise.\n */\n supportsDirectML(): boolean {\n return this.capabilities?.gpu?.type === 'directml';\n }\n\n /**\n * Get the recommended backend for computation based on the available capabilities.\n * @returns {\"cuda\" | \"metal\" | \"directml\" | \"cpu\"} The recommended backend for computation.\n * @throws {Error} Throws an error if PlatformManager is not initialized.\n */\n getRecommendedBackend(): 'cuda' | 'metal' | 'directml' | 'cpu' {\n if (!this.capabilities) {\n throw new Error('PlatformManager not initialized');\n }\n\n const { gpu, supportedBackends } = this.capabilities;\n\n if (gpu?.type === 'cuda') return 'cuda';\n if (gpu?.type === 'metal') return 'metal';\n if (supportedBackends.includes('directml')) return 'directml';\n return 'cpu';\n }\n}\n\n// Export a helper function to get the singleton instance\nexport const getPlatformManager = (): PlatformManager => {\n return PlatformManager.getInstance();\n};\n","import { type GenerateTextParams, ModelType, logger } from '@elizaos/core';\n\n/**\n * Represents a StudioLMModel object with the following properties:\n * - id: string\n * - object: string\n * - created: number\n * - owned_by: string\n */\ninterface StudioLMModel {\n id: string;\n object: string;\n created: number;\n owned_by: string;\n}\n\n/**\n * Interface representing a chat message.\n * @property {string} role - The role of the sender, can be \"system\", \"user\", or \"assistant\".\n * @property {string} content - The content of the message.\n */\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\n/**\n * Interface representing a chat completion request.\n * @property {string} model - The model to be used for generating chat completions.\n * @property {ChatMessage[]} messages - An array of chat messages to provide context for the completion.\n * @property {number} [temperature] - The temperature parameter to control the randomness of the generated completions.\n * @property {number} [max_tokens] - The maximum number of tokens to generate in the completion.\n * @property {boolean} [stream] - Whether to generate completions in a streaming fashion.\n */\n\ninterface ChatCompletionRequest {\n model: string;\n messages: ChatMessage[];\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n}\n\n/**\n * Represents a response object for completing a chat session.\n * @typedef {Object} ChatCompletionResponse\n * @property {string} id - The unique identifier for the completion response.\n * @property {string} object - The type of object being returned.\n * @property {number} created - The timestamp of when the completion response was created.\n * @property {string} model - The type of model associated with the completion response.\n * @property {Object[]} choices - An array of choices made during the chat session.\n * @property {number} choices.index - The index of the choice within the array.\n * @property {ChatMessage} choices.message - The message associated with the choice.\n * @property {string} choices.finish_reason - The reason for finishing the chat session.\n */\ninterface ChatCompletionResponse {\n id: string;\n object: string;\n created: number;\n model: string;\n choices: {\n index: number;\n message: ChatMessage;\n finish_reason: string;\n }[];\n}\n\n/**\n * Class representing a Studio Language Model Manager.\n */\n\nexport class StudioLMManager {\n private static instance: StudioLMManager | null = null;\n private serverUrl: string;\n private initialized = false;\n private availableModels: StudioLMModel[] = [];\n private configuredModels = {\n small: process.env.STUDIOLM_SMALL_MODEL || 'lmstudio-community/deepseek-r1-distill-qwen-1.5b',\n medium: process.env.STUDIOLM_MEDIUM_MODEL || 'deepseek-r1-distill-qwen-7b',\n };\n\n /**\n * Private constructor for StudioLMManager.\n * Initializes with default serverUrl if not provided in environment variables.\n * Logs initialization information including serverUrl, configuredModels, and timestamp.\n */\n private constructor() {\n this.serverUrl = process.env.STUDIOLM_SERVER_URL || 'http://localhost:1234';\n logger.info('StudioLMManager initialized with configuration:', {\n serverUrl: this.serverUrl,\n configuredModels: this.configuredModels,\n timestamp: new Date().toISOString(),\n });\n }\n\n /**\n * Returns an instance of StudioLMManager. If an instance already exists, it returns the existing instance.\n * @returns {StudioLMManager} The instance of StudioLMManager\n */\n public static getInstance(): StudioLMManager {\n if (!StudioLMManager.instance) {\n StudioLMManager.instance = new StudioLMManager();\n }\n return StudioLMManager.instance;\n }\n\n /**\n * Check the status of the server by sending a request to the /v1/models endpoint.\n * @returns {Promise<boolean>} A Promise that resolves to true if the server responds with success status, false otherwise.\n */\n private async checkServerStatus(): Promise<boolean> {\n try {\n const response = await fetch(`${this.serverUrl}/v1/models`);\n if (!response.ok) {\n throw new Error(`Server responded with status: ${response.status}`);\n }\n return true;\n } catch (error) {\n logger.error('LM Studio server check failed:', {\n error: error instanceof Error ? error.message : String(error),\n serverUrl: this.serverUrl,\n timestamp: new Date().toISOString(),\n });\n return false;\n }\n }\n\n /**\n * Fetches the available models from the server and stores them in the 'availableModels' property.\n *\n * @returns {Promise<void>} A Promise that resolves when the models are fetched successfully or rejects with an error.\n */\n private async fetchAvailableModels(): Promise<void> {\n try {\n const response = await fetch(`${this.serverUrl}/v1/models`);\n if (!response.ok) {\n throw new Error(`Failed to fetch models: ${response.status}`);\n }\n\n const data = (await response.json()) as { data: StudioLMModel[] };\n this.availableModels = data.data;\n\n logger.info('LM Studio available models:', {\n count: this.availableModels.length,\n models: this.availableModels.map((m) => m.id),\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n logger.error('Failed to fetch LM Studio models:', {\n error: error instanceof Error ? error.message : String(error),\n serverUrl: this.serverUrl,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously tests the specified model with a chat completion request.\n * @param {string} modelId - The ID of the model to test.\n * @returns {Promise<boolean>} - A promise that resolves to true if the model test was successful, false otherwise.\n */\n private async testModel(modelId: string): Promise<boolean> {\n try {\n const testRequest: ChatCompletionRequest = {\n model: modelId,\n messages: [\n {\n role: 'system',\n content: 'Always answer in rhymes. Today is Thursday',\n },\n { role: 'user', content: 'What day is it today?' },\n ],\n temperature: 0.7,\n max_tokens: -1,\n stream: false,\n };\n\n logger.info(`Testing model ${modelId}...`);\n\n const response = await fetch(`${this.serverUrl}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(testRequest),\n });\n\n if (!response.ok) {\n throw new Error(`Model test failed with status: ${response.status}`);\n }\n\n const result = (await response.json()) as ChatCompletionResponse;\n\n if (!result.choices?.[0]?.message?.content) {\n throw new Error('No valid response content received');\n }\n\n logger.info(`Model ${modelId} test response:`, {\n content: result.choices[0].message.content,\n model: result.model,\n timestamp: new Date().toISOString(),\n });\n\n return true;\n } catch (error) {\n logger.error(`Model ${modelId} test failed:`, {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n return false;\n }\n }\n\n /**\n * Tests the configured text models to ensure they are working properly.\n * Logs the results of the test and any failed models.\n * @returns {Promise<void>} A promise that resolves when the test is complete.\n */\n private async testTextModels(): Promise<void> {\n logger.info('Testing configured text models...');\n\n const results = await Promise.all([\n this.testModel(this.configuredModels.small),\n this.testModel(this.configuredModels.medium),\n ]);\n\n const [smallWorking, mediumWorking] = results;\n\n if (!smallWorking || !mediumWorking) {\n const failedModels = [];\n if (!smallWorking) failedModels.push('small');\n if (!mediumWorking) failedModels.push('medium');\n\n logger.warn('Some models failed the test:', {\n failedModels,\n small: this.configuredModels.small,\n medium: this.configuredModels.medium,\n });\n } else {\n logger.success('All configured models passed the test');\n }\n }\n\n /**\n * Initializes StudioLM by checking server status, fetching available models,\n * and testing text models.\n *\n * @returns {Promise<void>} A Promise that resolves when initialization is complete\n */\n public async initialize(): Promise<void> {\n try {\n if (this.initialized) {\n logger.info('StudioLM already initialized, skipping initialization');\n return;\n }\n\n logger.info('Starting StudioLM initialization...');\n const serverAvailable = await this.checkServerStatus();\n\n if (!serverAvailable) {\n throw new Error('LM Studio server is not available');\n }\n\n await this.fetchAvailableModels();\n await this.testTextModels();\n\n this.initialized = true;\n logger.success('StudioLM initialization complete');\n } catch (error) {\n logger.error('StudioLM initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n throw error;\n }\n }\n\n /**\n * Retrieves the available models in the studio.\n *\n * @returns {StudioLMModel[]} An array of StudioLMModel objects representing the available models.\n */\n public getAvailableModels(): StudioLMModel[] {\n return this.availableModels;\n }\n\n /**\n * Check if the object is initialized.\n *\n * @returns {boolean} Returns true if the object is initialized, otherwise false.\n */\n public isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Asynchronously generates text using StudioLM based on provided parameters.\n *\n * @param {GenerateTextParams} params - The parameters for generating text.\n * @param {boolean} [isInitialized=false] - Flag to indicate if the model is already initialized.\n * @returns {Promise<string>} The generated text as a Promise.\n */\n public async generateText(params: GenerateTextParams, isInitialized = false): Promise<string> {\n try {\n // Log entry point with all parameters\n logger.info('StudioLM generateText entry:', {\n isInitialized,\n currentInitState: this.initialized,\n managerInitState: this.isInitialized(),\n modelType: params.modelType,\n contextLength: params.prompt?.length,\n timestamp: new Date().toISOString(),\n });\n\n // Only initialize if not already initialized and not marked as initialized\n if (!this.initialized && !isInitialized) {\n throw new Error('StudioLM not initialized. Please initialize before generating text.');\n }\n\n const messages: ChatMessage[] = [\n {\n role: 'system',\n content: 'You are a helpful AI assistant. Respond to the current request only.',\n },\n { role: 'user', content: params.prompt },\n ];\n\n logger.info('StudioLM preparing request:', {\n model:\n params.modelType === ModelType.TEXT_LARGE\n ? this.configuredModels.medium\n : this.configuredModels.small,\n messageCount: messages.length,\n timestamp: new Date().toISOString(),\n });\n\n logger.info('Incoming context structure:', {\n contextLength: params.prompt.length,\n hasAction: params.prompt.includes('action'),\n runtime: !!params.runtime,\n stopSequences: params.stopSequences,\n });\n\n const request: ChatCompletionRequest = {\n model:\n params.modelType === ModelType.TEXT_LARGE\n ? this.configuredModels.medium\n : this.configuredModels.small,\n messages,\n temperature: 0.7,\n max_tokens: 8192,\n stream: false,\n };\n\n const response = await fetch(`${this.serverUrl}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`StudioLM request failed: ${response.status}`);\n }\n\n const result = (await response.json()) as ChatCompletionResponse;\n\n if (!result.choices?.[0]?.message?.content) {\n throw new Error('No valid response content received from StudioLM');\n }\n\n let responseText = result.choices[0].message.content;\n\n // Log raw response for debugging\n logger.info('Raw response structure:', {\n responseLength: responseText.length,\n hasAction: responseText.includes('action'),\n hasThinkTag: responseText.includes('<think>'),\n });\n\n // Clean think tags if present\n if (responseText.includes('<think>')) {\n logger.info('Cleaning think tags from response');\n responseText = responseText.replace(/<think>[\\s\\S]*?<\\/think>\\n?/g, '');\n logger.info('Think tags removed from response');\n }\n\n logger.info('StudioLM request completed successfully:', {\n responseLength: responseText.length,\n hasThinkTags: responseText.includes('<think>'),\n timestamp: new Date().toISOString(),\n });\n\n return responseText;\n } catch (error) {\n logger.error('StudioLM text generation error:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n phase: 'text generation',\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n}\n","import { logger } from '@elizaos/core';\nimport { AutoTokenizer, type PreTrainedTokenizer } from '@huggingface/transformers';\n\n// Import the MODEL_SPECS type from a new types file we'll create later\nimport type { ModelSpec } from '../types';\n\n/**\n * Represents a Tokenizer Manager which manages tokenizers for different models.\n * * @class TokenizerManager\n */\nexport class TokenizerManager {\n private static instance: TokenizerManager | null = null;\n private tokenizers: Map<string, PreTrainedTokenizer>;\n private cacheDir: string;\n private modelsDir: string;\n\n /**\n * Constructor for creating a new instance of the class.\n *\n * @param {string} cacheDir - The directory for caching data.\n * @param {string} modelsDir - The directory for storing models.\n */\n private constructor(cacheDir: string, modelsDir: string) {\n this.tokenizers = new Map();\n this.cacheDir = cacheDir;\n this.modelsDir = modelsDir;\n }\n\n /**\n * Get the singleton instance of TokenizerManager class. If the instance does not exist, it will create a new one.\n *\n * @param {string} cacheDir - The directory to cache the tokenizer models.\n * @param {string} modelsDir - The directory where tokenizer models are stored.\n * @returns {TokenizerManager} The singleton instance of TokenizerManager.\n */\n static getInstance(cacheDir: string, modelsDir: string): TokenizerManager {\n if (!TokenizerManager.instance) {\n TokenizerManager.instance = new TokenizerManager(cacheDir, modelsDir);\n }\n return TokenizerManager.instance;\n }\n\n /**\n * Asynchronously loads a tokenizer based on the provided ModelSpec configuration.\n *\n * @param {ModelSpec} modelConfig - The configuration object for the model to load the tokenizer for.\n * @returns {Promise<PreTrainedTokenizer>} - A promise that resolves to the loaded tokenizer.\n */\n async loadTokenizer(modelConfig: ModelSpec): Promise<PreTrainedTokenizer> {\n try {\n const tokenizerKey = `${modelConfig.tokenizer.type}-${modelConfig.tokenizer.name}`;\n logger.info('Loading tokenizer:', {\n key: tokenizerKey,\n name: modelConfig.tokenizer.name,\n type: modelConfig.tokenizer.type,\n modelsDir: this.modelsDir,\n cacheDir: this.cacheDir,\n });\n\n if (this.tokenizers.has(tokenizerKey)) {\n logger.info('Using cached tokenizer:', { key: tokenizerKey });\n const cachedTokenizer = this.tokenizers.get(tokenizerKey);\n if (!cachedTokenizer) {\n throw new Error(`Tokenizer ${tokenizerKey} exists in map but returned undefined`);\n }\n return cachedTokenizer;\n }\n\n // Check if models directory exists\n const fs = await import('node:fs');\n if (!fs.existsSync(this.modelsDir)) {\n logger.warn('Models directory does not exist, creating it:', this.modelsDir);\n fs.mkdirSync(this.modelsDir, { recursive: true });\n }\n\n logger.info(\n 'Initializing new tokenizer from HuggingFace with models directory:',\n this.modelsDir\n );\n\n try {\n const tokenizer = await AutoTokenizer.from_pretrained(modelConfig.tokenizer.name, {\n cache_dir: this.modelsDir,\n local_files_only: false,\n });\n\n this.tokenizers.set(tokenizerKey, tokenizer);\n logger.success('Tokenizer loaded successfully:', { key: tokenizerKey });\n return tokenizer;\n } catch (tokenizeError) {\n logger.error('Failed to load tokenizer from HuggingFace:', {\n error: tokenizeError instanceof Error ? tokenizeError.message : String(tokenizeError),\n stack: tokenizeError instanceof Error ? tokenizeError.stack : undefined,\n tokenizer: modelConfig.tokenizer.name,\n modelsDir: this.modelsDir,\n });\n\n // Try again with local_files_only set to false and a longer timeout\n logger.info('Retrying tokenizer loading...');\n const tokenizer = await AutoTokenizer.from_pretrained(modelConfig.tokenizer.name, {\n cache_dir: this.modelsDir,\n local_files_only: false,\n });\n\n this.tokenizers.set(tokenizerKey, tokenizer);\n logger.success('Tokenizer loaded successfully on retry:', {\n key: tokenizerKey,\n });\n return tokenizer;\n }\n } catch (error) {\n logger.error('Failed to load tokenizer:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n model: modelConfig.name,\n tokenizer: modelConfig.tokenizer.name,\n modelsDir: this.modelsDir,\n });\n throw error;\n }\n }\n\n /**\n * Encodes the given text using the specified tokenizer model configuration.\n *\n * @param {string} text - The text to encode.\n * @param {ModelSpec} modelConfig - The configuration for the model tokenizer.\n * @returns {Promise<number[]>} - An array of integers representing the encoded text.\n * @throws {Error} - If the text encoding fails, an error is thrown.\n */\n async encode(text: string, modelConfig: ModelSpec): Promise<number[]> {\n try {\n logger.info('Encoding text with tokenizer:', {\n length: text.length,\n tokenizer: modelConfig.tokenizer.name,\n });\n\n const tokenizer = await this.loadTokenizer(modelConfig);\n\n logger.info('Tokenizer loaded, encoding text...');\n const encoded = await tokenizer.encode(text, {\n add_special_tokens: true,\n return_token_type_ids: false,\n });\n\n logger.info('Text encoded successfully:', {\n tokenCount: encoded.length,\n tokenizer: modelConfig.tokenizer.name,\n });\n return encoded;\n } catch (error) {\n logger.error('Text encoding failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n textLength: text.length,\n tokenizer: modelConfig.tokenizer.name,\n modelsDir: this.modelsDir,\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously decodes an array of tokens using a tokenizer based on the provided ModelSpec.\n *\n * @param {number[]} tokens - The array of tokens to be decoded.\n * @param {ModelSpec} modelConfig - The ModelSpec object containing information about the model and tokenizer to be used.\n * @returns {Promise<string>} - A Promise that resolves with the decoded text.\n * @throws {Error} - If an error occurs during token decoding.\n */\n async decode(tokens: number[], modelConfig: ModelSpec): Promise<string> {\n try {\n logger.info('Decoding tokens with tokenizer:', {\n count: tokens.length,\n tokenizer: modelConfig.tokenizer.name,\n });\n\n const tokenizer = await this.loadTokenizer(modelConfig);\n\n logger.info('Tokenizer loaded, decoding tokens...');\n const decoded = await tokenizer.decode(tokens, {\n skip_special_tokens: true,\n clean_up_tokenization_spaces: true,\n });\n\n logger.info('Tokens decoded successfully:', {\n textLength: decoded.length,\n tokenizer: modelConfig.tokenizer.name,\n });\n return decoded;\n } catch (error) {\n logger.error('Token decoding failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n tokenCount: tokens.length,\n tokenizer: modelConfig.tokenizer.name,\n modelsDir: this.modelsDir,\n });\n throw error;\n }\n }\n}\n","import { exec } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\nimport { logger } from '@elizaos/core';\nimport { nodewhisper } from 'nodejs-whisper';\n\nconst execAsync = promisify(exec);\n\n/**\n * Interface representing the result of a transcription process.\n * @interface\n * @property {string} text - The transcribed text.\n */\ninterface TranscriptionResult {\n text: string;\n}\n\n/**\n * Class representing a TranscribeManager.\n *\n * @property {TranscribeManager | null} instance - The singleton instance of the TranscribeManager class.\n * @property {string} cacheDir - The directory path for caching transcribed files.\n * @property {boolean} ffmpegAvailable - Flag indicating if ffmpeg is available for audio processing.\n * @property {string | null} ffmpegVersion - The version of ffmpeg if available.\n * @property {string | null} ffmpegPath - The path to the ffmpeg executable.\n * @property {boolean} ffmpegInitialized - Flag indicating if ffmpeg has been initialized.\n *\n * @constructor\n * Creates an instance of TranscribeManager with the specified cache directory.\n */\nexport class TranscribeManager {\n private static instance: TranscribeManager | null = null;\n private cacheDir: string;\n private ffmpegAvailable = false;\n private ffmpegVersion: string | null = null;\n private ffmpegPath: string | null = null;\n private ffmpegInitialized = false;\n\n /**\n * Constructor for TranscribeManager class.\n *\n * @param {string} cacheDir - The directory path for storing cached files.\n */\n private constructor(cacheDir: string) {\n this.cacheDir = path.join(cacheDir, 'whisper');\n logger.debug('Initializing TranscribeManager', {\n cacheDir: this.cacheDir,\n timestamp: new Date().toISOString(),\n });\n this.ensureCacheDirectory();\n }\n\n /**\n * Ensures that FFmpeg is initialized and available for use.\n * @returns {Promise<boolean>} A promise that resolves to a boolean value indicating if FFmpeg is available.\n */\n public async ensureFFmpeg(): Promise<boolean> {\n if (!this.ffmpegInitialized) {\n try {\n await this.initializeFFmpeg();\n this.ffmpegInitialized = true;\n } catch (error) {\n logger.error('FFmpeg initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n return false;\n }\n }\n return this.ffmpegAvailable;\n }\n\n /**\n * Checks if FFmpeg is available.\n * @returns {boolean} True if FFmpeg is available, false otherwise.\n */\n public isFFmpegAvailable(): boolean {\n return this.ffmpegAvailable;\n }\n\n /**\n * Asynchronously retrieves the FFmpeg version if it hasn't been fetched yet.\n * If the FFmpeg version has already been fetched, it will return the stored version.\n * @returns A Promise that resolves with the FFmpeg version as a string, or null if the version is not available.\n */\n public async getFFmpegVersion(): Promise<string | null> {\n if (!this.ffmpegVersion) {\n await this.fetchFFmpegVersion();\n }\n return this.ffmpegVersion;\n }\n\n /**\n * Fetches the FFmpeg version by executing the command \"ffmpeg -version\".\n * Updates the class property ffmpegVersion with the retrieved version.\n * Logs the FFmpeg version information or error message.\n * @returns {Promise<void>} A Promise that resolves once the FFmpeg version is fetched and logged.\n */\n private async fetchFFmpegVersion(): Promise<void> {\n try {\n const { stdout } = await execAsync('ffmpeg -version');\n this.ffmpegVersion = stdout.split('\\n')[0];\n logger.info('FFmpeg version:', {\n version: this.ffmpegVersion,\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n this.ffmpegVersion = null;\n logger.error('Failed to get FFmpeg version:', {\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n /**\n * Initializes FFmpeg by performing the following steps:\n * 1. Checks for FFmpeg availability in PATH\n * 2. Retrieves FFmpeg version information\n * 3. Verifies FFmpeg capabilities\n *\n * If FFmpeg is available, logs a success message with version, path, and timestamp.\n * If FFmpeg is not available, logs installation instructions.\n *\n * @returns A Promise that resolves once FFmpeg has been successfully initialized\n */\n private async initializeFFmpeg(): Promise<void> {\n try {\n // First check if ffmpeg exists in PATH\n await this.checkFFmpegAvailability();\n\n if (this.ffmpegAvailable) {\n // Get FFmpeg version info\n await this.fetchFFmpegVersion();\n\n // Verify FFmpeg capabilities\n await this.verifyFFmpegCapabilities();\n\n // logger.success(\"FFmpeg initialized successfully\", {\n // version: this.ffmpegVersion,\n // path: this.ffmpegPath,\n // timestamp: new Date().toISOString()\n // });\n } else {\n this.logFFmpegInstallInstructions();\n }\n } catch (error) {\n this.ffmpegAvailable = false;\n logger.error('FFmpeg initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n timestamp: new Date().toISOString(),\n });\n this.logFFmpegInstallInstructions();\n }\n }\n\n /**\n * Asynchronously checks for the availability of FFmpeg in the system by executing a command to find the FFmpeg location.\n * Updates the class properties `ffmpegPath` and `ffmpegAvailable` accordingly.\n * Logs relevant information such as FFmpeg location and potential errors using the logger.\n *\n * @returns A Promise that resolves with no value upon completion.\n */\n private async checkFFmpegAvailability(): Promise<void> {\n try {\n const { stdout, stderr } = await execAsync('which ffmpeg || where ffmpeg');\n this.ffmpegPath = stdout.trim();\n this.ffmpegAvailable = true;\n logger.info('FFmpeg found at:', {\n path: this.ffmpegPath,\n stderr: stderr ? stderr.trim() : undefined,\n timestamp: new Date().toISOString(),\n });\n } catch (error) {\n this.ffmpegAvailable = false;\n this.ffmpegPath = null;\n logger.error('FFmpeg not found in PATH:', {\n error: error instanceof Error ? error.message : String(error),\n stderr: error instanceof Error && 'stderr' in error ? error.stderr : undefined,\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n /**\n * Verifies the FFmpeg capabilities by checking if FFmpeg supports the required codecs and formats.\n *\n * @returns {Promise<void>} A Promise that resolves if FFmpeg has the required codecs, otherwise rejects with an error message.\n */\n private async verifyFFmpegCapabilities(): Promise<void> {\n try {\n // Check if FFmpeg supports required codecs and formats\n const { stdout } = await execAsync('ffmpeg -codecs');\n const hasRequiredCodecs = stdout.includes('pcm_s16le') && stdout.includes('wav');\n\n if (!hasRequiredCodecs) {\n throw new Error('FFmpeg installation missing required codecs (pcm_s16le, wav)');\n }\n\n // logger.info(\"FFmpeg capabilities verified\", {\n // hasRequiredCodecs,\n // timestamp: new Date().toISOString()\n // });\n } catch (error) {\n logger.error('FFmpeg capabilities verification failed:', {\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Logs instructions on how to install FFmpeg if it is not properly installed.\n */\n private logFFmpegInstallInstructions(): void {\n logger.warn('FFmpeg is required but not properly installed. Please install FFmpeg:', {\n instructions: {\n mac: 'brew install ffmpeg',\n ubuntu: 'sudo apt-get install ffmpeg',\n windows: 'choco install ffmpeg',\n manual: 'Download from https://ffmpeg.org/download.html',\n },\n requiredVersion: '4.0 or later',\n requiredCodecs: ['pcm_s16le', 'wav'],\n timestamp: new Date().toISOString(),\n });\n }\n\n /**\n * Gets the singleton instance of TranscribeManager, creates a new instance if it doesn't exist.\n *\n * @param {string} cacheDir - The directory path for caching transcriptions.\n * @returns {TranscribeManager} The singleton instance of TranscribeManager.\n */\n public static getInstance(cacheDir: string): TranscribeManager {\n if (!TranscribeManager.instance) {\n TranscribeManager.instance = new TranscribeManager(cacheDir);\n }\n return TranscribeManager.instance;\n }\n\n /**\n * Ensures that the cache directory exists. If it doesn't exist,\n * creates the directory using fs.mkdirSync with recursive set to true.\n * @returns {void}\n */\n private ensureCacheDirectory(): void {\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n // logger.info(\"Created whisper cache directory:\", this.cacheDir);\n }\n }\n\n /**\n * Converts an audio file to WAV format using FFmpeg.\n *\n * @param {string} inputPath - The input path of the audio file to convert.\n * @param {string} outputPath - The output path where the converted WAV file will be saved.\n * @returns {Promise<void>} A Promise that resolves when the conversion is completed.\n * @throws {Error} If FFmpeg is not installed or not properly configured, or if the audio conversion fails.\n */\n private async convertToWav(inputPath: string, outputPath: string): Promise<void> {\n if (!this.ffmpegAvailable) {\n throw new Error(\n 'FFmpeg is not installed or not properly configured. Please install FFmpeg to use audio transcription.'\n );\n }\n\n try {\n // Add -loglevel error to suppress FFmpeg output unless there's an error\n const { stderr } = await execAsync(\n `ffmpeg -y -loglevel error -i \"${inputPath}\" -acodec pcm_s16le -ar 16000 -ac 1 \"${outputPath}\"`\n );\n\n if (stderr) {\n logger.warn('FFmpeg conversion error:', {\n stderr,\n inputPath,\n outputPath,\n timestamp: new Date().toISOString(),\n });\n }\n\n if (!fs.existsSync(outputPath)) {\n throw new Error('WAV file was not created successfully');\n }\n } catch (error) {\n logger.error('Audio conversion failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n command: `ffmpeg -y -loglevel error -i \"${inputPath}\" -acodec pcm_s16le -ar 16000 -ac 1 \"${outputPath}\"`,\n ffmpegAvailable: this.ffmpegAvailable,\n ffmpegVersion: this.ffmpegVersion,\n ffmpegPath: this.ffmpegPath,\n timestamp: new Date().toISOString(),\n });\n throw new Error(\n `Failed to convert audio to WAV format: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Asynchronously preprocesses the audio by converting the provided audio buffer into a WAV file.\n * If FFmpeg is not installed, an error is thrown.\n *\n * @param {Buffer} audioBuffer The audio buffer to preprocess\n * @returns {Promise<string>} The path to the preprocessed WAV file\n * @throws {Error} If FFmpeg is not installed or if audio preprocessing fails\n */\n private async preprocessAudio(audioBuffer: Buffer): Promise<string> {\n if (!this.ffmpegAvailable) {\n throw new Error('FFmpeg is not installed. Please install FFmpeg to use audio transcription.');\n }\n\n try {\n const tempInputFile = path.join(this.cacheDir, `temp_input_${Date.now()}`);\n const tempWavFile = path.join(this.cacheDir, `temp_${Date.now()}.wav`);\n\n // logger.info(\"Creating temporary files\", {\n // inputFile: tempInputFile,\n // wavFile: tempWavFile,\n // bufferSize: audioBuffer.length,\n // timestamp: new Date().toISOString()\n // });\n\n // Write buffer to temporary file\n fs.writeFileSync(tempInputFile, audioBuffer);\n // logger.info(\"Temporary input file created\", {\n // path: tempInputFile,\n // size: audioBuffer.length,\n // timestamp: new Date().toISOString()\n // });\n\n // Convert to WAV format\n await this.convertToWav(tempInputFile, tempWavFile);\n\n // Clean up the input file\n if (fs.existsSync(tempInputFile)) {\n fs.unlinkSync(tempInputFile);\n // logger.info(\"Temporary input file cleaned up\", {\n // path: tempInputFile,\n // timestamp: new Date().toISOString()\n // });\n }\n\n return tempWavFile;\n } catch (error) {\n logger.error('Audio preprocessing failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n ffmpegAvailable: this.ffmpegAvailable,\n timestamp: new Date().toISOString(),\n });\n throw new Error(\n `Failed to preprocess audio: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Transcribes the audio buffer to text using whisper.\n *\n * @param {Buffer} audioBuffer The audio buffer to transcribe.\n * @returns {Promise<TranscriptionResult>} A promise that resolves with the transcription result.\n * @throws {Error} If FFmpeg is not installed or properly configured.\n */\n\n public async transcribe(audioBuffer: Buffer): Promise<TranscriptionResult> {\n await this.ensureFFmpeg();\n\n if (!this.ffmpegAvailable) {\n throw new Error(\n 'FFmpeg is not installed or not properly configured. Please install FFmpeg to use audio transcription.'\n );\n }\n\n try {\n // Preprocess audio to WAV format\n const wavFile = await this.preprocessAudio(audioBuffer);\n\n logger.info('Starting transcription with whisper...');\n\n // Save original stdout and stderr write functions\n const originalStdoutWrite = process.stdout.write;\n const originalStderrWrite = process.stderr.write;\n\n // Create a no-op function to suppress output\n const noopWrite = () => true;\n\n // Redirect stdout and stderr to suppress whisper output\n process.stdout.write = noopWrite;\n process.stderr.write = noopWrite;\n\n let output: string;\n try {\n // Transcribe using whisper with output suppressed\n output = await nodewhisper(wavFile, {\n modelName: 'base.en',\n autoDownloadModelName: 'base.en',\n verbose: false,\n whisperOptions: {\n outputInText: true,\n language: 'en',\n },\n });\n } finally {\n // Restore original stdout and stderr\n process.stdout.write = originalStdoutWrite;\n process.stderr.write = originalStderrWrite;\n }\n\n // Clean up temporary WAV file\n if (fs.existsSync(wavFile)) {\n fs.unlinkSync(wavFile);\n logger.info('Temporary WAV file cleaned up');\n }\n\n // Extract just the text content without timestamps\n const cleanText = output\n .split('\\n')\n .map((line) => {\n // Remove timestamps if present [00:00:00.000 --> 00:00:00.000]\n const textMatch = line.match(/](.+)$/);\n return textMatch ? textMatch[1].trim() : line.trim();\n })\n .filter((line) => line) // Remove empty lines\n .join(' ');\n\n logger.success('Transcription complete:', {\n textLength: cleanText.length,\n timestamp: new Date().toISOString(),\n });\n\n return { text: cleanText };\n } catch (error) {\n logger.error('Transcription failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n ffmpegAvailable: this.ffmpegAvailable,\n });\n throw error;\n }\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { logger } from '@elizaos/core';\nimport {\n type LlamaContext,\n type LlamaContextSequence,\n type LlamaModel,\n type Token,\n getLlama,\n} from 'node-llama-cpp';\nimport { MODEL_SPECS } from '../types';\nimport { prependWavHeader } from './audioUtils';\nimport { DownloadManager } from './downloadManager';\n\n/**\n * Interface representing the response from a Text-to-Speech (TTS) service.\n * @typedef { Object } TTSResponse\n * @property {number[]} tokens - The array of token ids representing the text to be converted to speech.\n * @property { Float32Array } [audio] - Optional Float32Array representing the audio data output from the TTS service.\n */\ninterface TTSResponse {\n tokens: number[];\n audio?: Float32Array;\n}\n\n/**\n * Class representing a Text-to-Speech Manager\n */\nexport class TTSManager {\n private static instance: TTSManager | null = null;\n private cacheDir: string;\n private model: LlamaModel | null = null;\n private ctx: LlamaContext | null = null;\n private sequence: LlamaContextSequence | null = null;\n private initialized = false;\n private downloadManager: DownloadManager;\n private modelsDir: string;\n\n /**\n * Creates a new instance of TTSManager with the provided cache directory.\n *\n * @param {string} cacheDir - The directory where cached data will be stored.\n */\n private constructor(cacheDir: string) {\n this.cacheDir = path.join(cacheDir, 'tts');\n this.modelsDir = process.env.LLAMALOCAL_PATH?.trim()\n ? path.resolve(process.env.LLAMALOCAL_PATH.trim())\n : path.join(process.cwd(), 'models');\n this.downloadManager = DownloadManager.getInstance(this.cacheDir, this.modelsDir);\n this.ensureCacheDirectory();\n logger.debug('TTSManager initialized');\n }\n\n /**\n * Returns an instance of TTSManager, creating a new one if none exist.\n *\n * @param {string} cacheDir - The directory path to store cached audio files.\n * @returns {TTSManager} An instance of TTSManager.\n */\n public static getInstance(cacheDir: string): TTSManager {\n if (!TTSManager.instance) {\n TTSManager.instance = new TTSManager(cacheDir);\n }\n return TTSManager.instance;\n }\n\n /**\n * Ensures that the cache directory exists. If it does not exist, the directory will be created.\n */\n private ensureCacheDirectory(): void {\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n logger.debug('Created TTS cache directory:', this.cacheDir);\n }\n }\n\n /**\n * Asynchronously initializes the TTS module with GGUF backend.\n * If already initialized or missing necessary components (model and context), it returns early.\n * Handles model download using different URL patterns as fallback if model not found locally.\n * Initializes the TTS model, creates context, and sets the sequence for TTS generation.\n * Logs detailed steps and final output of initialization.\n *\n * @returns {Promise<void>} A promise that resolves once the TTS module is fully initialized.\n */\n private async initialize(): Promise<void> {\n try {\n if (this.initialized && this.model && this.ctx) {\n return;\n }\n\n logger.info('Initializing TTS with GGUF backend...');\n\n const modelSpec = MODEL_SPECS.tts.base;\n const modelPath = path.join(this.modelsDir, modelSpec.name);\n\n // Log detailed model configuration and paths\n // logger.info(\"TTS model configuration:\", {\n // name: modelSpec.name,\n // repo: modelSpec.repo,\n // modelPath,\n // timestamp: new Date().toISOString()\n // });\n\n if (!fs.existsSync(modelPath)) {\n // Try different URL patterns in sequence\n const attempts = [\n {\n spec: { ...modelSpec },\n description: 'Standard URL with GGUF',\n url: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name}?download=true`,\n },\n {\n spec: { ...modelSpec, repo: modelSpec.repo.replace('-GGUF', '') },\n description: 'URL without GGUF suffix',\n url: `https://huggingface.co/${modelSpec.repo.replace('-GGUF', '')}/resolve/main/${modelSpec.name}?download=true`,\n },\n {\n spec: { ...modelSpec, name: modelSpec.name.replace('-Q8_0', '') },\n description: 'URL without quantization suffix',\n url: `https://huggingface.co/${modelSpec.repo}/resolve/main/${modelSpec.name.replace('-Q8_0', '')}.gguf?download=true`,\n },\n ];\n\n let lastError = null;\n for (const attempt of attempts) {\n try {\n logger.info('Attempting TTS model download:', {\n description: attempt.description,\n repo: attempt.spec.repo,\n name: attempt.spec.name,\n url: attempt.url,\n timestamp: new Date().toISOString(),\n });\n\n const barLength = 30;\n const emptyBar = '▱'.repeat(barLength);\n logger.info(`Downloading TTS model: ${emptyBar} 0%`);\n\n await this.downloadManager.downloadFromUrl(attempt.url, modelPath);\n\n const completedBar = '▰'.repeat(barLength);\n logger.info(`Downloading TTS model: ${completedBar} 100%`);\n logger.success('TTS model download successful with:', attempt.description);\n break;\n } catch (error) {\n lastError = error;\n logger.warn('TTS model download attempt failed:', {\n description: attempt.description,\n error: error instanceof Error ? error.message : String(error),\n timestamp: new Date().toISOString(),\n });\n }\n }\n\n if (!fs.existsSync(modelPath)) {\n throw lastError || new Error('All download attempts failed');\n }\n }\n\n logger.info('Loading TTS model...');\n const llama = await getLlama();\n this.model = await llama.loadModel({\n modelPath,\n gpuLayers: 0, // Force CPU for now until we add GPU support\n });\n\n this.ctx = await this.model.createContext({\n contextSize: modelSpec.contextSize,\n });\n\n this.sequence = this.ctx.getSequence();\n\n logger.success('TTS initialization complete', {\n modelPath,\n contextSize: modelSpec.contextSize,\n timestamp: new Date().toISOString(),\n });\n this.initialized = true;\n } catch (error) {\n logger.error('TTS initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n model: MODEL_SPECS.tts.base.name,\n timestamp: new Date().toISOString(),\n });\n throw error;\n }\n }\n\n /**\n * Asynchronously generates speech from a given text using the initialized TTS model.\n * @param {string} text - The text to generate speech from.\n * @returns {Promise<Readable>} A promise that resolves to a Readable stream containing the generated audio data.\n * @throws {Error} If the TTS model is not initialized or if no audio tokens are generated.\n */\n public async generateSpeech(text: string): Promise<Readable> {\n try {\n await this.initialize();\n\n if (!this.model || !this.ctx || !this.sequence) {\n throw new Error('TTS model not initialized');\n }\n\n logger.info('Starting speech generation for text:', { text });\n\n // Format prompt for TTS generation\n const prompt = `[SPEAKER=female_1][LANGUAGE=en]${text}`;\n logger.info('Formatted prompt:', { prompt });\n\n // Tokenize input\n logger.info('Tokenizing input...');\n const inputTokens = this.model.tokenize(prompt);\n logger.info('Input tokenized:', { tokenCount: inputTokens.length });\n\n // Generate audio tokens with optimized limit (2x input)\n const maxTokens = inputTokens.length * 2;\n logger.info('Starting token generation with optimized limit:', {\n maxTokens,\n });\n const responseTokens: Token[] = [];\n const _startTime = Date.now();\n\n try {\n for await (const token of this.sequence.evaluate(inputTokens, {\n temperature: 0.1,\n })) {\n responseTokens.push(token);\n\n // Update progress bar\n const percent = Math.round((responseTokens.length / maxTokens) * 100);\n const barLength = 30;\n const filledLength = Math.floor((responseTokens.length / maxTokens) * barLength);\n const progressBar = '▰'.repeat(filledLength) + '▱'.repeat(barLength - filledLength);\n logger.info(\n `Token generation: ${progressBar} ${percent}% (${responseTokens.length}/${maxTokens})`\n );\n\n // Stop if we hit our token limit\n if (responseTokens.length >= maxTokens) {\n logger.info('Token generation complete');\n break;\n }\n }\n } catch (error) {\n logger.error('Token generation error:', error);\n throw error;\n }\n\n // logger.info(\"Token generation stats:\", {\n // inputTokens: inputTokens.length,\n // outputTokens: responseTokens.length,\n // timeMs: Date.now() - startTime\n // });\n\n if (responseTokens.length === 0) {\n throw new Error('No audio tokens generated');\n }\n\n // Convert tokens to audio data\n logger.info('Converting tokens to audio data...');\n const audioData = this.processAudioResponse({\n tokens: responseTokens.map((t) => Number.parseInt(this.model.detokenize([t]), 10)),\n });\n\n logger.info('Audio data generated:', {\n byteLength: audioData.length,\n sampleRate: MODEL_SPECS.tts.base.sampleRate,\n });\n\n // Create WAV format\n const audioStream = prependWavHeader(\n Readable.from(audioData),\n audioData.length,\n MODEL_SPECS.tts.base.sampleRate,\n 1,\n 16\n );\n\n logger.success('Speech generation complete');\n return audioStream;\n } catch (error) {\n logger.error('Speech generation failed:', {\n error: error instanceof Error ? error.message : String(error),\n text,\n });\n throw error;\n }\n }\n\n /**\n * Processes the audio response from the TTS service by converting\n * the data to 16-bit PCM format.\n * If the response contains direct audio data, it converts Float32Array\n * to 16-bit PCM. If the response only contains tokens, it converts\n * them to PCM data. The actual conversion process may vary depending\n * on the model used.\n *\n * @param {TTSResponse} response - The response object from the TTS service\n * @returns {Buffer} The processed audio data in 16-bit PCM format\n */\n private processAudioResponse(response: TTSResponse): Buffer {\n if (response.audio) {\n // If we have direct audio data, convert Float32Array to 16-bit PCM\n const pcmData = new Int16Array(response.audio.length);\n for (let i = 0; i < response.audio.length; i++) {\n // Convert float to 16-bit PCM\n const s = Math.max(-1, Math.min(1, response.audio[i]));\n pcmData[i] = s < 0 ? s * 0x8000 : s * 0x7fff;\n }\n return Buffer.from(pcmData.buffer);\n }\n\n // If we only have tokens, convert them to PCM data\n // This is a placeholder implementation - actual conversion depends on model\n const pcmData = new Int16Array(response.tokens.length * 2);\n for (let i = 0; i < response.tokens.length; i++) {\n // Simple conversion for testing - replace with actual model-specific conversion\n pcmData[i * 2] = response.tokens[i] & 0xffff;\n pcmData[i * 2 + 1] = (response.tokens[i] >> 16) & 0xffff;\n }\n return Buffer.from(pcmData.buffer);\n }\n}\n","import { PassThrough, type Readable } from 'node:stream';\n\n/**\n * Generates a WAV header for audio data based on the input parameters.\n *\n * @param {number} audioLength - The length of the audio data in bytes.\n * @param {number} sampleRate - The sample rate of the audio data.\n * @param {number} [channelCount=1] - The number of audio channels (default is 1).\n * @param {number} [bitsPerSample=16] - The number of bits per audio sample (default is 16).\n * @returns {Buffer} - The WAV header as a Buffer.\n */\nexport function getWavHeader(\n audioLength: number,\n sampleRate: number,\n channelCount = 1,\n bitsPerSample = 16\n): Buffer {\n const wavHeader = Buffer.alloc(44);\n wavHeader.write('RIFF', 0);\n wavHeader.writeUInt32LE(36 + audioLength, 4); // Length of entire file in bytes minus 8\n wavHeader.write('WAVE', 8);\n wavHeader.write('fmt ', 12);\n wavHeader.writeUInt32LE(16, 16); // Length of format data\n wavHeader.writeUInt16LE(1, 20); // Type of format (1 is PCM)\n wavHeader.writeUInt16LE(channelCount, 22); // Number of channels\n wavHeader.writeUInt32LE(sampleRate, 24); // Sample rate\n wavHeader.writeUInt32LE((sampleRate * bitsPerSample * channelCount) / 8, 28); // Byte rate\n wavHeader.writeUInt16LE((bitsPerSample * channelCount) / 8, 32); // Block align\n wavHeader.writeUInt16LE(bitsPerSample, 34); // Bits per sample\n wavHeader.write('data', 36); // Data chunk header\n wavHeader.writeUInt32LE(audioLength, 40); // Data chunk size\n return wavHeader;\n}\n\n/**\n * Prepends a WAV header to an audio stream.\n *\n * @param {Readable} readable - The readable stream of audio data.\n * @param {number} audioLength - The length of the audio in seconds.\n * @param {number} sampleRate - The sample rate of the audio.\n * @param {number} [channelCount=1] - The number of audio channels. Default is 1.\n * @param {number} [bitsPerSample=16] - The number of bits per sample. Default is 16.\n * @returns {Readable} - A readable stream with the WAV header prepended to the audio data.\n */\nexport function prependWavHeader(\n readable: Readable,\n audioLength: number,\n sampleRate: number,\n channelCount = 1,\n bitsPerSample = 16\n): Readable {\n const wavHeader = getWavHeader(audioLength, sampleRate, channelCount, bitsPerSample);\n let pushedHeader = false;\n const passThrough = new PassThrough();\n readable.on('data', (data) => {\n if (!pushedHeader) {\n passThrough.push(wavHeader);\n pushedHeader = true;\n }\n passThrough.push(data);\n });\n readable.on('end', () => {\n passThrough.end();\n });\n return passThrough;\n}\n","import { existsSync } from 'node:fs';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { logger } from '@elizaos/core';\nimport {\n AutoProcessor,\n AutoTokenizer,\n Florence2ForConditionalGeneration,\n type Florence2Processor,\n type PreTrainedModel,\n type PreTrainedTokenizer,\n type ProgressCallback,\n type ProgressInfo,\n RawImage,\n type Tensor,\n env,\n} from '@huggingface/transformers';\nimport { MODEL_SPECS } from '../types';\nimport { DownloadManager } from './downloadManager';\n\n// Define valid types based on HF transformers types\n/**\n * Defines the type 'DeviceType' which can take one of the three string values: 'cpu', 'gpu', or 'auto'\n */\ntype DeviceType = 'cpu' | 'gpu' | 'auto';\n/**\n * Represents the available data types options.\n */\ntype DTypeType = 'fp32' | 'fp16' | 'auto';\n\n/**\n * Interface for platform configuration options.\n * @typedef {Object} PlatformConfig\n * @property {DeviceType} device - The type of device to use.\n * @property {DTypeType} dtype - The data type to use.\n * @property {boolean} useOnnx - Flag indicating whether to use ONNX for processing.\n */\ninterface PlatformConfig {\n device: DeviceType;\n dtype: DTypeType;\n useOnnx: boolean;\n}\n\n/**\n * Represents a model component with a name, type, and optionally a data type.\n * @interface ModelComponent\n * @property { string } name - The name of the model component.\n * @property { string } type - The type of the model component.\n * @property { DTypeType } [dtype] - The data type of the model component (optional).\n */\ninterface ModelComponent {\n name: string;\n type: string;\n dtype?: DTypeType;\n}\n\n/**\n * Class representing a VisionManager.\n * @property {VisionManager | null} instance - The static instance of VisionManager.\n * @property {Florence2ForConditionalGeneration | null} model - The model for conditional generation.\n * @property {Florence2Processor | null} processor - The processor for Florence2.\n * @property {PreTrainedTokenizer | null} tokenizer - The pre-trained tokenizer.\n * @property {string} modelsDir - The directory for models.\n * @property {string} cacheDir - The directory for caching.\n * @property {boolean} initialized - Flag indicating if the VisionManager has been initialized.\n * @property {DownloadManager} downloadManager - The manager for downloading.\n */\nexport class VisionManager {\n private static instance: VisionManager | null = null;\n private model: Florence2ForConditionalGeneration | null = null;\n private processor: Florence2Processor | null = null;\n private tokenizer: PreTrainedTokenizer | null = null;\n private modelsDir: string;\n private cacheDir: string;\n private initialized = false;\n private downloadManager: DownloadManager;\n private modelDownloaded = false;\n private tokenizerDownloaded = false;\n private processorDownloaded = false;\n private platformConfig: PlatformConfig;\n private modelComponents: ModelComponent[] = [\n { name: 'embed_tokens', type: 'embeddings' },\n { name: 'vision_encoder', type: 'encoder' },\n { name: 'decoder_model_merged', type: 'decoder' },\n { name: 'encoder_model', type: 'encoder' },\n ];\n\n /**\n * Constructor for VisionManager class.\n *\n * @param {string} cacheDir - The directory path for caching vision models.\n */\n private constructor(cacheDir: string) {\n this.modelsDir = path.join(path.dirname(cacheDir), 'models', 'vision');\n this.cacheDir = cacheDir;\n this.ensureModelsDirExists();\n this.downloadManager = DownloadManager.getInstance(this.cacheDir, this.modelsDir);\n this.platformConfig = this.getPlatformConfig();\n logger.debug('VisionManager initialized');\n }\n\n /**\n * Retrieves the platform configuration based on the operating system and architecture.\n * @returns {PlatformConfig} The platform configuration object with device, dtype, and useOnnx properties.\n */\n private getPlatformConfig(): PlatformConfig {\n const platform = os.platform();\n const arch = os.arch();\n\n // Default configuration\n let config: PlatformConfig = {\n device: 'cpu',\n dtype: 'fp32',\n useOnnx: true,\n };\n\n if (platform === 'darwin' && (arch === 'arm64' || arch === 'aarch64')) {\n // Apple Silicon\n config = {\n device: 'gpu',\n dtype: 'fp16',\n useOnnx: true,\n };\n } else if (platform === 'win32' || platform === 'linux') {\n // Windows or Linux with CUDA\n const hasCuda = process.env.CUDA_VISIBLE_DEVICES !== undefined;\n if (hasCuda) {\n config = {\n device: 'gpu',\n dtype: 'fp16',\n useOnnx: true,\n };\n }\n }\n return config;\n }\n\n /**\n * Ensures that the models directory exists. If it does not exist, it creates the directory.\n */\n private ensureModelsDirExists(): void {\n if (!existsSync(this.modelsDir)) {\n logger.debug(`Creating models directory at: ${this.modelsDir}`);\n fs.mkdirSync(this.modelsDir, { recursive: true });\n }\n }\n\n /**\n * Returns the singleton instance of VisionManager.\n * If an instance does not already exist, a new instance is created with the specified cache directory.\n *\n * @param {string} cacheDir - The directory where cache files will be stored.\n *\n * @returns {VisionManager} The singleton instance of VisionManager.\n */\n public static getInstance(cacheDir: string): VisionManager {\n if (!VisionManager.instance) {\n VisionManager.instance = new VisionManager(cacheDir);\n }\n return VisionManager.instance;\n }\n\n /**\n * Check if the cache exists for the specified model or tokenizer or processor.\n * @param {string} modelId - The ID of the model.\n * @param {\"model\" | \"tokenizer\" | \"processor\"} type - The type of the cache (\"model\", \"tokenizer\", or \"processor\").\n * @returns {boolean} - Returns true if cache exists, otherwise returns false.\n */\n private checkCacheExists(modelId: string, type: 'model' | 'tokenizer' | 'processor'): boolean {\n const modelPath = path.join(this.modelsDir, modelId.replace('/', '--'), type);\n if (existsSync(modelPath)) {\n logger.info(`${type} found at: ${modelPath}`);\n return true;\n }\n return false;\n }\n\n /**\n * Configures the model components based on the platform and architecture.\n * Sets the default data type (dtype) for components based on platform capabilities.\n * Updates all component dtypes to match the default dtype.\n */\n private configureModelComponents(): void {\n const platform = os.platform();\n const arch = os.arch();\n\n // Set dtype based on platform capabilities\n let defaultDtype: DTypeType = 'fp32';\n\n if (platform === 'darwin' && (arch === 'arm64' || arch === 'aarch64')) {\n // Apple Silicon can handle fp16\n defaultDtype = 'fp16';\n } else if (\n (platform === 'win32' || platform === 'linux') &&\n process.env.CUDA_VISIBLE_DEVICES !== undefined\n ) {\n // CUDA-enabled systems can handle fp16\n defaultDtype = 'fp16';\n }\n\n // Update all component dtypes\n this.modelComponents = this.modelComponents.map((component) => ({\n ...component,\n dtype: defaultDtype,\n }));\n\n logger.info('Model components configured with dtype:', {\n platform,\n arch,\n defaultDtype,\n components: this.modelComponents.map((c) => `${c.name}: ${c.dtype}`),\n });\n }\n\n /**\n * Get the model configuration based on the input component name.\n * @param {string} componentName - The name of the component to retrieve the configuration for.\n * @returns {object} The model configuration object containing device, dtype, and cache_dir.\n */\n private getModelConfig(componentName: string) {\n const component = this.modelComponents.find((c) => c.name === componentName);\n return {\n device: this.platformConfig.device,\n dtype: component?.dtype || 'fp32',\n cache_dir: this.modelsDir,\n };\n }\n\n /**\n * Asynchronous method to initialize the vision model by loading Florence2 model, vision tokenizer, and vision processor.\n *\n * @returns {Promise<void>} - Promise that resolves once the initialization process is completed.\n * @throws {Error} - If there is an error during the initialization process.\n */\n private async initialize() {\n try {\n if (this.initialized) {\n logger.info('Vision model already initialized, skipping initialization');\n return;\n }\n\n logger.info('Starting vision model initialization...');\n const modelSpec = MODEL_SPECS.vision;\n\n // Configure environment\n logger.info('Configuring environment for vision model...');\n env.allowLocalModels = true;\n env.allowRemoteModels = true;\n\n // Configure ONNX backend\n if (this.platformConfig.useOnnx) {\n env.backends.onnx.enabled = true;\n env.backends.onnx.logLevel = 'info';\n }\n\n // logger.info(\"Vision model configuration:\", {\n // modelId: modelSpec.modelId,\n // modelsDir: this.modelsDir,\n // allowLocalModels: env.allowLocalModels,\n // allowRemoteModels: env.allowRemoteModels,\n // platform: this.platformConfig\n // });\n\n // Initialize model with detailed logging\n logger.info('Loading Florence2 model...');\n try {\n let lastProgress = -1;\n const modelCached = this.checkCacheExists(modelSpec.modelId, 'model');\n\n const model = await Florence2ForConditionalGeneration.from_pretrained(modelSpec.modelId, {\n device: 'cpu',\n cache_dir: this.modelsDir,\n local_files_only: modelCached,\n revision: 'main',\n progress_callback: ((progressInfo: ProgressInfo) => {\n if (modelCached || this.modelDownloaded) return;\n const progress =\n 'progress' in progressInfo ? Math.max(0, Math.min(1, progressInfo.progress)) : 0;\n const currentProgress = Math.round(progress * 100);\n if (currentProgress > lastProgress + 9 || currentProgress === 100) {\n lastProgress = currentProgress;\n const barLength = 30;\n const filledLength = Math.floor((currentProgress / 100) * barLength);\n const progressBar = '▰'.repeat(filledLength) + '▱'.repeat(barLength - filledLength);\n logger.info(`Downloading vision model: ${progressBar} ${currentProgress}%`);\n if (currentProgress === 100) this.modelDownloaded = true;\n }\n }) as ProgressCallback,\n });\n\n this.model = model as unknown as Florence2ForConditionalGeneration;\n logger.success('Florence2 model loaded successfully');\n } catch (error) {\n logger.error('Failed to load Florence2 model:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelId: modelSpec.modelId,\n });\n throw error;\n }\n\n // Initialize tokenizer with detailed logging\n logger.info('Loading vision tokenizer...');\n try {\n const tokenizerCached = this.checkCacheExists(modelSpec.modelId, 'tokenizer');\n let tokenizerProgress = -1;\n\n this.tokenizer = await AutoTokenizer.from_pretrained(modelSpec.modelId, {\n cache_dir: this.modelsDir,\n local_files_only: tokenizerCached,\n progress_callback: ((progressInfo: ProgressInfo) => {\n if (tokenizerCached || this.tokenizerDownloaded) return;\n const progress =\n 'progress' in progressInfo ? Math.max(0, Math.min(1, progressInfo.progress)) : 0;\n const currentProgress = Math.round(progress * 100);\n if (currentProgress !== tokenizerProgress) {\n tokenizerProgress = currentProgress;\n const barLength = 30;\n const filledLength = Math.floor((currentProgress / 100) * barLength);\n const progressBar = '▰'.repeat(filledLength) + '▱'.repeat(barLength - filledLength);\n logger.info(`Downloading vision tokenizer: ${progressBar} ${currentProgress}%`);\n if (currentProgress === 100) this.tokenizerDownloaded = true;\n }\n }) as ProgressCallback,\n });\n logger.success('Vision tokenizer loaded successfully');\n } catch (error) {\n logger.error('Failed to load tokenizer:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelId: modelSpec.modelId,\n });\n throw error;\n }\n\n // Initialize processor with detailed logging\n logger.info('Loading vision processor...');\n try {\n const processorCached = this.checkCacheExists(modelSpec.modelId, 'processor');\n let processorProgress = -1;\n\n this.processor = (await AutoProcessor.from_pretrained(modelSpec.modelId, {\n device: 'cpu',\n cache_dir: this.modelsDir,\n local_files_only: processorCached,\n progress_callback: ((progressInfo: ProgressInfo) => {\n if (processorCached || this.processorDownloaded) return;\n const progress =\n 'progress' in progressInfo ? Math.max(0, Math.min(1, progressInfo.progress)) : 0;\n const currentProgress = Math.round(progress * 100);\n if (currentProgress !== processorProgress) {\n processorProgress = currentProgress;\n const barLength = 30;\n const filledLength = Math.floor((currentProgress / 100) * barLength);\n const progressBar = '▰'.repeat(filledLength) + '▱'.repeat(barLength - filledLength);\n logger.info(`Downloading vision processor: ${progressBar} ${currentProgress}%`);\n if (currentProgress === 100) this.processorDownloaded = true;\n }\n }) as ProgressCallback,\n })) as Florence2Processor;\n logger.success('Vision processor loaded successfully');\n } catch (error) {\n logger.error('Failed to load vision processor:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelId: modelSpec.modelId,\n });\n throw error;\n }\n\n this.initialized = true;\n logger.success('Vision model initialization complete');\n } catch (error) {\n logger.error('Vision model initialization failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n modelsDir: this.modelsDir,\n });\n throw error;\n }\n }\n\n /**\n * Fetches an image from a given URL and returns the image data as a Buffer along with its MIME type.\n *\n * @param {string} url - The URL of the image to fetch.\n * @returns {Promise<{ buffer: Buffer; mimeType: string }>} Object containing the image data as a Buffer and its MIME type.\n */\n private async fetchImage(url: string): Promise<{ buffer: Buffer; mimeType: string }> {\n try {\n logger.info(`Fetching image from URL: ${url.slice(0, 100)}...`);\n\n // Handle data URLs differently\n if (url.startsWith('data:')) {\n logger.info('Processing data URL...');\n const [header, base64Data] = url.split(',');\n const mimeType = header.split(';')[0].split(':')[1];\n const buffer = Buffer.from(base64Data, 'base64');\n logger.info('Data URL processed successfully');\n // logger.info(\"Data URL processed successfully:\", {\n // mimeType,\n // bufferSize: buffer.length\n // });\n return { buffer, mimeType };\n }\n\n // Handle regular URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch image: ${response.statusText}`);\n }\n const buffer = Buffer.from(await response.arrayBuffer());\n const mimeType = response.headers.get('content-type') || 'image/jpeg';\n\n logger.info('Image fetched successfully:', {\n mimeType,\n bufferSize: buffer.length,\n status: response.status,\n });\n\n return { buffer, mimeType };\n } catch (error) {\n logger.error('Failed to fetch image:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n url,\n });\n throw error;\n }\n }\n\n /**\n * Processes the image from the provided URL using the initialized vision model components.\n * @param {string} imageUrl - The URL of the image to process.\n * @returns {Promise<{ title: string; description: string }>} An object containing the title and description of the processed image.\n */\n public async processImage(imageUrl: string): Promise<{ title: string; description: string }> {\n try {\n logger.info('Starting image processing...');\n\n // Ensure model is initialized\n if (!this.initialized) {\n logger.info('Vision model not initialized, initializing now...');\n await this.initialize();\n }\n\n if (!this.model || !this.processor || !this.tokenizer) {\n throw new Error('Vision model components not properly initialized');\n }\n\n // Fetch and process image\n logger.info('Fetching image...');\n const { buffer, mimeType } = await this.fetchImage(imageUrl);\n\n // Process image\n logger.info('Creating image blob...');\n const blob = new Blob([buffer], { type: mimeType });\n logger.info('Converting blob to RawImage...');\n // @ts-ignore - RawImage.fromBlob expects web Blob but works with node Blob\n const image = await RawImage.fromBlob(blob);\n\n logger.info('Processing image with vision processor...');\n const visionInputs = await this.processor(image);\n logger.info('Constructing prompts...');\n const prompts = this.processor.construct_prompts('<DETAILED_CAPTION>');\n logger.info('Tokenizing prompts...');\n const textInputs = this.tokenizer(prompts);\n\n // Generate description\n logger.info('Generating image description...');\n const generatedIds = (await this.model.generate({\n ...textInputs,\n ...visionInputs,\n max_new_tokens: MODEL_SPECS.vision.maxTokens,\n })) as Tensor;\n\n logger.info('Decoding generated text...');\n const generatedText = this.tokenizer.batch_decode(generatedIds, {\n skip_special_tokens: false,\n })[0];\n\n logger.info('Post-processing generation...');\n const result = this.processor.post_process_generation(\n generatedText,\n '<DETAILED_CAPTION>',\n image.size\n );\n\n const detailedCaption = result['<DETAILED_CAPTION>'] as string;\n const response = {\n title: `${detailedCaption.split('.')[0]}.`,\n description: detailedCaption,\n };\n\n logger.success('Image processing complete:', {\n titleLength: response.title.length,\n descriptionLength: response.description.length,\n });\n\n return response;\n } catch (error) {\n logger.error('Image processing failed:', {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n imageUrl,\n modelInitialized: this.initialized,\n hasModel: !!this.model,\n hasProcessor: !!this.processor,\n hasTokenizer: !!this.tokenizer,\n });\n throw error;\n }\n }\n}\n"],"mappings":";AAAA,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,YAAAC,iBAAgB;AACzB,SAAS,qBAAqB;AAO9B,SAA6B,aAAAC,YAAwB,UAAAC,gBAAc;AACnE,SAAS,gBAAgB,qBAAqB;AAC9C;AAAA,EAEE;AAAA,EAIA,YAAAC;AAAA,OACK;;;AClBP,SAAS,cAAc;AACvB,SAAS,SAAS;AAUX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,cAAc,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACtC,0BAA0B,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACnD,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAGjD,mBAAmB,EAAE,OAAO,EAAE,QAAQ,wBAAwB;AAAA,EAC9D,cAAc,EAAE,OAAO,EAAE,QAAQ,6BAA6B;AAAA,EAC9D,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAC/C,wBAAwB,EAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EAC7C,oBAAoB,EAAE,OAAO,EAAE,QAAQ,kBAAkB;AAAA,EACzD,qBAAqB,EAAE,OAAO,EAAE,QAAQ,gBAAgB;AAAA,EACxD,oBAAoB,EAAE,OAAO,EAAE,QAAQ,gBAAgB;AAAA;AAAA,EAGvD,qBAAqB,EAAE,OAAO,EAAE,QAAQ,uBAAuB;AAAA,EAC/D,sBAAsB,EAAE,OAAO,EAAE,QAAQ,kDAAkD;AAAA,EAC3F,uBAAuB,EAAE,OAAO,EAAE,QAAQ,6BAA6B;AAAA,EACvE,0BAA0B,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,QAAQ,KAAK;AAC5E,CAAC;AAaD,SAAS,oBAAoB,QAAuC;AAElE,SAAO,KAAK,+CAA+C;AAAA,IACzD,cAAc,OAAO;AAAA,IACrB,0BAA0B,OAAO;AAAA,IACjC,wBAAwB,OAAO;AAAA,EACjC,CAAC;AAGD,MAAI,CAAC,OAAO,cAAc;AACxB,WAAO,eAAe;AACtB,WAAO,KAAK,+CAA+C;AAAA,EAC7D;AAGA,MAAI,OAAO,4BAA4B,OAAO,wBAAwB;AACpE,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AAEA,SAAO,KAAK,wBAAwB;AACtC;AAQA,eAAsB,eAAe,QAAiD;AACpF,MAAI;AAWF,UAAM,gBAAgB;AAAA,MACpB,cAAc;AAAA;AAAA,MACd,0BAA0B,OAAO,6BAA6B;AAAA,MAC9D,wBAAwB,OAAO,2BAA2B;AAAA,MAC1D,sBAAsB,OAAO,yBAAyB;AAAA,IACxD;AAKA,wBAAoB,aAAa;AAGjC,UAAM,aAAa;AAAA,MACjB,GAAG;AAAA,MACH,mBAAmB,OAAO,qBAAqB;AAAA,MAC/C,cAAc,OAAO,gBAAgB;AAAA,MACrC,wBAAwB,OAAO,0BAA0B;AAAA,MACzD,oBAAoB,OAAO,sBAAsB;AAAA,MACjD,qBAAqB,OAAO,uBAAuB;AAAA,MACnD,oBAAoB,OAAO,sBAAsB;AAAA,MACjD,qBAAqB,OAAO,uBAAuB;AAAA,MACnD,sBACE,OAAO,wBAAwB;AAAA,MACjC,uBAAuB,OAAO,yBAAyB;AAAA,MACvD,0BAA0B,OAAO,4BAA4B;AAAA,IAC/D;AAEA,UAAM,kBAAkB,aAAa,MAAM,UAAU;AAIrD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,EAAE,UAAU;AAC/B,YAAM,gBAAgB,MAAM,OACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,KAAK,IAAI,OAAO,EAAE,EACpD,KAAK,IAAI;AACZ,aAAO,MAAM,0BAA0B,aAAa;AACpD,YAAM,IAAI,MAAM;AAAA,EAAqC,aAAa,EAAE;AAAA,IACtE;AACA,WAAO,MAAM,oCAAoC;AAAA,MAC/C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,IAChD,CAAC;AACD,UAAM;AAAA,EACR;AACF;;;ACtBO,IAAM,cAA0B;AAAA,EACrC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,cAAc;AAAA,IACd,aAAa;AAAA,IACb,WAAW;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,cAAc;AAAA,IACd,aAAa;AAAA,IACb,WAAW;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,MACd,UAAU,CAAC,UAAU,UAAU,YAAY,UAAU;AAAA,MACrD,WAAW,CAAC,IAAI;AAAA,MAChB,UAAU,CAAC,iBAAiB,iBAAiB,mBAAmB,eAAe;AAAA,MAC/E,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,MACd,UAAU,CAAC,UAAU,UAAU,UAAU,YAAY,YAAY,UAAU;AAAA,MAC3E,WAAW,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,MACxC,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc;AAAA,MACd,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,WAAW,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAAA,MAClF,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,WAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;ACnPA,OAAO,QAAQ;AACf,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,UAAAC,eAAc;AAMhB,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAC3B,OAAe,WAAmC;AAAA,EAC1C;AAAA,EACA;AAAA;AAAA,EAEA,kBAA8C,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQtD,YAAY,UAAkB,WAAmB;AACvD,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAc,YAAY,UAAkB,WAAoC;AAC9E,QAAI,CAAC,iBAAgB,UAAU;AAC7B,uBAAgB,WAAW,IAAI,iBAAgB,UAAU,SAAS;AAAA,IACpE;AACA,WAAO,iBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,QAAI,CAAC,GAAG,WAAW,KAAK,QAAQ,GAAG;AACjC,SAAG,UAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC/C,MAAAA,QAAO,MAAM,yBAAyB;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA8B;AACpC,IAAAA,QAAO,MAAM,qCAAqC,KAAK,SAAS;AAChE,QAAI,CAAC,GAAG,WAAW,KAAK,SAAS,GAAG;AAClC,SAAG,UAAU,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAChD,MAAAA,QAAO,MAAM,0BAA0B;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,qBAAqB,KAAa,UAAiC;AAC/E,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,MAAAA,QAAO,KAAK,yBAAyB,QAAQ,EAAE;AAG/C,YAAM,WAAW,GAAG,QAAQ;AAG5B,UAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,YAAI;AACF,UAAAA,QAAO,KAAK,qCAAqC,QAAQ,EAAE;AAC3D,aAAG,WAAW,QAAQ;AAAA,QACxB,SAAS,KAAK;AACZ,UAAAA,QAAO;AAAA,YACL,6CAA6C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC/F;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA;AAAA,UACE,SAAS;AAAA,YACP,cAAc;AAAA,UAChB;AAAA,UACA,SAAS;AAAA;AAAA,QACX;AAAA,QACA,CAAC,aAAa;AACZ,cAAI,SAAS,eAAe,OAAO,SAAS,eAAe,KAAK;AAC9D,kBAAM,cAAc,SAAS,QAAQ;AACrC,gBAAI,CAAC,aAAa;AAChB,qBAAO,IAAI,MAAM,6BAA6B,CAAC;AAC/C;AAAA,YACF;AAGA,iBAAK,gBAAgB,OAAO,QAAQ;AACpC,iBAAK,aAAa,aAAa,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AACnE;AAAA,UACF;AAEA,cAAI,SAAS,eAAe,KAAK;AAC/B,mBAAO,IAAI,MAAM,uBAAuB,SAAS,UAAU,EAAE,CAAC;AAC9D;AAAA,UACF;AAEA,gBAAM,YAAY,OAAO,SAAS,SAAS,QAAQ,gBAAgB,KAAK,KAAK,EAAE;AAC/E,cAAI,iBAAiB;AACrB,cAAI,oBAAoB;AACxB,gBAAM,YAAY;AAGlB,gBAAM,WAAW,KAAK,SAAS,QAAQ;AACvC,UAAAA,QAAO,KAAK,eAAe,QAAQ,KAAK,SAAI,OAAO,SAAS,CAAC,KAAK;AAElE,gBAAM,OAAO,GAAG,kBAAkB,QAAQ;AAE1C,mBAAS,GAAG,QAAQ,CAAC,UAAU;AAC7B,8BAAkB,MAAM;AACxB,kBAAM,UAAU,KAAK,MAAO,iBAAiB,YAAa,GAAG;AAG7D,gBAAI,WAAW,oBAAoB,GAAG;AACpC,oBAAM,eAAe,KAAK,MAAO,iBAAiB,YAAa,SAAS;AACxE,oBAAM,cAAc,SAAI,OAAO,YAAY,IAAI,SAAI,OAAO,YAAY,YAAY;AAClF,cAAAA,QAAO,KAAK,eAAe,QAAQ,KAAK,WAAW,IAAI,OAAO,GAAG;AACjE,kCAAoB;AAAA,YACtB;AAAA,UACF,CAAC;AAED,mBAAS,KAAK,IAAI;AAElB,eAAK,GAAG,UAAU,MAAM;AACtB,iBAAK,MAAM,MAAM;AACf,kBAAI;AAEF,sBAAM,eAAe,SAAI,OAAO,SAAS;AACzC,gBAAAA,QAAO,KAAK,eAAe,QAAQ,KAAK,YAAY,OAAO;AAG3D,sBAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,oBAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,qBAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,gBAC3C;AAGA,oBAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,yBAAO,IAAI,MAAM,kBAAkB,QAAQ,iBAAiB,CAAC;AAC7D;AAAA,gBACF;AAGA,oBAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,sBAAI;AAEF,0BAAM,aAAa,GAAG,QAAQ;AAC9B,uBAAG,WAAW,UAAU,UAAU;AAClC,oBAAAA,QAAO,KAAK,oCAAoC,UAAU,EAAE;AAG5D,uBAAG,WAAW,UAAU,QAAQ;AAGhC,wBAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,yBAAG,WAAW,UAAU;AACxB,sBAAAA,QAAO,KAAK,gDAAgD,UAAU,EAAE;AAAA,oBAC1E;AAAA,kBACF,SAAS,SAAS;AAChB,oBAAAA,QAAO;AAAA,sBACL,yBAAyB,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,OAAO,CAAC;AAAA,oBACvF;AAGA,0BAAM,aAAa,GAAG,QAAQ;AAC9B,wBAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,0BAAI;AACF,2BAAG,WAAW,YAAY,QAAQ;AAClC,wBAAAA,QAAO,KAAK,6CAA6C,UAAU,EAAE;AAAA,sBACvE,SAAS,YAAY;AACnB,wBAAAA,QAAO;AAAA,0BACL,kCAAkC,sBAAsB,QAAQ,WAAW,UAAU,OAAO,UAAU,CAAC;AAAA,wBACzG;AAAA,sBACF;AAAA,oBACF;AAGA,wBAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,0BAAI;AACF,2BAAG,WAAW,QAAQ;AAAA,sBACxB,SAAS,WAAW;AAClB,wBAAAA,QAAO;AAAA,0BACL,iCAAiC,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAAA,wBACrG;AAAA,sBACF;AAAA,oBACF;AAEA,2BAAO,OAAO;AACd;AAAA,kBACF;AAAA,gBACF,OAAO;AAEL,qBAAG,WAAW,UAAU,QAAQ;AAAA,gBAClC;AAEA,gBAAAA,QAAO,QAAQ,eAAe,QAAQ,yBAAyB;AAG/D,qBAAK,gBAAgB,OAAO,QAAQ;AACpC,wBAAQ;AAAA,cACV,SAAS,KAAK;AACZ,gBAAAA,QAAO;AAAA,kBACL,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,gBAChF;AAEA,oBAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,sBAAI;AACF,uBAAG,WAAW,QAAQ;AAAA,kBACxB,SAAS,WAAW;AAClB,oBAAAA,QAAO;AAAA,sBACL,iCAAiC,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAAA,oBACrG;AAAA,kBACF;AAAA,gBACF;AAEA,qBAAK,gBAAgB,OAAO,QAAQ;AACpC,uBAAO,GAAG;AAAA,cACZ;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAED,eAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,YAAAA,QAAO,MAAM,qBAAqB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AACpF,iBAAK,MAAM,MAAM;AACf,kBAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,oBAAI;AACF,qBAAG,WAAW,QAAQ;AAAA,gBACxB,SAAS,WAAW;AAClB,kBAAAA,QAAO;AAAA,oBACL,6CAA6C,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAAA,kBACjH;AAAA,gBACF;AAAA,cACF;AAEA,mBAAK,gBAAgB,OAAO,QAAQ;AACpC,qBAAO,GAAG;AAAA,YACZ,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF;AAEA,cAAQ,GAAG,SAAS,CAAC,QAAQ;AAC3B,QAAAA,QAAO,MAAM,kBAAkB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AACjF,YAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,cAAI;AACF,eAAG,WAAW,QAAQ;AAAA,UACxB,SAAS,WAAW;AAClB,YAAAA,QAAO;AAAA,cACL,qDAAqD,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAAA,YACzH;AAAA,UACF;AAAA,QACF;AAEA,aAAK,gBAAgB,OAAO,QAAQ;AACpC,eAAO,GAAG;AAAA,MACZ,CAAC;AAED,cAAQ,GAAG,WAAW,MAAM;AAC1B,QAAAA,QAAO,MAAM,2BAA2B;AACxC,gBAAQ,QAAQ;AAChB,YAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,cAAI;AACF,eAAG,WAAW,QAAQ;AAAA,UACxB,SAAS,WAAW;AAClB,YAAAA,QAAO;AAAA,cACL,+CAA+C,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC;AAAA,YACnH;AAAA,UACF;AAAA,QACF;AAEA,aAAK,gBAAgB,OAAO,QAAQ;AACpC,eAAO,IAAI,MAAM,kBAAkB,CAAC;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,aAAa,KAAa,UAAiC;AAEtE,QAAI,KAAK,gBAAgB,IAAI,QAAQ,GAAG;AACtC,MAAAA,QAAO,KAAK,gBAAgB,QAAQ,qDAAqD;AACzF,YAAM,mBAAmB,KAAK,gBAAgB,IAAI,QAAQ;AAC1D,UAAI,kBAAkB;AACpB,eAAO;AAAA,MACT;AAEA,MAAAA,QAAO;AAAA,QACL,gBAAgB,QAAQ;AAAA,MAC1B;AAAA,IACF;AAGA,UAAM,kBAAkB,KAAK,qBAAqB,KAAK,QAAQ;AAC/D,SAAK,gBAAgB,IAAI,UAAU,eAAe;AAElD,QAAI;AACF,aAAO,MAAM;AAAA,IACf,SAAS,OAAO;AAEd,WAAK,gBAAgB,OAAO,QAAQ;AACpC,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,cAAc,WAAsB,WAAqC;AACpF,QAAI;AACF,MAAAA,QAAO,KAAK,kCAAkC;AAG9C,YAAM,WAAW,KAAK,QAAQ,SAAS;AACvC,UAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,QAAAA,QAAO,KAAK,6BAA6B,QAAQ;AACjD,WAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,MAC5C;AAEA,UAAI,CAAC,GAAG,WAAW,SAAS,GAAG;AAE7B,cAAM,WAAW;AAAA,UACf;AAAA,YACE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,IAAI,iBAAiB,UAAU,IAAI;AAAA,UAC9E;AAAA,UACA;AAAA,YACE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,KAAK,QAAQ,SAAS,EAAE,CAAC,iBAAiB,UAAU,IAAI;AAAA,UACnG;AAAA,UACA;AAAA,YACE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,IAAI,iBAAiB,UAAU,IAAI;AAAA,UAC9E;AAAA,UACA;AAAA,YACE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,KAAK,QAAQ,SAAS,EAAE,CAAC,iBAAiB,UAAU,IAAI;AAAA,UACnG;AAAA,QACF;AAUA,YAAI,YAAY;AAChB,YAAI,kBAAkB;AAEtB,mBAAW,WAAW,UAAU;AAC9B,cAAI;AACF,YAAAA,QAAO,KAAK,8BAA8B;AAAA,cACxC,aAAa,QAAQ;AAAA,cACrB,KAAK,QAAQ;AAAA,cACb,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAGD,kBAAM,KAAK,aAAa,QAAQ,KAAK,SAAS;AAE9C,YAAAA,QAAO;AAAA,cACL,4BAA4B,UAAU,IAAI,UAAU,QAAQ,WAAW;AAAA,YACzE;AACA,8BAAkB;AAClB;AAAA,UACF,SAAS,OAAO;AACd,wBAAY;AACZ,YAAAA,QAAO,KAAK,kCAAkC;AAAA,cAC5C,aAAa,QAAQ;AAAA,cACrB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,cAC5D,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,CAAC,iBAAiB;AACpB,gBAAM,aAAa,IAAI,MAAM,8BAA8B;AAAA,QAC7D;AAGA,eAAO;AAAA,MACT;AAGA,MAAAA,QAAO,KAAK,4BAA4B,SAAS;AAEjD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,0BAA0B;AAAA,QACrC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D;AAAA,QACA,OAAO,UAAU;AAAA,MACnB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,cAAsB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,gBAAgB,KAAa,UAAiC;AACzE,WAAO,KAAK,aAAa,KAAK,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,sBAAsB,SAAuB;AAClD,QAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,SAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACzC,MAAAA,QAAO,KAAK,sBAAsB,OAAO,EAAE;AAAA,IAC7C;AAAA,EACF;AACF;;;AC9cA,SAAkC,WAAW,UAAAC,eAAc;AA2CpD,IAAM,gBAAN,MAAM,eAAc;AAAA,EACzB,OAAe,WAAiC;AAAA,EACxC;AAAA,EACA,cAAc;AAAA,EACd,kBAAiC,CAAC;AAAA,EAClC,mBAAmB;AAAA,IACzB,OAAO,QAAQ,IAAI,sBAAsB;AAAA,IACzC,QAAQ,QAAQ,IAAI,uBAAuB;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc;AACpB,SAAK,YAAY,QAAQ,IAAI,qBAAqB;AAClD,IAAAA,QAAO,KAAK,iDAAiD;AAAA,MAC3D,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK;AAAA,MACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAc,cAA6B;AACzC,QAAI,CAAC,eAAc,UAAU;AAC3B,qBAAc,WAAW,IAAI,eAAc;AAAA,IAC7C;AACA,WAAO,eAAc;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,oBAAsC;AAClD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,WAAW;AACzD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,MACpE;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,+BAA+B;AAAA,QAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,WAAW,KAAK;AAAA,QAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,uBAAsC;AAClD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,WAAW;AACzD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,EAAE;AAAA,MAC9D;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAK,kBAAkB,KAAK;AAE5B,MAAAA,QAAO,KAAK,4BAA4B;AAAA,QACtC,OAAO,KAAK,gBAAgB;AAAA,QAC5B,QAAQ,KAAK,gBAAgB,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,kCAAkC;AAAA,QAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,WAAW,KAAK;AAAA,QAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,UAAU,SAAmC;AACzD,QAAI;AACF,YAAM,cAAc;AAAA,QAClB,OAAO;AAAA,QACP,QACE;AAAA,QACF,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,aAAa;AAAA,UACb,aAAa;AAAA,QACf;AAAA,MACF;AAEA,MAAAA,QAAO,KAAK,iBAAiB,OAAO,KAAK;AAEzC,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,iBAAiB;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,EAAE;AAAA,MACrE;AAEA,YAAM,SAAU,MAAM,SAAS,KAAK;AAEpC,UAAI,CAAC,OAAO,UAAU;AACpB,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AAEA,MAAAA,QAAO,KAAK,SAAS,OAAO,mBAAmB;AAAA,QAC7C,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,SAAS,OAAO,iBAAiB;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,iBAAgC;AAC5C,IAAAA,QAAO,KAAK,mCAAmC;AAE/C,UAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,MAChC,KAAK,UAAU,KAAK,iBAAiB,KAAK;AAAA,MAC1C,KAAK,UAAU,KAAK,iBAAiB,MAAM;AAAA,IAC7C,CAAC;AAED,UAAM,CAAC,cAAc,aAAa,IAAI;AAEtC,QAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,YAAM,eAAe,CAAC;AACtB,UAAI,CAAC,aAAc,cAAa,KAAK,OAAO;AAC5C,UAAI,CAAC,cAAe,cAAa,KAAK,QAAQ;AAE9C,MAAAA,QAAO,KAAK,gCAAgC;AAAA,QAC1C;AAAA,QACA,OAAO,KAAK,iBAAiB;AAAA,QAC7B,QAAQ,KAAK,iBAAiB;AAAA,MAChC,CAAC;AAAA,IACH,OAAO;AACL,MAAAA,QAAO,QAAQ,uCAAuC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,aAA4B;AACvC,QAAI;AACF,UAAI,KAAK,aAAa;AACpB,QAAAA,QAAO,KAAK,qDAAqD;AACjE;AAAA,MACF;AAEA,MAAAA,QAAO,KAAK,mCAAmC;AAC/C,YAAM,kBAAkB,MAAM,KAAK,kBAAkB;AAErD,UAAI,CAAC,iBAAiB;AACpB,cAAM,IAAI,MAAM,gCAAgC;AAAA,MAClD;AAEA,YAAM,KAAK,qBAAqB;AAChC,YAAM,KAAK,eAAe;AAE1B,WAAK,cAAc;AACnB,MAAAA,QAAO,QAAQ,gCAAgC;AAAA,IACjD,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,MAChD,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,qBAAoC;AACzC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,gBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,aAAa,QAA4B,gBAAgB,OAAwB;AAC5F,QAAI;AAEF,MAAAA,QAAO,KAAK,8BAA8B;AAAA,QACxC;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB,kBAAkB,KAAK,cAAc;AAAA,QACrC,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO,QAAQ;AAAA,QAC9B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAGD,UAAI,CAAC,KAAK,eAAe,CAAC,eAAe;AACvC,cAAM,IAAI,MAAM,mEAAmE;AAAA,MACrF;AAEA,MAAAA,QAAO,KAAK,6BAA6B;AAAA,QACvC,OACE,OAAO,cAAc,UAAU,aAC3B,KAAK,iBAAiB,SACtB,KAAK,iBAAiB;AAAA,QAC5B,eAAe,OAAO,OAAO;AAAA,QAC7B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,YAAM,UAAU;AAAA,QACd,OACE,OAAO,cAAc,UAAU,aAC3B,KAAK,iBAAiB,SACtB,KAAK,iBAAiB;AAAA,QAC5B,QAAQ,OAAO;AAAA,QACf,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,aAAa;AAAA,UACb,OAAO;AAAA,UACP,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,mBAAmB;AAAA,UACnB,kBAAkB;AAAA,QACpB;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,iBAAiB;AAAA,QAC7D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,EAAE;AAAA,MAC7D;AAEA,YAAM,SAAU,MAAM,SAAS,KAAK;AAEpC,UAAI,CAAC,OAAO,UAAU;AACpB,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AAEA,UAAI,eAAe,OAAO;AAG1B,MAAAA,QAAO,KAAK,2BAA2B;AAAA,QACrC,gBAAgB,aAAa;AAAA,QAC7B,WAAW,aAAa,SAAS,QAAQ;AAAA,QACzC,aAAa,aAAa,SAAS,SAAS;AAAA,MAC9C,CAAC;AAGD,UAAI,aAAa,SAAS,SAAS,GAAG;AACpC,QAAAA,QAAO,KAAK,mCAAmC;AAC/C,uBAAe,aAAa,QAAQ,gCAAgC,EAAE;AACtE,QAAAA,QAAO,KAAK,kCAAkC;AAAA,MAChD;AAEA,MAAAA,QAAO,KAAK,0CAA0C;AAAA,QACpD,gBAAgB,aAAa;AAAA,QAC7B,cAAc,aAAa,SAAS,SAAS;AAAA,QAC7C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,OAAO;AAAA,QACP,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC9WA,SAAS,YAAY;AACrB,OAAO,QAAQ;AACf,SAAS,iBAAiB;AAC1B,SAAS,UAAAC,eAAc;AAEvB,IAAM,YAAY,UAAU,IAAI;AAiEzB,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAC3B,OAAe;AAAA,EACP,eAA0C;AAAA;AAAA;AAAA;AAAA,EAK1C,cAAc;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvB,OAAO,cAA+B;AACpC,QAAI,CAAC,iBAAgB,UAAU;AAC7B,uBAAgB,WAAW,IAAI,iBAAgB;AAAA,IACjD;AACA,WAAO,iBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAA4B;AAChC,QAAI;AACF,MAAAA,QAAO,KAAK,oCAAoC;AAChD,WAAK,eAAe,MAAM,KAAK,yBAAyB;AAAA,IAM1D,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC;AACnD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,2BAAwD;AACpE,UAAM,WAAW,QAAQ;AACzB,UAAM,UAAU,KAAK,WAAW;AAChC,UAAM,MAAM,MAAM,KAAK,UAAU;AACjC,UAAM,oBAAoB,MAAM,KAAK,qBAAqB,UAAU,GAAG;AACvE,UAAM,uBAAuB,KAAK,wBAAwB,SAAS,GAAG;AAEtE,WAAO;AAAA,MACL;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAwB;AAC9B,UAAM,OAAO,GAAG,KAAK;AACrB,UAAM,cAAc,GAAG,SAAS;AAChC,UAAM,aAAa,GAAG,QAAQ;AAE9B,WAAO;AAAA,MACL,OAAO,KAAK,CAAC,EAAE;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK,CAAC,EAAE;AAAA,MACf,cAAc,QAAQ;AAAA,MACtB,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAuC;AACnD,UAAM,WAAW,QAAQ;AAEzB,QAAI;AACF,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,iBAAO,MAAM,KAAK,aAAa;AAAA,QACjC,KAAK;AACH,iBAAO,MAAM,KAAK,iBAAiB;AAAA,QACrC,KAAK;AACH,iBAAO,MAAM,KAAK,eAAe;AAAA,QACnC;AACE,iBAAO;AAAA,MACX;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC;AAC9C,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,eAAmC;AAC/C,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,UAAU,oCAAoC;AACvE,YAAM,iBAAiB,OAAO,YAAY,EAAE,SAAS,OAAO;AAE5D,UAAI,gBAAgB;AAClB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,QAClB;AAAA,MACF;AAGA,YAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM,UAAU,oCAAoC;AAChF,aAAO;AAAA,QACL,MAAM,QAAQ,MAAM,gBAAgB,EAAE,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC,GAAG,KAAK,KAAK;AAAA,QACpE,MAAM;AAAA,QACN,gBAAgB;AAAA,MAClB;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC;AAClD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,mBAA8C;AAC1D,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,UAAU,0CAA0C;AAC7E,YAAM,UAAU,OAAO,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;AAG3C,UAAI,QAAQ,YAAY,EAAE,SAAS,QAAQ,GAAG;AAC5C,cAAM,EAAE,QAAQ,WAAW,IAAI,MAAM;AAAA,UACnC;AAAA,QACF;AACA,cAAM,CAAC,MAAM,SAAS,IAAI,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACnE,cAAM,SAAS,OAAO,SAAS,SAAS;AAExC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,SAAS,MAAM,KAAK,uBAAuB;AAAA,QAC7C;AAAA,MACF;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,gCAAgC,EAAE,MAAM,CAAC;AACtD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,iBAA4C;AACxD,QAAI;AAEF,YAAM,EAAE,OAAO,IAAI,MAAM;AAAA,QACvB;AAAA,MACF;AACA,UAAI,QAAQ;AACV,cAAM,CAAC,MAAM,SAAS,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAC/D,cAAM,SAAS,OAAO,SAAS,SAAS;AAExC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,SAAS,MAAM,KAAK,uBAAuB;AAAA,QAC7C;AAAA,MACF;AAAA,IACF,QAAQ;AAEN,UAAI;AACF,cAAM,EAAE,OAAO,IAAI,MAAM,UAAU,qBAAqB;AACxD,eAAO;AAAA,UACL,MAAM,OAAO,MAAM,GAAG,EAAE,IAAI,GAAG,KAAK,KAAK;AAAA,UACzC,MAAM;AAAA,QACR;AAAA,MACF,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC;AACpD,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,yBAA0C;AACtD,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM;AAAA,QACvB;AAAA,MACF;AACA,aAAO,OAAO,KAAK;AAAA,IACrB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,qBACZ,UACA,KACuD;AACvD,UAAM,WAAyD,CAAC,KAAK;AAErE,QAAI,KAAK;AACP,cAAQ,UAAU;AAAA,QAChB,KAAK;AACH,mBAAS,KAAK,OAAO;AACrB;AAAA,QACF,KAAK;AACH,cAAI,IAAI,SAAS,QAAQ;AACvB,qBAAS,KAAK,MAAM;AAAA,UACtB;AACA,mBAAS,KAAK,UAAU;AACxB;AAAA,QACF,KAAK;AACH,cAAI,IAAI,SAAS,QAAQ;AACvB,qBAAS,KAAK,MAAM;AAAA,UACtB;AACA;AAAA,MACJ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,wBACN,KACA,KAC8B;AAE9B,QAAI,KAAK,gBAAgB;AACvB,aAAO,IAAI,OAAO,QAAQ,KAAK,OAAO,OAAO,OAAO,WAAW;AAAA,IACjE;AAGA,QAAI,KAAK,SAAS,QAAQ;AACxB,YAAM,YAAY,IAAI,UAAU,KAAK;AACrC,UAAI,YAAY,GAAI,QAAO;AAC3B,UAAI,YAAY,EAAG,QAAO;AAAA,IAC5B;AAGA,QAAI,IAAI,OAAO,QAAQ,KAAK,OAAO,OAAO,KAAM,QAAO;AAGvD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAsC;AACpC,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAA0B;AACxB,WAAO,CAAC,CAAC,KAAK,cAAc,KAAK;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAyB;AACvB,WAAO,CAAC,CAAC,KAAK,cAAc;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAwB;AACtB,WAAO,KAAK,cAAc,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAyB;AACvB,WAAO,KAAK,cAAc,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAA4B;AAC1B,WAAO,KAAK,cAAc,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,wBAA+D;AAC7D,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,UAAM,EAAE,KAAK,kBAAkB,IAAI,KAAK;AAExC,QAAI,KAAK,SAAS,OAAQ,QAAO;AACjC,QAAI,KAAK,SAAS,QAAS,QAAO;AAClC,QAAI,kBAAkB,SAAS,UAAU,EAAG,QAAO;AACnD,WAAO;AAAA,EACT;AACF;AAGO,IAAM,qBAAqB,MAAuB;AACvD,SAAO,gBAAgB,YAAY;AACrC;;;AC/bA,SAAkC,aAAAC,YAAW,UAAAC,eAAc;AAuEpD,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAC3B,OAAe,WAAmC;AAAA,EAC1C;AAAA,EACA,cAAc;AAAA,EACd,kBAAmC,CAAC;AAAA,EACpC,mBAAmB;AAAA,IACzB,OAAO,QAAQ,IAAI,wBAAwB;AAAA,IAC3C,QAAQ,QAAQ,IAAI,yBAAyB;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAc;AACpB,SAAK,YAAY,QAAQ,IAAI,uBAAuB;AACpD,IAAAA,QAAO,KAAK,mDAAmD;AAAA,MAC7D,WAAW,KAAK;AAAA,MAChB,kBAAkB,KAAK;AAAA,MACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAA+B;AAC3C,QAAI,CAAC,iBAAgB,UAAU;AAC7B,uBAAgB,WAAW,IAAI,iBAAgB;AAAA,IACjD;AACA,WAAO,iBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,oBAAsC;AAClD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,YAAY;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,MACpE;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,kCAAkC;AAAA,QAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,WAAW,KAAK;AAAA,QAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,uBAAsC;AAClD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,YAAY;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,EAAE;AAAA,MAC9D;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAK,kBAAkB,KAAK;AAE5B,MAAAA,QAAO,KAAK,+BAA+B;AAAA,QACzC,OAAO,KAAK,gBAAgB;AAAA,QAC5B,QAAQ,KAAK,gBAAgB,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,QAC5C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,qCAAqC;AAAA,QAChD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,WAAW,KAAK;AAAA,QAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,UAAU,SAAmC;AACzD,QAAI;AACF,YAAM,cAAqC;AAAA,QACzC,OAAO;AAAA,QACP,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,UACA,EAAE,MAAM,QAAQ,SAAS,wBAAwB;AAAA,QACnD;AAAA,QACA,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAEA,MAAAA,QAAO,KAAK,iBAAiB,OAAO,KAAK;AAEzC,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,wBAAwB;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,EAAE;AAAA,MACrE;AAEA,YAAM,SAAU,MAAM,SAAS,KAAK;AAEpC,UAAI,CAAC,OAAO,UAAU,CAAC,GAAG,SAAS,SAAS;AAC1C,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACtD;AAEA,MAAAA,QAAO,KAAK,SAAS,OAAO,mBAAmB;AAAA,QAC7C,SAAS,OAAO,QAAQ,CAAC,EAAE,QAAQ;AAAA,QACnC,OAAO,OAAO;AAAA,QACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,SAAS,OAAO,iBAAiB;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,iBAAgC;AAC5C,IAAAA,QAAO,KAAK,mCAAmC;AAE/C,UAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,MAChC,KAAK,UAAU,KAAK,iBAAiB,KAAK;AAAA,MAC1C,KAAK,UAAU,KAAK,iBAAiB,MAAM;AAAA,IAC7C,CAAC;AAED,UAAM,CAAC,cAAc,aAAa,IAAI;AAEtC,QAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,YAAM,eAAe,CAAC;AACtB,UAAI,CAAC,aAAc,cAAa,KAAK,OAAO;AAC5C,UAAI,CAAC,cAAe,cAAa,KAAK,QAAQ;AAE9C,MAAAA,QAAO,KAAK,gCAAgC;AAAA,QAC1C;AAAA,QACA,OAAO,KAAK,iBAAiB;AAAA,QAC7B,QAAQ,KAAK,iBAAiB;AAAA,MAChC,CAAC;AAAA,IACH,OAAO;AACL,MAAAA,QAAO,QAAQ,uCAAuC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,aAA4B;AACvC,QAAI;AACF,UAAI,KAAK,aAAa;AACpB,QAAAA,QAAO,KAAK,uDAAuD;AACnE;AAAA,MACF;AAEA,MAAAA,QAAO,KAAK,qCAAqC;AACjD,YAAM,kBAAkB,MAAM,KAAK,kBAAkB;AAErD,UAAI,CAAC,iBAAiB;AACpB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,YAAM,KAAK,qBAAqB;AAChC,YAAM,KAAK,eAAe;AAE1B,WAAK,cAAc;AACnB,MAAAA,QAAO,QAAQ,kCAAkC;AAAA,IACnD,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,mCAAmC;AAAA,QAC9C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,MAChD,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,qBAAsC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,gBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAa,aAAa,QAA4B,gBAAgB,OAAwB;AAC5F,QAAI;AAEF,MAAAA,QAAO,KAAK,gCAAgC;AAAA,QAC1C;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB,kBAAkB,KAAK,cAAc;AAAA,QACrC,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO,QAAQ;AAAA,QAC9B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAGD,UAAI,CAAC,KAAK,eAAe,CAAC,eAAe;AACvC,cAAM,IAAI,MAAM,qEAAqE;AAAA,MACvF;AAEA,YAAM,WAA0B;AAAA,QAC9B;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,QACA,EAAE,MAAM,QAAQ,SAAS,OAAO,OAAO;AAAA,MACzC;AAEA,MAAAA,QAAO,KAAK,+BAA+B;AAAA,QACzC,OACE,OAAO,cAAcD,WAAU,aAC3B,KAAK,iBAAiB,SACtB,KAAK,iBAAiB;AAAA,QAC5B,cAAc,SAAS;AAAA,QACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,MAAAC,QAAO,KAAK,+BAA+B;AAAA,QACzC,eAAe,OAAO,OAAO;AAAA,QAC7B,WAAW,OAAO,OAAO,SAAS,QAAQ;AAAA,QAC1C,SAAS,CAAC,CAAC,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,MACxB,CAAC;AAED,YAAM,UAAiC;AAAA,QACrC,OACE,OAAO,cAAcD,WAAU,aAC3B,KAAK,iBAAiB,SACtB,KAAK,iBAAiB;AAAA,QAC5B;AAAA,QACA,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AAEA,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,SAAS,wBAAwB;AAAA,QACpE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,EAAE;AAAA,MAC/D;AAEA,YAAM,SAAU,MAAM,SAAS,KAAK;AAEpC,UAAI,CAAC,OAAO,UAAU,CAAC,GAAG,SAAS,SAAS;AAC1C,cAAM,IAAI,MAAM,kDAAkD;AAAA,MACpE;AAEA,UAAI,eAAe,OAAO,QAAQ,CAAC,EAAE,QAAQ;AAG7C,MAAAC,QAAO,KAAK,2BAA2B;AAAA,QACrC,gBAAgB,aAAa;AAAA,QAC7B,WAAW,aAAa,SAAS,QAAQ;AAAA,QACzC,aAAa,aAAa,SAAS,SAAS;AAAA,MAC9C,CAAC;AAGD,UAAI,aAAa,SAAS,SAAS,GAAG;AACpC,QAAAA,QAAO,KAAK,mCAAmC;AAC/C,uBAAe,aAAa,QAAQ,gCAAgC,EAAE;AACtE,QAAAA,QAAO,KAAK,kCAAkC;AAAA,MAChD;AAEA,MAAAA,QAAO,KAAK,4CAA4C;AAAA,QACtD,gBAAgB,aAAa;AAAA,QAC7B,cAAc,aAAa,SAAS,SAAS;AAAA,QAC7C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,mCAAmC;AAAA,QAC9C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,OAAO;AAAA,QACP,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACvZA,SAAS,UAAAC,eAAc;AACvB,SAAS,qBAA+C;AASjD,IAAM,mBAAN,MAAM,kBAAiB;AAAA,EAC5B,OAAe,WAAoC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAY,UAAkB,WAAmB;AACvD,SAAK,aAAa,oBAAI,IAAI;AAC1B,SAAK,WAAW;AAChB,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,YAAY,UAAkB,WAAqC;AACxE,QAAI,CAAC,kBAAiB,UAAU;AAC9B,wBAAiB,WAAW,IAAI,kBAAiB,UAAU,SAAS;AAAA,IACtE;AACA,WAAO,kBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAc,aAAsD;AACxE,QAAI;AACF,YAAM,eAAe,GAAG,YAAY,UAAU,IAAI,IAAI,YAAY,UAAU,IAAI;AAChF,MAAAA,QAAO,KAAK,sBAAsB;AAAA,QAChC,KAAK;AAAA,QACL,MAAM,YAAY,UAAU;AAAA,QAC5B,MAAM,YAAY,UAAU;AAAA,QAC5B,WAAW,KAAK;AAAA,QAChB,UAAU,KAAK;AAAA,MACjB,CAAC;AAED,UAAI,KAAK,WAAW,IAAI,YAAY,GAAG;AACrC,QAAAA,QAAO,KAAK,2BAA2B,EAAE,KAAK,aAAa,CAAC;AAC5D,cAAM,kBAAkB,KAAK,WAAW,IAAI,YAAY;AACxD,YAAI,CAAC,iBAAiB;AACpB,gBAAM,IAAI,MAAM,aAAa,YAAY,uCAAuC;AAAA,QAClF;AACA,eAAO;AAAA,MACT;AAGA,YAAMC,MAAK,MAAM,OAAO,SAAS;AACjC,UAAI,CAACA,IAAG,WAAW,KAAK,SAAS,GAAG;AAClC,QAAAD,QAAO,KAAK,iDAAiD,KAAK,SAAS;AAC3E,QAAAC,IAAG,UAAU,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAClD;AAEA,MAAAD,QAAO;AAAA,QACL;AAAA,QACA,KAAK;AAAA,MACP;AAEA,UAAI;AACF,cAAM,YAAY,MAAM,cAAc,gBAAgB,YAAY,UAAU,MAAM;AAAA,UAChF,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,QACpB,CAAC;AAED,aAAK,WAAW,IAAI,cAAc,SAAS;AAC3C,QAAAA,QAAO,QAAQ,kCAAkC,EAAE,KAAK,aAAa,CAAC;AACtE,eAAO;AAAA,MACT,SAAS,eAAe;AACtB,QAAAA,QAAO,MAAM,8CAA8C;AAAA,UACzD,OAAO,yBAAyB,QAAQ,cAAc,UAAU,OAAO,aAAa;AAAA,UACpF,OAAO,yBAAyB,QAAQ,cAAc,QAAQ;AAAA,UAC9D,WAAW,YAAY,UAAU;AAAA,UACjC,WAAW,KAAK;AAAA,QAClB,CAAC;AAGD,QAAAA,QAAO,KAAK,+BAA+B;AAC3C,cAAM,YAAY,MAAM,cAAc,gBAAgB,YAAY,UAAU,MAAM;AAAA,UAChF,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,QACpB,CAAC;AAED,aAAK,WAAW,IAAI,cAAc,SAAS;AAC3C,QAAAA,QAAO,QAAQ,2CAA2C;AAAA,UACxD,KAAK;AAAA,QACP,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,6BAA6B;AAAA,QACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,OAAO,YAAY;AAAA,QACnB,WAAW,YAAY,UAAU;AAAA,QACjC,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,MAAc,aAA2C;AACpE,QAAI;AACF,MAAAA,QAAO,KAAK,iCAAiC;AAAA,QAC3C,QAAQ,KAAK;AAAA,QACb,WAAW,YAAY,UAAU;AAAA,MACnC,CAAC;AAED,YAAM,YAAY,MAAM,KAAK,cAAc,WAAW;AAEtD,MAAAA,QAAO,KAAK,oCAAoC;AAChD,YAAM,UAAU,MAAM,UAAU,OAAO,MAAM;AAAA,QAC3C,oBAAoB;AAAA,QACpB,uBAAuB;AAAA,MACzB,CAAC;AAED,MAAAA,QAAO,KAAK,8BAA8B;AAAA,QACxC,YAAY,QAAQ;AAAA,QACpB,WAAW,YAAY,UAAU;AAAA,MACnC,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,yBAAyB;AAAA,QACpC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAY,KAAK;AAAA,QACjB,WAAW,YAAY,UAAU;AAAA,QACjC,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,QAAkB,aAAyC;AACtE,QAAI;AACF,MAAAA,QAAO,KAAK,mCAAmC;AAAA,QAC7C,OAAO,OAAO;AAAA,QACd,WAAW,YAAY,UAAU;AAAA,MACnC,CAAC;AAED,YAAM,YAAY,MAAM,KAAK,cAAc,WAAW;AAEtD,MAAAA,QAAO,KAAK,sCAAsC;AAClD,YAAM,UAAU,MAAM,UAAU,OAAO,QAAQ;AAAA,QAC7C,qBAAqB;AAAA,QACrB,8BAA8B;AAAA,MAChC,CAAC;AAED,MAAAA,QAAO,KAAK,gCAAgC;AAAA,QAC1C,YAAY,QAAQ;AAAA,QACpB,WAAW,YAAY,UAAU;AAAA,MACnC,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,0BAA0B;AAAA,QACrC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAY,OAAO;AAAA,QACnB,WAAW,YAAY,UAAU;AAAA,QACjC,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACzMA,SAAS,QAAAE,aAAY;AACrB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,UAAAC,eAAc;AACvB,SAAS,mBAAmB;AAE5B,IAAMC,aAAYF,WAAUH,KAAI;AAwBzB,IAAM,oBAAN,MAAM,mBAAkB;AAAA,EAC7B,OAAe,WAAqC;AAAA,EAC5C;AAAA,EACA,kBAAkB;AAAA,EAClB,gBAA+B;AAAA,EAC/B,aAA4B;AAAA,EAC5B,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,YAAY,UAAkB;AACpC,SAAK,WAAWE,MAAK,KAAK,UAAU,SAAS;AAC7C,IAAAE,QAAO,MAAM,kCAAkC;AAAA,MAC7C,UAAU,KAAK;AAAA,MACf,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AACD,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,eAAiC;AAC5C,QAAI,CAAC,KAAK,mBAAmB;AAC3B,UAAI;AACF,cAAM,KAAK,iBAAiB;AAC5B,aAAK,oBAAoB;AAAA,MAC3B,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,iCAAiC;AAAA,UAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,UAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,oBAA6B;AAClC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,mBAA2C;AACtD,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,KAAK,mBAAmB;AAAA,IAChC;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,qBAAoC;AAChD,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAMC,WAAU,iBAAiB;AACpD,WAAK,gBAAgB,OAAO,MAAM,IAAI,EAAE,CAAC;AACzC,MAAAD,QAAO,KAAK,mBAAmB;AAAA,QAC7B,SAAS,KAAK;AAAA,QACd,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,gBAAgB;AACrB,MAAAA,QAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,mBAAkC;AAC9C,QAAI;AAEF,YAAM,KAAK,wBAAwB;AAEnC,UAAI,KAAK,iBAAiB;AAExB,cAAM,KAAK,mBAAmB;AAG9B,cAAM,KAAK,yBAAyB;AAAA,MAOtC,OAAO;AACL,aAAK,6BAA6B;AAAA,MACpC;AAAA,IACF,SAAS,OAAO;AACd,WAAK,kBAAkB;AACvB,MAAAA,QAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,WAAK,6BAA6B;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,0BAAyC;AACrD,QAAI;AACF,YAAM,EAAE,QAAQ,OAAO,IAAI,MAAMC,WAAU,8BAA8B;AACzE,WAAK,aAAa,OAAO,KAAK;AAC9B,WAAK,kBAAkB;AACvB,MAAAD,QAAO,KAAK,oBAAoB;AAAA,QAC9B,MAAM,KAAK;AAAA,QACX,QAAQ,SAAS,OAAO,KAAK,IAAI;AAAA,QACjC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,WAAK,kBAAkB;AACvB,WAAK,aAAa;AAClB,MAAAA,QAAO,MAAM,6BAA6B;AAAA,QACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,QAAQ,iBAAiB,SAAS,YAAY,QAAQ,MAAM,SAAS;AAAA,QACrE,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,2BAA0C;AACtD,QAAI;AAEF,YAAM,EAAE,OAAO,IAAI,MAAMC,WAAU,gBAAgB;AACnD,YAAM,oBAAoB,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,KAAK;AAE/E,UAAI,CAAC,mBAAmB;AACtB,cAAM,IAAI,MAAM,8DAA8D;AAAA,MAChF;AAAA,IAMF,SAAS,OAAO;AACd,MAAAD,QAAO,MAAM,4CAA4C;AAAA,QACvD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,+BAAqC;AAC3C,IAAAA,QAAO,KAAK,yEAAyE;AAAA,MACnF,cAAc;AAAA,QACZ,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,MACjB,gBAAgB,CAAC,aAAa,KAAK;AAAA,MACnC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,YAAY,UAAqC;AAC7D,QAAI,CAAC,mBAAkB,UAAU;AAC/B,yBAAkB,WAAW,IAAI,mBAAkB,QAAQ;AAAA,IAC7D;AACA,WAAO,mBAAkB;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,uBAA6B;AACnC,QAAI,CAACH,IAAG,WAAW,KAAK,QAAQ,GAAG;AACjC,MAAAA,IAAG,UAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,IAEjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,aAAa,WAAmB,YAAmC;AAC/E,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,EAAE,OAAO,IAAI,MAAMI;AAAA,QACvB,iCAAiC,SAAS,wCAAwC,UAAU;AAAA,MAC9F;AAEA,UAAI,QAAQ;AACV,QAAAD,QAAO,KAAK,4BAA4B;AAAA,UACtC;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AAAA,MACH;AAEA,UAAI,CAACH,IAAG,WAAW,UAAU,GAAG;AAC9B,cAAM,IAAI,MAAM,uCAAuC;AAAA,MACzD;AAAA,IACF,SAAS,OAAO;AACd,MAAAG,QAAO,MAAM,4BAA4B;AAAA,QACvC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,SAAS,iCAAiC,SAAS,wCAAwC,UAAU;AAAA,QACrG,iBAAiB,KAAK;AAAA,QACtB,eAAe,KAAK;AAAA,QACpB,YAAY,KAAK;AAAA,QACjB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM,IAAI;AAAA,QACR,0CAA0C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,gBAAgB,aAAsC;AAClE,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F;AAEA,QAAI;AACF,YAAM,gBAAgBF,MAAK,KAAK,KAAK,UAAU,cAAc,KAAK,IAAI,CAAC,EAAE;AACzE,YAAM,cAAcA,MAAK,KAAK,KAAK,UAAU,QAAQ,KAAK,IAAI,CAAC,MAAM;AAUrE,MAAAD,IAAG,cAAc,eAAe,WAAW;AAQ3C,YAAM,KAAK,aAAa,eAAe,WAAW;AAGlD,UAAIA,IAAG,WAAW,aAAa,GAAG;AAChC,QAAAA,IAAG,WAAW,aAAa;AAAA,MAK7B;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAG,QAAO,MAAM,+BAA+B;AAAA,QAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,iBAAiB,KAAK;AAAA,QACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM,IAAI;AAAA,QACR,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,WAAW,aAAmD;AACzE,UAAM,KAAK,aAAa;AAExB,QAAI,CAAC,KAAK,iBAAiB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,UAAU,MAAM,KAAK,gBAAgB,WAAW;AAEtD,MAAAA,QAAO,KAAK,wCAAwC;AAGpD,YAAM,sBAAsB,QAAQ,OAAO;AAC3C,YAAM,sBAAsB,QAAQ,OAAO;AAG3C,YAAM,YAAY,MAAM;AAGxB,cAAQ,OAAO,QAAQ;AACvB,cAAQ,OAAO,QAAQ;AAEvB,UAAI;AACJ,UAAI;AAEF,iBAAS,MAAM,YAAY,SAAS;AAAA,UAClC,WAAW;AAAA,UACX,uBAAuB;AAAA,UACvB,SAAS;AAAA,UACT,gBAAgB;AAAA,YACd,cAAc;AAAA,YACd,UAAU;AAAA,UACZ;AAAA,QACF,CAAC;AAAA,MACH,UAAE;AAEA,gBAAQ,OAAO,QAAQ;AACvB,gBAAQ,OAAO,QAAQ;AAAA,MACzB;AAGA,UAAIH,IAAG,WAAW,OAAO,GAAG;AAC1B,QAAAA,IAAG,WAAW,OAAO;AACrB,QAAAG,QAAO,KAAK,+BAA+B;AAAA,MAC7C;AAGA,YAAM,YAAY,OACf,MAAM,IAAI,EACV,IAAI,CAAC,SAAS;AAEb,cAAM,YAAY,KAAK,MAAM,QAAQ;AACrC,eAAO,YAAY,UAAU,CAAC,EAAE,KAAK,IAAI,KAAK,KAAK;AAAA,MACrD,CAAC,EACA,OAAO,CAAC,SAAS,IAAI,EACrB,KAAK,GAAG;AAEX,MAAAA,QAAO,QAAQ,2BAA2B;AAAA,QACxC,YAAY,UAAU;AAAA,QACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAED,aAAO,EAAE,MAAM,UAAU;AAAA,IAC3B,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,yBAAyB;AAAA,QACpC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,iBAAiB,KAAK;AAAA,MACxB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AChcA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,UAAAC,eAAc;AACvB;AAAA,EAKE;AAAA,OACK;;;ACVP,SAAS,mBAAkC;AAWpC,SAAS,aACd,aACA,YACA,eAAe,GACf,gBAAgB,IACR;AACR,QAAM,YAAY,OAAO,MAAM,EAAE;AACjC,YAAU,MAAM,QAAQ,CAAC;AACzB,YAAU,cAAc,KAAK,aAAa,CAAC;AAC3C,YAAU,MAAM,QAAQ,CAAC;AACzB,YAAU,MAAM,QAAQ,EAAE;AAC1B,YAAU,cAAc,IAAI,EAAE;AAC9B,YAAU,cAAc,GAAG,EAAE;AAC7B,YAAU,cAAc,cAAc,EAAE;AACxC,YAAU,cAAc,YAAY,EAAE;AACtC,YAAU,cAAe,aAAa,gBAAgB,eAAgB,GAAG,EAAE;AAC3E,YAAU,cAAe,gBAAgB,eAAgB,GAAG,EAAE;AAC9D,YAAU,cAAc,eAAe,EAAE;AACzC,YAAU,MAAM,QAAQ,EAAE;AAC1B,YAAU,cAAc,aAAa,EAAE;AACvC,SAAO;AACT;AAYO,SAAS,iBACd,UACA,aACA,YACA,eAAe,GACf,gBAAgB,IACN;AACV,QAAM,YAAY,aAAa,aAAa,YAAY,cAAc,aAAa;AACnF,MAAI,eAAe;AACnB,QAAM,cAAc,IAAI,YAAY;AACpC,WAAS,GAAG,QAAQ,CAAC,SAAS;AAC5B,QAAI,CAAC,cAAc;AACjB,kBAAY,KAAK,SAAS;AAC1B,qBAAe;AAAA,IACjB;AACA,gBAAY,KAAK,IAAI;AAAA,EACvB,CAAC;AACD,WAAS,GAAG,OAAO,MAAM;AACvB,gBAAY,IAAI;AAAA,EAClB,CAAC;AACD,SAAO;AACT;;;ADpCO,IAAM,aAAN,MAAM,YAAW;AAAA,EACtB,OAAe,WAA8B;AAAA,EACrC;AAAA,EACA,QAA2B;AAAA,EAC3B,MAA2B;AAAA,EAC3B,WAAwC;AAAA,EACxC,cAAc;AAAA,EACd;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,UAAkB;AACpC,SAAK,WAAWC,MAAK,KAAK,UAAU,KAAK;AACzC,SAAK,YAAY,QAAQ,IAAI,iBAAiB,KAAK,IAC/CA,MAAK,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,CAAC,IAC/CA,MAAK,KAAK,QAAQ,IAAI,GAAG,QAAQ;AACrC,SAAK,kBAAkB,gBAAgB,YAAY,KAAK,UAAU,KAAK,SAAS;AAChF,SAAK,qBAAqB;AAC1B,IAAAC,QAAO,MAAM,wBAAwB;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAc,YAAY,UAA8B;AACtD,QAAI,CAAC,YAAW,UAAU;AACxB,kBAAW,WAAW,IAAI,YAAW,QAAQ;AAAA,IAC/C;AACA,WAAO,YAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAA6B;AACnC,QAAI,CAACC,IAAG,WAAW,KAAK,QAAQ,GAAG;AACjC,MAAAA,IAAG,UAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC/C,MAAAD,QAAO,MAAM,gCAAgC,KAAK,QAAQ;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,aAA4B;AACxC,QAAI;AACF,UAAI,KAAK,eAAe,KAAK,SAAS,KAAK,KAAK;AAC9C;AAAA,MACF;AAEA,MAAAA,QAAO,KAAK,uCAAuC;AAEnD,YAAM,YAAY,YAAY,IAAI;AAClC,YAAM,YAAYD,MAAK,KAAK,KAAK,WAAW,UAAU,IAAI;AAU1D,UAAI,CAACE,IAAG,WAAW,SAAS,GAAG;AAE7B,cAAM,WAAW;AAAA,UACf;AAAA,YACE,MAAM,EAAE,GAAG,UAAU;AAAA,YACrB,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,IAAI,iBAAiB,UAAU,IAAI;AAAA,UAC9E;AAAA,UACA;AAAA,YACE,MAAM,EAAE,GAAG,WAAW,MAAM,UAAU,KAAK,QAAQ,SAAS,EAAE,EAAE;AAAA,YAChE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,KAAK,QAAQ,SAAS,EAAE,CAAC,iBAAiB,UAAU,IAAI;AAAA,UACnG;AAAA,UACA;AAAA,YACE,MAAM,EAAE,GAAG,WAAW,MAAM,UAAU,KAAK,QAAQ,SAAS,EAAE,EAAE;AAAA,YAChE,aAAa;AAAA,YACb,KAAK,0BAA0B,UAAU,IAAI,iBAAiB,UAAU,KAAK,QAAQ,SAAS,EAAE,CAAC;AAAA,UACnG;AAAA,QACF;AAEA,YAAI,YAAY;AAChB,mBAAW,WAAW,UAAU;AAC9B,cAAI;AACF,YAAAD,QAAO,KAAK,kCAAkC;AAAA,cAC5C,aAAa,QAAQ;AAAA,cACrB,MAAM,QAAQ,KAAK;AAAA,cACnB,MAAM,QAAQ,KAAK;AAAA,cACnB,KAAK,QAAQ;AAAA,cACb,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAED,kBAAM,YAAY;AAClB,kBAAM,WAAW,SAAI,OAAO,SAAS;AACrC,YAAAA,QAAO,KAAK,0BAA0B,QAAQ,KAAK;AAEnD,kBAAM,KAAK,gBAAgB,gBAAgB,QAAQ,KAAK,SAAS;AAEjE,kBAAM,eAAe,SAAI,OAAO,SAAS;AACzC,YAAAA,QAAO,KAAK,0BAA0B,YAAY,OAAO;AACzD,YAAAA,QAAO,QAAQ,uCAAuC,QAAQ,WAAW;AACzE;AAAA,UACF,SAAS,OAAO;AACd,wBAAY;AACZ,YAAAA,QAAO,KAAK,sCAAsC;AAAA,cAChD,aAAa,QAAQ;AAAA,cACrB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,cAC5D,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YACpC,CAAC;AAAA,UACH;AAAA,QACF;AAEA,YAAI,CAACC,IAAG,WAAW,SAAS,GAAG;AAC7B,gBAAM,aAAa,IAAI,MAAM,8BAA8B;AAAA,QAC7D;AAAA,MACF;AAEA,MAAAD,QAAO,KAAK,sBAAsB;AAClC,YAAM,QAAQ,MAAM,SAAS;AAC7B,WAAK,QAAQ,MAAM,MAAM,UAAU;AAAA,QACjC;AAAA,QACA,WAAW;AAAA;AAAA,MACb,CAAC;AAED,WAAK,MAAM,MAAM,KAAK,MAAM,cAAc;AAAA,QACxC,aAAa,UAAU;AAAA,MACzB,CAAC;AAED,WAAK,WAAW,KAAK,IAAI,YAAY;AAErC,MAAAA,QAAO,QAAQ,+BAA+B;AAAA,QAC5C;AAAA,QACA,aAAa,UAAU;AAAA,QACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,WAAK,cAAc;AAAA,IACrB,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,8BAA8B;AAAA,QACzC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,YAAY,IAAI,KAAK;AAAA,QAC5B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,eAAe,MAAiC;AAC3D,QAAI;AACF,YAAM,KAAK,WAAW;AAEtB,UAAI,CAAC,KAAK,SAAS,CAAC,KAAK,OAAO,CAAC,KAAK,UAAU;AAC9C,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AAEA,MAAAA,QAAO,KAAK,wCAAwC,EAAE,KAAK,CAAC;AAG5D,YAAM,SAAS,kCAAkC,IAAI;AACrD,MAAAA,QAAO,KAAK,qBAAqB,EAAE,OAAO,CAAC;AAG3C,MAAAA,QAAO,KAAK,qBAAqB;AACjC,YAAM,cAAc,KAAK,MAAM,SAAS,MAAM;AAC9C,MAAAA,QAAO,KAAK,oBAAoB,EAAE,YAAY,YAAY,OAAO,CAAC;AAGlE,YAAM,YAAY,YAAY,SAAS;AACvC,MAAAA,QAAO,KAAK,mDAAmD;AAAA,QAC7D;AAAA,MACF,CAAC;AACD,YAAM,iBAA0B,CAAC;AACjC,YAAM,aAAa,KAAK,IAAI;AAE5B,UAAI;AACF,yBAAiB,SAAS,KAAK,SAAS,SAAS,aAAa;AAAA,UAC5D,aAAa;AAAA,QACf,CAAC,GAAG;AACF,yBAAe,KAAK,KAAK;AAGzB,gBAAM,UAAU,KAAK,MAAO,eAAe,SAAS,YAAa,GAAG;AACpE,gBAAM,YAAY;AAClB,gBAAM,eAAe,KAAK,MAAO,eAAe,SAAS,YAAa,SAAS;AAC/E,gBAAM,cAAc,SAAI,OAAO,YAAY,IAAI,SAAI,OAAO,YAAY,YAAY;AAClF,UAAAA,QAAO;AAAA,YACL,qBAAqB,WAAW,IAAI,OAAO,MAAM,eAAe,MAAM,IAAI,SAAS;AAAA,UACrF;AAGA,cAAI,eAAe,UAAU,WAAW;AACtC,YAAAA,QAAO,KAAK,2BAA2B;AACvC;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,2BAA2B,KAAK;AAC7C,cAAM;AAAA,MACR;AAQA,UAAI,eAAe,WAAW,GAAG;AAC/B,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AAGA,MAAAA,QAAO,KAAK,oCAAoC;AAChD,YAAM,YAAY,KAAK,qBAAqB;AAAA,QAC1C,QAAQ,eAAe,IAAI,CAAC,MAAM,OAAO,SAAS,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAAA,MACnF,CAAC;AAED,MAAAA,QAAO,KAAK,yBAAyB;AAAA,QACnC,YAAY,UAAU;AAAA,QACtB,YAAY,YAAY,IAAI,KAAK;AAAA,MACnC,CAAC;AAGD,YAAM,cAAc;AAAA,QAClB,SAAS,KAAK,SAAS;AAAA,QACvB,UAAU;AAAA,QACV,YAAY,IAAI,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF;AAEA,MAAAA,QAAO,QAAQ,4BAA4B;AAC3C,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,6BAA6B;AAAA,QACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,qBAAqB,UAA+B;AAC1D,QAAI,SAAS,OAAO;AAElB,YAAME,WAAU,IAAI,WAAW,SAAS,MAAM,MAAM;AACpD,eAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;AAE9C,cAAM,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,SAAS,MAAM,CAAC,CAAC,CAAC;AACrD,QAAAA,SAAQ,CAAC,IAAI,IAAI,IAAI,IAAI,QAAS,IAAI;AAAA,MACxC;AACA,aAAO,OAAO,KAAKA,SAAQ,MAAM;AAAA,IACnC;AAIA,UAAM,UAAU,IAAI,WAAW,SAAS,OAAO,SAAS,CAAC;AACzD,aAAS,IAAI,GAAG,IAAI,SAAS,OAAO,QAAQ,KAAK;AAE/C,cAAQ,IAAI,CAAC,IAAI,SAAS,OAAO,CAAC,IAAI;AACtC,cAAQ,IAAI,IAAI,CAAC,IAAK,SAAS,OAAO,CAAC,KAAK,KAAM;AAAA,IACpD;AACA,WAAO,OAAO,KAAK,QAAQ,MAAM;AAAA,EACnC;AACF;;;AEnUA,SAAS,kBAAkB;AAC3B,OAAOC,SAAQ;AACf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAOC,cAAa;AACpB,SAAS,UAAAC,eAAc;AACvB;AAAA,EACE;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EAMA;AAAA,EAEA;AAAA,OACK;AAmDA,IAAM,gBAAN,MAAM,eAAc;AAAA,EACzB,OAAe,WAAiC;AAAA,EACxC,QAAkD;AAAA,EAClD,YAAuC;AAAA,EACvC,YAAwC;AAAA,EACxC;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB;AAAA,EACA,kBAAoC;AAAA,IAC1C,EAAE,MAAM,gBAAgB,MAAM,aAAa;AAAA,IAC3C,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,IAC1C,EAAE,MAAM,wBAAwB,MAAM,UAAU;AAAA,IAChD,EAAE,MAAM,iBAAiB,MAAM,UAAU;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,YAAY,UAAkB;AACpC,SAAK,YAAYC,MAAK,KAAKA,MAAK,QAAQ,QAAQ,GAAG,UAAU,QAAQ;AACrE,SAAK,WAAW;AAChB,SAAK,sBAAsB;AAC3B,SAAK,kBAAkB,gBAAgB,YAAY,KAAK,UAAU,KAAK,SAAS;AAChF,SAAK,iBAAiB,KAAK,kBAAkB;AAC7C,IAAAC,QAAO,MAAM,2BAA2B;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAoC;AAC1C,UAAM,WAAWC,IAAG,SAAS;AAC7B,UAAM,OAAOA,IAAG,KAAK;AAGrB,QAAI,SAAyB;AAAA,MAC3B,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAEA,QAAI,aAAa,aAAa,SAAS,WAAW,SAAS,YAAY;AAErE,eAAS;AAAA,QACP,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF,WAAW,aAAa,WAAW,aAAa,SAAS;AAEvD,YAAM,UAAUC,SAAQ,IAAI,yBAAyB;AACrD,UAAI,SAAS;AACX,iBAAS;AAAA,UACP,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA8B;AACpC,QAAI,CAAC,WAAW,KAAK,SAAS,GAAG;AAC/B,MAAAF,QAAO,MAAM,iCAAiC,KAAK,SAAS,EAAE;AAC9D,MAAAG,IAAG,UAAU,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAc,YAAY,UAAiC;AACzD,QAAI,CAAC,eAAc,UAAU;AAC3B,qBAAc,WAAW,IAAI,eAAc,QAAQ;AAAA,IACrD;AACA,WAAO,eAAc;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,iBAAiB,SAAiB,MAAoD;AAC5F,UAAM,YAAYJ,MAAK,KAAK,KAAK,WAAW,QAAQ,QAAQ,KAAK,IAAI,GAAG,IAAI;AAC5E,QAAI,WAAW,SAAS,GAAG;AACzB,MAAAC,QAAO,KAAK,GAAG,IAAI,cAAc,SAAS,EAAE;AAC5C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,2BAAiC;AACvC,UAAM,WAAWC,IAAG,SAAS;AAC7B,UAAM,OAAOA,IAAG,KAAK;AAGrB,QAAI,eAA0B;AAE9B,QAAI,aAAa,aAAa,SAAS,WAAW,SAAS,YAAY;AAErE,qBAAe;AAAA,IACjB,YACG,aAAa,WAAW,aAAa,YACtCC,SAAQ,IAAI,yBAAyB,QACrC;AAEA,qBAAe;AAAA,IACjB;AAGA,SAAK,kBAAkB,KAAK,gBAAgB,IAAI,CAAC,eAAe;AAAA,MAC9D,GAAG;AAAA,MACH,OAAO;AAAA,IACT,EAAE;AAEF,IAAAF,QAAO,KAAK,2CAA2C;AAAA,MACrD;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,KAAK,gBAAgB,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE;AAAA,IACrE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,eAAe,eAAuB;AAC5C,UAAM,YAAY,KAAK,gBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AAC3E,WAAO;AAAA,MACL,QAAQ,KAAK,eAAe;AAAA,MAC5B,OAAO,WAAW,SAAS;AAAA,MAC3B,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,aAAa;AACzB,QAAI;AACF,UAAI,KAAK,aAAa;AACpB,QAAAA,QAAO,KAAK,2DAA2D;AACvE;AAAA,MACF;AAEA,MAAAA,QAAO,KAAK,yCAAyC;AACrD,YAAM,YAAY,YAAY;AAG9B,MAAAA,QAAO,KAAK,6CAA6C;AACzD,UAAI,mBAAmB;AACvB,UAAI,oBAAoB;AAGxB,UAAI,KAAK,eAAe,SAAS;AAC/B,YAAI,SAAS,KAAK,UAAU;AAC5B,YAAI,SAAS,KAAK,WAAW;AAAA,MAC/B;AAWA,MAAAA,QAAO,KAAK,4BAA4B;AACxC,UAAI;AACF,YAAI,eAAe;AACnB,cAAM,cAAc,KAAK,iBAAiB,UAAU,SAAS,OAAO;AAEpE,cAAM,QAAQ,MAAM,kCAAkC,gBAAgB,UAAU,SAAS;AAAA,UACvF,QAAQ;AAAA,UACR,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,UAClB,UAAU;AAAA,UACV,mBAAoB,CAAC,iBAA+B;AAClD,gBAAI,eAAe,KAAK,gBAAiB;AACzC,kBAAM,WACJ,cAAc,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,QAAQ,CAAC,IAAI;AACjF,kBAAM,kBAAkB,KAAK,MAAM,WAAW,GAAG;AACjD,gBAAI,kBAAkB,eAAe,KAAK,oBAAoB,KAAK;AACjE,6BAAe;AACf,oBAAM,YAAY;AAClB,oBAAM,eAAe,KAAK,MAAO,kBAAkB,MAAO,SAAS;AACnE,oBAAM,cAAc,SAAI,OAAO,YAAY,IAAI,SAAI,OAAO,YAAY,YAAY;AAClF,cAAAA,QAAO,KAAK,6BAA6B,WAAW,IAAI,eAAe,GAAG;AAC1E,kBAAI,oBAAoB,IAAK,MAAK,kBAAkB;AAAA,YACtD;AAAA,UACF;AAAA,QACF,CAAC;AAED,aAAK,QAAQ;AACb,QAAAA,QAAO,QAAQ,qCAAqC;AAAA,MACtD,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,mCAAmC;AAAA,UAC9C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,UAC9C,SAAS,UAAU;AAAA,QACrB,CAAC;AACD,cAAM;AAAA,MACR;AAGA,MAAAA,QAAO,KAAK,6BAA6B;AACzC,UAAI;AACF,cAAM,kBAAkB,KAAK,iBAAiB,UAAU,SAAS,WAAW;AAC5E,YAAI,oBAAoB;AAExB,aAAK,YAAY,MAAMI,eAAc,gBAAgB,UAAU,SAAS;AAAA,UACtE,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,UAClB,mBAAoB,CAAC,iBAA+B;AAClD,gBAAI,mBAAmB,KAAK,oBAAqB;AACjD,kBAAM,WACJ,cAAc,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,QAAQ,CAAC,IAAI;AACjF,kBAAM,kBAAkB,KAAK,MAAM,WAAW,GAAG;AACjD,gBAAI,oBAAoB,mBAAmB;AACzC,kCAAoB;AACpB,oBAAM,YAAY;AAClB,oBAAM,eAAe,KAAK,MAAO,kBAAkB,MAAO,SAAS;AACnE,oBAAM,cAAc,SAAI,OAAO,YAAY,IAAI,SAAI,OAAO,YAAY,YAAY;AAClF,cAAAJ,QAAO,KAAK,iCAAiC,WAAW,IAAI,eAAe,GAAG;AAC9E,kBAAI,oBAAoB,IAAK,MAAK,sBAAsB;AAAA,YAC1D;AAAA,UACF;AAAA,QACF,CAAC;AACD,QAAAA,QAAO,QAAQ,sCAAsC;AAAA,MACvD,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,6BAA6B;AAAA,UACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,UAC9C,SAAS,UAAU;AAAA,QACrB,CAAC;AACD,cAAM;AAAA,MACR;AAGA,MAAAA,QAAO,KAAK,6BAA6B;AACzC,UAAI;AACF,cAAM,kBAAkB,KAAK,iBAAiB,UAAU,SAAS,WAAW;AAC5E,YAAI,oBAAoB;AAExB,aAAK,YAAa,MAAM,cAAc,gBAAgB,UAAU,SAAS;AAAA,UACvE,QAAQ;AAAA,UACR,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,UAClB,mBAAoB,CAAC,iBAA+B;AAClD,gBAAI,mBAAmB,KAAK,oBAAqB;AACjD,kBAAM,WACJ,cAAc,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,QAAQ,CAAC,IAAI;AACjF,kBAAM,kBAAkB,KAAK,MAAM,WAAW,GAAG;AACjD,gBAAI,oBAAoB,mBAAmB;AACzC,kCAAoB;AACpB,oBAAM,YAAY;AAClB,oBAAM,eAAe,KAAK,MAAO,kBAAkB,MAAO,SAAS;AACnE,oBAAM,cAAc,SAAI,OAAO,YAAY,IAAI,SAAI,OAAO,YAAY,YAAY;AAClF,cAAAA,QAAO,KAAK,iCAAiC,WAAW,IAAI,eAAe,GAAG;AAC9E,kBAAI,oBAAoB,IAAK,MAAK,sBAAsB;AAAA,YAC1D;AAAA,UACF;AAAA,QACF,CAAC;AACD,QAAAA,QAAO,QAAQ,sCAAsC;AAAA,MACvD,SAAS,OAAO;AACd,QAAAA,QAAO,MAAM,oCAAoC;AAAA,UAC/C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,UAC9C,SAAS,UAAU;AAAA,QACrB,CAAC;AACD,cAAM;AAAA,MACR;AAEA,WAAK,cAAc;AACnB,MAAAA,QAAO,QAAQ,sCAAsC;AAAA,IACvD,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,uCAAuC;AAAA,QAClD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,WAAW,KAAK;AAAA,MAClB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,WAAW,KAA4D;AACnF,QAAI;AACF,MAAAA,QAAO,KAAK,4BAA4B,IAAI,MAAM,GAAG,GAAG,CAAC,KAAK;AAG9D,UAAI,IAAI,WAAW,OAAO,GAAG;AAC3B,QAAAA,QAAO,KAAK,wBAAwB;AACpC,cAAM,CAAC,QAAQ,UAAU,IAAI,IAAI,MAAM,GAAG;AAC1C,cAAMK,YAAW,OAAO,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAClD,cAAMC,UAAS,OAAO,KAAK,YAAY,QAAQ;AAC/C,QAAAN,QAAO,KAAK,iCAAiC;AAK7C,eAAO,EAAE,QAAAM,SAAQ,UAAAD,UAAS;AAAA,MAC5B;AAGA,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,0BAA0B,SAAS,UAAU,EAAE;AAAA,MACjE;AACA,YAAM,SAAS,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC;AACvD,YAAM,WAAW,SAAS,QAAQ,IAAI,cAAc,KAAK;AAEzD,MAAAL,QAAO,KAAK,+BAA+B;AAAA,QACzC;AAAA,QACA,YAAY,OAAO;AAAA,QACnB,QAAQ,SAAS;AAAA,MACnB,CAAC;AAED,aAAO,EAAE,QAAQ,SAAS;AAAA,IAC5B,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,0BAA0B;AAAA,QACrC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,aAAa,UAAmE;AAC3F,QAAI;AACF,MAAAA,QAAO,KAAK,8BAA8B;AAG1C,UAAI,CAAC,KAAK,aAAa;AACrB,QAAAA,QAAO,KAAK,mDAAmD;AAC/D,cAAM,KAAK,WAAW;AAAA,MACxB;AAEA,UAAI,CAAC,KAAK,SAAS,CAAC,KAAK,aAAa,CAAC,KAAK,WAAW;AACrD,cAAM,IAAI,MAAM,kDAAkD;AAAA,MACpE;AAGA,MAAAA,QAAO,KAAK,mBAAmB;AAC/B,YAAM,EAAE,QAAQ,SAAS,IAAI,MAAM,KAAK,WAAW,QAAQ;AAG3D,MAAAA,QAAO,KAAK,wBAAwB;AACpC,YAAM,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,SAAS,CAAC;AAClD,MAAAA,QAAO,KAAK,gCAAgC;AAE5C,YAAM,QAAQ,MAAM,SAAS,SAAS,IAAI;AAE1C,MAAAA,QAAO,KAAK,2CAA2C;AACvD,YAAM,eAAe,MAAM,KAAK,UAAU,KAAK;AAC/C,MAAAA,QAAO,KAAK,yBAAyB;AACrC,YAAM,UAAU,KAAK,UAAU,kBAAkB,oBAAoB;AACrE,MAAAA,QAAO,KAAK,uBAAuB;AACnC,YAAM,aAAa,KAAK,UAAU,OAAO;AAGzC,MAAAA,QAAO,KAAK,iCAAiC;AAC7C,YAAM,eAAgB,MAAM,KAAK,MAAM,SAAS;AAAA,QAC9C,GAAG;AAAA,QACH,GAAG;AAAA,QACH,gBAAgB,YAAY,OAAO;AAAA,MACrC,CAAC;AAED,MAAAA,QAAO,KAAK,4BAA4B;AACxC,YAAM,gBAAgB,KAAK,UAAU,aAAa,cAAc;AAAA,QAC9D,qBAAqB;AAAA,MACvB,CAAC,EAAE,CAAC;AAEJ,MAAAA,QAAO,KAAK,+BAA+B;AAC3C,YAAM,SAAS,KAAK,UAAU;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,MAAM;AAAA,MACR;AAEA,YAAM,kBAAkB,OAAO,oBAAoB;AACnD,YAAM,WAAW;AAAA,QACf,OAAO,GAAG,gBAAgB,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,QACvC,aAAa;AAAA,MACf;AAEA,MAAAA,QAAO,QAAQ,8BAA8B;AAAA,QAC3C,aAAa,SAAS,MAAM;AAAA,QAC5B,mBAAmB,SAAS,YAAY;AAAA,MAC1C,CAAC;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,4BAA4B;AAAA,QACvC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C;AAAA,QACA,kBAAkB,KAAK;AAAA,QACvB,UAAU,CAAC,CAAC,KAAK;AAAA,QACjB,cAAc,CAAC,CAAC,KAAK;AAAA,QACrB,cAAc,CAAC,CAAC,KAAK;AAAA,MACvB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AXneA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAYO,MAAK,QAAQ,UAAU;AAQzC,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA8BA,IAAM,iBAAN,MAAM,gBAAe;AAAA,EACnB,OAAe,WAAkC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAuC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,iBAAiB;AAAA;AAAA,EAGjB,gCAAsD;AAAA,EACtD,iCAAuD;AAAA,EACvD,+BAAqD;AAAA,EACrD,4BAAkD;AAAA,EAClD,mCAAyD;AAAA,EACzD,yBAA+C;AAAA,EAC/C,4BAAkD;AAAA,EAClD,8BAAoD;AAAA,EAEpD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AAEpB,UAAM,YAAYA,MAAK,KAAK,QAAQ,IAAI,GAAG,QAAQ;AAGnD,QAAI,QAAQ,IAAI,iBAAiB,KAAK,GAAG;AACvC,WAAK,YAAYA,MAAK,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,CAAC;AAAA,IAClE,OAAO;AAEL,UAAI,CAACC,IAAG,WAAW,SAAS,GAAG;AAC7B,QAAAA,IAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAC3C,QAAAC,SAAO,MAAM,0BAA0B;AAAA,MACzC;AACA,WAAK,YAAY;AAAA,IACnB;AAGA,SAAK,YAAYF,MAAK,KAAK,KAAK,WAAW,yCAAyC;AAEpF,SAAK,kBAAkBA,MAAK,KAAK,KAAK,WAAW,iCAAiC;AAGlF,UAAM,cAAc,QAAQ,IAAI,WAAW,KAAK;AAChD,QAAI,aAAa;AACf,WAAK,WAAWA,MAAK,QAAQ,WAAW;AAAA,IAC1C,OAAO;AACL,YAAM,WAAWA,MAAK,KAAK,QAAQ,IAAI,GAAG,OAAO;AAEjD,UAAI,CAACC,IAAG,WAAW,QAAQ,GAAG;AAC5B,QAAAA,IAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAC1C,QAAAC,SAAO,MAAM,oCAAoC,QAAQ;AAAA,MAC3D;AACA,WAAK,WAAW;AAAA,IAClB;AAGA,SAAK,kBAAkB,gBAAgB,YAAY,KAAK,UAAU,KAAK,SAAS;AAGhF,SAAK,mBAAmB,iBAAiB,YAAY,KAAK,UAAU,KAAK,SAAS;AAGlF,SAAK,gBAAgB,cAAc,YAAY,KAAK,QAAQ;AAG5D,SAAK,oBAAoB,kBAAkB,YAAY,KAAK,QAAQ;AAGpE,SAAK,aAAa,WAAW,YAAY,KAAK,QAAQ;AAGtD,QAAI,QAAQ,IAAI,6BAA6B,QAAQ;AACnD,WAAK,kBAAkB,gBAAgB,YAAY;AAAA,IACrD;AAGA,QAAI,QAAQ,IAAI,2BAA2B,QAAQ;AACjD,WAAK,gBAAgB,cAAc,YAAY;AAAA,IACjD;AAGA,SAAK,oBAAoB,YAAY;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAc,cAA8B;AAC1C,QAAI,CAAC,gBAAe,UAAU;AAC5B,sBAAe,WAAW,IAAI,gBAAe;AAAA,IAC/C;AACA,WAAO,gBAAe;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,wBAAuC;AACnD,QAAI;AACF,MAAAA,SAAO,KAAK,yCAAyC;AAGrD,YAAM,SAAS;AAAA,QACb,cAAc,QAAQ,IAAI;AAAA,QAC1B,0BAA0B,QAAQ,IAAI;AAAA,QACtC,wBAAwB,QAAQ,IAAI;AAAA,MACtC;AAGA,YAAM,kBAAkB,MAAM,eAAe,MAAM;AAInD,MAAAA,SAAO,KAAK,qCAAqC;AAGjD,cAAQ,IAAI,eAAe,OAAO,gBAAgB,YAAY;AAC9D,cAAQ,IAAI,2BAA2B,OAAO,gBAAgB,wBAAwB;AACtF,cAAQ,IAAI,yBAAyB,OAAO,gBAAgB,sBAAsB;AAQlF,MAAAA,SAAO,QAAQ,qCAAqC;AAAA,IACtD,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,kCAAkC;AAAA,QAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,MAChD,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,mBAAkC;AAC9C,QAAI;AACF,MAAAA,SAAO,KAAK,+BAA+B;AAG3C,UAAI,CAAC,KAAK,eAAe;AACvB,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AAGA,YAAM,KAAK,cAAc,WAAW;AAEpC,UAAI,CAAC,KAAK,cAAc,cAAc,GAAG;AACvC,cAAM,IAAI,MAAM,2DAA2D;AAAA,MAC7E;AAEA,MAAAA,SAAO,QAAQ,gCAAgC;AAAA,IACjD,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,qBAAoC;AAChD,QAAI;AACF,MAAAA,SAAO,KAAK,iCAAiC;AAG7C,UAAI,CAAC,KAAK,iBAAiB;AACzB,cAAM,IAAI,MAAM,kDAAkD;AAAA,MACpE;AAGA,YAAM,KAAK,gBAAgB,WAAW;AAEtC,UAAI,CAAC,KAAK,gBAAgB,cAAc,GAAG;AACzC,cAAM,IAAI,MAAM,6DAA6D;AAAA,MAC/E;AAEA,WAAK,sBAAsB;AAC3B,MAAAA,SAAO,QAAQ,kCAAkC;AAAA,IACnD,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,mCAAmC;AAAA,QAC9C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,cAAc,WAA4C;AACtE,UAAM,YAAY,cAAcC,WAAU,aAAa,YAAY,SAAS,YAAY;AACxF,UAAM,YAAY,cAAcA,WAAU,aAAa,KAAK,kBAAkB,KAAK;AACnF,QAAI;AACF,aAAO,MAAM,KAAK,gBAAgB,cAAc,WAAW,SAAS;AAAA,IACtE,SAAS,OAAO;AACd,MAAAD,SAAO,MAAM,0BAA0B;AAAA,QACrC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,4BAA2C;AACtD,QAAI;AACF,YAAM,kBAAkB,mBAAmB;AAC3C,YAAM,gBAAgB,WAAW;AACjC,YAAM,eAAe,gBAAgB,gBAAgB;AAErD,MAAAA,SAAO,KAAK,mCAAmC;AAAA,QAC7C,UAAU,aAAa;AAAA,QACvB,KAAK,aAAa,KAAK,QAAQ;AAAA,QAC/B,kBAAkB,aAAa;AAAA,QAC/B,mBAAmB,aAAa;AAAA,MAClC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,MAAAA,SAAO,KAAK,8BAA8B,KAAK;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAW,YAA2BC,WAAU,YAA2B;AAC/E,QAAI,cAAcA,WAAU,YAAY;AACtC,YAAM,KAAK,oBAAoB;AAAA,IACjC,OAAO;AACL,YAAM,KAAK,mBAAmB;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,sBAAqC;AAChD,QAAI;AACF,MAAAD,SAAO,KAAK,iCAAiC;AAC7C,MAAAA,SAAO,KAAK,qBAAqB,KAAK,SAAS;AAG/C,UAAI,CAACD,IAAG,WAAW,KAAK,SAAS,GAAG;AAClC,QAAAC,SAAO,KAAK,iDAAiD,KAAK,SAAS;AAC3E,QAAAD,IAAG,UAAU,KAAK,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,MAClD;AAEA,UAAI,CAAC,KAAK,gBAAgB;AACxB,QAAAC,SAAO,KAAK,8DAA8D;AAS1E,cAAM,YAAY;AAClB,cAAM,WAAW,SAAI,OAAO,SAAS;AACrC,QAAAA,SAAO,KAAK,gCAAgC,QAAQ,KAAK;AAGzD,aAAK,iBAAiB,MAAM,cAAc,KAAK;AAAA,UAC7C,UAAU,KAAK;AAAA,UACf,OAAO,eAAe;AAAA,UACtB,WAAW;AAAA,UACX,sBAAsB;AAAA,QACxB,CAAC;AAGD,cAAM,eAAe,SAAI,OAAO,SAAS;AACzC,QAAAA,SAAO,KAAK,gCAAgC,YAAY,OAAO;AAC/D,QAAAA,SAAO,QAAQ,6CAA6C;AAAA,MAC9D;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,iDAAiD;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,WAAW,KAAK;AAAA,QAChB,OAAO,eAAe;AAAA,MACxB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,yBAAyB,QAA6C;AAC1E,QAAI;AACF,YAAM,cAAc,KAAK,mBAAmB;AAC5C,MAAAA,SAAO,KAAK,yCAAyC;AAAA,QACnD,aAAa,YAAY;AAAA,QACzB,WAAW,OAAO;AAAA,QAClB,qBAAqB,KAAK;AAAA,QAC1B,mBAAmB,KAAK;AAAA,QACxB,iBAAiB,QAAQ,IAAI,6BAA6B;AAAA,QAC1D,eAAe,QAAQ,IAAI,2BAA2B;AAAA,MACxD,CAAC;AAED,UAAI,YAAY,WAAW,YAAY;AAErC,YAAI,QAAQ,IAAI,6BAA6B,QAAQ;AACnD,UAAAA,SAAO;AAAA,YACL;AAAA,UACF;AACA,iBAAO,KAAK,aAAa,MAAM;AAAA,QACjC;AAGA,YAAI,CAAC,KAAK,iBAAiB;AACzB,UAAAA,SAAO,KAAK,gEAAgE;AAC5E,iBAAO,KAAK,aAAa,MAAM;AAAA,QACjC;AAGA,YAAI,CAAC,KAAK,qBAAqB;AAC7B,UAAAA,SAAO,KAAK,+CAA+C;AAC3D,gBAAM,KAAK,mBAAmB;AAAA,QAChC;AAGA,eAAO,MAAM,KAAK,gBAAgB,aAAa,QAAQ,KAAK,mBAAmB;AAAA,MACjF;AAEA,UAAI,YAAY,WAAW,UAAU;AAEnC,YAAI,QAAQ,IAAI,2BAA2B,QAAQ;AACjD,UAAAA,SAAO,KAAK,4EAA4E;AACxF,iBAAO,KAAK,aAAa,MAAM;AAAA,QACjC;AAGA,YAAI,CAAC,KAAK,eAAe;AACvB,UAAAA,SAAO,KAAK,8DAA8D;AAC1E,iBAAO,KAAK,aAAa,MAAM;AAAA,QACjC;AAGA,YAAI,CAAC,KAAK,qBAAqB,CAAC,KAAK,cAAc,cAAc,GAAG;AAClE,UAAAA,SAAO,KAAK,iDAAiD;AAC7D,gBAAM,KAAK,cAAc,WAAW;AACpC,eAAK,oBAAoB;AAAA,QAC3B;AAGA,eAAO,MAAM,KAAK,cAAc,aAAa,QAAQ,KAAK,iBAAiB;AAAA,MAC7E;AAGA,aAAO,KAAK,aAAa,MAAM;AAAA,IACjC,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,gDAAgD;AAAA,QAC3D,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAC9C,aAAa,KAAK,mBAAmB,EAAE;AAAA,MACzC,CAAC;AAED,aAAO,KAAK,aAAa,MAAM;AAAA,IACjC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,QAA6C;AAC9D,QAAI;AAEF,UAAI,OAAO,cAAcC,WAAU,YAAY;AAC7C,cAAM,KAAK,oBAAoB;AAE/B,YAAI,CAAC,KAAK,aAAa;AACrB,gBAAM,IAAI,MAAM,oCAAoC;AAAA,QACtD;AAEA,aAAK,oBAAoB,YAAY;AACrC,cAAM,cAAc,KAAK;AAGzB,aAAK,MAAM,MAAM,YAAY,cAAc;AAAA,UACzC,aAAa,YAAY,OAAO;AAAA,QAClC,CAAC;AAAA,MACH,OAAO;AACL,cAAM,KAAK,mBAAmB;AAE9B,YAAI,CAAC,KAAK,YAAY;AACpB,gBAAM,IAAI,MAAM,mCAAmC;AAAA,QACrD;AAEA,aAAK,oBAAoB,YAAY;AACrC,cAAM,aAAa,KAAK;AAGxB,aAAK,MAAM,MAAM,WAAW,cAAc;AAAA,UACxC,aAAa,YAAY,MAAM;AAAA,QACjC,CAAC;AAAA,MACH;AAEA,UAAI,CAAC,KAAK,KAAK;AACb,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAGA,WAAK,WAAW,KAAK,IAAI,YAAY;AAIrC,WAAK,cAAc,IAAI,iBAAiB;AAAA,QACtC,iBAAiB,KAAK;AAAA,MACxB,CAAC;AAED,UAAI,CAAC,KAAK,aAAa;AACrB,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AACA,MAAAD,SAAO,KAAK,uCAAuC,OAAO,SAAS;AAEnE,MAAAA,SAAO,KAAK,8BAA8B;AAAA,QACxC,eAAe,OAAO,OAAO;AAAA,QAC7B,WAAW,OAAO,OAAO,SAAS,QAAQ;AAAA,QAC1C,SAAS,CAAC,CAAC,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,MACxB,CAAC;AAED,YAAM,SAAS,MAAM,KAAK,iBAAiB,OAAO,OAAO,QAAQ,KAAK,iBAAiB;AACvF,MAAAA,SAAO,KAAK,iBAAiB,EAAE,OAAO,OAAO,OAAO,CAAC;AAGrD,YAAM,gBAAgB;AACtB,YAAM,KAAK,YAAY,OAAO,eAAe;AAAA,QAC3C,WAAW;AAAA;AAAA,QACX,aAAa;AAAA,MACf,CAAC;AAED,UAAI,WAAW,MAAM,KAAK,YAAY,OAAO,OAAO,QAAQ;AAAA,QAC1D,WAAW;AAAA,QACX,aAAa;AAAA,QACb,MAAM;AAAA,QACN,eAAe;AAAA,UACb,oBAAoB,MAAM,KAAK,WAAY,SAAS,cAAc,KAAK,GAAG,CAAC;AAAA,UAC3E,SAAS;AAAA,UACT,kBAAkB;AAAA,UAClB,iBAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAGD,MAAAA,SAAO,KAAK,2BAA2B;AAAA,QACrC,gBAAgB,SAAS;AAAA,QACzB,WAAW,SAAS,SAAS,QAAQ;AAAA,QACrC,aAAa,SAAS,SAAS,SAAS;AAAA,MAC1C,CAAC;AAGD,UAAI,SAAS,SAAS,SAAS,GAAG;AAChC,QAAAA,SAAO,KAAK,mCAAmC;AAC/C,mBAAW,SAAS,QAAQ,gCAAgC,EAAE;AAC9D,QAAAA,SAAO,KAAK,kCAAkC;AAAA,MAChD;AAGA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,2BAA2B,KAAK;AAC7C,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAkB,MAAiC;AACvD,QAAI;AAEF,YAAM,KAAK,kBAAkB;AAE7B,UAAI,CAAC,KAAK,gBAAgB;AACxB,cAAM,IAAI,MAAM,sCAAsC;AAAA,MACxD;AAEA,MAAAA,SAAO,KAAK,+BAA+B;AAC3C,YAAM,YAAY,MAAM,KAAK,eAAe,WAAW,IAAI;AAC3D,YAAM,aAAa,UAAU;AAC7B,MAAAA,SAAO,KAAK,iCAAiC,EAAE,WAAW,CAAC;AAE3D,aAAO,MAAM,KAAK,SAAS;AAAA,IAC7B,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,gCAAgC;AAAA,QAC3C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA;AAAA,QAE9C,YAAY,MAAM,UAAU;AAAA,MAC9B,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,cACX,WACA,UACiD;AACjD,QAAI;AAEF,YAAM,KAAK,eAAe;AAG1B,YAAM,SAAS,UAAU,SAAS,QAAQ;AAC1C,YAAM,UAAU,QAAQ,QAAQ,WAAW,MAAM;AACjD,aAAO,MAAM,KAAK,cAAc,aAAa,OAAO;AAAA,IACtD,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,6BAA6B,KAAK;AAC/C,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,gBAAgB,aAAsC;AACjE,QAAI;AAEF,YAAM,KAAK,sBAAsB;AAEjC,YAAM,SAAS,MAAM,KAAK,kBAAkB,WAAW,WAAW;AAClE,aAAO,OAAO;AAAA,IAChB,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,+BAA+B;AAAA,QAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,YAAY,YAAY;AAAA,MAC1B,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,eAAe,MAAiC;AAC3D,QAAI;AAEF,YAAM,KAAK,YAAY;AAEvB,aAAO,MAAM,KAAK,WAAW,eAAe,IAAI;AAAA,IAClD,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,6BAA6B;AAAA,QACxC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,YAAY,KAAK;AAAA,MACnB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,sBAAwC;AAC7C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,uBAAkC;AACvC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,qBAAsC;AAC3C,QAAI;AAEF,YAAM,SAA0B;AAAA,QAC9B,QAAQ;AAAA,QACR,WAAWC,WAAU;AAAA,MACvB;AAGA,UAAI,QAAQ,IAAI,6BAA6B,UAAU,KAAK,iBAAiB;AAC3E,eAAO,SAAS;AAAA,MAClB,WAAW,QAAQ,IAAI,2BAA2B,UAAU,KAAK,eAAe;AAC9E,eAAO,SAAS;AAAA,MAClB;AAEA,MAAAD,SAAO,KAAK,+BAA+B,MAAM;AACjD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,wCAAwC,KAAK;AAE1D,aAAO,EAAE,QAAQ,SAAS,WAAWC,WAAU,WAAW;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,WACA,eACA,aACA,cACY;AAEZ,QAAI,eAAe;AACjB,aAAO,QAAQ,QAAQ,IAAI;AAAA,IAC7B;AAGA,QAAI,aAAa;AACf,MAAAD,SAAO,KAAK,eAAe,SAAS,gCAAgC;AACpE,YAAM;AACN,aAAO,QAAQ,QAAQ,IAAI;AAAA,IAC7B;AAGA,IAAAA,SAAO,KAAK,qBAAqB,SAAS,KAAK;AAC/C,WAAO,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBAAoC;AAChD,QAAI,KAAK,sBAAuB;AAEhC,QAAI,CAAC,KAAK,+BAA+B;AACvC,WAAK,iCAAiC,YAAY;AAChD,cAAM,KAAK,sBAAsB;AACjC,cAAM,KAAK,0BAA0B;AAGrC,cAAM,KAAK,cAAcC,WAAU,UAAU;AAG7C,YAAI;AAEF,eAAK,QAAQ,MAAMC,UAAS;AAE5B,gBAAM,aAAa,MAAM,KAAK,MAAM,UAAU;AAAA,YAC5C,WAAW;AAAA,YACX,WAAW,KAAK;AAAA,YAChB,WAAW;AAAA,UACb,CAAC;AAED,eAAK,aAAa;AAElB,gBAAM,MAAM,MAAM,WAAW,cAAc;AAAA,YACzC,aAAa,YAAY,MAAM;AAAA,UACjC,CAAC;AAED,eAAK,MAAM;AACX,eAAK,WAAW;AAChB,eAAK,wBAAwB;AAC7B,UAAAF,SAAO,KAAK,sCAAsC;AAAA,QACpD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,qCAAqC,KAAK;AACvD,eAAK,gCAAgC;AACrC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,sBAAqC;AACjD,QAAI,KAAK,uBAAwB;AAEjC,QAAI,CAAC,KAAK,gCAAgC;AACxC,WAAK,kCAAkC,YAAY;AAEjD,YAAI,CAAC,KAAK,OAAO;AACf,gBAAM,KAAK,mBAAmB;AAAA,QAChC;AAEA,cAAM,KAAK,cAAcC,WAAU,UAAU;AAG7C,YAAI;AACF,gBAAM,cAAc,MAAM,KAAK,MAAO,UAAU;AAAA,YAC9C,WAAW;AAAA,YACX,WAAW,KAAK;AAAA,YAChB,WAAW;AAAA,UACb,CAAC;AAED,eAAK,cAAc;AACnB,eAAK,yBAAyB;AAC9B,UAAAD,SAAO,KAAK,uCAAuC;AAAA,QACrD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,sCAAsC,KAAK;AACxD,eAAK,iCAAiC;AACtC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAAmC;AAC/C,QAAI,KAAK,qBAAsB;AAE/B,QAAI,CAAC,KAAK,8BAA8B;AACtC,WAAK,gCAAgC,YAAY;AAC/C,YAAI;AACF,gBAAM,KAAK,oBAAoB;AAC/B,eAAK,uBAAuB;AAC5B,UAAAA,SAAO,KAAK,0CAA0C;AAAA,QACxD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,yCAAyC,KAAK;AAC3D,eAAK,+BAA+B;AACpC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAgC;AAC5C,QAAI,KAAK,kBAAmB;AAE5B,QAAI,CAAC,KAAK,2BAA2B;AACnC,WAAK,6BAA6B,YAAY;AAC5C,YAAI;AAIF,eAAK,oBAAoB;AACzB,UAAAA,SAAO,KAAK,uCAAuC;AAAA,QACrD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,sCAAsC,KAAK;AACxD,eAAK,4BAA4B;AACjC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,wBAAuC;AACnD,QAAI,KAAK,yBAA0B;AAEnC,QAAI,CAAC,KAAK,kCAAkC;AAC1C,WAAK,oCAAoC,YAAY;AACnD,YAAI;AAIF,eAAK,2BAA2B;AAChC,UAAAA,SAAO,KAAK,8CAA8C;AAAA,QAC5D,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,6CAA6C,KAAK;AAC/D,eAAK,mCAAmC;AACxC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cAA6B;AACzC,QAAI,KAAK,eAAgB;AAEzB,QAAI,CAAC,KAAK,wBAAwB;AAChC,WAAK,0BAA0B,YAAY;AACzC,YAAI;AAIF,eAAK,iBAAiB;AACtB,UAAAA,SAAO,KAAK,oCAAoC;AAAA,QAClD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,mCAAmC,KAAK;AACrD,eAAK,yBAAyB;AAC9B,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBAAgC;AAC5C,QAAI,KAAK,kBAAmB;AAE5B,QAAI,CAAC,KAAK,2BAA2B;AACnC,WAAK,6BAA6B,YAAY;AAC5C,YAAI;AACF,gBAAM,KAAK,iBAAiB;AAC5B,eAAK,oBAAoB;AACzB,UAAAA,SAAO,KAAK,iCAAiC;AAAA,QAC/C,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,gCAAgC,KAAK;AAClD,eAAK,4BAA4B;AACjC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAkC;AAC9C,QAAI,KAAK,oBAAqB;AAE9B,QAAI,CAAC,KAAK,6BAA6B;AACrC,WAAK,+BAA+B,YAAY;AAC9C,YAAI;AACF,gBAAM,KAAK,mBAAmB;AAC9B,eAAK,sBAAsB;AAC3B,UAAAA,SAAO,KAAK,mCAAmC;AAAA,QACjD,SAAS,OAAO;AACd,UAAAA,SAAO,MAAM,kCAAkC,KAAK;AACpD,eAAK,8BAA8B;AACnC,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAEA,UAAM,KAAK;AAAA,EACb;AACF;AAGA,IAAM,iBAAiB,eAAe,YAAY;AAM3C,IAAM,gBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,MAAM,OAAO;AACX,QAAI;AACF,MAAAA,SAAO,MAAM,iCAAiC;AAE9C,MAAAA,SAAO,QAAQ,yDAAyD;AAAA,IAC1E,SAAS,OAAO;AACd,MAAAA,SAAO,MAAM,iCAAiC;AAAA,QAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,MAChD,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,CAACC,WAAU,UAAU,GAAG,OACtB,SACA,EAAE,QAAQ,gBAAgB,CAAC,EAAE,MAC1B;AACH,UAAI;AACF,cAAM,cAAc,eAAe,mBAAmB;AAEtD,YAAI,YAAY,WAAW,SAAS;AAClC,iBAAO,MAAM,eAAe,yBAAyB;AAAA,YACnD;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAWA,WAAU;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,eAAO,MAAM,eAAe,aAAa;AAAA,UACvC;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAWA,WAAU;AAAA,QACvB,CAAC;AAAA,MACH,SAAS,OAAO;AACd,QAAAD,SAAO,MAAM,gCAAgC,KAAK;AAClD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,UAAU,GAAG,OACtB,SACA,EAAE,QAAQ,gBAAgB,CAAC,EAAE,MAC1B;AACH,UAAI;AACF,cAAM,cAAc,eAAe,mBAAmB;AAEtD,YAAI,YAAY,WAAW,SAAS;AAClC,iBAAO,MAAM,eAAe,yBAAyB;AAAA,YACnD;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAWA,WAAU;AAAA,UACvB,CAAC;AAAA,QACH;AAEA,eAAO,MAAM,eAAe,aAAa;AAAA,UACvC;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAWA,WAAU;AAAA,QACvB,CAAC;AAAA,MACH,SAAS,OAAO;AACd,QAAAD,SAAO,MAAM,gCAAgC,KAAK;AAClD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,cAAc,GAAG,OAAO,UAAyB,WAAgC;AAC1F,YAAM,OAAO,QAAQ;AACrB,UAAI;AAEF,YAAI,CAAC,MAAM;AACT,UAAAD,SAAO,MAAM,+DAA+D;AAC5E,iBAAO,IAAI,MAAM,GAAG,EAAE,KAAK,CAAC;AAAA,QAC9B;AAGA,eAAO,MAAM,eAAe,kBAAkB,IAAI;AAAA,MACpD,SAAS,OAAO;AACd,QAAAA,SAAO,MAAM,oCAAoC;AAAA,UAC/C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,UAAU;AAAA,UACV,UAAU,OAAO;AAAA,UACjB,eAAe,SAAS,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI;AAAA,QACjE,CAAC;AACD,eAAO,IAAI,MAAM,GAAG,EAAE,KAAK,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,YAAY,GAAG,OAAO,SAAwB,WAAmC;AAC1F,UAAI;AACF,QAAAD,SAAO,KAAK,8CAA8C;AAAA,UACxD,QAAQ,OAAO;AAAA,UACf,WAAW,CAAC,CAAC,OAAO;AAAA,UACpB,aAAa,OAAO;AAAA,QACtB,CAAC;AAGD,YAAI,aAAa,OAAO;AACxB,YAAI,CAAC,WAAW,SAAS,SAAS,KAAK,CAAC,WAAW,SAAS,yBAAyB,GAAG;AACtF,wBACE;AAAA,QACJ;AAEA,cAAM,cAAc,eAAe,mBAAmB;AAGtD,YAAI;AACJ,YAAI,YAAY,WAAW,SAAS;AAClC,yBAAe,MAAM,eAAe,yBAAyB;AAAA,YAC3D,QAAQ;AAAA,YACR,eAAe,OAAO;AAAA,YACtB;AAAA,YACA,WAAWC,WAAU;AAAA,UACvB,CAAC;AAAA,QACH,OAAO;AACL,yBAAe,MAAM,eAAe,aAAa;AAAA,YAC/C,QAAQ;AAAA,YACR,eAAe,OAAO;AAAA,YACtB;AAAA,YACA,WAAWA,WAAU;AAAA,UACvB,CAAC;AAAA,QACH;AAGA,YAAI;AAEF,gBAAM,cAAc,CAAC,SAAyB;AAE5C,kBAAM,iBAAiB;AACvB,kBAAM,QAAQ,KAAK,MAAM,cAAc;AAEvC,gBAAI,SAAS,MAAM,CAAC,GAAG;AACrB,qBAAO,MAAM,CAAC,EAAE,KAAK;AAAA,YACvB;AAIA,kBAAM,mBAAmB;AACzB,kBAAM,eAAe,KAAK,MAAM,gBAAgB;AAEhD,gBAAI,gBAAgB,aAAa,CAAC,GAAG;AACnC,qBAAO,aAAa,CAAC,EAAE,KAAK;AAAA,YAC9B;AAGA,mBAAO,KAAK,KAAK;AAAA,UACnB;AAEA,gBAAM,oBAAoB,YAAY,YAAY;AAClD,UAAAD,SAAO,MAAM,wBAAwB,iBAAiB;AAEtD,cAAI;AACJ,cAAI;AACF,yBAAa,KAAK,MAAM,iBAAiB;AAAA,UAC3C,SAAS,YAAY;AAEnB,YAAAA,SAAO,MAAM,4DAA4D;AAGzE,kBAAM,YAAY,kBACf,QAAQ,+BAA+B,aAAa,EAEpD,QAAQ,yDAAyD,QAAQ,EAEzE,QAAQ,qBAAqB,WAAW,EAExC,QAAQ,gBAAgB,IAAI;AAE/B,gBAAI;AACF,2BAAa,KAAK,MAAM,SAAS;AAAA,YACnC,SAAS,YAAY;AACnB,cAAAA,SAAO,MAAM,sCAAsC,UAAU;AAC7D,oBAAM,IAAI,MAAM,kCAAkC;AAAA,YACpD;AAAA,UACF;AAGA,cAAI,OAAO,QAAQ;AACjB,gBAAI;AAEF,yBAAW,OAAO,OAAO,KAAK,OAAO,MAAM,GAAG;AAC5C,oBAAI,EAAE,OAAO,aAAa;AACxB,6BAAW,GAAG,IAAI;AAAA,gBACpB;AAAA,cACF;AAAA,YACF,SAAS,aAAa;AACpB,cAAAA,SAAO,MAAM,6BAA6B,WAAW;AAAA,YACvD;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,SAAS,YAAY;AACnB,UAAAA,SAAO,MAAM,yBAAyB,UAAU;AAChD,UAAAA,SAAO,MAAM,iBAAiB,YAAY;AAC1C,gBAAM,IAAI,MAAM,kCAAkC;AAAA,QACpD;AAAA,MACF,SAAS,OAAO;AACd,QAAAA,SAAO,MAAM,kCAAkC,KAAK;AACpD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,YAAY,GAAG,OAAO,SAAwB,WAAmC;AAC1F,UAAI;AACF,QAAAD,SAAO,KAAK,8CAA8C;AAAA,UACxD,QAAQ,OAAO;AAAA,UACf,WAAW,CAAC,CAAC,OAAO;AAAA,UACpB,aAAa,OAAO;AAAA,QACtB,CAAC;AAGD,YAAI,aAAa,OAAO;AACxB,YAAI,CAAC,WAAW,SAAS,SAAS,KAAK,CAAC,WAAW,SAAS,yBAAyB,GAAG;AACtF,wBACE;AAAA,QACJ;AAEA,cAAM,cAAc,eAAe,mBAAmB;AAGtD,YAAI;AACJ,YAAI,YAAY,WAAW,SAAS;AAClC,yBAAe,MAAM,eAAe,yBAAyB;AAAA,YAC3D,QAAQ;AAAA,YACR,eAAe,OAAO;AAAA,YACtB;AAAA,YACA,WAAWC,WAAU;AAAA,UACvB,CAAC;AAAA,QACH,OAAO;AACL,yBAAe,MAAM,eAAe,aAAa;AAAA,YAC/C,QAAQ;AAAA,YACR,eAAe,OAAO;AAAA,YACtB;AAAA,YACA,WAAWA,WAAU;AAAA,UACvB,CAAC;AAAA,QACH;AAGA,YAAI;AAEF,gBAAM,cAAc,CAAC,SAAyB;AAE5C,kBAAM,iBAAiB;AACvB,kBAAM,QAAQ,KAAK,MAAM,cAAc;AAEvC,gBAAI,SAAS,MAAM,CAAC,GAAG;AACrB,qBAAO,MAAM,CAAC,EAAE,KAAK;AAAA,YACvB;AAIA,kBAAM,mBAAmB;AACzB,kBAAM,eAAe,KAAK,MAAM,gBAAgB;AAEhD,gBAAI,gBAAgB,aAAa,CAAC,GAAG;AACnC,qBAAO,aAAa,CAAC,EAAE,KAAK;AAAA,YAC9B;AAGA,mBAAO,KAAK,KAAK;AAAA,UACnB;AAGA,gBAAM,cAAc,CAAC,aAA6B;AAEhD,mBACE,SAEG,QAAQ,uBAAuB,IAAI,EACnC,QAAQ,qBAAqB,IAAI,EACjC,QAAQ,0BAA0B,IAAI;AAAA,UAE7C;AAEA,gBAAM,oBAAoB,YAAY,YAAY;AAClD,gBAAM,kBAAkB,YAAY,iBAAiB;AACrD,UAAAD,SAAO,MAAM,wBAAwB,eAAe;AAEpD,cAAI;AACJ,cAAI;AACF,yBAAa,KAAK,MAAM,eAAe;AAAA,UACzC,SAAS,YAAY;AAEnB,YAAAA,SAAO,MAAM,4DAA4D;AAGzE,kBAAM,YAAY,gBACf,QAAQ,+BAA+B,aAAa,EAEpD,QAAQ,yDAAyD,QAAQ,EAEzE,QAAQ,qBAAqB,WAAW,EAExC,QAAQ,gBAAgB,IAAI;AAE/B,gBAAI;AACF,2BAAa,KAAK,MAAM,SAAS;AAAA,YACnC,SAAS,YAAY;AACnB,cAAAA,SAAO,MAAM,sCAAsC,UAAU;AAC7D,oBAAM,IAAI,MAAM,kCAAkC;AAAA,YACpD;AAAA,UACF;AAGA,cAAI,OAAO,QAAQ;AACjB,gBAAI;AAEF,yBAAW,OAAO,OAAO,KAAK,OAAO,MAAM,GAAG;AAC5C,oBAAI,EAAE,OAAO,aAAa;AACxB,6BAAW,GAAG,IAAI;AAAA,gBACpB;AAAA,cACF;AAAA,YACF,SAAS,aAAa;AACpB,cAAAA,SAAO,MAAM,6BAA6B,WAAW;AAAA,YACvD;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,SAAS,YAAY;AACnB,UAAAA,SAAO,MAAM,yBAAyB,UAAU;AAChD,UAAAA,SAAO,MAAM,iBAAiB,YAAY;AAC1C,gBAAM,IAAI,MAAM,kCAAkC;AAAA,QACpD;AAAA,MACF,SAAS,OAAO;AACd,QAAAA,SAAO,MAAM,kCAAkC,KAAK;AACpD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,qBAAqB,GAAG,OACjC,UACA,EAAE,KAAK,MACJ;AACH,UAAI;AACF,cAAM,UAAU,eAAe,oBAAoB;AACnD,cAAM,SAAS,eAAe,qBAAqB;AACnD,eAAO,MAAM,QAAQ,OAAO,MAAM,MAAM;AAAA,MAC1C,SAAS,OAAO;AACd,QAAAD,SAAO,MAAM,2CAA2C,KAAK;AAC7D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,qBAAqB,GAAG,OACjC,UACA,EAAE,OAAO,MACN;AACH,UAAI;AACF,cAAM,UAAU,eAAe,oBAAoB;AACnD,cAAM,SAAS,eAAe,qBAAqB;AACnD,eAAO,MAAM,QAAQ,OAAO,QAAQ,MAAM;AAAA,MAC5C,SAAS,OAAO;AACd,QAAAD,SAAO,MAAM,2CAA2C,KAAK;AAC7D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,iBAAiB,GAAG,OAAO,UAAyB,aAAqB;AAClF,UAAI;AACF,QAAAD,SAAO,KAAK,8BAA8B,QAAQ;AAGlD,cAAM,WAAW,MAAM,MAAM,QAAQ;AACrC,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,0BAA0B,SAAS,UAAU,EAAE;AAAA,QACjE;AAEA,cAAM,SAAS,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC;AACvD,cAAM,WAAW,SAAS,QAAQ,IAAI,cAAc,KAAK;AAEzD,eAAO,MAAM,eAAe,cAAc,QAAQ,QAAQ;AAAA,MAC5D,SAAS,OAAO;AACd,QAAAA,SAAO,MAAM,uCAAuC;AAAA,UAClD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D;AAAA,QACF,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,aAAa,GAAG,OAAO,UAAyB,gBAAwB;AACjF,UAAI;AACF,QAAAD,SAAO,KAAK,mCAAmC;AAAA,UAC7C,YAAY,YAAY;AAAA,QAC1B,CAAC;AAED,eAAO,MAAM,eAAe,gBAAgB,WAAW;AAAA,MACzD,SAAS,OAAO;AACd,QAAAA,SAAO,MAAM,mCAAmC;AAAA,UAC9C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,YAAY,YAAY;AAAA,QAC1B,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,CAACC,WAAU,cAAc,GAAG,OAAO,UAAyB,SAAiB;AAC3E,UAAI;AACF,eAAO,MAAM,eAAe,eAAe,IAAI;AAAA,MACjD,SAAS,OAAO;AACd,QAAAD,SAAO,MAAM,oCAAoC;AAAA,UAC/C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,YAAY,KAAK;AAAA,QACnB,CAAC;AACD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,8BAA8B;AAG1C,oBAAM,SAAS,MAAM,QAAQ,SAASC,WAAU,YAAY;AAAA,gBAC1D,QACE;AAAA,gBACF,eAAe,CAAC;AAAA,cAClB,CAAC;AAED,cAAAD,SAAO,KAAK,mBAAmB,MAAM;AAErC,kBAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,sBAAM,IAAI,MAAM,6BAA6B;AAAA,cAC/C;AAEA,kBAAI,CAAC,OAAO,SAAS,YAAY,GAAG;AAClC,sBAAM,IAAI,MAAM,0CAA0C;AAAA,cAC5D;AAEA,cAAAA,SAAO,QAAQ,4CAA4C;AAAA,YAC7D,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,+BAA+B;AAAA,gBAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,gCAAgC;AAE5C,oBAAM,SAAS,MAAM,QAAQ,SAASC,WAAU,YAAY;AAAA,gBAC1D,QACE;AAAA,gBACF,eAAe,CAAC;AAAA,cAClB,CAAC;AAED,cAAAD,SAAO,KAAK,yBAAyB,MAAM;AAE3C,kBAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,sBAAM,IAAI,MAAM,mCAAmC;AAAA,cACrD;AAEA,kBAAI,OAAO,SAAS,IAAI;AACtB,sBAAM,IAAI,MAAM,4CAA4C;AAAA,cAC9D;AAEA,cAAAA,SAAO,QAAQ,wCAAwC;AAAA,YACzD,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,2BAA2B;AAAA,gBACtC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,8BAA8B;AAG1C,oBAAM,YAAY,MAAM,QAAQ,SAASC,WAAU,gBAAgB;AAAA,gBACjE,MAAM;AAAA,cACR,CAAC;AAED,cAAAD,SAAO,KAAK,wCAAwC,UAAU,MAAM;AAEpE,kBAAI,CAAC,MAAM,QAAQ,SAAS,GAAG;AAC7B,sBAAM,IAAI,MAAM,2BAA2B;AAAA,cAC7C;AAEA,kBAAI,UAAU,WAAW,GAAG;AAC1B,sBAAM,IAAI,MAAM,0BAA0B;AAAA,cAC5C;AAEA,kBAAI,UAAU,KAAK,CAAC,QAAQ,OAAO,QAAQ,QAAQ,GAAG;AACpD,sBAAM,IAAI,MAAM,uCAAuC;AAAA,cACzD;AAGA,oBAAM,gBAAgB,MAAM,QAAQ,SAASC,WAAU,gBAAgB,IAAI;AAC3E,kBAAI,CAAC,MAAM,QAAQ,aAAa,KAAK,cAAc,KAAK,CAAC,QAAQ,QAAQ,CAAC,GAAG;AAC3E,sBAAM,IAAI,MAAM,uCAAuC;AAAA,cACzD;AAEA,cAAAD,SAAO,QAAQ,4CAA4C;AAAA,YAC7D,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,+BAA+B;AAAA,gBAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,qCAAqC;AACjD,oBAAM,OAAO;AAEb,oBAAM,SAAS,MAAM,QAAQ,SAASC,WAAU,uBAAuB,EAAE,KAAK,CAAC;AAC/E,cAAAD,SAAO,KAAK,mBAAmB,EAAE,OAAO,OAAO,OAAO,CAAC;AAEvD,kBAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,sBAAM,IAAI,MAAM,+BAA+B;AAAA,cACjD;AAEA,kBAAI,OAAO,WAAW,GAAG;AACvB,sBAAM,IAAI,MAAM,qBAAqB;AAAA,cACvC;AAEA,kBAAI,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,UAAU,KAAK,CAAC,GAAG;AACpD,sBAAM,IAAI,MAAM,mCAAmC;AAAA,cACrD;AAEA,cAAAA,SAAO,QAAQ,mDAAmD;AAAA,YACpE,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,sCAAsC;AAAA,gBACjD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,qCAAqC;AAGjD,oBAAM,eAAe;AACrB,oBAAM,SAAS,MAAM,QAAQ,SAASC,WAAU,uBAAuB;AAAA,gBACrE,MAAM;AAAA,cACR,CAAC;AAGD,oBAAM,cAAc,MAAM,QAAQ,SAASA,WAAU,uBAAuB;AAAA,gBAC1E;AAAA,cACF,CAAC;AACD,cAAAD,SAAO,KAAK,4BAA4B;AAAA,gBACtC,UAAU;AAAA,gBACV,SAAS;AAAA,cACX,CAAC;AAED,kBAAI,OAAO,gBAAgB,UAAU;AACnC,sBAAM,IAAI,MAAM,gCAAgC;AAAA,cAClD;AAEA,cAAAA,SAAO,QAAQ,mDAAmD;AAAA,YACpE,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,sCAAsC;AAAA,gBACjD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,iCAAiC;AAE7C,oBAAM,WACJ;AACF,oBAAM,SAAS,MAAM,QAAQ,SAASC,WAAU,mBAAmB,QAAQ;AAE3E,cAAAD,SAAO,KAAK,6BAA6B,MAAM;AAE/C,kBAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,sBAAM,IAAI,MAAM,yBAAyB;AAAA,cAC3C;AAEA,kBAAI,CAAC,OAAO,SAAS,CAAC,OAAO,aAAa;AACxC,sBAAM,IAAI,MAAM,0CAA0C;AAAA,cAC5D;AAEA,kBAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,gBAAgB,UAAU;AAC9E,sBAAM,IAAI,MAAM,sCAAsC;AAAA,cACxD;AAEA,cAAAA,SAAO,QAAQ,+CAA+C;AAAA,YAChE,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,kCAAkC;AAAA,gBAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,6BAA6B;AAGzC,oBAAM,YAAY,IAAI,WAAW;AAAA,gBAC/B;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,cACF,CAAC;AACD,oBAAM,cAAc,OAAO,KAAK,SAAS;AAEzC,oBAAM,gBAAgB,MAAM,QAAQ,SAASC,WAAU,eAAe,WAAW;AACjF,cAAAD,SAAO,KAAK,yBAAyB,aAAa;AAElD,kBAAI,OAAO,kBAAkB,UAAU;AACrC,sBAAM,IAAI,MAAM,sCAAsC;AAAA,cACxD;AAEA,cAAAA,SAAO,QAAQ,2CAA2C;AAAA,YAC5D,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,8BAA8B;AAAA,gBACzC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAAY;AACrB,gBAAI;AACF,cAAAA,SAAO,KAAK,8BAA8B;AAE1C,oBAAM,WAAW;AACjB,oBAAM,cAAc,MAAM,QAAQ,SAASC,WAAU,gBAAgB,QAAQ;AAE7E,kBAAI,EAAE,uBAAuBE,YAAW;AACtC,sBAAM,IAAI,MAAM,qCAAqC;AAAA,cACvD;AAGA,kBAAI,eAAe;AACnB,0BAAY,GAAG,QAAQ,MAAM;AAC3B,+BAAe;AAAA,cACjB,CAAC;AAED,oBAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,4BAAY,GAAG,OAAO,MAAM;AAC1B,sBAAI,CAAC,cAAc;AACjB,2BAAO,IAAI,MAAM,oCAAoC,CAAC;AAAA,kBACxD,OAAO;AACL,4BAAQ,IAAI;AAAA,kBACd;AAAA,gBACF,CAAC;AACD,4BAAY,GAAG,SAAS,MAAM;AAAA,cAChC,CAAC;AAED,cAAAH,SAAO,QAAQ,4CAA4C;AAAA,YAC7D,SAAS,OAAO;AACd,cAAAA,SAAO,MAAM,+BAA+B;AAAA,gBAC1C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,gBAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,cAChD,CAAC;AACD,oBAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","names":["fs","path","Readable","ModelType","logger","getLlama","logger","logger","logger","ModelType","logger","logger","fs","exec","fs","path","promisify","logger","execAsync","fs","path","logger","path","logger","fs","pcmData","fs","os","path","process","logger","AutoTokenizer","path","logger","os","process","fs","AutoTokenizer","mimeType","buffer","path","fs","logger","ModelType","getLlama","Readable"]}
|