learngraph 0.3.0 → 0.4.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.
Files changed (33) hide show
  1. package/dist/cjs/llm/adapters/gemini.js +156 -0
  2. package/dist/cjs/llm/adapters/gemini.js.map +1 -0
  3. package/dist/cjs/llm/adapters/index.js +12 -1
  4. package/dist/cjs/llm/adapters/index.js.map +1 -1
  5. package/dist/cjs/llm/adapters/mediapipe.js +290 -0
  6. package/dist/cjs/llm/adapters/mediapipe.js.map +1 -0
  7. package/dist/cjs/llm/adapters/openrouter.js +190 -0
  8. package/dist/cjs/llm/adapters/openrouter.js.map +1 -0
  9. package/dist/cjs/llm/index.js +9 -1
  10. package/dist/cjs/llm/index.js.map +1 -1
  11. package/dist/esm/llm/adapters/gemini.js +151 -0
  12. package/dist/esm/llm/adapters/gemini.js.map +1 -0
  13. package/dist/esm/llm/adapters/index.js +3 -0
  14. package/dist/esm/llm/adapters/index.js.map +1 -1
  15. package/dist/esm/llm/adapters/mediapipe.js +252 -0
  16. package/dist/esm/llm/adapters/mediapipe.js.map +1 -0
  17. package/dist/esm/llm/adapters/openrouter.js +185 -0
  18. package/dist/esm/llm/adapters/openrouter.js.map +1 -0
  19. package/dist/esm/llm/index.js +1 -1
  20. package/dist/esm/llm/index.js.map +1 -1
  21. package/dist/types/llm/adapters/gemini.d.ts +30 -0
  22. package/dist/types/llm/adapters/gemini.d.ts.map +1 -0
  23. package/dist/types/llm/adapters/index.d.ts +3 -0
  24. package/dist/types/llm/adapters/index.d.ts.map +1 -1
  25. package/dist/types/llm/adapters/mediapipe.d.ts +113 -0
  26. package/dist/types/llm/adapters/mediapipe.d.ts.map +1 -0
  27. package/dist/types/llm/adapters/openrouter.d.ts +58 -0
  28. package/dist/types/llm/adapters/openrouter.d.ts.map +1 -0
  29. package/dist/types/llm/index.d.ts +2 -2
  30. package/dist/types/llm/index.d.ts.map +1 -1
  31. package/dist/types/types/llm.d.ts +40 -1
  32. package/dist/types/types/llm.d.ts.map +1 -1
  33. package/package.json +6 -2
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ /**
3
+ * OpenRouter LLM adapter
4
+ *
5
+ * OpenRouter provides access to many models through a single API:
6
+ * - OpenAI (GPT-4, GPT-3.5)
7
+ * - Anthropic (Claude)
8
+ * - Google (Gemini, PaLM)
9
+ * - Meta (Llama)
10
+ * - Mistral
11
+ * - And many more
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.OpenRouterAdapter = exports.OPENROUTER_MODELS = void 0;
17
+ exports.createOpenRouterAdapter = createOpenRouterAdapter;
18
+ const base_js_1 = require("./base.js");
19
+ /**
20
+ * Popular models available on OpenRouter
21
+ */
22
+ exports.OPENROUTER_MODELS = {
23
+ // OpenAI
24
+ 'openai/gpt-4o': 'openai/gpt-4o',
25
+ 'openai/gpt-4-turbo': 'openai/gpt-4-turbo',
26
+ 'openai/gpt-3.5-turbo': 'openai/gpt-3.5-turbo',
27
+ // Anthropic
28
+ 'anthropic/claude-3.5-sonnet': 'anthropic/claude-3.5-sonnet',
29
+ 'anthropic/claude-3-opus': 'anthropic/claude-3-opus',
30
+ 'anthropic/claude-3-haiku': 'anthropic/claude-3-haiku',
31
+ // Google
32
+ 'google/gemini-pro': 'google/gemini-pro',
33
+ 'google/gemini-pro-1.5': 'google/gemini-pro-1.5',
34
+ // Meta
35
+ 'meta-llama/llama-3.1-70b-instruct': 'meta-llama/llama-3.1-70b-instruct',
36
+ 'meta-llama/llama-3.1-8b-instruct': 'meta-llama/llama-3.1-8b-instruct',
37
+ // Mistral
38
+ 'mistralai/mistral-large': 'mistralai/mistral-large',
39
+ 'mistralai/mistral-medium': 'mistralai/mistral-medium',
40
+ 'mistralai/mixtral-8x7b-instruct': 'mistralai/mixtral-8x7b-instruct',
41
+ // DeepSeek
42
+ 'deepseek/deepseek-chat': 'deepseek/deepseek-chat',
43
+ 'deepseek/deepseek-coder': 'deepseek/deepseek-coder',
44
+ // Qwen
45
+ 'qwen/qwen-2.5-72b-instruct': 'qwen/qwen-2.5-72b-instruct',
46
+ };
47
+ /**
48
+ * Adapter for OpenRouter API
49
+ *
50
+ * OpenRouter provides unified access to 100+ models from various providers.
51
+ * See https://openrouter.ai/docs for full documentation.
52
+ */
53
+ class OpenRouterAdapter extends base_js_1.BaseLLMAdapter {
54
+ baseUrl;
55
+ siteUrl;
56
+ appName;
57
+ constructor(config) {
58
+ super(config);
59
+ this.baseUrl = config.baseUrl ?? 'https://openrouter.ai/api/v1';
60
+ if (config.siteUrl) {
61
+ this.siteUrl = config.siteUrl;
62
+ }
63
+ if (config.appName) {
64
+ this.appName = config.appName;
65
+ }
66
+ }
67
+ get provider() {
68
+ return 'openrouter';
69
+ }
70
+ async complete(request) {
71
+ if (!this.isConfigured()) {
72
+ throw new base_js_1.LLMError('OpenRouter adapter is not configured. Set OPENROUTER_API_KEY environment variable.', 'NOT_CONFIGURED', this.provider);
73
+ }
74
+ const openRouterRequest = this.buildRequest(request);
75
+ try {
76
+ const response = await this.executeRequest(openRouterRequest);
77
+ return this.parseResponse(response);
78
+ }
79
+ catch (error) {
80
+ if (error instanceof base_js_1.LLMError) {
81
+ throw error;
82
+ }
83
+ throw new base_js_1.LLMError(`OpenRouter API request failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'API_ERROR', this.provider, error instanceof Error ? error : undefined);
84
+ }
85
+ }
86
+ buildRequest(request) {
87
+ const openRouterRequest = {
88
+ model: this.config.model,
89
+ messages: request.messages.map((m) => ({
90
+ role: m.role,
91
+ content: m.content,
92
+ })),
93
+ max_tokens: request.maxTokens ?? this.config.maxTokens ?? 4096,
94
+ temperature: request.temperature ?? this.config.temperature ?? 0.3,
95
+ };
96
+ // Handle JSON response format
97
+ if (request.responseFormat === 'json') {
98
+ openRouterRequest.response_format = { type: 'json_object' };
99
+ }
100
+ return openRouterRequest;
101
+ }
102
+ async executeRequest(request) {
103
+ const headers = {
104
+ 'Content-Type': 'application/json',
105
+ Authorization: `Bearer ${this.config.apiKey}`,
106
+ };
107
+ // Add optional OpenRouter-specific headers for rankings
108
+ if (this.siteUrl) {
109
+ headers['HTTP-Referer'] = this.siteUrl;
110
+ }
111
+ if (this.appName) {
112
+ headers['X-Title'] = this.appName;
113
+ }
114
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
115
+ method: 'POST',
116
+ headers,
117
+ body: JSON.stringify(request),
118
+ signal: AbortSignal.timeout(this.config.timeout ?? 60000),
119
+ });
120
+ if (!response.ok) {
121
+ const errorBody = await response.text();
122
+ let errorMessage = `HTTP ${response.status}`;
123
+ try {
124
+ const errorJson = JSON.parse(errorBody);
125
+ errorMessage = errorJson.error?.message ?? errorMessage;
126
+ }
127
+ catch {
128
+ errorMessage = errorBody || errorMessage;
129
+ }
130
+ if (response.status === 429) {
131
+ throw new base_js_1.LLMError(`Rate limit exceeded: ${errorMessage}`, 'RATE_LIMIT', this.provider);
132
+ }
133
+ if (response.status === 402) {
134
+ throw new base_js_1.LLMError(`Payment required or insufficient credits: ${errorMessage}`, 'API_ERROR', this.provider);
135
+ }
136
+ throw new base_js_1.LLMError(`OpenRouter API error: ${errorMessage}`, 'API_ERROR', this.provider);
137
+ }
138
+ return response.json();
139
+ }
140
+ parseResponse(response) {
141
+ if (!response.choices || response.choices.length === 0) {
142
+ throw new base_js_1.LLMError('No choices in OpenRouter response', 'INVALID_RESPONSE', this.provider);
143
+ }
144
+ const choice = response.choices[0];
145
+ if (!choice) {
146
+ throw new base_js_1.LLMError('No choice in OpenRouter response', 'INVALID_RESPONSE', this.provider);
147
+ }
148
+ const content = choice.message.content;
149
+ // Try to parse JSON if present
150
+ let json;
151
+ try {
152
+ json = this.parseJSON(content);
153
+ }
154
+ catch {
155
+ // Not JSON, that's fine
156
+ }
157
+ // Map finish reasons to our standard format
158
+ const finishReason = choice.finish_reason === 'stop' ? 'stop' :
159
+ choice.finish_reason === 'length' ? 'length' :
160
+ choice.finish_reason === 'content_filter' ? 'content_filter' : 'stop';
161
+ return {
162
+ content,
163
+ json,
164
+ usage: {
165
+ promptTokens: response.usage.prompt_tokens,
166
+ completionTokens: response.usage.completion_tokens,
167
+ totalTokens: response.usage.total_tokens,
168
+ },
169
+ model: response.model,
170
+ finishReason,
171
+ };
172
+ }
173
+ }
174
+ exports.OpenRouterAdapter = OpenRouterAdapter;
175
+ /**
176
+ * Create an OpenRouter adapter from environment variables
177
+ */
178
+ function createOpenRouterAdapter(model = 'anthropic/claude-3.5-sonnet', overrides) {
179
+ const apiKey = typeof process !== 'undefined' ? process.env.OPENROUTER_API_KEY : undefined;
180
+ const config = {
181
+ provider: 'openrouter',
182
+ model,
183
+ ...overrides,
184
+ };
185
+ if (apiKey) {
186
+ config.apiKey = apiKey;
187
+ }
188
+ return new OpenRouterAdapter(config);
189
+ }
190
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../../../src/llm/adapters/openrouter.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * @packageDocumentation
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.buildDecompositionPrompt = exports.buildBloomPrompt = exports.buildPrerequisitePrompt = exports.buildExtractionPrompt = exports.DECOMPOSITION_SCHEMA = exports.BLOOM_ANALYSIS_SCHEMA = exports.PREREQUISITE_SCHEMA = exports.EXTRACTION_SCHEMA = exports.SYSTEM_PROMPTS = exports.createOrchestrator = exports.LLMOrchestrator = exports.createOllamaAdapter = exports.OllamaAdapter = exports.createAnthropicAdapter = exports.AnthropicAdapter = exports.createOpenAIAdapter = exports.OpenAIAdapter = exports.DEFAULT_CONFIG = exports.LLMError = exports.BaseLLMAdapter = void 0;
8
+ exports.buildDecompositionPrompt = exports.buildBloomPrompt = exports.buildPrerequisitePrompt = exports.buildExtractionPrompt = exports.DECOMPOSITION_SCHEMA = exports.BLOOM_ANALYSIS_SCHEMA = exports.PREREQUISITE_SCHEMA = exports.EXTRACTION_SCHEMA = exports.SYSTEM_PROMPTS = exports.createOrchestrator = exports.LLMOrchestrator = exports.MEDIAPIPE_MODELS = exports.createMediaPipeAdapter = exports.MediaPipeAdapter = exports.OPENROUTER_MODELS = exports.createOpenRouterAdapter = exports.OpenRouterAdapter = exports.createGeminiAdapter = exports.GeminiAdapter = exports.createOllamaAdapter = exports.OllamaAdapter = exports.createAnthropicAdapter = exports.AnthropicAdapter = exports.createOpenAIAdapter = exports.OpenAIAdapter = exports.DEFAULT_CONFIG = exports.LLMError = exports.BaseLLMAdapter = void 0;
9
9
  // ─────────────────────────────────────────────────────────────────────────────
10
10
  // Adapters
11
11
  // ─────────────────────────────────────────────────────────────────────────────
@@ -19,6 +19,14 @@ Object.defineProperty(exports, "AnthropicAdapter", { enumerable: true, get: func
19
19
  Object.defineProperty(exports, "createAnthropicAdapter", { enumerable: true, get: function () { return index_js_1.createAnthropicAdapter; } });
20
20
  Object.defineProperty(exports, "OllamaAdapter", { enumerable: true, get: function () { return index_js_1.OllamaAdapter; } });
21
21
  Object.defineProperty(exports, "createOllamaAdapter", { enumerable: true, get: function () { return index_js_1.createOllamaAdapter; } });
22
+ Object.defineProperty(exports, "GeminiAdapter", { enumerable: true, get: function () { return index_js_1.GeminiAdapter; } });
23
+ Object.defineProperty(exports, "createGeminiAdapter", { enumerable: true, get: function () { return index_js_1.createGeminiAdapter; } });
24
+ Object.defineProperty(exports, "OpenRouterAdapter", { enumerable: true, get: function () { return index_js_1.OpenRouterAdapter; } });
25
+ Object.defineProperty(exports, "createOpenRouterAdapter", { enumerable: true, get: function () { return index_js_1.createOpenRouterAdapter; } });
26
+ Object.defineProperty(exports, "OPENROUTER_MODELS", { enumerable: true, get: function () { return index_js_1.OPENROUTER_MODELS; } });
27
+ Object.defineProperty(exports, "MediaPipeAdapter", { enumerable: true, get: function () { return index_js_1.MediaPipeAdapter; } });
28
+ Object.defineProperty(exports, "createMediaPipeAdapter", { enumerable: true, get: function () { return index_js_1.createMediaPipeAdapter; } });
29
+ Object.defineProperty(exports, "MEDIAPIPE_MODELS", { enumerable: true, get: function () { return index_js_1.MEDIAPIPE_MODELS; } });
22
30
  // ─────────────────────────────────────────────────────────────────────────────
23
31
  // Orchestrator
24
32
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA6BH,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAChF,gDAU6B;AAT3B,0GAAA,cAAc,OAAA;AACd,oGAAA,QAAQ,OAAA;AACR,0GAAA,cAAc,OAAA;AACd,yGAAA,aAAa,OAAA;AACb,+GAAA,mBAAmB,OAAA;AACnB,4GAAA,gBAAgB,OAAA;AAChB,kHAAA,sBAAsB,OAAA;AACtB,yGAAA,aAAa,OAAA;AACb,+GAAA,mBAAmB,OAAA;AAIrB,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAChF,qDAAwE;AAA/D,kHAAA,eAAe,OAAA;AAAE,qHAAA,kBAAkB,OAAA;AAE5C,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAChF,2CAUsB;AATpB,4GAAA,cAAc,OAAA;AACd,+GAAA,iBAAiB,OAAA;AACjB,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA;AACrB,kHAAA,oBAAoB,OAAA;AACpB,mHAAA,qBAAqB,OAAA;AACrB,qHAAA,uBAAuB,OAAA;AACvB,8GAAA,gBAAgB,OAAA;AAChB,sHAAA,wBAAwB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAgCH,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAChF,gDAkB6B;AAjB3B,0GAAA,cAAc,OAAA;AACd,oGAAA,QAAQ,OAAA;AACR,0GAAA,cAAc,OAAA;AACd,yGAAA,aAAa,OAAA;AACb,+GAAA,mBAAmB,OAAA;AACnB,4GAAA,gBAAgB,OAAA;AAChB,kHAAA,sBAAsB,OAAA;AACtB,yGAAA,aAAa,OAAA;AACb,+GAAA,mBAAmB,OAAA;AACnB,yGAAA,aAAa,OAAA;AACb,+GAAA,mBAAmB,OAAA;AACnB,6GAAA,iBAAiB,OAAA;AACjB,mHAAA,uBAAuB,OAAA;AACvB,6GAAA,iBAAiB,OAAA;AACjB,4GAAA,gBAAgB,OAAA;AAChB,kHAAA,sBAAsB,OAAA;AACtB,4GAAA,gBAAgB,OAAA;AAIlB,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAChF,qDAAwE;AAA/D,kHAAA,eAAe,OAAA;AAAE,qHAAA,kBAAkB,OAAA;AAE5C,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAChF,2CAUsB;AATpB,4GAAA,cAAc,OAAA;AACd,+GAAA,iBAAiB,OAAA;AACjB,iHAAA,mBAAmB,OAAA;AACnB,mHAAA,qBAAqB,OAAA;AACrB,kHAAA,oBAAoB,OAAA;AACpB,mHAAA,qBAAqB,OAAA;AACrB,qHAAA,uBAAuB,OAAA;AACvB,8GAAA,gBAAgB,OAAA;AAChB,sHAAA,wBAAwB,OAAA"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Google Gemini LLM adapter
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import { BaseLLMAdapter, LLMError } from './base.js';
7
+ /**
8
+ * Adapter for Google Gemini models
9
+ *
10
+ * Supports:
11
+ * - gemini-2.0-flash-exp
12
+ * - gemini-1.5-pro
13
+ * - gemini-1.5-flash
14
+ * - gemini-1.0-pro
15
+ */
16
+ export class GeminiAdapter extends BaseLLMAdapter {
17
+ baseUrl;
18
+ constructor(config) {
19
+ super(config);
20
+ // Use Google AI Studio API by default
21
+ this.baseUrl =
22
+ config.baseUrl ?? 'https://generativelanguage.googleapis.com/v1beta';
23
+ }
24
+ get provider() {
25
+ return 'gemini';
26
+ }
27
+ async complete(request) {
28
+ if (!this.isConfigured()) {
29
+ throw new LLMError('Gemini adapter is not configured. Set GOOGLE_API_KEY or GEMINI_API_KEY environment variable.', 'NOT_CONFIGURED', this.provider);
30
+ }
31
+ const geminiRequest = this.buildRequest(request);
32
+ try {
33
+ const response = await this.executeRequest(geminiRequest);
34
+ return this.parseResponse(response);
35
+ }
36
+ catch (error) {
37
+ if (error instanceof LLMError) {
38
+ throw error;
39
+ }
40
+ throw new LLMError(`Gemini API request failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'API_ERROR', this.provider, error instanceof Error ? error : undefined);
41
+ }
42
+ }
43
+ buildRequest(request) {
44
+ const geminiRequest = {
45
+ contents: [],
46
+ generationConfig: {
47
+ maxOutputTokens: request.maxTokens ?? this.config.maxTokens ?? 4096,
48
+ temperature: request.temperature ?? this.config.temperature ?? 0.3,
49
+ },
50
+ };
51
+ // Handle JSON response format
52
+ if (request.responseFormat === 'json') {
53
+ geminiRequest.generationConfig.responseMimeType = 'application/json';
54
+ }
55
+ // Convert messages to Gemini format
56
+ for (const message of request.messages) {
57
+ if (message.role === 'system') {
58
+ // Gemini uses systemInstruction for system messages
59
+ geminiRequest.systemInstruction = {
60
+ parts: [{ text: message.content }],
61
+ };
62
+ }
63
+ else {
64
+ geminiRequest.contents.push({
65
+ role: message.role === 'assistant' ? 'model' : 'user',
66
+ parts: [{ text: message.content }],
67
+ });
68
+ }
69
+ }
70
+ return geminiRequest;
71
+ }
72
+ async executeRequest(request) {
73
+ const url = `${this.baseUrl}/models/${this.config.model}:generateContent?key=${this.config.apiKey}`;
74
+ const response = await fetch(url, {
75
+ method: 'POST',
76
+ headers: {
77
+ 'Content-Type': 'application/json',
78
+ },
79
+ body: JSON.stringify(request),
80
+ signal: AbortSignal.timeout(this.config.timeout ?? 60000),
81
+ });
82
+ if (!response.ok) {
83
+ const errorBody = await response.text();
84
+ let errorMessage = `HTTP ${response.status}`;
85
+ try {
86
+ const errorJson = JSON.parse(errorBody);
87
+ errorMessage = errorJson.error?.message ?? errorMessage;
88
+ }
89
+ catch {
90
+ errorMessage = errorBody || errorMessage;
91
+ }
92
+ if (response.status === 429) {
93
+ throw new LLMError(`Rate limit exceeded: ${errorMessage}`, 'RATE_LIMIT', this.provider);
94
+ }
95
+ throw new LLMError(`Gemini API error: ${errorMessage}`, 'API_ERROR', this.provider);
96
+ }
97
+ return response.json();
98
+ }
99
+ parseResponse(response) {
100
+ if (!response.candidates || response.candidates.length === 0) {
101
+ throw new LLMError('No candidates in Gemini response', 'INVALID_RESPONSE', this.provider);
102
+ }
103
+ const candidate = response.candidates[0];
104
+ if (!candidate) {
105
+ throw new LLMError('No candidate in Gemini response', 'INVALID_RESPONSE', this.provider);
106
+ }
107
+ const content = candidate.content.parts.map((p) => p.text).join('');
108
+ // Try to parse JSON if present
109
+ let json;
110
+ try {
111
+ json = this.parseJSON(content);
112
+ }
113
+ catch {
114
+ // Not JSON, that's fine
115
+ }
116
+ // Map Gemini finish reasons to our standard format
117
+ const finishReason = candidate.finishReason === 'STOP' ? 'stop' :
118
+ candidate.finishReason === 'MAX_TOKENS' ? 'length' :
119
+ candidate.finishReason === 'SAFETY' ? 'content_filter' : 'stop';
120
+ return {
121
+ content,
122
+ json,
123
+ usage: {
124
+ promptTokens: response.usageMetadata?.promptTokenCount ?? 0,
125
+ completionTokens: response.usageMetadata?.candidatesTokenCount ?? 0,
126
+ totalTokens: response.usageMetadata?.totalTokenCount ?? 0,
127
+ },
128
+ model: this.config.model,
129
+ finishReason,
130
+ };
131
+ }
132
+ }
133
+ /**
134
+ * Create a Gemini adapter from environment variables
135
+ */
136
+ export function createGeminiAdapter(model = 'gemini-2.0-flash-exp', overrides) {
137
+ // Support both GOOGLE_API_KEY and GEMINI_API_KEY
138
+ const apiKey = typeof process !== 'undefined'
139
+ ? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY
140
+ : undefined;
141
+ const config = {
142
+ provider: 'gemini',
143
+ model,
144
+ ...overrides,
145
+ };
146
+ if (apiKey) {
147
+ config.apiKey = apiKey;
148
+ }
149
+ return new GeminiAdapter(config);
150
+ }
151
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../../src/llm/adapters/gemini.ts"],"names":[],"mappings":"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"}
@@ -7,4 +7,7 @@ export { BaseLLMAdapter, LLMError, DEFAULT_CONFIG } from './base.js';
7
7
  export { OpenAIAdapter, createOpenAIAdapter } from './openai.js';
