cactus-ai-sdk-provider
Version:
Cactus provider for Vercel AI SDK - enables on-device LLM inference in React Native
1 lines • 22.7 kB
Source Map (JSON)
{"version":3,"sources":["../index.ts","../provider.ts","../cactus-chat-language-model.ts","../model-manager.ts"],"sourcesContent":["// Main provider exports\nexport { cactus, createCactus } from './provider';\nexport type { \n CactusProvider, \n CactusProviderSettings,\n CactusChatSettings \n} from './provider';\n\n// Language model exports\nexport { CactusChatLanguageModel, ModelStatus } from './cactus-chat-language-model';\nexport type { CactusChatLanguageModelConfig } from './cactus-chat-language-model';\n\n// Model management exports\nexport { ModelManager } from './model-manager';\nexport type { ModelEntry, DownloadOptions } from './model-manager';\n\n// Re-export relevant types from AI SDK for convenience\nexport type { \n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2Prompt,\n LanguageModelV2Message,\n LanguageModelV2Usage,\n LanguageModelV2FinishReason \n} from '@ai-sdk/provider';","import { generateId } from '@ai-sdk/provider-utils';\nimport { ProviderV2 } from '@ai-sdk/provider';\nimport { CactusChatLanguageModel } from './cactus-chat-language-model';\n\nexport interface CactusChatSettings {}\n\nexport interface CactusProvider extends ProviderV2 {\n (modelUrl: string, settings?: CactusChatSettings): CactusChatLanguageModel;\n\n languageModel(\n modelUrl: string,\n settings?: CactusChatSettings,\n ): CactusChatLanguageModel;\n}\n\nexport interface CactusProviderSettings {\n model?: any;\n generateId?: () => string;\n}\n\nexport function createCactus(\n options: CactusProviderSettings = {},\n): CactusProvider {\n const createChatModel = (\n modelUrl: string,\n settings: CactusChatSettings = {},\n ) =>\n new CactusChatLanguageModel(modelUrl, settings, {\n provider: 'cactus',\n generateId: options.generateId ?? generateId,\n });\n\n const provider = function (modelUrl: string, settings?: CactusChatSettings) {\n if (new.target) {\n throw new Error(\n 'The model factory function cannot be called with the new keyword.',\n );\n }\n\n return createChatModel(modelUrl, settings);\n };\n\n provider.languageModel = createChatModel;\n\n return provider as CactusProvider;\n}\n\nexport const cactus = createCactus();","import {\n LanguageModelV2,\n LanguageModelV2CallOptions,\n LanguageModelV2Content,\n LanguageModelV2FinishReason,\n LanguageModelV2StreamPart,\n LanguageModelV2Usage,\n LanguageModelV2CallWarning,\n LanguageModelV2Prompt,\n LanguageModelV2TextPart,\n LanguageModelV2ResponseMetadata,\n SharedV2Headers,\n} from '@ai-sdk/provider';\nimport { CactusChatSettings } from './provider';\nimport {\n CactusLM,\n CompletionParams,\n NativeCompletionResult,\n CactusOAICompatibleMessage,\n} from 'cactus-react-native';\nimport { ModelManager, DownloadOptions } from './model-manager';\n\nexport enum ModelStatus {\n IDLE,\n DOWNLOADING,\n INITIALIZING,\n READY,\n ERROR,\n}\n\nexport interface CactusChatLanguageModelConfig {\n provider: string;\n generateId?: () => string;\n}\n\nexport class CactusChatLanguageModel implements LanguageModelV2 {\n readonly specificationVersion = 'v2';\n readonly provider: string;\n readonly modelId: string;\n readonly modelUrl: string;\n\n private lm: CactusLM | null = null;\n private status: ModelStatus = ModelStatus.IDLE;\n private lastError: Error | null = null;\n private modelManager = new ModelManager();\n\n constructor(\n modelUrlOrPath: string,\n private readonly settings: CactusChatSettings,\n private readonly config: CactusChatLanguageModelConfig,\n ) {\n this.modelUrl = modelUrlOrPath;\n \n // Support both URLs and direct paths\n try {\n this.modelId = this.modelManager.getModelPath(modelUrlOrPath);\n } catch {\n // If model manager can't handle it (no RNFS), use as-is\n this.modelId = modelUrlOrPath;\n }\n \n this.provider = config.provider; // 'cactus'\n }\n\n public getStatus(): ModelStatus {\n return this.status;\n }\n\n public getLastError(): Error | null {\n return this.lastError; // useful for debugging when this.status is ModelStatus.ERROR\n }\n\n /**\n * List all downloaded models\n */\n async listDownloadedModels() {\n return this.modelManager.listModels();\n }\n\n /**\n * Get storage info for all downloaded models\n */\n async getStorageInfo() {\n return this.modelManager.getStorageInfo();\n }\n\n /**\n * Download the model if it's a URL\n */\n async downloadModel(options: DownloadOptions = {}): Promise<string> {\n this.status = ModelStatus.DOWNLOADING;\n\n try {\n const localPath = await this.modelManager.downloadModel(this.modelUrl, options);\n this.status = ModelStatus.IDLE;\n return localPath;\n } catch (e) {\n this.lastError = e as Error;\n this.status = ModelStatus.ERROR;\n throw e;\n }\n }\n\n /**\n * Delete the downloaded model\n */\n async deleteModel(): Promise<void> {\n await this.modelManager.deleteModel(this.modelUrl);\n this.status = ModelStatus.IDLE;\n }\n\n async initialize(): Promise<void> {\n if (this.status === ModelStatus.READY) return;\n \n // Check if model is downloaded (for URLs)\n const isDownloaded = await this.modelManager.isDownloaded(this.modelUrl);\n if (!isDownloaded) {\n throw new Error('Model not downloaded. Call downloadModel() first.');\n }\n\n this.status = ModelStatus.INITIALIZING;\n try {\n const { lm, error } = await CactusLM.init({ model: this.modelId });\n if (error) throw error;\n this.lm = lm;\n this.status = ModelStatus.READY;\n } catch (e) {\n this.lastError = e as Error;\n this.status = ModelStatus.ERROR;\n throw e;\n }\n }\n\n private assertIsReady(): void {\n if (this.status !== ModelStatus.READY || !this.lm) {\n throw new Error(\n `Model not ready. Status: ${\n ModelStatus[this.status]\n }. Error: ${this.lastError?.message}`,\n );\n }\n }\n\n private convertToCactusMessages(\n prompt: LanguageModelV2Prompt,\n ): CactusOAICompatibleMessage[] {\n return prompt.map(message => {\n if (message.role === 'system') {\n return { role: 'system', content: message.content };\n }\n const content = message.content\n .filter(part => part.type === 'text')\n .map(part => (part as LanguageModelV2TextPart).text)\n .join('');\n return { role: message.role, content };\n });\n }\n\n private getCactusParams(\n options: LanguageModelV2CallOptions,\n ): CompletionParams {\n const params: CompletionParams = {};\n if (options.temperature != null) params.temperature = options.temperature;\n if (options.maxOutputTokens != null) params.n_predict = options.maxOutputTokens;\n if (options.stopSequences != null) params.stop = options.stopSequences;\n return params;\n }\n\n get supportedUrls(): Record<string, RegExp[]> {return {}} // cactus is on-device only\n\n async doGenerate(\n options: LanguageModelV2CallOptions,\n ): Promise<{\n content: Array<LanguageModelV2Content>;\n finishReason: LanguageModelV2FinishReason;\n usage: LanguageModelV2Usage;\n warnings: Array<LanguageModelV2CallWarning>;\n request?: { body?: unknown };\n response?: LanguageModelV2ResponseMetadata & {\n headers?: SharedV2Headers;\n body?: unknown;\n };\n }> {\n this.assertIsReady();\n const messages = this.convertToCactusMessages(options.prompt);\n const params = this.getCactusParams(options);\n const result: NativeCompletionResult = await this.lm!.completion(\n messages,\n params,\n );\n return {\n content: [{ type: 'text', text: result.content }],\n finishReason: 'stop' as const,\n usage: {\n inputTokens: result.tokens_evaluated,\n outputTokens: result.tokens_predicted,\n totalTokens: result.tokens_evaluated + result.tokens_predicted,\n },\n warnings: [],\n };\n }\n\n async doStream(\n options: LanguageModelV2CallOptions,\n ): Promise<{\n stream: ReadableStream<LanguageModelV2StreamPart>;\n warnings: Array<LanguageModelV2CallWarning>;\n request?: { body?: unknown };\n response?: {\n headers?: SharedV2Headers;\n };\n }> {\n this.assertIsReady();\n const messages = this.convertToCactusMessages(options.prompt);\n const params = this.getCactusParams(options);\n\n const stream = new ReadableStream<LanguageModelV2StreamPart>({\n start: async (controller) => {\n controller.enqueue({ type: 'stream-start', warnings: [] });\n try {\n const result = await this.lm!.completion(messages, params, data => {\n controller.enqueue({ type: 'text-delta', id: 'text', delta: data.token });\n });\n controller.enqueue({\n type: 'finish',\n finishReason: 'stop',\n usage: {\n inputTokens: result.tokens_evaluated,\n outputTokens: result.tokens_predicted,\n totalTokens:\n result.tokens_evaluated + result.tokens_predicted,\n },\n });\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return { stream, warnings: [] };\n }\n} ","export interface ModelEntry {\n url: string;\n localPath: string;\n status: 'pending' | 'ready' | 'error';\n}\n\nexport interface DownloadOptions {\n onProgress?: (progress: number) => void;\n}\n\nexport class ModelManager {\n private rnfs: any = null;\n private cache = new Map<string, ModelEntry>();\n \n constructor() {\n // Try to load RNFS, but don't fail if missing\n try {\n this.rnfs = require('react-native-fs');\n } catch (e) {\n // RNFS not available - basic mode only\n }\n }\n \n /**\n * Check if RNFS is available for model management features\n */\n get isRNFSAvailable(): boolean {\n return this.rnfs !== null;\n }\n \n /**\n * Get the local file path for a model URL\n * @throws Error if RNFS is not available\n */\n getModelPath(urlOrPath: string): string {\n // If it's already a local path, return as-is\n if (!urlOrPath.startsWith('http://') && !urlOrPath.startsWith('https://')) {\n return urlOrPath;\n }\n \n if (!this.rnfs) {\n throw new Error(\n 'react-native-fs is required for automatic model paths. ' +\n 'Please install it or provide a direct file path instead of a URL.'\n );\n }\n \n const filename = urlOrPath.split('/').pop()?.replace(/[^a-zA-Z0-9.-]/g, '_') || 'model.gguf';\n return `${this.rnfs.DocumentDirectoryPath}/cactus-models/${filename}`;\n }\n \n /**\n * Download a model from a URL\n * @throws Error if RNFS is not available\n */\n async downloadModel(url: string, options?: DownloadOptions): Promise<string> {\n if (!this.rnfs) {\n throw new Error(\n 'react-native-fs is required for model downloads. ' +\n 'Please install it with: npm install react-native-fs'\n );\n }\n \n const localPath = this.getModelPath(url);\n const modelDir = `${this.rnfs.DocumentDirectoryPath}/cactus-models`;\n \n // Ensure directory exists\n if (!(await this.rnfs.exists(modelDir))) {\n await this.rnfs.mkdir(modelDir);\n }\n \n // Check if already downloaded\n if (await this.rnfs.exists(localPath)) {\n // Update cache and return\n this.cache.set(url, { url, localPath, status: 'ready' });\n return localPath;\n }\n \n // Update cache status\n this.cache.set(url, { url, localPath, status: 'pending' });\n \n try {\n // Download with progress callback\n await this.rnfs.downloadFile({\n fromUrl: url,\n toFile: localPath,\n progress: (res: { bytesWritten: number; contentLength: number }) => {\n if (options?.onProgress) {\n options.onProgress(res.bytesWritten / res.contentLength);\n }\n }\n }).promise;\n \n // Update cache status\n this.cache.set(url, { url, localPath, status: 'ready' });\n return localPath;\n } catch (error) {\n // Update cache status and cleanup\n this.cache.set(url, { url, localPath, status: 'error' });\n \n // Try to delete partial file\n try {\n if (await this.rnfs.exists(localPath)) {\n await this.rnfs.unlink(localPath);\n }\n } catch {\n // Ignore cleanup errors\n }\n \n throw error;\n }\n }\n \n /**\n * Check if a model is downloaded\n */\n async isDownloaded(urlOrPath: string): Promise<boolean> {\n // If it's a local path, assume it exists (will be checked during init)\n if (!urlOrPath.startsWith('http://') && !urlOrPath.startsWith('https://')) {\n return true;\n }\n \n // Check cache first\n const cached = this.cache.get(urlOrPath);\n if (cached?.status === 'ready') {\n return true;\n }\n \n // Need RNFS to check filesystem\n if (!this.rnfs) {\n return false;\n }\n \n try {\n const localPath = this.getModelPath(urlOrPath);\n const exists = await this.rnfs.exists(localPath);\n \n // Update cache if file exists\n if (exists) {\n this.cache.set(urlOrPath, { url: urlOrPath, localPath, status: 'ready' });\n }\n \n return exists;\n } catch {\n return false;\n }\n }\n \n /**\n * Delete a downloaded model\n */\n async deleteModel(urlOrPath: string): Promise<void> {\n if (!this.rnfs) {\n throw new Error('react-native-fs is required to delete models');\n }\n \n const localPath = this.getModelPath(urlOrPath);\n \n if (await this.rnfs.exists(localPath)) {\n await this.rnfs.unlink(localPath);\n }\n \n // Remove from cache\n this.cache.delete(urlOrPath);\n }\n \n /**\n * List all downloaded models\n */\n async listModels(): Promise<ModelEntry[]> {\n if (!this.rnfs) {\n // Return only cached entries\n return Array.from(this.cache.values());\n }\n \n const modelDir = `${this.rnfs.DocumentDirectoryPath}/cactus-models`;\n \n try {\n if (!(await this.rnfs.exists(modelDir))) {\n return [];\n }\n \n const files = await this.rnfs.readDir(modelDir);\n const models: ModelEntry[] = [];\n \n for (const file of files) {\n if (file.isFile() && file.name.endsWith('.gguf')) {\n // Try to find in cache by path\n let found = false;\n for (const [url, entry] of this.cache.entries()) {\n if (entry.localPath === file.path) {\n models.push(entry);\n found = true;\n break;\n }\n }\n \n // If not in cache, create basic entry\n if (!found) {\n models.push({\n url: file.path,\n localPath: file.path,\n status: 'ready'\n });\n }\n }\n }\n \n return models;\n } catch {\n return [];\n }\n }\n \n /**\n * Get storage info for all models\n */\n async getStorageInfo(): Promise<{ totalSize: number; modelCount: number }> {\n if (!this.rnfs) {\n return { totalSize: 0, modelCount: 0 };\n }\n \n const models = await this.listModels();\n let totalSize = 0;\n \n for (const model of models) {\n try {\n const stat = await this.rnfs.stat(model.localPath);\n totalSize += stat.size;\n } catch {\n // Ignore stat errors\n }\n }\n \n return {\n totalSize,\n modelCount: models.length\n };\n }\n}"],"mappings":"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","names":["ModelStatus"]}