@visualprd/mcp-server 1.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.
Files changed (58) hide show
  1. package/README.md +396 -0
  2. package/dist/cli.d.ts +9 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +27 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +20 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +243 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/intelligence/context-optimizer.d.ts +93 -0
  11. package/dist/intelligence/context-optimizer.d.ts.map +1 -0
  12. package/dist/intelligence/context-optimizer.js +481 -0
  13. package/dist/intelligence/context-optimizer.js.map +1 -0
  14. package/dist/intelligence/error-analyzer.d.ts +49 -0
  15. package/dist/intelligence/error-analyzer.d.ts.map +1 -0
  16. package/dist/intelligence/error-analyzer.js +765 -0
  17. package/dist/intelligence/error-analyzer.js.map +1 -0
  18. package/dist/intelligence/gap-filler.d.ts +56 -0
  19. package/dist/intelligence/gap-filler.d.ts.map +1 -0
  20. package/dist/intelligence/gap-filler.js +410 -0
  21. package/dist/intelligence/gap-filler.js.map +1 -0
  22. package/dist/intelligence/guidance-generator.d.ts +43 -0
  23. package/dist/intelligence/guidance-generator.d.ts.map +1 -0
  24. package/dist/intelligence/guidance-generator.js +314 -0
  25. package/dist/intelligence/guidance-generator.js.map +1 -0
  26. package/dist/intelligence/index.d.ts +132 -0
  27. package/dist/intelligence/index.d.ts.map +1 -0
  28. package/dist/intelligence/index.js +683 -0
  29. package/dist/intelligence/index.js.map +1 -0
  30. package/dist/server-http.d.ts +9 -0
  31. package/dist/server-http.d.ts.map +1 -0
  32. package/dist/server-http.js +141 -0
  33. package/dist/server-http.js.map +1 -0
  34. package/dist/services/api-key-service.d.ts +68 -0
  35. package/dist/services/api-key-service.d.ts.map +1 -0
  36. package/dist/services/api-key-service.js +298 -0
  37. package/dist/services/api-key-service.js.map +1 -0
  38. package/dist/services/llm-client.d.ts +66 -0
  39. package/dist/services/llm-client.d.ts.map +1 -0
  40. package/dist/services/llm-client.js +141 -0
  41. package/dist/services/llm-client.js.map +1 -0
  42. package/dist/services/model-registry.d.ts +135 -0
  43. package/dist/services/model-registry.d.ts.map +1 -0
  44. package/dist/services/model-registry.js +276 -0
  45. package/dist/services/model-registry.js.map +1 -0
  46. package/dist/services/visualprd-client.d.ts +191 -0
  47. package/dist/services/visualprd-client.d.ts.map +1 -0
  48. package/dist/services/visualprd-client.js +805 -0
  49. package/dist/services/visualprd-client.js.map +1 -0
  50. package/dist/tools/index.d.ts +803 -0
  51. package/dist/tools/index.d.ts.map +1 -0
  52. package/dist/tools/index.js +570 -0
  53. package/dist/tools/index.js.map +1 -0
  54. package/dist/types/index.d.ts +497 -0
  55. package/dist/types/index.d.ts.map +1 -0
  56. package/dist/types/index.js +8 -0
  57. package/dist/types/index.js.map +1 -0
  58. package/package.json +48 -0
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * LLM Client
4
+ *
5
+ * Handles communication with LLM APIs via OpenRouter.
6
+ * Supports dynamic model switching for intelligent guidance.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LLMClient = void 0;
10
+ const DEFAULT_CONFIG = {
11
+ baseUrl: 'https://openrouter.ai/api/v1',
12
+ model: 'anthropic/claude-3.5-sonnet',
13
+ maxTokens: 4096,
14
+ temperature: 0.7,
15
+ };
16
+ class LLMClient {
17
+ config;
18
+ constructor(config) {
19
+ this.config = {
20
+ apiKey: config.apiKey || process.env.OPENROUTER_API_KEY || '',
21
+ model: config.model || DEFAULT_CONFIG.model,
22
+ baseUrl: config.baseUrl || DEFAULT_CONFIG.baseUrl,
23
+ maxTokens: config.maxTokens || DEFAULT_CONFIG.maxTokens,
24
+ temperature: config.temperature ?? DEFAULT_CONFIG.temperature,
25
+ };
26
+ }
27
+ /**
28
+ * Update the model dynamically (for real-time switching)
29
+ */
30
+ setModel(model) {
31
+ console.error(`[LLMClient] Switching model from ${this.config.model} to ${model}`);
32
+ this.config.model = model;
33
+ }
34
+ /**
35
+ * Get the current model
36
+ */
37
+ getModel() {
38
+ return this.config.model;
39
+ }
40
+ /**
41
+ * Send a completion request to the LLM
42
+ */
43
+ async complete(messages, options) {
44
+ if (!this.config.apiKey) {
45
+ throw new Error('OpenRouter API key is not configured');
46
+ }
47
+ const requestBody = {
48
+ model: this.config.model,
49
+ messages,
50
+ max_tokens: options?.maxTokens || this.config.maxTokens,
51
+ temperature: options?.temperature ?? this.config.temperature,
52
+ };
53
+ if (options?.jsonMode) {
54
+ requestBody.response_format = { type: 'json_object' };
55
+ }
56
+ console.error(`[LLMClient] Calling ${this.config.model} with ${messages.length} messages`);
57
+ const response = await fetch(`${this.config.baseUrl}/chat/completions`, {
58
+ method: 'POST',
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ Authorization: `Bearer ${this.config.apiKey}`,
62
+ 'HTTP-Referer': 'https://visualprd.com',
63
+ 'X-Title': 'VisualPRD MCP Server',
64
+ },
65
+ body: JSON.stringify(requestBody),
66
+ });
67
+ if (!response.ok) {
68
+ const errorText = await response.text();
69
+ console.error(`[LLMClient] API error: ${response.status} - ${errorText}`);
70
+ throw new Error(`LLM API error: ${response.status} - ${errorText}`);
71
+ }
72
+ const data = await response.json();
73
+ const choice = data.choices?.[0];
74
+ if (!choice) {
75
+ throw new Error('No response from LLM');
76
+ }
77
+ const result = {
78
+ content: choice.message?.content || '',
79
+ model: data.model || this.config.model,
80
+ tokensUsed: {
81
+ prompt: data.usage?.prompt_tokens || 0,
82
+ completion: data.usage?.completion_tokens || 0,
83
+ total: data.usage?.total_tokens || 0,
84
+ },
85
+ finishReason: choice.finish_reason || 'unknown',
86
+ };
87
+ console.error(`[LLMClient] Response received: ${result.tokensUsed.total} tokens`);
88
+ return result;
89
+ }
90
+ /**
91
+ * Analyze data with a structured JSON response
92
+ */
93
+ async analyzeJSON(systemPrompt, userPrompt, options) {
94
+ const messages = [
95
+ { role: 'system', content: systemPrompt },
96
+ { role: 'user', content: userPrompt },
97
+ ];
98
+ const response = await this.complete(messages, {
99
+ maxTokens: options?.maxTokens,
100
+ jsonMode: true,
101
+ temperature: 0.5, // Lower temp for structured output
102
+ });
103
+ try {
104
+ // Try to parse as JSON
105
+ let jsonContent = response.content.trim();
106
+ // Handle markdown code blocks
107
+ if (jsonContent.startsWith('```json')) {
108
+ jsonContent = jsonContent.slice(7);
109
+ }
110
+ if (jsonContent.startsWith('```')) {
111
+ jsonContent = jsonContent.slice(3);
112
+ }
113
+ if (jsonContent.endsWith('```')) {
114
+ jsonContent = jsonContent.slice(0, -3);
115
+ }
116
+ const result = JSON.parse(jsonContent.trim());
117
+ return { result, tokensUsed: response.tokensUsed.total };
118
+ }
119
+ catch (error) {
120
+ console.error('[LLMClient] Failed to parse JSON response:', error);
121
+ console.error('[LLMClient] Raw response:', response.content);
122
+ throw new Error('Failed to parse LLM JSON response');
123
+ }
124
+ }
125
+ /**
126
+ * Simple text generation for guidance
127
+ */
128
+ async generateText(systemPrompt, userPrompt, options) {
129
+ const messages = [
130
+ { role: 'system', content: systemPrompt },
131
+ { role: 'user', content: userPrompt },
132
+ ];
133
+ const response = await this.complete(messages, {
134
+ maxTokens: options?.maxTokens,
135
+ temperature: 0.7,
136
+ });
137
+ return { text: response.content, tokensUsed: response.tokensUsed.total };
138
+ }
139
+ }
140
+ exports.LLMClient = LLMClient;
141
+ //# sourceMappingURL=llm-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../../src/services/llm-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Model Registry Service for MCP Server
3
+ *
4
+ * Connects to Firestore to load:
5
+ * 1. User's model preferences from users/{userId}/mcpSettings
6
+ * 2. Centralized model registry from system/models
7
+ *
8
+ * This allows the MCP server to use user-configured AI models
9
+ * for thinking, vision, and execution tasks.
10
+ */
11
+ export interface MCPModel {
12
+ id: string;
13
+ name: string;
14
+ provider: string;
15
+ description?: string;
16
+ enabled: boolean;
17
+ categories: ('thinking' | 'vision' | 'execution')[];
18
+ pricing: {
19
+ inputCostPer1M: number;
20
+ outputCostPer1M: number;
21
+ };
22
+ contextWindow: number;
23
+ supportsVision?: boolean;
24
+ supportsToolCalling?: boolean;
25
+ supportsDeepThinking?: boolean;
26
+ supportsInternetSearch?: boolean;
27
+ costTier: 'affordable' | 'medium' | 'high';
28
+ status: 'online' | 'degraded' | 'offline';
29
+ }
30
+ export interface UserMCPSettings {
31
+ enabled: boolean;
32
+ thinkingModel: string;
33
+ preferredTier: 'lite' | 'pro' | 'unlimited';
34
+ usage?: {
35
+ totalCalls: number;
36
+ totalTokens: number;
37
+ aiCallsMade: number;
38
+ ruleBasedCalls: number;
39
+ lastUsed?: Date;
40
+ };
41
+ apiKeyConfigured: boolean;
42
+ }
43
+ export interface ModelRegistry {
44
+ mcpModels: MCPModel[];
45
+ defaultModels: {
46
+ free: {
47
+ vision: string;
48
+ thinking: string;
49
+ execution: string;
50
+ };
51
+ lite: {
52
+ vision: string;
53
+ thinking: string;
54
+ execution: string;
55
+ };
56
+ pro: {
57
+ vision: string;
58
+ thinking: string;
59
+ execution: string;
60
+ };
61
+ unlimited: {
62
+ vision: string;
63
+ thinking: string;
64
+ execution: string;
65
+ };
66
+ };
67
+ phaseModels?: Record<string, Record<string, string>>;
68
+ version: number;
69
+ }
70
+ export interface ModelConfig {
71
+ thinkingModel: string;
72
+ visionModel?: string;
73
+ executionModel?: string;
74
+ userTier: 'free' | 'lite' | 'pro' | 'unlimited';
75
+ source: 'user_preference' | 'tier_default' | 'fallback';
76
+ }
77
+ export declare class ModelRegistryService {
78
+ private db;
79
+ private registryCache;
80
+ private cacheTimestamp;
81
+ private readonly CACHE_TTL_MS;
82
+ constructor();
83
+ /**
84
+ * Get model configuration for a user.
85
+ * Loads user preferences and falls back to tier defaults.
86
+ */
87
+ getModelConfig(userId: string): Promise<ModelConfig>;
88
+ /**
89
+ * Load user's MCP settings from Firestore.
90
+ */
91
+ getUserSettings(userId: string): Promise<UserMCPSettings | null>;
92
+ /**
93
+ * Load the centralized model registry.
94
+ * Uses caching to reduce Firestore reads.
95
+ */
96
+ getRegistry(): Promise<ModelRegistry>;
97
+ /**
98
+ * Get a specific model by ID.
99
+ */
100
+ getModel(modelId: string): Promise<MCPModel | null>;
101
+ /**
102
+ * Get model pricing for cost calculations.
103
+ */
104
+ getModelPricing(modelId: string): Promise<{
105
+ input: number;
106
+ output: number;
107
+ }>;
108
+ /**
109
+ * Get all enabled models for a specific role.
110
+ */
111
+ getModelsForRole(role: 'thinking' | 'vision' | 'execution'): Promise<MCPModel[]>;
112
+ /**
113
+ * Get fallback models for a given model.
114
+ * Used when the primary model fails.
115
+ */
116
+ getFallbackModels(modelId: string, role: 'thinking' | 'vision' | 'execution'): Promise<string[]>;
117
+ /**
118
+ * Calculate cost for an API call.
119
+ */
120
+ calculateCost(modelId: string, inputTokens: number, outputTokens: number): Promise<number>;
121
+ /**
122
+ * Record usage for tracking.
123
+ */
124
+ recordUsage(userId: string, modelId: string, inputTokens: number, outputTokens: number, costUSD: number): Promise<void>;
125
+ /**
126
+ * Clear the registry cache.
127
+ */
128
+ clearCache(): void;
129
+ /**
130
+ * Get default registry when Firestore is unavailable.
131
+ */
132
+ private getDefaultRegistry;
133
+ }
134
+ export declare function getModelRegistryService(): ModelRegistryService;
135
+ //# sourceMappingURL=model-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/services/model-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ /**
3
+ * Model Registry Service for MCP Server
4
+ *
5
+ * Connects to Firestore to load:
6
+ * 1. User's model preferences from users/{userId}/mcpSettings
7
+ * 2. Centralized model registry from system/models
8
+ *
9
+ * This allows the MCP server to use user-configured AI models
10
+ * for thinking, vision, and execution tasks.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.ModelRegistryService = void 0;
14
+ exports.getModelRegistryService = getModelRegistryService;
15
+ const firestore_1 = require("@google-cloud/firestore");
16
+ // ============================================================================
17
+ // DEFAULT MODELS (Fallback if Firestore unavailable)
18
+ // ============================================================================
19
+ const DEFAULT_MODELS = {
20
+ free: {
21
+ thinking: 'google/gemini-2.0-flash-lite-001',
22
+ vision: 'openai/gpt-4o-mini',
23
+ execution: 'google/gemini-2.0-flash-lite-001',
24
+ },
25
+ lite: {
26
+ thinking: 'google/gemini-2.0-flash-001',
27
+ vision: 'openai/gpt-4o-mini',
28
+ execution: 'google/gemini-2.0-flash-001',
29
+ },
30
+ pro: {
31
+ thinking: 'anthropic/claude-sonnet-4',
32
+ vision: 'openai/gpt-4o',
33
+ execution: 'openai/gpt-4o',
34
+ },
35
+ unlimited: {
36
+ thinking: 'anthropic/claude-sonnet-4',
37
+ vision: 'openai/gpt-4o',
38
+ execution: 'openai/gpt-4o',
39
+ },
40
+ };
41
+ // ============================================================================
42
+ // MODEL REGISTRY SERVICE
43
+ // ============================================================================
44
+ class ModelRegistryService {
45
+ db;
46
+ registryCache = null;
47
+ cacheTimestamp = 0;
48
+ CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
49
+ constructor() {
50
+ this.db = new firestore_1.Firestore({
51
+ projectId: process.env.FIREBASE_PROJECT_ID || 'visualprd-staging',
52
+ });
53
+ }
54
+ /**
55
+ * Get model configuration for a user.
56
+ * Loads user preferences and falls back to tier defaults.
57
+ */
58
+ async getModelConfig(userId) {
59
+ try {
60
+ // Load user's MCP settings
61
+ const userSettings = await this.getUserSettings(userId);
62
+ // Determine user tier
63
+ const userTier = userSettings?.preferredTier || 'free';
64
+ // If user has a custom thinking model, use it
65
+ if (userSettings?.thinkingModel) {
66
+ return {
67
+ thinkingModel: userSettings.thinkingModel,
68
+ visionModel: undefined, // Can be extended later
69
+ executionModel: undefined,
70
+ userTier,
71
+ source: 'user_preference',
72
+ };
73
+ }
74
+ // Fall back to tier defaults from registry
75
+ const registry = await this.getRegistry();
76
+ const defaults = registry.defaultModels[userTier] || DEFAULT_MODELS[userTier];
77
+ return {
78
+ thinkingModel: defaults.thinking,
79
+ visionModel: defaults.vision,
80
+ executionModel: defaults.execution,
81
+ userTier,
82
+ source: 'tier_default',
83
+ };
84
+ }
85
+ catch (error) {
86
+ console.error('[ModelRegistry] Error loading model config:', error);
87
+ // Ultimate fallback
88
+ return {
89
+ thinkingModel: DEFAULT_MODELS.free.thinking,
90
+ visionModel: DEFAULT_MODELS.free.vision,
91
+ executionModel: DEFAULT_MODELS.free.execution,
92
+ userTier: 'free',
93
+ source: 'fallback',
94
+ };
95
+ }
96
+ }
97
+ /**
98
+ * Load user's MCP settings from Firestore.
99
+ */
100
+ async getUserSettings(userId) {
101
+ try {
102
+ const settingsRef = this.db.collection('users').doc(userId).collection('mcpSettings').doc('settings');
103
+ const doc = await settingsRef.get();
104
+ if (!doc.exists) {
105
+ console.log(`[ModelRegistry] No MCP settings for user ${userId}`);
106
+ return null;
107
+ }
108
+ return doc.data();
109
+ }
110
+ catch (error) {
111
+ console.error(`[ModelRegistry] Error loading user settings:`, error);
112
+ return null;
113
+ }
114
+ }
115
+ /**
116
+ * Load the centralized model registry.
117
+ * Uses caching to reduce Firestore reads.
118
+ */
119
+ async getRegistry() {
120
+ // Check cache
121
+ if (this.registryCache && (Date.now() - this.cacheTimestamp < this.CACHE_TTL_MS)) {
122
+ return this.registryCache;
123
+ }
124
+ try {
125
+ const registryRef = this.db.collection('system').doc('models');
126
+ const doc = await registryRef.get();
127
+ if (!doc.exists) {
128
+ console.log('[ModelRegistry] No registry found, using defaults');
129
+ return this.getDefaultRegistry();
130
+ }
131
+ const data = doc.data();
132
+ this.registryCache = data;
133
+ this.cacheTimestamp = Date.now();
134
+ console.log(`[ModelRegistry] Loaded ${data.mcpModels?.length || 0} models from registry`);
135
+ return data;
136
+ }
137
+ catch (error) {
138
+ console.error('[ModelRegistry] Error loading registry:', error);
139
+ return this.getDefaultRegistry();
140
+ }
141
+ }
142
+ /**
143
+ * Get a specific model by ID.
144
+ */
145
+ async getModel(modelId) {
146
+ const registry = await this.getRegistry();
147
+ return registry.mcpModels?.find(m => m.id === modelId) || null;
148
+ }
149
+ /**
150
+ * Get model pricing for cost calculations.
151
+ */
152
+ async getModelPricing(modelId) {
153
+ const model = await this.getModel(modelId);
154
+ if (model) {
155
+ return {
156
+ input: model.pricing.inputCostPer1M,
157
+ output: model.pricing.outputCostPer1M,
158
+ };
159
+ }
160
+ // Conservative default if model not found
161
+ console.warn(`[ModelRegistry] Model ${modelId} not found, using default pricing`);
162
+ return { input: 3.0, output: 15.0 };
163
+ }
164
+ /**
165
+ * Get all enabled models for a specific role.
166
+ */
167
+ async getModelsForRole(role) {
168
+ const registry = await this.getRegistry();
169
+ return (registry.mcpModels || [])
170
+ .filter(m => m.enabled && m.categories.includes(role))
171
+ .sort((a, b) => {
172
+ // Sort by cost tier (affordable first)
173
+ const tierOrder = { affordable: 0, medium: 1, high: 2 };
174
+ return (tierOrder[a.costTier] || 1) - (tierOrder[b.costTier] || 1);
175
+ });
176
+ }
177
+ /**
178
+ * Get fallback models for a given model.
179
+ * Used when the primary model fails.
180
+ */
181
+ async getFallbackModels(modelId, role) {
182
+ const registry = await this.getRegistry();
183
+ const primaryModel = registry.mcpModels?.find(m => m.id === modelId);
184
+ if (!primaryModel) {
185
+ // Return tier defaults
186
+ return [DEFAULT_MODELS.free[role]];
187
+ }
188
+ // Get models in same category, sorted by cost (cheaper first)
189
+ const fallbacks = (registry.mcpModels || [])
190
+ .filter(m => m.id !== modelId &&
191
+ m.enabled &&
192
+ m.categories.includes(role) &&
193
+ m.status === 'online')
194
+ .sort((a, b) => a.pricing.inputCostPer1M - b.pricing.inputCostPer1M)
195
+ .map(m => m.id);
196
+ return fallbacks;
197
+ }
198
+ /**
199
+ * Calculate cost for an API call.
200
+ */
201
+ async calculateCost(modelId, inputTokens, outputTokens) {
202
+ const pricing = await this.getModelPricing(modelId);
203
+ const inputCost = (inputTokens / 1_000_000) * pricing.input;
204
+ const outputCost = (outputTokens / 1_000_000) * pricing.output;
205
+ return inputCost + outputCost;
206
+ }
207
+ /**
208
+ * Record usage for tracking.
209
+ */
210
+ async recordUsage(userId, modelId, inputTokens, outputTokens, costUSD) {
211
+ try {
212
+ const budgetRef = this.db
213
+ .collection('users')
214
+ .doc(userId)
215
+ .collection('mcpBudget')
216
+ .doc('budget');
217
+ const doc = await budgetRef.get();
218
+ if (doc.exists) {
219
+ const data = doc.data();
220
+ const currentMonth = data.currentMonth || {
221
+ totalCostUSD: 0,
222
+ tokenCount: { input: 0, output: 0 },
223
+ callCount: 0,
224
+ byModel: {},
225
+ byTool: {},
226
+ };
227
+ // Update totals
228
+ currentMonth.totalCostUSD += costUSD;
229
+ currentMonth.tokenCount.input += inputTokens;
230
+ currentMonth.tokenCount.output += outputTokens;
231
+ currentMonth.callCount += 1;
232
+ // Update by-model breakdown
233
+ if (!currentMonth.byModel[modelId]) {
234
+ currentMonth.byModel[modelId] = { costUSD: 0, calls: 0, tokensIn: 0, tokensOut: 0 };
235
+ }
236
+ currentMonth.byModel[modelId].costUSD += costUSD;
237
+ currentMonth.byModel[modelId].calls += 1;
238
+ currentMonth.byModel[modelId].tokensIn += inputTokens;
239
+ currentMonth.byModel[modelId].tokensOut += outputTokens;
240
+ await budgetRef.update({ currentMonth, updatedAt: new Date() });
241
+ }
242
+ }
243
+ catch (error) {
244
+ console.error('[ModelRegistry] Error recording usage:', error);
245
+ // Don't throw - usage recording is non-critical
246
+ }
247
+ }
248
+ /**
249
+ * Clear the registry cache.
250
+ */
251
+ clearCache() {
252
+ this.registryCache = null;
253
+ this.cacheTimestamp = 0;
254
+ console.log('[ModelRegistry] Cache cleared');
255
+ }
256
+ /**
257
+ * Get default registry when Firestore is unavailable.
258
+ */
259
+ getDefaultRegistry() {
260
+ return {
261
+ mcpModels: [],
262
+ defaultModels: DEFAULT_MODELS,
263
+ version: 0,
264
+ };
265
+ }
266
+ }
267
+ exports.ModelRegistryService = ModelRegistryService;
268
+ // Singleton instance
269
+ let _instance = null;
270
+ function getModelRegistryService() {
271
+ if (!_instance) {
272
+ _instance = new ModelRegistryService();
273
+ }
274
+ return _instance;
275
+ }
276
+ //# sourceMappingURL=model-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/services/model-registry.ts"],"names":[],"mappings":"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"}