8
8
  export { AnthropicAdapter, createAnthropicAdapter } from './anthropic.js';
9
9
  export { OllamaAdapter, createOllamaAdapter } from './ollama.js';
10
+ export { GeminiAdapter, createGeminiAdapter } from './gemini.js';
11
+ export { OpenRouterAdapter, createOpenRouterAdapter, OPENROUTER_MODELS } from './openrouter.js';
12
+ export { MediaPipeAdapter, createMediaPipeAdapter, MEDIAPIPE_MODELS } from './mediapipe.js';
10
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/llm/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/llm/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * MediaPipe LLM Inference adapter for local Gemma models
3
+ *
4
+ * This adapter integrates with Google's MediaPipe LLM Inference Task API
5
+ * to run Gemma models locally using WebGPU acceleration.
6
+ *
7
+ * Supported models:
8
+ * - Gemma 2B / 7B
9
+ * - Gemma 2 2B
10
+ * - Gemma 3n (2B, 4B parameters)
11
+ *
12
+ * Requirements:
13
+ * - WebGPU-capable browser or Node.js with WebGPU support
14
+ * - @mediapipe/tasks-genai package
15
+ * - Downloaded model weights (.bin file)
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ import { BaseLLMAdapter, LLMError } from './base.js';
20
+ /**
21
+ * Gemma model variants for MediaPipe
22
+ */
23
+ export const MEDIAPIPE_MODELS = {
24
+ 'gemma-2b': 'gemma-2b-it-gpu-int4.bin',
25
+ 'gemma-7b': 'gemma-7b-it-gpu-int8.bin',
26
+ 'gemma2-2b': 'gemma2-2b-it-gpu-int4.bin',
27
+ 'gemma3n-e2b': 'gemma-3n-E2B-it-int4.task',
28
+ 'gemma3n-e4b': 'gemma-3n-E4B-it-int4.task',
29
+ };
30
+ /**
31
+ * Adapter for MediaPipe LLM Inference API
32
+ *
33
+ * Runs Gemma models locally using WebGPU acceleration.
34
+ * The adapter lazily loads the model on first use.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { MediaPipeAdapter } from 'learngraph/llm';
39
+ *
40
+ * const adapter = new MediaPipeAdapter({
41
+ * provider: 'mediapipe',
42
+ * model: 'gemma3n-e2b',
43
+ * modelPath: '/models/gemma-3n-E2B-it-int4.task',
44
+ * });
45
+ *
46
+ * // Use with orchestrator
47
+ * const orchestrator = createOrchestrator(adapter);
48
+ * ```
49
+ */
50
+ export class MediaPipeAdapter extends BaseLLMAdapter {
51
+ inference = null;
52
+ modelPath;
53
+ randomSeed;
54
+ topK;
55
+ loraRanks;
56
+ initPromise = null;
57
+ constructor(config) {
58
+ super(config);
59
+ this.modelPath = config.modelPath;
60
+ this.topK = config.topK ?? 40;
61
+ if (config.randomSeed !== undefined) {
62
+ this.randomSeed = config.randomSeed;
63
+ }
64
+ if (config.loraRanks !== undefined) {
65
+ this.loraRanks = config.loraRanks;
66
+ }
67
+ }
68
+ get provider() {
69
+ return 'mediapipe';
70
+ }
71
+ /**
72
+ * Check if MediaPipe is configured (model path exists)
73
+ */
74
+ isConfigured() {
75
+ return !!this.modelPath;
76
+ }
77
+ /**
78
+ * Initialize the MediaPipe LLM Inference engine
79
+ * Called automatically on first request
80
+ */
81
+ async initialize() {
82
+ if (this.inference) {
83
+ return;
84
+ }
85
+ // Prevent multiple simultaneous initializations
86
+ if (this.initPromise) {
87
+ return this.initPromise;
88
+ }
89
+ this.initPromise = this.doInitialize();
90
+ await this.initPromise;
91
+ }
92
+ async doInitialize() {
93
+ try {
94
+ // Dynamic import of MediaPipe
95
+ // Users must install @mediapipe/tasks-genai separately
96
+ const mediapipe = await this.loadMediaPipe();
97
+ const maxTokens = this.config.maxTokens ?? 1024;
98
+ const temperature = this.config.temperature ?? 0.3;
99
+ const options = {
100
+ baseOptions: {
101
+ modelAssetPath: this.modelPath,
102
+ },
103
+ maxTokens,
104
+ temperature,
105
+ topK: this.topK,
106
+ };
107
+ if (this.randomSeed !== undefined) {
108
+ options.randomSeed = this.randomSeed;
109
+ }
110
+ if (this.loraRanks !== undefined) {
111
+ options.loraRanks = this.loraRanks;
112
+ }
113
+ this.inference = await mediapipe.LlmInference.createFromOptions(options);
114
+ }
115
+ catch (error) {
116
+ this.initPromise = null;
117
+ throw new LLMError(`Failed to initialize MediaPipe: ${error instanceof Error ? error.message : 'Unknown error'}. ` +
118
+ 'Make sure @mediapipe/tasks-genai is installed and the model file exists.', 'NOT_CONFIGURED', this.provider, error instanceof Error ? error : undefined);
119
+ }
120
+ }
121
+ /**
122
+ * Load MediaPipe library dynamically
123
+ */
124
+ async loadMediaPipe() {
125
+ try {
126
+ // Try to import the MediaPipe package dynamically
127
+ // @ts-expect-error - Dynamic import of optional dependency
128
+ const module = await import('@mediapipe/tasks-genai');
129
+ return module;
130
+ }
131
+ catch {
132
+ throw new Error('MediaPipe tasks-genai not found. Install it with: npm install @mediapipe/tasks-genai');
133
+ }
134
+ }
135
+ async complete(request) {
136
+ if (!this.isConfigured()) {
137
+ throw new LLMError('MediaPipe adapter is not configured. Provide modelPath in config.', 'NOT_CONFIGURED', this.provider);
138
+ }
139
+ // Initialize on first use
140
+ await this.initialize();
141
+ if (!this.inference) {
142
+ throw new LLMError('MediaPipe inference engine not initialized', 'NOT_CONFIGURED', this.provider);
143
+ }
144
+ // Build prompt from messages
145
+ const prompt = this.buildPrompt(request);
146
+ try {
147
+ const response = await this.inference.generateResponse(prompt);
148
+ return this.parseGeneratedResponse(response, prompt);
149
+ }
150
+ catch (error) {
151
+ throw new LLMError(`MediaPipe generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'API_ERROR', this.provider, error instanceof Error ? error : undefined);
152
+ }
153
+ }
154
+ /**
155
+ * Build a prompt string from chat messages
156
+ * Uses Gemma's instruction format
157
+ */
158
+ buildPrompt(request) {
159
+ const parts = [];
160
+ for (const message of request.messages) {
161
+ switch (message.role) {
162
+ case 'system':
163
+ // Gemma uses <start_of_turn> format
164
+ parts.push(`<start_of_turn>user\n${message.content}<end_of_turn>`);
165
+ break;
166
+ case 'user':
167
+ parts.push(`<start_of_turn>user\n${message.content}<end_of_turn>`);
168
+ break;
169
+ case 'assistant':
170
+ parts.push(`<start_of_turn>model\n${message.content}<end_of_turn>`);
171
+ break;
172
+ }
173
+ }
174
+ // Add model turn prefix
175
+ parts.push('<start_of_turn>model\n');
176
+ // Add JSON format instruction if requested
177
+ if (request.responseFormat === 'json') {
178
+ return parts.join('\n') + '\nRespond with valid JSON only:\n';
179
+ }
180
+ return parts.join('\n');
181
+ }
182
+ /**
183
+ * Parse the generated response
184
+ */
185
+ parseGeneratedResponse(response, prompt) {
186
+ // Estimate tokens (rough approximation: ~4 chars per token)
187
+ const promptTokens = Math.ceil(prompt.length / 4);
188
+ const completionTokens = Math.ceil(response.length / 4);
189
+ // Try to parse JSON if present
190
+ let json;
191
+ try {
192
+ json = this.parseJSON(response);
193
+ }
194
+ catch {
195
+ // Not JSON, that's fine
196
+ }
197
+ return {
198
+ content: response,
199
+ json,
200
+ usage: {
201
+ promptTokens,
202
+ completionTokens,
203
+ totalTokens: promptTokens + completionTokens,
204
+ },
205
+ model: this.config.model,
206
+ finishReason: 'stop', // MediaPipe doesn't provide finish reason, assume stop
207
+ };
208
+ }
209
+ /**
210
+ * Close the inference engine and release resources
211
+ */
212
+ close() {
213
+ if (this.inference) {
214
+ this.inference.close();
215
+ this.inference = null;
216
+ this.initPromise = null;
217
+ }
218
+ }
219
+ }
220
+ /**
221
+ * Create a MediaPipe adapter for local Gemma models
222
+ *
223
+ * @param modelPath - Path to the model file (.bin or .task)
224
+ * @param model - Model identifier (for reference)
225
+ * @param overrides - Additional configuration options
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * // Using a Gemma 3n model
230
+ * const adapter = createMediaPipeAdapter(
231
+ * '/models/gemma-3n-E2B-it-int4.task',
232
+ * 'gemma3n-e2b'
233
+ * );
234
+ *
235
+ * // With custom options
236
+ * const adapter = createMediaPipeAdapter(
237
+ * '/models/gemma2-2b-it-gpu-int4.bin',
238
+ * 'gemma2-2b',
239
+ * { maxTokens: 2048, temperature: 0.5 }
240
+ * );
241
+ * ```
242
+ */
243
+ export function createMediaPipeAdapter(modelPath, model = 'gemma3n', overrides) {
244
+ const config = {
245
+ provider: 'mediapipe',
246
+ model,
247
+ modelPath,
248
+ ...overrides,
249
+ };
250
+ return new MediaPipeAdapter(config);
251
+ }
252
+ //# sourceMappingURL=mediapipe.js.map