@automagik/omni 2.260921.1 → 2.260921.3

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/dist/index.js CHANGED
@@ -137424,7 +137424,7 @@ import { fileURLToPath } from "url";
137424
137424
  // package.json
137425
137425
  var package_default = {
137426
137426
  name: "@automagik/omni",
137427
- version: "2.260921.1",
137427
+ version: "2.260921.3",
137428
137428
  repository: {
137429
137429
  type: "git",
137430
137430
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -251115,7 +251115,7 @@ var init_sentry_scrub = __esm(() => {
251115
251115
  var require_package7 = __commonJS((exports, module) => {
251116
251116
  module.exports = {
251117
251117
  name: "@omni/api",
251118
- version: "2.260921.1",
251118
+ version: "2.260921.3",
251119
251119
  private: true,
251120
251120
  type: "module",
251121
251121
  exports: {
@@ -362264,7 +362264,319 @@ function buildWhatsAppMessageContext(rawPayload, chatId, instance4, text3) {
362264
362264
  return { isDirectMessage, mentionsBot, isReplyToBot, text: text3 };
362265
362265
  }
362266
362266
 
362267
+ // ../api/src/services/model-catalog.ts
362268
+ var exports_model_catalog = {};
362269
+ __export(exports_model_catalog, {
362270
+ fetchOpenAiCatalog: () => fetchOpenAiCatalog,
362271
+ fetchGeminiCatalog: () => fetchGeminiCatalog
362272
+ });
362273
+ function defaultFetch(url, init5) {
362274
+ return fetch(url, init5);
362275
+ }
362276
+ function readId(record2) {
362277
+ if (typeof record2 !== "object" || record2 === null)
362278
+ return;
362279
+ const id = record2.id ?? record2.name;
362280
+ return typeof id === "string" && id.length > 0 ? id : undefined;
362281
+ }
362282
+ function parseGeminiCatalog(payload) {
362283
+ const raw2 = payload?.models;
362284
+ if (!Array.isArray(raw2))
362285
+ return [];
362286
+ const models = [];
362287
+ const seen = new Set;
362288
+ for (const entry of raw2) {
362289
+ const rawId = readId(entry);
362290
+ if (!rawId)
362291
+ continue;
362292
+ const id = rawId.replace(/^models\//, "");
362293
+ if (!id || seen.has(id))
362294
+ continue;
362295
+ const declared = entry.supportedGenerationMethods;
362296
+ const methods = Array.isArray(declared) ? declared.filter((method) => typeof method === "string") : [];
362297
+ seen.add(id);
362298
+ models.push({ id, methods });
362299
+ }
362300
+ return models;
362301
+ }
362302
+ function parseOpenAiCatalog(payload) {
362303
+ const raw2 = payload?.data;
362304
+ if (!Array.isArray(raw2))
362305
+ return [];
362306
+ const models = [];
362307
+ const seen = new Set;
362308
+ for (const entry of raw2) {
362309
+ const id = readId(entry);
362310
+ if (!id || seen.has(id))
362311
+ continue;
362312
+ seen.add(id);
362313
+ models.push({ id, methods: [] });
362314
+ }
362315
+ return models;
362316
+ }
362317
+ async function fetchGeminiCatalog(apiKey, deps = {}) {
362318
+ if (!apiKey)
362319
+ return null;
362320
+ const doFetch = deps.fetchImpl ?? defaultFetch;
362321
+ const timeoutMs = deps.timeoutMs ?? CATALOG_TIMEOUT_MS;
362322
+ const collected = [];
362323
+ let pageToken;
362324
+ try {
362325
+ for (let page = 0;page < MAX_GEMINI_PAGES; page += 1) {
362326
+ const url = new URL(GEMINI_MODELS_URL);
362327
+ url.searchParams.set("key", apiKey);
362328
+ url.searchParams.set("pageSize", String(GEMINI_PAGE_SIZE));
362329
+ if (pageToken)
362330
+ url.searchParams.set("pageToken", pageToken);
362331
+ const res = await doFetch(url.toString(), { signal: AbortSignal.timeout(timeoutMs) });
362332
+ if (!res.ok)
362333
+ return null;
362334
+ const payload = await res.json();
362335
+ collected.push(...parseGeminiCatalog(payload));
362336
+ const next = payload?.nextPageToken;
362337
+ if (typeof next !== "string" || next.length === 0)
362338
+ break;
362339
+ pageToken = next;
362340
+ }
362341
+ } catch {
362342
+ return null;
362343
+ }
362344
+ return collected;
362345
+ }
362346
+ async function fetchOpenAiCatalog(apiKey, deps = {}) {
362347
+ if (!apiKey)
362348
+ return null;
362349
+ const doFetch = deps.fetchImpl ?? defaultFetch;
362350
+ const timeoutMs = deps.timeoutMs ?? CATALOG_TIMEOUT_MS;
362351
+ try {
362352
+ const res = await doFetch(OPENAI_MODELS_URL, {
362353
+ headers: { Authorization: `Bearer ${apiKey}` },
362354
+ signal: AbortSignal.timeout(timeoutMs)
362355
+ });
362356
+ if (!res.ok)
362357
+ return null;
362358
+ const payload = await res.json();
362359
+ return parseOpenAiCatalog(payload);
362360
+ } catch {
362361
+ return null;
362362
+ }
362363
+ }
362364
+ var GEMINI_MODELS_URL = "https://generativelanguage.googleapis.com/v1beta/models", OPENAI_MODELS_URL = "https://api.openai.com/v1/models", CATALOG_TIMEOUT_MS = 5000, GEMINI_PAGE_SIZE = 200, MAX_GEMINI_PAGES = 10;
362365
+
362366
+ // ../api/src/services/model-resolver.ts
362367
+ var exports_model_resolver = {};
362368
+ __export(exports_model_resolver, {
362369
+ resolveModel: () => resolveModel2,
362370
+ parseVersion: () => parseVersion
362371
+ });
362372
+ function parseVersion(id) {
362373
+ const match2 = id.match(/(?:^|[-_/])(\d+(?:\.\d+)*)(?=[-_/.]|$)/);
362374
+ const captured = match2?.[1];
362375
+ if (!captured)
362376
+ return [];
362377
+ return captured.split(".").map((part) => Number.parseInt(part, 10)).filter((n2) => Number.isFinite(n2));
362378
+ }
362379
+ function compareVersionDesc(a, b3) {
362380
+ const len = Math.max(a.length, b3.length);
362381
+ for (let i = 0;i < len; i += 1) {
362382
+ const left = a[i];
362383
+ const right = b3[i];
362384
+ if (left === undefined)
362385
+ return 1;
362386
+ if (right === undefined)
362387
+ return -1;
362388
+ if (left !== right)
362389
+ return right - left;
362390
+ }
362391
+ return 0;
362392
+ }
362393
+ function isVariantId(id) {
362394
+ const tokens = idTokens(id);
362395
+ const last = tokens.at(-1) ?? "";
362396
+ return VARIANT_SUFFIX_TOKENS.includes(last);
362397
+ }
362398
+ function nameTier(id, version3) {
362399
+ if (version3.length > 0)
362400
+ return 1;
362401
+ return isVariantId(id) ? 2 : 0;
362402
+ }
362403
+ function idTokens(id) {
362404
+ return id.toLowerCase().split(/[-_/]+/).filter((token) => token.length > 0);
362405
+ }
362406
+ function isRejected(id) {
362407
+ const tokens = idTokens(id);
362408
+ return REJECTED_TOKENS.some((token) => tokens.includes(token));
362409
+ }
362410
+ function previewTier(id) {
362411
+ return idTokens(id).includes("preview") ? 1 : 0;
362412
+ }
362413
+ function aliasTier(id) {
362414
+ return idTokens(id).includes("latest") ? 1 : 0;
362415
+ }
362416
+ function compareCandidateDesc(a, b3, cheapFirst) {
362417
+ if (a.alias !== b3.alias)
362418
+ return a.alias - b3.alias;
362419
+ if (a.tier !== b3.tier)
362420
+ return a.tier - b3.tier;
362421
+ if (a.name !== b3.name)
362422
+ return a.name - b3.name;
362423
+ const byExtra = compareExtraAsc(a.extra, b3.extra);
362424
+ const byVersion = compareVersionDesc(a.version, b3.version);
362425
+ if (cheapFirst) {
362426
+ if (byExtra !== 0)
362427
+ return byExtra;
362428
+ if (byVersion !== 0)
362429
+ return byVersion;
362430
+ } else {
362431
+ if (byVersion !== 0)
362432
+ return byVersion;
362433
+ if (byExtra !== 0)
362434
+ return byExtra;
362435
+ }
362436
+ if (a.id.length !== b3.id.length)
362437
+ return a.id.length - b3.id.length;
362438
+ return a.id.localeCompare(b3.id);
362439
+ }
362440
+ function compareExtraAsc(a, b3) {
362441
+ const len = Math.max(a.length, b3.length);
362442
+ for (let i = 0;i < len; i += 1) {
362443
+ const left = a[i] ?? Number.POSITIVE_INFINITY;
362444
+ const right = b3[i] ?? Number.POSITIVE_INFINITY;
362445
+ if (left !== right)
362446
+ return left - right;
362447
+ }
362448
+ return 0;
362449
+ }
362450
+ function hasMethod(model, method) {
362451
+ if (model.methods.length === 0)
362452
+ return true;
362453
+ return model.methods.includes(method);
362454
+ }
362455
+ function resolveOpenAi(catalog, role) {
362456
+ const pattern = OPENAI_ROLE_PATTERNS[role];
362457
+ if (!pattern)
362458
+ return null;
362459
+ const scored = [];
362460
+ for (const model of catalog) {
362461
+ const id = model.id;
362462
+ if (isRejected(id))
362463
+ continue;
362464
+ if (!pattern.test(id))
362465
+ continue;
362466
+ scored.push({
362467
+ id,
362468
+ alias: aliasTier(id),
362469
+ tier: previewTier(id),
362470
+ name: nameTier(id, parseVersion(id)),
362471
+ version: parseVersion(id),
362472
+ extra: []
362473
+ });
362474
+ }
362475
+ if (scored.length === 0)
362476
+ return null;
362477
+ scored.sort((a, b3) => compareCandidateDesc(a, b3, role === "chat-fast"));
362478
+ return scored[0]?.id ?? null;
362479
+ }
362480
+ function geminiExtra(role, id) {
362481
+ if (role !== "chat-fast")
362482
+ return [];
362483
+ return [idTokens(id).includes("lite") ? 0 : 1];
362484
+ }
362485
+ function resolveGemini(catalog, role) {
362486
+ const fragment2 = GEMINI_ROLE_FRAGMENT[role];
362487
+ if (!fragment2)
362488
+ return null;
362489
+ const requiredMethod = GEMINI_ROLE_METHOD[role];
362490
+ const isChatStyle = role === "chat-fast" || role === "chat" || role === "vision" || role === "transcribe";
362491
+ const scored = [];
362492
+ for (const model of catalog) {
362493
+ const lower = model.id.toLowerCase();
362494
+ if (!lower.includes(fragment2))
362495
+ continue;
362496
+ if (isRejected(model.id))
362497
+ continue;
362498
+ if (isChatStyle && GEMINI_NON_CHAT_FRAGMENTS.some((family) => lower.includes(family)))
362499
+ continue;
362500
+ if (requiredMethod && !hasMethod(model, requiredMethod))
362501
+ continue;
362502
+ scored.push({
362503
+ id: model.id,
362504
+ alias: aliasTier(model.id),
362505
+ tier: previewTier(model.id),
362506
+ name: nameTier(model.id, parseVersion(model.id)),
362507
+ version: parseVersion(model.id),
362508
+ extra: geminiExtra(role, model.id)
362509
+ });
362510
+ }
362511
+ if (scored.length === 0)
362512
+ return null;
362513
+ scored.sort((a, b3) => compareCandidateDesc(a, b3, role === "chat-fast"));
362514
+ return scored[0]?.id ?? null;
362515
+ }
362516
+ function resolveModel2(catalog, provider, role) {
362517
+ if (!catalog || catalog.length === 0)
362518
+ return null;
362519
+ const model = provider === "openai" ? resolveOpenAi(catalog, role) : resolveGemini(catalog, role);
362520
+ if (!model)
362521
+ return null;
362522
+ return { model, role, provider, source: "catalog" };
362523
+ }
362524
+ var GEMINI_SPECIAL_FAMILIES, VARIANT_SUFFIX_TOKENS, REJECTED_TOKENS, OPENAI_ROLE_PATTERNS, GEMINI_ROLE_FRAGMENT, GEMINI_ROLE_METHOD, GEMINI_NON_CHAT_FRAGMENTS;
362525
+ var init_model_resolver = __esm(() => {
362526
+ GEMINI_SPECIAL_FAMILIES = ["lyria", "veo", "embedding", "embed", "aqa", "imagen", "gemma"];
362527
+ VARIANT_SUFFIX_TOKENS = ["turbo", "diarize", "mini", "lite", "nano", "hd", "flash", "pro", "max", "fast"];
362528
+ REJECTED_TOKENS = ["exp", "experimental", "deprecated", "legacy", "alpha", "beta"];
362529
+ OPENAI_ROLE_PATTERNS = {
362530
+ "chat-fast": null,
362531
+ chat: null,
362532
+ transcribe: /^(?:gpt-[\w.-]*transcribe[\w.-]*|whisper-[\w.-]+)$/,
362533
+ tts: /-tts$/,
362534
+ image: /^gpt-image-[\w.-]+$/,
362535
+ music: null,
362536
+ video: null,
362537
+ vision: null
362538
+ };
362539
+ GEMINI_ROLE_FRAGMENT = {
362540
+ "chat-fast": "flash",
362541
+ chat: "flash",
362542
+ transcribe: "transcribe",
362543
+ tts: "tts",
362544
+ image: "image",
362545
+ music: "lyria",
362546
+ video: "veo",
362547
+ vision: "flash"
362548
+ };
362549
+ GEMINI_ROLE_METHOD = {
362550
+ "chat-fast": "generateContent",
362551
+ chat: "generateContent",
362552
+ transcribe: "generateContent",
362553
+ tts: "generateContent",
362554
+ image: "generateContent",
362555
+ music: null,
362556
+ video: "predictLongRunning",
362557
+ vision: "generateContent"
362558
+ };
362559
+ GEMINI_NON_CHAT_FRAGMENTS = [...GEMINI_SPECIAL_FAMILIES, "tts", "image"];
362560
+ });
362561
+
362267
362562
  // ../api/src/services/response-gate.ts
362563
+ async function resolveGateModelFromCatalog(provider, settings) {
362564
+ const fallback = provider === "openai" ? DEFAULT_GATE_MODEL_OPENAI : DEFAULT_GATE_MODEL_GEMINI;
362565
+ try {
362566
+ const { fetchGeminiCatalog: fetchGeminiCatalog2, fetchOpenAiCatalog: fetchOpenAiCatalog2 } = await Promise.resolve().then(() => exports_model_catalog);
362567
+ const { resolveModel: resolveModel3 } = await Promise.resolve().then(() => (init_model_resolver(), exports_model_resolver));
362568
+ const key = provider === "openai" ? await settings.getSecret("openai.api_key", "OPENAI_API_KEY") : await settings.getSecret("gemini.api_key", "GEMINI_API_KEY");
362569
+ if (!key)
362570
+ return { model: fallback, source: "constant" };
362571
+ const catalog = provider === "openai" ? await fetchOpenAiCatalog2(key) : await fetchGeminiCatalog2(key);
362572
+ const resolved = resolveModel3(catalog, provider, "chat-fast");
362573
+ if (!resolved)
362574
+ return { model: fallback, source: "constant" };
362575
+ return { model: resolved.model, source: "catalog" };
362576
+ } catch {
362577
+ return { model: fallback, source: "constant" };
362578
+ }
362579
+ }
362268
362580
  async function resolveGateProvider(settings) {
362269
362581
  const configured = await settings.getString("gate.provider", "GATE_PROVIDER");
362270
362582
  return configured?.trim().toLowerCase() === "openai" ? "openai" : DEFAULT_GATE_PROVIDER;
@@ -362272,10 +362584,11 @@ async function resolveGateProvider(settings) {
362272
362584
  async function resolveGateModel(provider, instanceModel, settings) {
362273
362585
  if (instanceModel)
362274
362586
  return instanceModel;
362275
- if (provider === "openai") {
362276
- return await settings.getString("gate.openai.model", "GATE_OPENAI_MODEL") ?? DEFAULT_GATE_MODEL_OPENAI;
362277
- }
362278
- return await settings.getString("gate.gemini.model", "GATE_GEMINI_MODEL") ?? DEFAULT_GATE_MODEL_GEMINI;
362587
+ const configured = provider === "openai" ? await settings.getString("gate.openai.model", "GATE_OPENAI_MODEL") : await settings.getString("gate.gemini.model", "GATE_GEMINI_MODEL");
362588
+ if (configured)
362589
+ return configured;
362590
+ const discovered = await resolveGateModelFromCatalog(provider, settings);
362591
+ return discovered.model;
362279
362592
  }
362280
362593
  async function callGeminiGate(prompt, model, settings, signal2) {
362281
362594
  const apiKey = await settings.getSecret("gemini.api_key", "GEMINI_API_KEY");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260921.1",
3
+ "version": "2.260921.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",