@houtini/lm 2.4.1 → 2.8.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.
@@ -0,0 +1,557 @@
1
+ /**
2
+ * SQLite-backed model profile cache.
3
+ *
4
+ * On startup, houtini-lm fetches available models from the LLM server and
5
+ * looks up each one on HuggingFace's free API. The results are cached in a
6
+ * local SQLite database so subsequent startups are instant (no network).
7
+ *
8
+ * Uses sql.js (pure WASM) — zero native deps, works everywhere.
9
+ */
10
+ import initSqlJs from 'sql.js';
11
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ import { homedir } from 'node:os';
14
+ const PROMPT_HINTS = [
15
+ {
16
+ pattern: /glm[- ]?4/i,
17
+ hints: {
18
+ codeTemp: 0.1,
19
+ chatTemp: 0.3,
20
+ outputConstraint: 'Respond with ONLY the requested output. No step-by-step reasoning. No preamble. Use markdown formatting: bullet points for lists, fenced code blocks for code.',
21
+ bestTaskTypes: ['chat', 'analysis'],
22
+ },
23
+ },
24
+ {
25
+ pattern: /qwen3.*coder|qwen.*coder/i,
26
+ hints: {
27
+ codeTemp: 0.1,
28
+ chatTemp: 0.3,
29
+ outputConstraint: 'Be direct. Output only what was asked for. Use markdown formatting: bullet points for lists, fenced code blocks for code. No preamble.',
30
+ bestTaskTypes: ['code'],
31
+ },
32
+ },
33
+ {
34
+ pattern: /qwen3(?!.*coder)(?!.*vl)/i,
35
+ hints: {
36
+ codeTemp: 0.2,
37
+ chatTemp: 0.3,
38
+ outputConstraint: 'Be direct. Output only what was asked for. Use markdown formatting: bullet points for lists, fenced code blocks for code. No preamble.',
39
+ bestTaskTypes: ['chat', 'analysis', 'code'],
40
+ },
41
+ },
42
+ {
43
+ pattern: /llama[- ]?3/i,
44
+ hints: {
45
+ codeTemp: 0.2,
46
+ chatTemp: 0.4,
47
+ outputConstraint: '',
48
+ bestTaskTypes: ['chat', 'code', 'analysis'],
49
+ },
50
+ },
51
+ {
52
+ pattern: /nemotron/i,
53
+ hints: {
54
+ codeTemp: 0.1,
55
+ chatTemp: 0.3,
56
+ outputConstraint: '',
57
+ bestTaskTypes: ['analysis', 'code'],
58
+ },
59
+ },
60
+ {
61
+ pattern: /granite/i,
62
+ hints: {
63
+ codeTemp: 0.2,
64
+ chatTemp: 0.3,
65
+ outputConstraint: '',
66
+ bestTaskTypes: ['code', 'chat'],
67
+ },
68
+ },
69
+ {
70
+ pattern: /gpt[- ]?oss/i,
71
+ hints: {
72
+ codeTemp: 0.2,
73
+ chatTemp: 0.4,
74
+ outputConstraint: '',
75
+ bestTaskTypes: ['chat', 'code', 'analysis'],
76
+ },
77
+ },
78
+ {
79
+ pattern: /nomic.*embed|embed.*nomic/i,
80
+ hints: {
81
+ codeTemp: 0,
82
+ chatTemp: 0,
83
+ outputConstraint: '',
84
+ bestTaskTypes: ['embedding'],
85
+ },
86
+ },
87
+ ];
88
+ /**
89
+ * Get prompt hints for a model by ID or architecture.
90
+ */
91
+ export function getPromptHints(modelId, arch) {
92
+ for (const { pattern, hints } of PROMPT_HINTS) {
93
+ if (pattern.test(modelId))
94
+ return hints;
95
+ if (arch && pattern.test(arch))
96
+ return hints;
97
+ }
98
+ // Sensible defaults for unknown models
99
+ return {
100
+ codeTemp: 0.2,
101
+ chatTemp: 0.3,
102
+ outputConstraint: '',
103
+ bestTaskTypes: ['chat', 'code', 'analysis'],
104
+ };
105
+ }
106
+ // ── Constants ────────────────────────────────────────────────────────
107
+ const DB_DIR = join(homedir(), '.houtini-lm');
108
+ const DB_PATH = join(DB_DIR, 'model-cache.db');
109
+ const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
110
+ const HF_TIMEOUT_MS = 8000;
111
+ // ── Database ─────────────────────────────────────────────────────────
112
+ let db = null;
113
+ export async function initDb() {
114
+ if (db)
115
+ return db;
116
+ const SQL = await initSqlJs();
117
+ // Load existing DB from disk if it exists
118
+ if (existsSync(DB_PATH)) {
119
+ try {
120
+ const buf = readFileSync(DB_PATH);
121
+ db = new SQL.Database(buf);
122
+ }
123
+ catch {
124
+ // Corrupt DB — start fresh
125
+ db = new SQL.Database();
126
+ }
127
+ }
128
+ else {
129
+ db = new SQL.Database();
130
+ }
131
+ // Create table if not exists
132
+ db.run(`
133
+ CREATE TABLE IF NOT EXISTS model_profiles (
134
+ model_id TEXT PRIMARY KEY,
135
+ hf_id TEXT,
136
+ pipeline_tag TEXT,
137
+ architectures TEXT,
138
+ license TEXT,
139
+ downloads INTEGER,
140
+ likes INTEGER,
141
+ library_name TEXT,
142
+ family TEXT,
143
+ description TEXT,
144
+ strengths TEXT,
145
+ weaknesses TEXT,
146
+ best_for TEXT,
147
+ emits_think_blocks INTEGER NOT NULL DEFAULT 0,
148
+ supports_thinking_toggle INTEGER NOT NULL DEFAULT 0,
149
+ fetched_at INTEGER NOT NULL,
150
+ source TEXT NOT NULL DEFAULT 'huggingface'
151
+ )
152
+ `);
153
+ // Migrate: add thinking columns if upgrading from older schema
154
+ try {
155
+ db.run('ALTER TABLE model_profiles ADD COLUMN emits_think_blocks INTEGER NOT NULL DEFAULT 0');
156
+ }
157
+ catch { /* column already exists */ }
158
+ try {
159
+ db.run('ALTER TABLE model_profiles ADD COLUMN supports_thinking_toggle INTEGER NOT NULL DEFAULT 0');
160
+ }
161
+ catch { /* column already exists */ }
162
+ return db;
163
+ }
164
+ function saveDb() {
165
+ if (!db)
166
+ return;
167
+ try {
168
+ mkdirSync(DB_DIR, { recursive: true });
169
+ const data = db.export();
170
+ writeFileSync(DB_PATH, Buffer.from(data));
171
+ }
172
+ catch (err) {
173
+ process.stderr.write(`[houtini-lm] Failed to save model cache: ${err}\n`);
174
+ }
175
+ }
176
+ // ── Cache operations ─────────────────────────────────────────────────
177
+ export async function getCachedProfile(modelId) {
178
+ const database = await initDb();
179
+ const stmt = database.prepare('SELECT * FROM model_profiles WHERE model_id = ?');
180
+ try {
181
+ stmt.bind([modelId]);
182
+ if (stmt.step()) {
183
+ const row = stmt.getAsObject();
184
+ return {
185
+ modelId: row.model_id,
186
+ hfId: row.hf_id,
187
+ pipelineTag: row.pipeline_tag,
188
+ architectures: row.architectures,
189
+ license: row.license,
190
+ downloads: row.downloads,
191
+ likes: row.likes,
192
+ libraryName: row.library_name,
193
+ family: row.family,
194
+ description: row.description,
195
+ strengths: row.strengths,
196
+ weaknesses: row.weaknesses,
197
+ bestFor: row.best_for,
198
+ emitsThinkBlocks: !!row.emits_think_blocks,
199
+ supportsThinkingToggle: !!row.supports_thinking_toggle,
200
+ fetchedAt: row.fetched_at,
201
+ source: row.source,
202
+ };
203
+ }
204
+ return null;
205
+ }
206
+ finally {
207
+ stmt.free();
208
+ }
209
+ }
210
+ /**
211
+ * Insert or update a profile in the DB. Saves to disk immediately by default.
212
+ * Pass skipSave=true during batch operations, then call flushDb() when done.
213
+ */
214
+ export async function upsertProfile(profile, skipSave = false) {
215
+ const database = await initDb();
216
+ database.run(`INSERT OR REPLACE INTO model_profiles
217
+ (model_id, hf_id, pipeline_tag, architectures, license, downloads, likes, library_name,
218
+ family, description, strengths, weaknesses, best_for, emits_think_blocks, supports_thinking_toggle, fetched_at, source)
219
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
220
+ profile.modelId,
221
+ profile.hfId,
222
+ profile.pipelineTag,
223
+ profile.architectures,
224
+ profile.license,
225
+ profile.downloads,
226
+ profile.likes,
227
+ profile.libraryName,
228
+ profile.family,
229
+ profile.description,
230
+ profile.strengths,
231
+ profile.weaknesses,
232
+ profile.bestFor,
233
+ profile.emitsThinkBlocks ? 1 : 0,
234
+ profile.supportsThinkingToggle ? 1 : 0,
235
+ profile.fetchedAt,
236
+ profile.source,
237
+ ]);
238
+ if (!skipSave)
239
+ saveDb();
240
+ }
241
+ /** Flush DB to disk. Call after batch upsertProfile(…, true) operations. */
242
+ export function flushDb() {
243
+ saveDb();
244
+ }
245
+ export function isCacheStale(profile) {
246
+ return Date.now() - profile.fetchedAt > CACHE_TTL_MS;
247
+ }
248
+ /**
249
+ * Convert a cached profile to the ModelProfile format used by the rest of the app.
250
+ */
251
+ export function toModelProfile(cached) {
252
+ if (!cached.family || !cached.description)
253
+ return null;
254
+ return {
255
+ family: cached.family,
256
+ description: cached.description,
257
+ strengths: cached.strengths ? JSON.parse(cached.strengths) : [],
258
+ weaknesses: cached.weaknesses ? JSON.parse(cached.weaknesses) : [],
259
+ bestFor: cached.bestFor ? JSON.parse(cached.bestFor) : [],
260
+ };
261
+ }
262
+ /**
263
+ * Detect thinking/reasoning support from HF model metadata.
264
+ * Checks the chat_template for enable_thinking and <think> patterns,
265
+ * rather than hardcoding per-family knowledge.
266
+ */
267
+ function detectThinkingSupport(card) {
268
+ const chatTemplate = card.config?.tokenizer_config?.chat_template || '';
269
+ // Does the template reference <think> blocks at all?
270
+ const emitsThinkBlocks = /<think>/.test(chatTemplate) || /thinking/.test(chatTemplate.toLowerCase());
271
+ // Does the template support enable_thinking toggle? (Qwen3 pattern)
272
+ const supportsThinkingToggle = /enable_thinking/.test(chatTemplate);
273
+ return { emitsThinkBlocks, supportsThinkingToggle };
274
+ }
275
+ async function fetchHF(url) {
276
+ const controller = new AbortController();
277
+ const timer = setTimeout(() => controller.abort(), HF_TIMEOUT_MS);
278
+ try {
279
+ return await fetch(url, { headers: { Accept: 'application/json' }, signal: controller.signal });
280
+ }
281
+ finally {
282
+ clearTimeout(timer);
283
+ }
284
+ }
285
+ /**
286
+ * Try to find a model on HuggingFace given a local model ID and optional publisher.
287
+ * Returns the HF card or null.
288
+ */
289
+ async function lookupHF(modelId, publisher) {
290
+ const candidates = [];
291
+ if (modelId.includes('/')) {
292
+ candidates.push(modelId);
293
+ }
294
+ if (publisher && !modelId.includes('/')) {
295
+ candidates.push(`${publisher}/${modelId}`);
296
+ }
297
+ for (const hfId of candidates) {
298
+ try {
299
+ const res = await fetchHF(`https://huggingface.co/api/models/${hfId}`);
300
+ if (res.ok)
301
+ return (await res.json());
302
+ }
303
+ catch {
304
+ // skip
305
+ }
306
+ }
307
+ return null;
308
+ }
309
+ // ── Auto-profile generation ──────────────────────────────────────────
310
+ // When HF gives us metadata but we don't have a hardcoded profile,
311
+ // generate a reasonable one from the available data.
312
+ function inferProfileFromHF(card, modelId) {
313
+ const tag = card.pipeline_tag || '';
314
+ const tags = card.tags || [];
315
+ const arch = card.config?.architectures?.[0] || '';
316
+ // Extract org/family from HF ID
317
+ const parts = card.id.split('/');
318
+ const org = parts.length > 1 ? parts[0] : '';
319
+ const modelName = parts.length > 1 ? parts[1] : parts[0];
320
+ // Infer family name from model ID
321
+ const family = inferFamily(modelName, org);
322
+ // Infer description
323
+ let description = `${org ? org + "'s " : ''}${family} model.`;
324
+ if (tag === 'text-generation')
325
+ description += ' Text generation / chat model.';
326
+ else if (tag === 'image-text-to-text')
327
+ description += ' Vision-language model — handles text and image inputs.';
328
+ else if (tag === 'feature-extraction' || tag === 'sentence-similarity')
329
+ description += ' Embedding model for semantic search.';
330
+ if (card.cardData?.license)
331
+ description += ` License: ${card.cardData.license}.`;
332
+ // Infer strengths from tags
333
+ const strengths = [];
334
+ const weaknesses = [];
335
+ const bestFor = [];
336
+ if (tag === 'text-generation') {
337
+ strengths.push('text generation', 'instruction following');
338
+ bestFor.push('general delegation', 'Q&A');
339
+ }
340
+ if (tag === 'image-text-to-text') {
341
+ strengths.push('image understanding', 'visual Q&A');
342
+ bestFor.push('screenshot analysis', 'diagram interpretation');
343
+ }
344
+ if (tags.includes('code') || modelName.toLowerCase().includes('code')) {
345
+ strengths.push('code generation');
346
+ bestFor.push('code tasks');
347
+ }
348
+ if (tags.includes('math') || modelName.toLowerCase().includes('math')) {
349
+ strengths.push('mathematics', 'reasoning');
350
+ bestFor.push('math/science questions');
351
+ }
352
+ if (tags.includes('conversational')) {
353
+ strengths.push('conversation');
354
+ bestFor.push('chat', 'brainstorming');
355
+ }
356
+ // Default if nothing specific found
357
+ if (strengths.length === 0)
358
+ strengths.push('general reasoning');
359
+ if (bestFor.length === 0)
360
+ bestFor.push('general delegation');
361
+ const thinking = detectThinkingSupport(card);
362
+ return {
363
+ family,
364
+ description,
365
+ strengths: JSON.stringify(strengths),
366
+ weaknesses: JSON.stringify(weaknesses),
367
+ bestFor: JSON.stringify(bestFor),
368
+ emitsThinkBlocks: thinking.emitsThinkBlocks,
369
+ supportsThinkingToggle: thinking.supportsThinkingToggle,
370
+ };
371
+ }
372
+ function inferFamily(modelName, org) {
373
+ // Try to extract a clean family name from the model ID
374
+ // e.g. "glm-4.7-flash" -> "GLM-4", "qwen3-coder-30b" -> "Qwen3 Coder"
375
+ const lower = modelName.toLowerCase();
376
+ // Common patterns
377
+ const familyPatterns = [
378
+ [/^glm[- ]?(\d)/i, 'GLM-$1'],
379
+ [/^qwen(\d)[- ]?coder/i, 'Qwen$1 Coder'],
380
+ [/^qwen(\d)[- ]?vl/i, 'Qwen$1 VL'],
381
+ [/^qwen(\d)/i, 'Qwen$1'],
382
+ [/^llama[- ]?(\d)/i, 'LLaMA $1'],
383
+ [/^nemotron/i, 'Nemotron'],
384
+ [/^granite/i, 'Granite'],
385
+ [/^mistral/i, 'Mistral'],
386
+ [/^mixtral/i, 'Mixtral'],
387
+ [/^deepseek/i, 'DeepSeek'],
388
+ [/^phi[- ]?(\d)/i, 'Phi-$1'],
389
+ [/^gemma[- ]?(\d)/i, 'Gemma $1'],
390
+ [/^starcoder/i, 'StarCoder'],
391
+ [/^codestral/i, 'Codestral'],
392
+ [/^command[- ]?r/i, 'Command R'],
393
+ [/^internlm/i, 'InternLM'],
394
+ [/^yi[- ]?(\d)/i, 'Yi-$1'],
395
+ [/^nomic/i, 'Nomic'],
396
+ [/^gpt[- ]?oss/i, 'GPT-OSS'],
397
+ [/^minimax/i, 'MiniMax'],
398
+ [/^kimi/i, 'Kimi'],
399
+ ];
400
+ for (const [pattern, replacement] of familyPatterns) {
401
+ if (pattern.test(lower)) {
402
+ return modelName.replace(pattern, replacement);
403
+ }
404
+ }
405
+ // Fallback: use org + first meaningful part of name
406
+ const firstPart = modelName.split(/[-_ ]/)[0];
407
+ return org ? `${org}/${firstPart}` : firstPart;
408
+ }
409
+ /**
410
+ * Profile all models at startup. For each model:
411
+ * 1. Check SQLite cache — if fresh, skip
412
+ * 2. Look up on HuggingFace — if found, auto-generate profile and cache
413
+ * 3. If HF miss, cache as "inferred" with whatever metadata we have
414
+ *
415
+ * Runs in the background — never blocks server startup.
416
+ */
417
+ export async function profileModelsAtStartup(models) {
418
+ const database = await initDb();
419
+ let profiledCount = 0;
420
+ let cachedCount = 0;
421
+ for (const model of models) {
422
+ try {
423
+ // Check cache
424
+ const cached = await getCachedProfile(model.id);
425
+ if (cached && !isCacheStale(cached)) {
426
+ cachedCount++;
427
+ continue;
428
+ }
429
+ // Look up on HuggingFace
430
+ const card = await lookupHF(model.id, model.publisher);
431
+ if (card) {
432
+ const inferred = inferProfileFromHF(card, model.id);
433
+ await upsertProfile({
434
+ modelId: model.id,
435
+ hfId: card.id,
436
+ pipelineTag: card.pipeline_tag || null,
437
+ architectures: card.config?.architectures ? JSON.stringify(card.config.architectures) : null,
438
+ license: card.cardData?.license || null,
439
+ downloads: card.downloads || null,
440
+ likes: card.likes || null,
441
+ libraryName: card.library_name || null,
442
+ family: inferred.family || null,
443
+ description: inferred.description || null,
444
+ strengths: inferred.strengths || null,
445
+ weaknesses: inferred.weaknesses || null,
446
+ bestFor: inferred.bestFor || null,
447
+ emitsThinkBlocks: inferred.emitsThinkBlocks || false,
448
+ supportsThinkingToggle: inferred.supportsThinkingToggle || false,
449
+ fetchedAt: Date.now(),
450
+ source: 'huggingface',
451
+ }, true);
452
+ profiledCount++;
453
+ }
454
+ else {
455
+ // No HF match — cache a minimal profile so we don't retry
456
+ await upsertProfile({
457
+ modelId: model.id,
458
+ hfId: null,
459
+ pipelineTag: model.type || null,
460
+ architectures: model.arch ? JSON.stringify([model.arch]) : null,
461
+ license: null,
462
+ downloads: null,
463
+ likes: null,
464
+ libraryName: null,
465
+ family: inferFamily(model.id.split('/').pop() || model.id, model.publisher || ''),
466
+ description: `${model.publisher ? model.publisher + "'s " : ''}local model. No HuggingFace card found.`,
467
+ strengths: null,
468
+ weaknesses: null,
469
+ bestFor: null,
470
+ emitsThinkBlocks: false,
471
+ supportsThinkingToggle: false,
472
+ fetchedAt: Date.now(),
473
+ source: 'inferred',
474
+ }, true);
475
+ profiledCount++;
476
+ }
477
+ }
478
+ catch (err) {
479
+ process.stderr.write(`[houtini-lm] Failed to profile ${model.id}: ${err}\n`);
480
+ }
481
+ }
482
+ // Flush all changes to disk in one write
483
+ if (profiledCount > 0)
484
+ flushDb();
485
+ process.stderr.write(`[houtini-lm] Model cache: ${cachedCount} cached, ${profiledCount} profiled, ${models.length} total\n`);
486
+ }
487
+ /**
488
+ * Get a profile for display — checks SQLite first, returns formatted enrichment line.
489
+ */
490
+ export async function getHFEnrichmentLine(modelId) {
491
+ const cached = await getCachedProfile(modelId);
492
+ if (!cached || cached.source === 'inferred')
493
+ return '';
494
+ const parts = [];
495
+ if (cached.pipelineTag)
496
+ parts.push(`HF task: ${cached.pipelineTag}`);
497
+ if (cached.libraryName)
498
+ parts.push(`library: ${cached.libraryName}`);
499
+ if (cached.downloads)
500
+ parts.push(`${cached.downloads.toLocaleString()} downloads`);
501
+ if (cached.likes)
502
+ parts.push(`${cached.likes.toLocaleString()} likes`);
503
+ if (cached.license)
504
+ parts.push(`license: ${cached.license}`);
505
+ if (cached.architectures) {
506
+ try {
507
+ const archs = JSON.parse(cached.architectures);
508
+ if (archs.length)
509
+ parts.push(`HF arch: ${archs.join(', ')}`);
510
+ }
511
+ catch { /* skip */ }
512
+ }
513
+ return parts.length > 0 ? ` HuggingFace: ${parts.join(' · ')}` : '';
514
+ }
515
+ /**
516
+ * Get all cached profiles (for diagnostics or export).
517
+ */
518
+ export async function getAllCachedProfiles() {
519
+ const database = await initDb();
520
+ const results = [];
521
+ const stmt = database.prepare('SELECT * FROM model_profiles ORDER BY model_id');
522
+ while (stmt.step()) {
523
+ const row = stmt.getAsObject();
524
+ results.push({
525
+ modelId: row.model_id,
526
+ hfId: row.hf_id,
527
+ pipelineTag: row.pipeline_tag,
528
+ architectures: row.architectures,
529
+ license: row.license,
530
+ downloads: row.downloads,
531
+ likes: row.likes,
532
+ libraryName: row.library_name,
533
+ family: row.family,
534
+ description: row.description,
535
+ strengths: row.strengths,
536
+ weaknesses: row.weaknesses,
537
+ bestFor: row.best_for,
538
+ emitsThinkBlocks: !!row.emits_think_blocks,
539
+ supportsThinkingToggle: !!row.supports_thinking_toggle,
540
+ fetchedAt: row.fetched_at,
541
+ source: row.source,
542
+ });
543
+ }
544
+ stmt.free();
545
+ return results;
546
+ }
547
+ /**
548
+ * Query thinking support for a model from the cache.
549
+ * Returns null if model is not cached.
550
+ */
551
+ export async function getThinkingSupport(modelId) {
552
+ const cached = await getCachedProfile(modelId);
553
+ if (!cached)
554
+ return null;
555
+ return { emitsThinkBlocks: cached.emitsThinkBlocks, supportsThinkingToggle: cached.supportsThinkingToggle };
556
+ }
557
+ //# sourceMappingURL=model-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-cache.js","sourceRoot":"","sources":["../src/model-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,SAA4B,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAiDlC,MAAM,YAAY,GAA8C;IAC9D;QACE,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,gKAAgK;YAElL,aAAa,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;SACpC;KACF;IACD;QACE,OAAO,EAAE,2BAA2B;QACpC,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,wIAAwI;YAE1J,aAAa,EAAE,CAAC,MAAM,CAAC;SACxB;KACF;IACD;QACE,OAAO,EAAE,2BAA2B;QACpC,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,wIAAwI;YAE1J,aAAa,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC;SAC5C;KACF;IACD;QACE,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,EAAE;YAEpB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;SAC5C;KACF;IACD;QACE,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,EAAE;YAEpB,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;SACpC;KACF;IACD;QACE,OAAO,EAAE,UAAU;QACnB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,EAAE;YAEpB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;SAChC;KACF;IACD;QACE,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,GAAG;YACb,gBAAgB,EAAE,EAAE;YAEpB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;SAC5C;KACF;IACD;QACE,OAAO,EAAE,4BAA4B;QACrC,KAAK,EAAE;YACL,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC;YACX,gBAAgB,EAAE,EAAE;YAEpB,aAAa,EAAE,CAAC,WAAW,CAAC;SAC7B;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,IAAa;IAC3D,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,YAAY,EAAE,CAAC;QAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/C,CAAC;IACD,uCAAuC;IACvC,OAAO;QACL,QAAQ,EAAE,GAAG;QACb,QAAQ,EAAE,GAAG;QACb,gBAAgB,EAAE,EAAE;QACpB,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED,wEAAwE;AAExE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAC/C,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AACvD,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,wEAAwE;AAExE,IAAI,EAAE,GAAoB,IAAI,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;IAE9B,0CAA0C;IAC1C,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YAClC,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;YAC3B,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,6BAA6B;IAC7B,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;GAoBN,CAAC,CAAC;IAEH,+DAA+D;IAC/D,IAAI,CAAC;QACH,EAAE,CAAC,GAAG,CAAC,qFAAqF,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,EAAE,CAAC,GAAG,CAAC,2FAA2F,CAAC,CAAC;IACtG,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAEvC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,MAAM;IACb,IAAI,CAAC,EAAE;QAAE,OAAO;IAChB,IAAI,CAAC;QACH,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;QACzB,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,GAAG,IAAI,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,wEAAwE;AAExE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC;IACjF,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAErB,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAA6B,CAAC;YAC1D,OAAO;gBACL,OAAO,EAAE,GAAG,CAAC,QAAkB;gBAC/B,IAAI,EAAE,GAAG,CAAC,KAAsB;gBAChC,WAAW,EAAE,GAAG,CAAC,YAA6B;gBAC9C,aAAa,EAAE,GAAG,CAAC,aAA8B;gBACjD,OAAO,EAAE,GAAG,CAAC,OAAwB;gBACrC,SAAS,EAAE,GAAG,CAAC,SAA0B;gBACzC,KAAK,EAAE,GAAG,CAAC,KAAsB;gBACjC,WAAW,EAAE,GAAG,CAAC,YAA6B;gBAC9C,MAAM,EAAE,GAAG,CAAC,MAAuB;gBACnC,WAAW,EAAE,GAAG,CAAC,WAA4B;gBAC7C,SAAS,EAAE,GAAG,CAAC,SAA0B;gBACzC,UAAU,EAAE,GAAG,CAAC,UAA2B;gBAC3C,OAAO,EAAE,GAAG,CAAC,QAAyB;gBACtC,gBAAgB,EAAE,CAAC,CAAE,GAAG,CAAC,kBAA6B;gBACtD,sBAAsB,EAAE,CAAC,CAAE,GAAG,CAAC,wBAAmC;gBAClE,SAAS,EAAE,GAAG,CAAC,UAAoB;gBACnC,MAAM,EAAE,GAAG,CAAC,MAA+C;aAC5D,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA2B,EAAE,QAAQ,GAAG,KAAK;IAC/E,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,GAAG,CACV;;;gEAG4D,EAC5D;QACE,OAAO,CAAC,OAAO;QACf,OAAO,CAAC,IAAI;QACZ,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,aAAa;QACrB,OAAO,CAAC,OAAO;QACf,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,KAAK;QACb,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,MAAM;QACd,OAAO,CAAC,WAAW;QACnB,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,UAAU;QAClB,OAAO,CAAC,OAAO;QACf,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,MAAM;KACf,CACF,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,OAAO;IACrB,MAAM,EAAE,CAAC;AACX,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAA2B;IACtD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAA0B;IACvD,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACvD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;QAC/D,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;QAClE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;KAC1D,CAAC;AACJ,CAAC;AA2BD;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,IAAiB;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,aAAa,IAAI,EAAE,CAAC;IAExE,qDAAqD;IACrD,MAAM,gBAAgB,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;IAErG,oEAAoE;IACpE,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEpE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;AACtD,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAW;IAChC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,aAAa,CAAC,CAAC;IAClE,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClG,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,QAAQ,CAAC,OAAe,EAAE,SAAkB;IACzD,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,SAAS,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxC,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,qCAAqC,IAAI,EAAE,CAAC,CAAC;YACvE,IAAI,GAAG,CAAC,EAAE;gBAAE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgB,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wEAAwE;AACxE,mEAAmE;AACnE,qDAAqD;AAErD,SAAS,kBAAkB,CAAC,IAAiB,EAAE,OAAe;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEnD,gCAAgC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzD,kCAAkC;IAClC,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE3C,oBAAoB;IACpB,IAAI,WAAW,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,SAAS,CAAC;IAC9D,IAAI,GAAG,KAAK,iBAAiB;QAAE,WAAW,IAAI,gCAAgC,CAAC;SAC1E,IAAI,GAAG,KAAK,oBAAoB;QAAE,WAAW,IAAI,yDAAyD,CAAC;SAC3G,IAAI,GAAG,KAAK,oBAAoB,IAAI,GAAG,KAAK,qBAAqB;QAAE,WAAW,IAAI,uCAAuC,CAAC;IAC/H,IAAI,IAAI,CAAC,QAAQ,EAAE,OAAO;QAAE,WAAW,IAAI,aAAa,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC;IAEjF,4BAA4B;IAC5B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;QAC9B,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtE,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtE,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,CAAC;IAED,oCAAoC;IACpC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAE7C,OAAO;QACL,MAAM;QACN,WAAW;QACX,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;QACpC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;QACtC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAChC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB,EAAE,GAAW;IACjD,uDAAuD;IACvD,sEAAsE;IACtE,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAEtC,kBAAkB;IAClB,MAAM,cAAc,GAAuB;QACzC,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAC5B,CAAC,sBAAsB,EAAE,cAAc,CAAC;QACxC,CAAC,mBAAmB,EAAE,WAAW,CAAC;QAClC,CAAC,YAAY,EAAE,QAAQ,CAAC;QACxB,CAAC,kBAAkB,EAAE,UAAU,CAAC;QAChC,CAAC,YAAY,EAAE,UAAU,CAAC;QAC1B,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,YAAY,EAAE,UAAU,CAAC;QAC1B,CAAC,gBAAgB,EAAE,QAAQ,CAAC;QAC5B,CAAC,kBAAkB,EAAE,UAAU,CAAC;QAChC,CAAC,aAAa,EAAE,WAAW,CAAC;QAC5B,CAAC,aAAa,EAAE,WAAW,CAAC;QAC5B,CAAC,iBAAiB,EAAE,WAAW,CAAC;QAChC,CAAC,YAAY,EAAE,UAAU,CAAC;QAC1B,CAAC,eAAe,EAAE,OAAO,CAAC;QAC1B,CAAC,SAAS,EAAE,OAAO,CAAC;QACpB,CAAC,eAAe,EAAE,SAAS,CAAC;QAC5B,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,QAAQ,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,cAAc,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAWD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAA2B;IACtE,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC;IAChC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,cAAc;YACd,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAChD,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpC,WAAW,EAAE,CAAC;gBACd,SAAS;YACX,CAAC;YAED,yBAAyB;YACzB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YAEvD,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpD,MAAM,aAAa,CAAC;oBAClB,OAAO,EAAE,KAAK,CAAC,EAAE;oBACjB,IAAI,EAAE,IAAI,CAAC,EAAE;oBACb,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;oBACtC,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;oBAC5F,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI;oBACvC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;oBACjC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;oBACzB,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;oBACtC,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,IAAI;oBAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,IAAI;oBACzC,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,IAAI;oBACrC,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI;oBACvC,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI;oBACjC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,IAAI,KAAK;oBACpD,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB,IAAI,KAAK;oBAChE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,MAAM,EAAE,aAAa;iBACtB,EAAE,IAAI,CAAC,CAAC;gBACT,aAAa,EAAE,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,0DAA0D;gBAC1D,MAAM,aAAa,CAAC;oBAClB,OAAO,EAAE,KAAK,CAAC,EAAE;oBACjB,IAAI,EAAE,IAAI;oBACV,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;oBAC/B,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;oBAC/D,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;oBACjF,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,yCAAyC;oBACvG,SAAS,EAAE,IAAI;oBACf,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,IAAI;oBACb,gBAAgB,EAAE,KAAK;oBACvB,sBAAsB,EAAE,KAAK;oBAC7B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,MAAM,EAAE,UAAU;iBACnB,EAAE,IAAI,CAAC,CAAC;gBACT,aAAa,EAAE,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,IAAI,aAAa,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6BAA6B,WAAW,YAAY,aAAa,cAAc,MAAM,CAAC,MAAM,UAAU,CACvG,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAEvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACnF,IAAI,MAAM,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,MAAM,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAa,CAAC;YAC3D,IAAI,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC;IAChC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAA6B,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC;YACX,OAAO,EAAE,GAAG,CAAC,QAAkB;YAC/B,IAAI,EAAE,GAAG,CAAC,KAAsB;YAChC,WAAW,EAAE,GAAG,CAAC,YAA6B;YAC9C,aAAa,EAAE,GAAG,CAAC,aAA8B;YACjD,OAAO,EAAE,GAAG,CAAC,OAAwB;YACrC,SAAS,EAAE,GAAG,CAAC,SAA0B;YACzC,KAAK,EAAE,GAAG,CAAC,KAAsB;YACjC,WAAW,EAAE,GAAG,CAAC,YAA6B;YAC9C,MAAM,EAAE,GAAG,CAAC,MAAuB;YACnC,WAAW,EAAE,GAAG,CAAC,WAA4B;YAC7C,SAAS,EAAE,GAAG,CAAC,SAA0B;YACzC,UAAU,EAAE,GAAG,CAAC,UAA2B;YAC3C,OAAO,EAAE,GAAG,CAAC,QAAyB;YACtC,gBAAgB,EAAE,CAAC,CAAE,GAAG,CAAC,kBAA6B;YACtD,sBAAsB,EAAE,CAAC,CAAE,GAAG,CAAC,wBAAmC;YAClE,SAAS,EAAE,GAAG,CAAC,UAAoB;YACnC,MAAM,EAAE,GAAG,CAAC,MAA+C;SAC5D,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,EAAE,CAAC;AAC9G,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@houtini/lm",
3
- "version": "2.4.1",
3
+ "version": "2.8.0",
4
4
  "type": "module",
5
5
  "description": "MCP server for local LLMs — connects to LM Studio or any OpenAI-compatible endpoint",
6
6
  "mcpName": "io.github.houtini-ai/lm",
@@ -30,7 +30,7 @@
30
30
  "llm"
31
31
  ],
32
32
  "author": "Richard Baxter <richard@richardbaxter.co> (https://richardbaxter.co)",
33
- "license": "MIT",
33
+ "license": "Apache-2.0",
34
34
  "homepage": "https://houtini.ai",
35
35
  "repository": {
36
36
  "type": "git",
@@ -44,10 +44,12 @@
44
44
  "url": "https://github.com/sponsors/houtini-ai"
45
45
  },
46
46
  "dependencies": {
47
- "@modelcontextprotocol/sdk": "^1.26.0"
47
+ "@modelcontextprotocol/sdk": "^1.26.0",
48
+ "sql.js": "^1.14.1"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@types/node": "^22.0.0",
52
+ "@types/sql.js": "^1.4.9",
51
53
  "typescript": "^5.7.0"
52
54
  },
53
55
  "engines": {