@capgo/capacitor-llm 8.0.19 → 8.1.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/CapgoCapacitorLlm.podspec +1 -9
- package/Package.swift +21 -3
- package/README.md +137 -163
- package/android/build.gradle +3 -2
- package/android/src/main/java/ee/forgr/capgo_llm/LLM.java +605 -283
- package/android/src/main/java/ee/forgr/capgo_llm/LLMPlugin.java +36 -63
- package/dist/docs.json +66 -35
- package/dist/esm/definitions.d.ts +28 -20
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +6 -0
- package/dist/esm/web.js +68 -39
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +68 -39
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +68 -39
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/LLMPlugin/LLMPlugin.swift +384 -613
- package/ios/Sources/LiteRTLM/Benchmark.swift +83 -0
- package/ios/Sources/LiteRTLM/Capabilities.swift +41 -0
- package/ios/Sources/LiteRTLM/Config.swift +172 -0
- package/ios/Sources/LiteRTLM/Conversation.swift +472 -0
- package/ios/Sources/LiteRTLM/Engine.swift +208 -0
- package/ios/Sources/LiteRTLM/ExperimentalFlags.swift +142 -0
- package/ios/Sources/LiteRTLM/LiteRTLMError.swift +156 -0
- package/ios/Sources/LiteRTLM/Message.swift +225 -0
- package/ios/Sources/LiteRTLM/Tool.swift +291 -0
- package/ios/Sources/LiteRTLM/ToolManager.swift +152 -0
- package/package.json +6 -5
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\n\nimport type {\n LLMPlugin,\n DownloadModelOptions,\n DownloadModelResult,\n ModelOptions,\n TextFromAiEvent,\n AiFinishedEvent,\n DownloadProgressEvent,\n ReadinessChangeEvent,\n} from './definitions';\n\ninterface ChatSession {\n id: string;\n llm: any;\n isActive: boolean;\n}\n\nexport class CapgoLLMWeb extends WebPlugin implements LLMPlugin {\n private llm: any = null;\n private chatSessions: Map<string, ChatSession> = new Map();\n private readiness = 'not-loaded';\n\n async getReadiness(): Promise<{ readiness: string }> {\n return { readiness: this.readiness };\n }\n\n async createChat(): Promise<{ id: string; instructions?: string }> {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n });\n\n return { id: chatId };\n }\n\n async sendMessage(options: { chatId: string; message: string }): Promise<void> {\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n\n try {\n // Generate response using MediaPipe GenAI streaming API\n const response = session.llm.generateResponseStream(options.message);\n\n for await (const partialResponse of response) {\n // Send incremental text\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n } as TextFromAiEvent);\n }\n\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n } as AiFinishedEvent);\n } catch (error) {\n console.error('Error generating response:', error);\n throw error;\n }\n }\n\n async setModel(options: ModelOptions): Promise<void> {\n const engine = options.engine ?? 'auto';\n const normalizedPath = options.path.toLowerCase();\n const wantsApple = engine === 'apple' || (engine === 'auto' && normalizedPath === 'apple intelligence');\n const wantsExecuTorch =\n engine === 'executorch' || (engine === 'auto' && (options.tokenizerPath || normalizedPath.endsWith('.pte')));\n\n if (wantsApple) {\n throw new Error('Apple Intelligence is only available on native iOS.');\n }\n\n if (wantsExecuTorch) {\n throw new Error('ExecuTorch is only available on native iOS and Android.');\n }\n\n try {\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n\n // Create LLM configuration\n const config: any = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n\n const genai = await FilesetResolver.forGenAiTasks(\n 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm',\n );\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n } catch (error) {\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n throw error;\n }\n }\n\n async downloadModel(options: DownloadModelOptions): Promise<DownloadModelResult> {\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n\n // Read the response with progress\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n\n const chunks: Uint8Array[] = [];\n let downloadedBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n } as DownloadProgressEvent);\n }\n\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result: DownloadModelResult = {\n path: options.url,\n };\n\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n\n return result;\n } catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\n\nimport type {\n LLMPlugin,\n DownloadModelOptions,\n DownloadModelResult,\n ModelOptions,\n TextFromAiEvent,\n AiFinishedEvent,\n GenerationErrorEvent,\n DownloadProgressEvent,\n ReadinessChangeEvent,\n} from './definitions';\n\ninterface ChatTurn {\n role: 'user' | 'model';\n content: string;\n}\n\ninterface ChatSession {\n id: string;\n llm: LlmInference;\n isActive: boolean;\n modelPath: string;\n modelType: string;\n history: ChatTurn[];\n}\n\nexport class CapgoLLMWeb extends WebPlugin implements LLMPlugin {\n private llm: LlmInference | null = null;\n private chatSessions: Map<string, ChatSession> = new Map();\n private readiness = 'not-loaded';\n private modelPath = '';\n private modelType = 'task';\n\n async getReadiness(): Promise<{ readiness: string }> {\n return { readiness: this.readiness };\n }\n\n async createChat(): Promise<{ id: string; instructions?: string }> {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n modelPath: this.modelPath,\n modelType: this.modelType,\n history: [],\n });\n\n return { id: chatId };\n }\n\n async sendMessage(options: { chatId: string; message: string }): Promise<void> {\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n\n let hasStreamed = false;\n let responseText = '';\n\n try {\n const prompt = this.buildPrompt(session, options.message);\n\n const finalResponse = await session.llm.generateResponse(prompt, (partialResponse, done) => {\n if (done || !partialResponse) {\n return;\n }\n\n hasStreamed = true;\n responseText += partialResponse;\n\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n } as TextFromAiEvent);\n });\n\n if (!hasStreamed && finalResponse) {\n responseText = finalResponse;\n this.notifyListeners('textFromAi', {\n text: finalResponse,\n chatId: options.chatId,\n isChunk: true,\n } as TextFromAiEvent);\n }\n\n session.history.push(\n { role: 'user', content: options.message },\n { role: 'model', content: responseText || finalResponse },\n );\n\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n } as AiFinishedEvent);\n } catch (error) {\n console.error('Error generating response:', error);\n const message = error instanceof Error ? error.message : String(error);\n if (hasStreamed) {\n this.notifyListeners('generationError', {\n chatId: options.chatId,\n error: message,\n } as GenerationErrorEvent);\n return;\n }\n\n throw error;\n }\n }\n\n async setModel(options: ModelOptions): Promise<void> {\n try {\n this.closeCurrentModel();\n\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n\n // Create LLM configuration\n const config: any = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n\n const genai = await FilesetResolver.forGenAiTasks(\n 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm',\n );\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n this.modelPath = options.path;\n this.modelType = this.resolveModelType(options);\n this.chatSessions.clear();\n\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n } catch (error) {\n this.closeCurrentModel();\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness } as ReadinessChangeEvent);\n throw error;\n }\n }\n\n async downloadModel(options: DownloadModelOptions): Promise<DownloadModelResult> {\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n\n // Read the response with progress\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n\n const chunks: Uint8Array[] = [];\n let downloadedBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n } as DownloadProgressEvent);\n }\n\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result: DownloadModelResult = {\n path: options.url,\n };\n\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n\n return result;\n } catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n\n private closeCurrentModel(): void {\n this.chatSessions.clear();\n this.llm?.close();\n this.llm = null;\n this.modelPath = '';\n this.modelType = 'task';\n }\n\n private resolveModelType(options: ModelOptions): string {\n if (options.modelType?.trim()) {\n return options.modelType.trim().toLowerCase();\n }\n\n const extension = options.path.split('.').pop();\n return extension ? extension.toLowerCase() : 'task';\n }\n\n private buildPrompt(session: ChatSession, message: string): string {\n if (!this.usesGemmaChatTemplate(session)) {\n return message;\n }\n\n const history = [...session.history, { role: 'user' as const, content: message }];\n return `${history\n .map((turn) => `<start_of_turn>${turn.role}\\n${turn.content}<end_of_turn>`)\n .join('\\n')}\\n<start_of_turn>model\\n`;\n }\n\n private usesGemmaChatTemplate(session: ChatSession): boolean {\n return /gemma/i.test(session.modelPath) || session.modelType === 'litertlm';\n }\n}\n"]}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -7,19 +7,14 @@ const CapgoLLM = core.registerPlugin('CapgoLLM', {
|
|
|
7
7
|
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CapgoLLMWeb()),
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
var __asyncValues = (globalThis && globalThis.__asyncValues) || function (o) {
|
|
11
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
-
var m = o[Symbol.asyncIterator], i;
|
|
13
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
14
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
15
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
16
|
-
};
|
|
17
10
|
class CapgoLLMWeb extends core.WebPlugin {
|
|
18
11
|
constructor() {
|
|
19
12
|
super(...arguments);
|
|
20
13
|
this.llm = null;
|
|
21
14
|
this.chatSessions = new Map();
|
|
22
15
|
this.readiness = 'not-loaded';
|
|
16
|
+
this.modelPath = '';
|
|
17
|
+
this.modelType = 'task';
|
|
23
18
|
}
|
|
24
19
|
async getReadiness() {
|
|
25
20
|
return { readiness: this.readiness };
|
|
@@ -33,11 +28,13 @@ class CapgoLLMWeb extends core.WebPlugin {
|
|
|
33
28
|
id: chatId,
|
|
34
29
|
llm: this.llm,
|
|
35
30
|
isActive: true,
|
|
31
|
+
modelPath: this.modelPath,
|
|
32
|
+
modelType: this.modelType,
|
|
33
|
+
history: [],
|
|
36
34
|
});
|
|
37
35
|
return { id: chatId };
|
|
38
36
|
}
|
|
39
37
|
async sendMessage(options) {
|
|
40
|
-
var _a, e_1, _b, _c;
|
|
41
38
|
const session = this.chatSessions.get(options.chatId);
|
|
42
39
|
if (!session) {
|
|
43
40
|
throw new Error(`Chat session ${options.chatId} not found`);
|
|
@@ -45,29 +42,31 @@ class CapgoLLMWeb extends core.WebPlugin {
|
|
|
45
42
|
if (!session.isActive) {
|
|
46
43
|
throw new Error(`Chat session ${options.chatId} is not active`);
|
|
47
44
|
}
|
|
45
|
+
let hasStreamed = false;
|
|
46
|
+
let responseText = '';
|
|
48
47
|
try {
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
_c = response_1_1.value;
|
|
54
|
-
_d = false;
|
|
55
|
-
const partialResponse = _c;
|
|
56
|
-
// Send incremental text
|
|
57
|
-
this.notifyListeners('textFromAi', {
|
|
58
|
-
text: partialResponse,
|
|
59
|
-
chatId: options.chatId,
|
|
60
|
-
isChunk: true,
|
|
61
|
-
});
|
|
48
|
+
const prompt = this.buildPrompt(session, options.message);
|
|
49
|
+
const finalResponse = await session.llm.generateResponse(prompt, (partialResponse, done) => {
|
|
50
|
+
if (done || !partialResponse) {
|
|
51
|
+
return;
|
|
62
52
|
}
|
|
53
|
+
hasStreamed = true;
|
|
54
|
+
responseText += partialResponse;
|
|
55
|
+
this.notifyListeners('textFromAi', {
|
|
56
|
+
text: partialResponse,
|
|
57
|
+
chatId: options.chatId,
|
|
58
|
+
isChunk: true,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
if (!hasStreamed && finalResponse) {
|
|
62
|
+
responseText = finalResponse;
|
|
63
|
+
this.notifyListeners('textFromAi', {
|
|
64
|
+
text: finalResponse,
|
|
65
|
+
chatId: options.chatId,
|
|
66
|
+
isChunk: true,
|
|
67
|
+
});
|
|
63
68
|
}
|
|
64
|
-
|
|
65
|
-
finally {
|
|
66
|
-
try {
|
|
67
|
-
if (!_d && !_a && (_b = response_1.return)) await _b.call(response_1);
|
|
68
|
-
}
|
|
69
|
-
finally { if (e_1) throw e_1.error; }
|
|
70
|
-
}
|
|
69
|
+
session.history.push({ role: 'user', content: options.message }, { role: 'model', content: responseText || finalResponse });
|
|
71
70
|
// Notify completion
|
|
72
71
|
this.notifyListeners('aiFinished', {
|
|
73
72
|
chatId: options.chatId,
|
|
@@ -75,22 +74,20 @@ class CapgoLLMWeb extends core.WebPlugin {
|
|
|
75
74
|
}
|
|
76
75
|
catch (error) {
|
|
77
76
|
console.error('Error generating response:', error);
|
|
77
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
78
|
+
if (hasStreamed) {
|
|
79
|
+
this.notifyListeners('generationError', {
|
|
80
|
+
chatId: options.chatId,
|
|
81
|
+
error: message,
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
78
85
|
throw error;
|
|
79
86
|
}
|
|
80
87
|
}
|
|
81
88
|
async setModel(options) {
|
|
82
|
-
var _a;
|
|
83
|
-
const engine = (_a = options.engine) !== null && _a !== void 0 ? _a : 'auto';
|
|
84
|
-
const normalizedPath = options.path.toLowerCase();
|
|
85
|
-
const wantsApple = engine === 'apple' || (engine === 'auto' && normalizedPath === 'apple intelligence');
|
|
86
|
-
const wantsExecuTorch = engine === 'executorch' || (engine === 'auto' && (options.tokenizerPath || normalizedPath.endsWith('.pte')));
|
|
87
|
-
if (wantsApple) {
|
|
88
|
-
throw new Error('Apple Intelligence is only available on native iOS.');
|
|
89
|
-
}
|
|
90
|
-
if (wantsExecuTorch) {
|
|
91
|
-
throw new Error('ExecuTorch is only available on native iOS and Android.');
|
|
92
|
-
}
|
|
93
89
|
try {
|
|
90
|
+
this.closeCurrentModel();
|
|
94
91
|
// Update readiness
|
|
95
92
|
this.readiness = 'loading';
|
|
96
93
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
@@ -107,11 +104,15 @@ class CapgoLLMWeb extends core.WebPlugin {
|
|
|
107
104
|
const genai = await tasksGenai.FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');
|
|
108
105
|
// Create LLM instance
|
|
109
106
|
this.llm = await tasksGenai.LlmInference.createFromOptions(genai, config);
|
|
107
|
+
this.modelPath = options.path;
|
|
108
|
+
this.modelType = this.resolveModelType(options);
|
|
109
|
+
this.chatSessions.clear();
|
|
110
110
|
// Update readiness
|
|
111
111
|
this.readiness = 'ready';
|
|
112
112
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
113
113
|
}
|
|
114
114
|
catch (error) {
|
|
115
|
+
this.closeCurrentModel();
|
|
115
116
|
this.readiness = 'error';
|
|
116
117
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
117
118
|
throw error;
|
|
@@ -175,6 +176,34 @@ class CapgoLLMWeb extends core.WebPlugin {
|
|
|
175
176
|
async getPluginVersion() {
|
|
176
177
|
return { version: 'web' };
|
|
177
178
|
}
|
|
179
|
+
closeCurrentModel() {
|
|
180
|
+
var _a;
|
|
181
|
+
this.chatSessions.clear();
|
|
182
|
+
(_a = this.llm) === null || _a === void 0 ? void 0 : _a.close();
|
|
183
|
+
this.llm = null;
|
|
184
|
+
this.modelPath = '';
|
|
185
|
+
this.modelType = 'task';
|
|
186
|
+
}
|
|
187
|
+
resolveModelType(options) {
|
|
188
|
+
var _a;
|
|
189
|
+
if ((_a = options.modelType) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
190
|
+
return options.modelType.trim().toLowerCase();
|
|
191
|
+
}
|
|
192
|
+
const extension = options.path.split('.').pop();
|
|
193
|
+
return extension ? extension.toLowerCase() : 'task';
|
|
194
|
+
}
|
|
195
|
+
buildPrompt(session, message) {
|
|
196
|
+
if (!this.usesGemmaChatTemplate(session)) {
|
|
197
|
+
return message;
|
|
198
|
+
}
|
|
199
|
+
const history = [...session.history, { role: 'user', content: message }];
|
|
200
|
+
return `${history
|
|
201
|
+
.map((turn) => `<start_of_turn>${turn.role}\n${turn.content}<end_of_turn>`)
|
|
202
|
+
.join('\n')}\n<start_of_turn>model\n`;
|
|
203
|
+
}
|
|
204
|
+
usesGemmaChatTemplate(session) {
|
|
205
|
+
return /gemma/i.test(session.modelPath) || session.modelType === 'litertlm';
|
|
206
|
+
}
|
|
178
207
|
}
|
|
179
208
|
|
|
180
209
|
var web = /*#__PURE__*/Object.freeze({
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapgoLLM = registerPlugin('CapgoLLM', {\n web: () => import('./web').then((m) => new m.CapgoLLMWeb()),\n});\nexport * from './definitions';\nexport { CapgoLLM };\n//# sourceMappingURL=index.js.map","var __asyncValues = (this && this.__asyncValues) || function (o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nimport { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\nexport class CapgoLLMWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.llm = null;\n this.chatSessions = new Map();\n this.readiness = 'not-loaded';\n }\n async getReadiness() {\n return { readiness: this.readiness };\n }\n async createChat() {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n });\n return { id: chatId };\n }\n async sendMessage(options) {\n var _a, e_1, _b, _c;\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n try {\n // Generate response using MediaPipe GenAI streaming API\n const response = session.llm.generateResponseStream(options.message);\n try {\n for (var _d = true, response_1 = __asyncValues(response), response_1_1; response_1_1 = await response_1.next(), _a = response_1_1.done, !_a; _d = true) {\n _c = response_1_1.value;\n _d = false;\n const partialResponse = _c;\n // Send incremental text\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = response_1.return)) await _b.call(response_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n });\n }\n catch (error) {\n console.error('Error generating response:', error);\n throw error;\n }\n }\n async setModel(options) {\n var _a;\n const engine = (_a = options.engine) !== null && _a !== void 0 ? _a : 'auto';\n const normalizedPath = options.path.toLowerCase();\n const wantsApple = engine === 'apple' || (engine === 'auto' && normalizedPath === 'apple intelligence');\n const wantsExecuTorch = engine === 'executorch' || (engine === 'auto' && (options.tokenizerPath || normalizedPath.endsWith('.pte')));\n if (wantsApple) {\n throw new Error('Apple Intelligence is only available on native iOS.');\n }\n if (wantsExecuTorch) {\n throw new Error('ExecuTorch is only available on native iOS and Android.');\n }\n try {\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n // Create LLM configuration\n const config = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n const genai = await FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n }\n catch (error) {\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n throw error;\n }\n }\n async downloadModel(options) {\n var _a;\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n // Read the response with progress\n const reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n const chunks = [];\n let downloadedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n });\n }\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result = {\n path: options.url,\n };\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n return result;\n }\n catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin","FilesetResolver","LlmInference"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapgoLLM = registerPlugin('CapgoLLM', {\n web: () => import('./web').then((m) => new m.CapgoLLMWeb()),\n});\nexport * from './definitions';\nexport { CapgoLLM };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\nexport class CapgoLLMWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.llm = null;\n this.chatSessions = new Map();\n this.readiness = 'not-loaded';\n this.modelPath = '';\n this.modelType = 'task';\n }\n async getReadiness() {\n return { readiness: this.readiness };\n }\n async createChat() {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n modelPath: this.modelPath,\n modelType: this.modelType,\n history: [],\n });\n return { id: chatId };\n }\n async sendMessage(options) {\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n let hasStreamed = false;\n let responseText = '';\n try {\n const prompt = this.buildPrompt(session, options.message);\n const finalResponse = await session.llm.generateResponse(prompt, (partialResponse, done) => {\n if (done || !partialResponse) {\n return;\n }\n hasStreamed = true;\n responseText += partialResponse;\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n });\n if (!hasStreamed && finalResponse) {\n responseText = finalResponse;\n this.notifyListeners('textFromAi', {\n text: finalResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n }\n session.history.push({ role: 'user', content: options.message }, { role: 'model', content: responseText || finalResponse });\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n });\n }\n catch (error) {\n console.error('Error generating response:', error);\n const message = error instanceof Error ? error.message : String(error);\n if (hasStreamed) {\n this.notifyListeners('generationError', {\n chatId: options.chatId,\n error: message,\n });\n return;\n }\n throw error;\n }\n }\n async setModel(options) {\n try {\n this.closeCurrentModel();\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n // Create LLM configuration\n const config = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n const genai = await FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n this.modelPath = options.path;\n this.modelType = this.resolveModelType(options);\n this.chatSessions.clear();\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n }\n catch (error) {\n this.closeCurrentModel();\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n throw error;\n }\n }\n async downloadModel(options) {\n var _a;\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n // Read the response with progress\n const reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n const chunks = [];\n let downloadedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n });\n }\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result = {\n path: options.url,\n };\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n return result;\n }\n catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n closeCurrentModel() {\n var _a;\n this.chatSessions.clear();\n (_a = this.llm) === null || _a === void 0 ? void 0 : _a.close();\n this.llm = null;\n this.modelPath = '';\n this.modelType = 'task';\n }\n resolveModelType(options) {\n var _a;\n if ((_a = options.modelType) === null || _a === void 0 ? void 0 : _a.trim()) {\n return options.modelType.trim().toLowerCase();\n }\n const extension = options.path.split('.').pop();\n return extension ? extension.toLowerCase() : 'task';\n }\n buildPrompt(session, message) {\n if (!this.usesGemmaChatTemplate(session)) {\n return message;\n }\n const history = [...session.history, { role: 'user', content: message }];\n return `${history\n .map((turn) => `<start_of_turn>${turn.role}\\n${turn.content}<end_of_turn>`)\n .join('\\n')}\\n<start_of_turn>model\\n`;\n }\n usesGemmaChatTemplate(session) {\n return /gemma/i.test(session.modelPath) || session.modelType === 'litertlm';\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin","FilesetResolver","LlmInference"],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -5,19 +5,14 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
5
5
|
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CapgoLLMWeb()),
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
var __asyncValues = (globalThis && globalThis.__asyncValues) || function (o) {
|
|
9
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
10
|
-
var m = o[Symbol.asyncIterator], i;
|
|
11
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
12
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
13
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
14
|
-
};
|
|
15
8
|
class CapgoLLMWeb extends core.WebPlugin {
|
|
16
9
|
constructor() {
|
|
17
10
|
super(...arguments);
|
|
18
11
|
this.llm = null;
|
|
19
12
|
this.chatSessions = new Map();
|
|
20
13
|
this.readiness = 'not-loaded';
|
|
14
|
+
this.modelPath = '';
|
|
15
|
+
this.modelType = 'task';
|
|
21
16
|
}
|
|
22
17
|
async getReadiness() {
|
|
23
18
|
return { readiness: this.readiness };
|
|
@@ -31,11 +26,13 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
31
26
|
id: chatId,
|
|
32
27
|
llm: this.llm,
|
|
33
28
|
isActive: true,
|
|
29
|
+
modelPath: this.modelPath,
|
|
30
|
+
modelType: this.modelType,
|
|
31
|
+
history: [],
|
|
34
32
|
});
|
|
35
33
|
return { id: chatId };
|
|
36
34
|
}
|
|
37
35
|
async sendMessage(options) {
|
|
38
|
-
var _a, e_1, _b, _c;
|
|
39
36
|
const session = this.chatSessions.get(options.chatId);
|
|
40
37
|
if (!session) {
|
|
41
38
|
throw new Error(`Chat session ${options.chatId} not found`);
|
|
@@ -43,29 +40,31 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
43
40
|
if (!session.isActive) {
|
|
44
41
|
throw new Error(`Chat session ${options.chatId} is not active`);
|
|
45
42
|
}
|
|
43
|
+
let hasStreamed = false;
|
|
44
|
+
let responseText = '';
|
|
46
45
|
try {
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
_c = response_1_1.value;
|
|
52
|
-
_d = false;
|
|
53
|
-
const partialResponse = _c;
|
|
54
|
-
// Send incremental text
|
|
55
|
-
this.notifyListeners('textFromAi', {
|
|
56
|
-
text: partialResponse,
|
|
57
|
-
chatId: options.chatId,
|
|
58
|
-
isChunk: true,
|
|
59
|
-
});
|
|
46
|
+
const prompt = this.buildPrompt(session, options.message);
|
|
47
|
+
const finalResponse = await session.llm.generateResponse(prompt, (partialResponse, done) => {
|
|
48
|
+
if (done || !partialResponse) {
|
|
49
|
+
return;
|
|
60
50
|
}
|
|
51
|
+
hasStreamed = true;
|
|
52
|
+
responseText += partialResponse;
|
|
53
|
+
this.notifyListeners('textFromAi', {
|
|
54
|
+
text: partialResponse,
|
|
55
|
+
chatId: options.chatId,
|
|
56
|
+
isChunk: true,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
if (!hasStreamed && finalResponse) {
|
|
60
|
+
responseText = finalResponse;
|
|
61
|
+
this.notifyListeners('textFromAi', {
|
|
62
|
+
text: finalResponse,
|
|
63
|
+
chatId: options.chatId,
|
|
64
|
+
isChunk: true,
|
|
65
|
+
});
|
|
61
66
|
}
|
|
62
|
-
|
|
63
|
-
finally {
|
|
64
|
-
try {
|
|
65
|
-
if (!_d && !_a && (_b = response_1.return)) await _b.call(response_1);
|
|
66
|
-
}
|
|
67
|
-
finally { if (e_1) throw e_1.error; }
|
|
68
|
-
}
|
|
67
|
+
session.history.push({ role: 'user', content: options.message }, { role: 'model', content: responseText || finalResponse });
|
|
69
68
|
// Notify completion
|
|
70
69
|
this.notifyListeners('aiFinished', {
|
|
71
70
|
chatId: options.chatId,
|
|
@@ -73,22 +72,20 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
73
72
|
}
|
|
74
73
|
catch (error) {
|
|
75
74
|
console.error('Error generating response:', error);
|
|
75
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
76
|
+
if (hasStreamed) {
|
|
77
|
+
this.notifyListeners('generationError', {
|
|
78
|
+
chatId: options.chatId,
|
|
79
|
+
error: message,
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
76
83
|
throw error;
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
86
|
async setModel(options) {
|
|
80
|
-
var _a;
|
|
81
|
-
const engine = (_a = options.engine) !== null && _a !== void 0 ? _a : 'auto';
|
|
82
|
-
const normalizedPath = options.path.toLowerCase();
|
|
83
|
-
const wantsApple = engine === 'apple' || (engine === 'auto' && normalizedPath === 'apple intelligence');
|
|
84
|
-
const wantsExecuTorch = engine === 'executorch' || (engine === 'auto' && (options.tokenizerPath || normalizedPath.endsWith('.pte')));
|
|
85
|
-
if (wantsApple) {
|
|
86
|
-
throw new Error('Apple Intelligence is only available on native iOS.');
|
|
87
|
-
}
|
|
88
|
-
if (wantsExecuTorch) {
|
|
89
|
-
throw new Error('ExecuTorch is only available on native iOS and Android.');
|
|
90
|
-
}
|
|
91
87
|
try {
|
|
88
|
+
this.closeCurrentModel();
|
|
92
89
|
// Update readiness
|
|
93
90
|
this.readiness = 'loading';
|
|
94
91
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
@@ -105,11 +102,15 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
105
102
|
const genai = await tasksGenai.FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');
|
|
106
103
|
// Create LLM instance
|
|
107
104
|
this.llm = await tasksGenai.LlmInference.createFromOptions(genai, config);
|
|
105
|
+
this.modelPath = options.path;
|
|
106
|
+
this.modelType = this.resolveModelType(options);
|
|
107
|
+
this.chatSessions.clear();
|
|
108
108
|
// Update readiness
|
|
109
109
|
this.readiness = 'ready';
|
|
110
110
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
111
111
|
}
|
|
112
112
|
catch (error) {
|
|
113
|
+
this.closeCurrentModel();
|
|
113
114
|
this.readiness = 'error';
|
|
114
115
|
this.notifyListeners('readinessChange', { readiness: this.readiness });
|
|
115
116
|
throw error;
|
|
@@ -173,6 +174,34 @@ var capacitorLLM = (function (exports, core, tasksGenai) {
|
|
|
173
174
|
async getPluginVersion() {
|
|
174
175
|
return { version: 'web' };
|
|
175
176
|
}
|
|
177
|
+
closeCurrentModel() {
|
|
178
|
+
var _a;
|
|
179
|
+
this.chatSessions.clear();
|
|
180
|
+
(_a = this.llm) === null || _a === void 0 ? void 0 : _a.close();
|
|
181
|
+
this.llm = null;
|
|
182
|
+
this.modelPath = '';
|
|
183
|
+
this.modelType = 'task';
|
|
184
|
+
}
|
|
185
|
+
resolveModelType(options) {
|
|
186
|
+
var _a;
|
|
187
|
+
if ((_a = options.modelType) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
188
|
+
return options.modelType.trim().toLowerCase();
|
|
189
|
+
}
|
|
190
|
+
const extension = options.path.split('.').pop();
|
|
191
|
+
return extension ? extension.toLowerCase() : 'task';
|
|
192
|
+
}
|
|
193
|
+
buildPrompt(session, message) {
|
|
194
|
+
if (!this.usesGemmaChatTemplate(session)) {
|
|
195
|
+
return message;
|
|
196
|
+
}
|
|
197
|
+
const history = [...session.history, { role: 'user', content: message }];
|
|
198
|
+
return `${history
|
|
199
|
+
.map((turn) => `<start_of_turn>${turn.role}\n${turn.content}<end_of_turn>`)
|
|
200
|
+
.join('\n')}\n<start_of_turn>model\n`;
|
|
201
|
+
}
|
|
202
|
+
usesGemmaChatTemplate(session) {
|
|
203
|
+
return /gemma/i.test(session.modelPath) || session.modelType === 'litertlm';
|
|
204
|
+
}
|
|
176
205
|
}
|
|
177
206
|
|
|
178
207
|
var web = /*#__PURE__*/Object.freeze({
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapgoLLM = registerPlugin('CapgoLLM', {\n web: () => import('./web').then((m) => new m.CapgoLLMWeb()),\n});\nexport * from './definitions';\nexport { CapgoLLM };\n//# sourceMappingURL=index.js.map","var __asyncValues = (this && this.__asyncValues) || function (o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nimport { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\nexport class CapgoLLMWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.llm = null;\n this.chatSessions = new Map();\n this.readiness = 'not-loaded';\n }\n async getReadiness() {\n return { readiness: this.readiness };\n }\n async createChat() {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n });\n return { id: chatId };\n }\n async sendMessage(options) {\n var _a, e_1, _b, _c;\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n try {\n // Generate response using MediaPipe GenAI streaming API\n const response = session.llm.generateResponseStream(options.message);\n try {\n for (var _d = true, response_1 = __asyncValues(response), response_1_1; response_1_1 = await response_1.next(), _a = response_1_1.done, !_a; _d = true) {\n _c = response_1_1.value;\n _d = false;\n const partialResponse = _c;\n // Send incremental text\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = response_1.return)) await _b.call(response_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n });\n }\n catch (error) {\n console.error('Error generating response:', error);\n throw error;\n }\n }\n async setModel(options) {\n var _a;\n const engine = (_a = options.engine) !== null && _a !== void 0 ? _a : 'auto';\n const normalizedPath = options.path.toLowerCase();\n const wantsApple = engine === 'apple' || (engine === 'auto' && normalizedPath === 'apple intelligence');\n const wantsExecuTorch = engine === 'executorch' || (engine === 'auto' && (options.tokenizerPath || normalizedPath.endsWith('.pte')));\n if (wantsApple) {\n throw new Error('Apple Intelligence is only available on native iOS.');\n }\n if (wantsExecuTorch) {\n throw new Error('ExecuTorch is only available on native iOS and Android.');\n }\n try {\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n // Create LLM configuration\n const config = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n const genai = await FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n }\n catch (error) {\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n throw error;\n }\n }\n async downloadModel(options) {\n var _a;\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n // Read the response with progress\n const reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n const chunks = [];\n let downloadedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n });\n }\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result = {\n path: options.url,\n };\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n return result;\n }\n catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","this","WebPlugin","FilesetResolver","LlmInference"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapgoLLM = registerPlugin('CapgoLLM', {\n web: () => import('./web').then((m) => new m.CapgoLLMWeb()),\n});\nexport * from './definitions';\nexport { CapgoLLM };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { FilesetResolver, LlmInference } from '@mediapipe/tasks-genai';\nexport class CapgoLLMWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.llm = null;\n this.chatSessions = new Map();\n this.readiness = 'not-loaded';\n this.modelPath = '';\n this.modelType = 'task';\n }\n async getReadiness() {\n return { readiness: this.readiness };\n }\n async createChat() {\n if (!this.llm) {\n throw new Error('Model not loaded. Call setModel first.');\n }\n const chatId = `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n this.chatSessions.set(chatId, {\n id: chatId,\n llm: this.llm,\n isActive: true,\n modelPath: this.modelPath,\n modelType: this.modelType,\n history: [],\n });\n return { id: chatId };\n }\n async sendMessage(options) {\n const session = this.chatSessions.get(options.chatId);\n if (!session) {\n throw new Error(`Chat session ${options.chatId} not found`);\n }\n if (!session.isActive) {\n throw new Error(`Chat session ${options.chatId} is not active`);\n }\n let hasStreamed = false;\n let responseText = '';\n try {\n const prompt = this.buildPrompt(session, options.message);\n const finalResponse = await session.llm.generateResponse(prompt, (partialResponse, done) => {\n if (done || !partialResponse) {\n return;\n }\n hasStreamed = true;\n responseText += partialResponse;\n this.notifyListeners('textFromAi', {\n text: partialResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n });\n if (!hasStreamed && finalResponse) {\n responseText = finalResponse;\n this.notifyListeners('textFromAi', {\n text: finalResponse,\n chatId: options.chatId,\n isChunk: true,\n });\n }\n session.history.push({ role: 'user', content: options.message }, { role: 'model', content: responseText || finalResponse });\n // Notify completion\n this.notifyListeners('aiFinished', {\n chatId: options.chatId,\n });\n }\n catch (error) {\n console.error('Error generating response:', error);\n const message = error instanceof Error ? error.message : String(error);\n if (hasStreamed) {\n this.notifyListeners('generationError', {\n chatId: options.chatId,\n error: message,\n });\n return;\n }\n throw error;\n }\n }\n async setModel(options) {\n try {\n this.closeCurrentModel();\n // Update readiness\n this.readiness = 'loading';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n // Create LLM configuration\n const config = {\n baseOptions: {\n modelAssetPath: options.path,\n },\n maxTokens: options.maxTokens || 2048,\n topK: options.topk || 40,\n temperature: options.temperature || 0.8,\n randomSeed: options.randomSeed || 0,\n };\n const genai = await FilesetResolver.forGenAiTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm');\n // Create LLM instance\n this.llm = await LlmInference.createFromOptions(genai, config);\n this.modelPath = options.path;\n this.modelType = this.resolveModelType(options);\n this.chatSessions.clear();\n // Update readiness\n this.readiness = 'ready';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n }\n catch (error) {\n this.closeCurrentModel();\n this.readiness = 'error';\n this.notifyListeners('readinessChange', { readiness: this.readiness });\n throw error;\n }\n }\n async downloadModel(options) {\n var _a;\n try {\n // For web, we'll simulate download by fetching and storing in IndexedDB or returning the URL\n const response = await fetch(options.url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/octet-stream',\n },\n });\n if (!response.ok) {\n throw new Error(`Failed to download model: ${response.statusText}`);\n }\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : undefined;\n // Read the response with progress\n const reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();\n if (!reader) {\n throw new Error('Failed to get reader from response');\n }\n const chunks = [];\n let downloadedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n if (value) {\n chunks.push(value);\n downloadedBytes += value.length;\n }\n // Notify progress\n const progress = totalBytes ? (downloadedBytes / totalBytes) * 100 : 0;\n this.notifyListeners('downloadProgress', {\n progress,\n totalBytes,\n downloadedBytes,\n });\n }\n // For web, we'll return the original URL as the path\n // In a real implementation, you might want to store this in IndexedDB\n const result = {\n path: options.url,\n };\n // Handle companion file if provided\n if (options.companionUrl) {\n // For web, just return the companion URL\n result.companionPath = options.companionUrl;\n }\n return result;\n }\n catch (error) {\n console.error('Error downloading model:', error);\n throw error;\n }\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n closeCurrentModel() {\n var _a;\n this.chatSessions.clear();\n (_a = this.llm) === null || _a === void 0 ? void 0 : _a.close();\n this.llm = null;\n this.modelPath = '';\n this.modelType = 'task';\n }\n resolveModelType(options) {\n var _a;\n if ((_a = options.modelType) === null || _a === void 0 ? void 0 : _a.trim()) {\n return options.modelType.trim().toLowerCase();\n }\n const extension = options.path.split('.').pop();\n return extension ? extension.toLowerCase() : 'task';\n }\n buildPrompt(session, message) {\n if (!this.usesGemmaChatTemplate(session)) {\n return message;\n }\n const history = [...session.history, { role: 'user', content: message }];\n return `${history\n .map((turn) => `<start_of_turn>${turn.role}\\n${turn.content}<end_of_turn>`)\n .join('\\n')}\\n<start_of_turn>model\\n`;\n }\n usesGemmaChatTemplate(session) {\n return /gemma/i.test(session.modelPath) || session.modelType === 'litertlm';\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin","FilesetResolver","LlmInference"],"mappings":"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"}
|