@automagik/omni 2.260916.11 → 2.260921.1

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.260916.11",
137427
+ version: "2.260921.1",
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.260916.11",
251118
+ version: "2.260921.1",
251119
251119
  private: true,
251120
251120
  type: "module",
251121
251121
  exports: {
@@ -339767,7 +339767,7 @@ var init_client7 = __esm(() => {
339767
339767
  IMAGE_GEN: "gemini-3.1-flash-image",
339768
339768
  VIDEO_GEN: "veo-3.1-generate-preview",
339769
339769
  VISION: "gemini-3.1-flash-lite",
339770
- STT: "gemini-3.1-flash-lite"
339770
+ STT: "gemini-3.5-flash-lite"
339771
339771
  };
339772
339772
  });
339773
339773
 
@@ -339987,7 +339987,7 @@ function extractAudio(response) {
339987
339987
  }
339988
339988
  return null;
339989
339989
  }
339990
- var log68, DEFAULT_PRO_MODEL = "lyria-3-pro-preview", DEFAULT_CLIP_MODEL = "lyria-3-clip-preview";
339990
+ var log68, DEFAULT_PRO_MODEL = "lyria-3.5", DEFAULT_CLIP_MODEL = "lyria-3-clip-preview";
339991
339991
  var init_musicgen = __esm(() => {
339992
339992
  init_src();
339993
339993
  init_client7();
@@ -340604,7 +340604,7 @@ ${base2}`;
340604
340604
  return base2;
340605
340605
  }
340606
340606
  }
340607
- var log72, DEFAULT_VISION_MODEL = "gemini-3.1-flash-lite-preview", DEFAULT_PROMPT2 = "Describe this image in clear, concise detail. Mention key subjects, actions, colors, setting, and any legible text.";
340607
+ var log72, DEFAULT_VISION_MODEL = "gemini-3.5-flash-lite", DEFAULT_PROMPT2 = "Describe this image in clear, concise detail. Mention key subjects, actions, colors, setting, and any legible text.";
340608
340608
  var init_vision2 = __esm(() => {
340609
340609
  init_src();
340610
340610
  init_client7();
@@ -342731,7 +342731,7 @@ new Groq({ apiKey, dangerouslyAllowBrowser: true })`);
342731
342731
  });
342732
342732
 
342733
342733
  // ../media-processing/src/models.ts
342734
- var GEMINI_MODEL = "gemini-3-flash-preview", OPENAI_VISION_MODEL = "gpt-4o-mini", OPENAI_AUDIO_CHAT_MODEL = "gpt-audio-mini", OPENAI_TRANSCRIBE_MODEL = "gpt-4o-transcribe", GEMINI_AUDIO_MODEL = "gemini-3.1-flash-lite", GROQ_WHISPER_MODEL = "whisper-large-v3-turbo";
342734
+ var GEMINI_MODEL = "gemini-3.5-flash-lite", OPENAI_VISION_MODEL = "gpt-5.6-luna", OPENAI_AUDIO_CHAT_MODEL = "gpt-audio-mini", OPENAI_TRANSCRIBE_MODEL = "gpt-transcribe", GEMINI_AUDIO_MODEL = "gemini-3.5-flash-lite", GROQ_WHISPER_MODEL = "whisper-large-v3-turbo";
342735
342735
  var init_models2 = () => {};
342736
342736
 
342737
342737
  // ../media-processing/src/pricing.ts
@@ -342813,6 +342813,12 @@ var init_pricing = __esm(() => {
342813
342813
  unit: "per_minute",
342814
342814
  inputRate: 0.006
342815
342815
  },
342816
+ "openai_whisper:gpt-transcribe": {
342817
+ model: "gpt-transcribe",
342818
+ provider: "openai",
342819
+ unit: "per_minute",
342820
+ inputRate: 0.006
342821
+ },
342816
342822
  "openai_vision:gpt-4o-mini": {
342817
342823
  model: "gpt-4o-mini",
342818
342824
  provider: "openai",
@@ -342827,6 +342833,20 @@ var init_pricing = __esm(() => {
342827
342833
  inputRate: 2.5,
342828
342834
  outputRate: 10
342829
342835
  },
342836
+ "openai_vision:gpt-5.6-luna": {
342837
+ model: "gpt-5.6-luna",
342838
+ provider: "openai",
342839
+ unit: "per_million_tokens",
342840
+ inputRate: 0.2,
342841
+ outputRate: 1.2
342842
+ },
342843
+ "gemini_vision:gemini-3.5-flash-lite": {
342844
+ model: "gemini-3.5-flash-lite",
342845
+ provider: "google",
342846
+ unit: "per_million_tokens",
342847
+ inputRate: 0.15,
342848
+ outputRate: 0.6
342849
+ },
342830
342850
  "gemini_vision:gemini-3-flash-preview": {
342831
342851
  model: "gemini-3-flash-preview",
342832
342852
  provider: "google",
@@ -342834,6 +342854,13 @@ var init_pricing = __esm(() => {
342834
342854
  inputRate: 0.15,
342835
342855
  outputRate: 0.6
342836
342856
  },
342857
+ "gemini_video:gemini-3.5-flash-lite": {
342858
+ model: "gemini-3.5-flash-lite",
342859
+ provider: "google",
342860
+ unit: "per_million_tokens",
342861
+ inputRate: 0.15,
342862
+ outputRate: 0.6
342863
+ },
342837
342864
  "gemini_video:gemini-3-flash-preview": {
342838
342865
  model: "gemini-3-flash-preview",
342839
342866
  provider: "google",
@@ -350024,10 +350051,16 @@ var init_image = __esm(() => {
350024
350051
  geminiClient = null;
350025
350052
  geminiModel = null;
350026
350053
  openaiClient = null;
350054
+ get geminiModelId() {
350055
+ return this.config.geminiVisionModel ?? GEMINI_MODEL;
350056
+ }
350057
+ get openaiVisionModelId() {
350058
+ return this.config.openaiVisionModel ?? OPENAI_VISION_MODEL;
350059
+ }
350027
350060
  getGeminiModel() {
350028
350061
  if (!this.geminiModel && this.config.geminiApiKey) {
350029
350062
  this.geminiClient = new GoogleGenerativeAI(this.config.geminiApiKey);
350030
- this.geminiModel = this.geminiClient.getGenerativeModel({ model: GEMINI_MODEL });
350063
+ this.geminiModel = this.geminiClient.getGenerativeModel({ model: this.geminiModelId });
350031
350064
  this.log.info("Gemini model initialized");
350032
350065
  }
350033
350066
  return this.geminiModel;
@@ -350070,7 +350103,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350070
350103
  async describeWithGemini(imageData, mimeType, prompt) {
350071
350104
  const model = this.getGeminiModel();
350072
350105
  if (!model) {
350073
- return this.createFailedResult("Gemini not configured (missing API key)", "google", GEMINI_MODEL);
350106
+ return this.createFailedResult("Gemini not configured (missing API key)", "google", this.geminiModelId);
350074
350107
  }
350075
350108
  const timeouts = getMediaTimeouts();
350076
350109
  const runGemini = async (timeoutMs) => this.executeWithResilience("gemini", async () => {
@@ -350108,7 +350141,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350108
350141
  }
350109
350142
  }
350110
350143
  const { text: text3, inputTokens, outputTokens } = callResult;
350111
- const costCents = calculateCost("gemini_vision", GEMINI_MODEL, {
350144
+ const costCents = calculateCost("gemini_vision", this.geminiModelId, {
350112
350145
  inputTokens,
350113
350146
  outputTokens
350114
350147
  });
@@ -350118,7 +350151,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350118
350151
  contentFormat: "text",
350119
350152
  processingType: "description",
350120
350153
  provider: "google",
350121
- model: GEMINI_MODEL,
350154
+ model: this.geminiModelId,
350122
350155
  processingTimeMs: 0,
350123
350156
  inputTokens,
350124
350157
  outputTokens,
@@ -350128,13 +350161,13 @@ Additional context (caption): ${options.caption}` : basePrompt;
350128
350161
  const errorMsg = error3 instanceof Error ? error3.message : String(error3);
350129
350162
  const isCircuit = this.isCircuitOpen(error3);
350130
350163
  this.log.error("Gemini description error", { error: errorMsg, circuitOpen: isCircuit });
350131
- return this.createFailedResult(errorMsg, "google", GEMINI_MODEL);
350164
+ return this.createFailedResult(errorMsg, "google", this.geminiModelId);
350132
350165
  }
350133
350166
  }
350134
350167
  async describeWithOpenAI(imageData, mimeType, prompt) {
350135
350168
  const client = this.getOpenAIClient();
350136
350169
  if (!client) {
350137
- return this.createFailedResult("OpenAI client not configured (missing API key)", "openai", OPENAI_VISION_MODEL);
350170
+ return this.createFailedResult("OpenAI client not configured (missing API key)", "openai", this.openaiVisionModelId);
350138
350171
  }
350139
350172
  const timeouts = getMediaTimeouts();
350140
350173
  try {
@@ -350142,7 +350175,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350142
350175
  const base64Data = imageData.toString("base64");
350143
350176
  const dataUrl = `data:${mimeType};base64,${base64Data}`;
350144
350177
  const response = await client.chat.completions.create({
350145
- model: OPENAI_VISION_MODEL,
350178
+ model: this.openaiVisionModelId,
350146
350179
  messages: [
350147
350180
  {
350148
350181
  role: "user",
@@ -350166,7 +350199,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350166
350199
  outputTokens: response.usage?.completion_tokens ?? 0
350167
350200
  };
350168
350201
  }, { timeoutMs: timeouts.imageTimeoutMs });
350169
- const costCents = calculateCost("openai_vision", OPENAI_VISION_MODEL, {
350202
+ const costCents = calculateCost("openai_vision", this.openaiVisionModelId, {
350170
350203
  inputTokens,
350171
350204
  outputTokens
350172
350205
  });
@@ -350176,7 +350209,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350176
350209
  contentFormat: "text",
350177
350210
  processingType: "description",
350178
350211
  provider: "openai",
350179
- model: OPENAI_VISION_MODEL,
350212
+ model: this.openaiVisionModelId,
350180
350213
  processingTimeMs: 0,
350181
350214
  inputTokens,
350182
350215
  outputTokens,
@@ -350185,7 +350218,7 @@ Additional context (caption): ${options.caption}` : basePrompt;
350185
350218
  } catch (error3) {
350186
350219
  const errorMsg = error3 instanceof Error ? error3.message : String(error3);
350187
350220
  this.log.error("OpenAI description error", { error: errorMsg });
350188
- return this.createFailedResult(errorMsg, "openai", OPENAI_VISION_MODEL);
350221
+ return this.createFailedResult(errorMsg, "openai", this.openaiVisionModelId);
350189
350222
  }
350190
350223
  }
350191
350224
  normalizeGeminiMimeType(mimeType) {
@@ -350298,10 +350331,13 @@ var init_video = __esm(() => {
350298
350331
  ];
350299
350332
  geminiClient = null;
350300
350333
  geminiModel = null;
350334
+ get geminiModelId() {
350335
+ return this.config.geminiVisionModel ?? GEMINI_MODEL;
350336
+ }
350301
350337
  getGeminiModel() {
350302
350338
  if (!this.geminiModel && this.config.geminiApiKey) {
350303
350339
  this.geminiClient = new GoogleGenerativeAI(this.config.geminiApiKey);
350304
- this.geminiModel = this.geminiClient.getGenerativeModel({ model: GEMINI_MODEL });
350340
+ this.geminiModel = this.geminiClient.getGenerativeModel({ model: this.geminiModelId });
350305
350341
  this.log.info("Gemini model initialized for video");
350306
350342
  }
350307
350343
  return this.geminiModel;
@@ -350344,7 +350380,7 @@ Additional context: ${options.caption}` : basePrompt;
350344
350380
  async describeWithGemini(videoData, mimeType, prompt) {
350345
350381
  const model = this.getGeminiModel();
350346
350382
  if (!model) {
350347
- return this.createFailedResult("Gemini not configured (missing API key)", "google", GEMINI_MODEL);
350383
+ return this.createFailedResult("Gemini not configured (missing API key)", "google", this.geminiModelId);
350348
350384
  }
350349
350385
  const timeouts = getMediaTimeouts();
350350
350386
  try {
@@ -350366,7 +350402,7 @@ Additional context: ${options.caption}` : basePrompt;
350366
350402
  outputTokens: usageMetadata?.candidatesTokenCount ?? 0
350367
350403
  };
350368
350404
  }, { timeoutMs: timeouts.videoTimeoutMs });
350369
- const costCents = calculateCost("gemini_video", GEMINI_MODEL, {
350405
+ const costCents = calculateCost("gemini_video", this.geminiModelId, {
350370
350406
  inputTokens,
350371
350407
  outputTokens
350372
350408
  });
@@ -350376,7 +350412,7 @@ Additional context: ${options.caption}` : basePrompt;
350376
350412
  contentFormat: "text",
350377
350413
  processingType: "description",
350378
350414
  provider: "google",
350379
- model: GEMINI_MODEL,
350415
+ model: this.geminiModelId,
350380
350416
  processingTimeMs: 0,
350381
350417
  inputTokens,
350382
350418
  outputTokens,
@@ -350386,7 +350422,7 @@ Additional context: ${options.caption}` : basePrompt;
350386
350422
  const errorMsg = error3 instanceof Error ? error3.message : String(error3);
350387
350423
  const isCircuit = this.isCircuitOpen(error3);
350388
350424
  this.log.error("Gemini video description error", { error: errorMsg, circuitOpen: isCircuit });
350389
- return this.createFailedResult(errorMsg, "google", GEMINI_MODEL);
350425
+ return this.createFailedResult(errorMsg, "google", this.geminiModelId);
350390
350426
  }
350391
350427
  }
350392
350428
  normalizeVideoMimeType(mimeType) {
@@ -359419,10 +359455,13 @@ var init_document = __esm(() => {
359419
359455
  ];
359420
359456
  geminiClient = null;
359421
359457
  geminiModel = null;
359458
+ get geminiModelId() {
359459
+ return this.config.geminiVisionModel ?? GEMINI_MODEL;
359460
+ }
359422
359461
  getGeminiModel() {
359423
359462
  if (!this.geminiModel && this.config.geminiApiKey) {
359424
359463
  this.geminiClient = new GoogleGenerativeAI(this.config.geminiApiKey);
359425
- this.geminiModel = this.geminiClient.getGenerativeModel({ model: GEMINI_MODEL });
359464
+ this.geminiModel = this.geminiClient.getGenerativeModel({ model: this.geminiModelId });
359426
359465
  this.log.info("Gemini model initialized for document OCR");
359427
359466
  }
359428
359467
  return this.geminiModel;
@@ -359845,7 +359884,7 @@ ${rows.join(`
359845
359884
  outputTokens: usageMetadata?.candidatesTokenCount ?? 0
359846
359885
  };
359847
359886
  }, { timeoutMs: timeouts.documentTimeoutMs });
359848
- const costCents = calculateCost("gemini_vision", GEMINI_MODEL, {
359887
+ const costCents = calculateCost("gemini_vision", this.geminiModelId, {
359849
359888
  inputTokens,
359850
359889
  outputTokens
359851
359890
  });
@@ -359855,7 +359894,7 @@ ${rows.join(`
359855
359894
  contentFormat: "markdown",
359856
359895
  processingType: "extraction",
359857
359896
  provider: "google",
359858
- model: GEMINI_MODEL,
359897
+ model: this.geminiModelId,
359859
359898
  processingTimeMs: 0,
359860
359899
  inputTokens,
359861
359900
  outputTokens,
@@ -359864,7 +359903,7 @@ ${rows.join(`
359864
359903
  } catch (error3) {
359865
359904
  const errorMsg = error3 instanceof Error ? error3.message : String(error3);
359866
359905
  this.log.error("Gemini OCR failed", { error: errorMsg });
359867
- return this.createFailedResult(errorMsg, "google", GEMINI_MODEL);
359906
+ return this.createFailedResult(errorMsg, "google", this.geminiModelId);
359868
359907
  }
359869
359908
  }
359870
359909
  createFailedResult(errorMessage, provider, model) {
@@ -362225,6 +362264,73 @@ function buildWhatsAppMessageContext(rawPayload, chatId, instance4, text3) {
362225
362264
  return { isDirectMessage, mentionsBot, isReplyToBot, text: text3 };
362226
362265
  }
362227
362266
 
362267
+ // ../api/src/services/response-gate.ts
362268
+ async function resolveGateProvider(settings) {
362269
+ const configured = await settings.getString("gate.provider", "GATE_PROVIDER");
362270
+ return configured?.trim().toLowerCase() === "openai" ? "openai" : DEFAULT_GATE_PROVIDER;
362271
+ }
362272
+ async function resolveGateModel(provider, instanceModel, settings) {
362273
+ if (instanceModel)
362274
+ 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;
362279
+ }
362280
+ async function callGeminiGate(prompt, model, settings, signal2) {
362281
+ const apiKey = await settings.getSecret("gemini.api_key", "GEMINI_API_KEY");
362282
+ if (!apiKey)
362283
+ return { ok: false, reason: "missing_key" };
362284
+ const url = `${GEMINI_GENERATE_URL2}/${model}:generateContent?key=${apiKey}`;
362285
+ const res = await fetch(url, {
362286
+ method: "POST",
362287
+ headers: { "Content-Type": "application/json" },
362288
+ body: JSON.stringify({
362289
+ contents: [{ parts: [{ text: prompt }] }],
362290
+ generationConfig: { maxOutputTokens: GATE_MAX_TOKENS, temperature: 0 }
362291
+ }),
362292
+ signal: signal2
362293
+ });
362294
+ if (!res.ok)
362295
+ return { ok: false, reason: "http_error", status: res.status };
362296
+ const data = await res.json();
362297
+ return { ok: true, answer: data.candidates?.[0]?.content?.parts?.[0]?.text?.trim().toLowerCase() ?? "" };
362298
+ }
362299
+ async function callOpenAiGate(prompt, model, settings, signal2) {
362300
+ const apiKey = await settings.getSecret("openai.api_key", "OPENAI_API_KEY");
362301
+ if (!apiKey)
362302
+ return { ok: false, reason: "missing_key" };
362303
+ const baseUrl = (await settings.getString("gate.openai.base_url", "GATE_OPENAI_BASE_URL") ?? DEFAULT_OPENAI_BASE_URL).trim().replace(/\/+$/, "");
362304
+ const res = await fetch(`${baseUrl}/chat/completions`, {
362305
+ method: "POST",
362306
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
362307
+ body: JSON.stringify({
362308
+ model,
362309
+ messages: [{ role: "user", content: prompt }],
362310
+ max_completion_tokens: GATE_MAX_TOKENS,
362311
+ temperature: 0
362312
+ }),
362313
+ signal: signal2
362314
+ });
362315
+ if (!res.ok)
362316
+ return { ok: false, reason: "http_error", status: res.status };
362317
+ const data = await res.json();
362318
+ return { ok: true, answer: data.choices?.[0]?.message?.content?.trim().toLowerCase() ?? "" };
362319
+ }
362320
+ async function runGateCall(provider, prompt, model, settings, timeoutMs = GATE_TIMEOUT_MS) {
362321
+ const controller = new AbortController;
362322
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
362323
+ try {
362324
+ return provider === "openai" ? await callOpenAiGate(prompt, model, settings, controller.signal) : await callGeminiGate(prompt, model, settings, controller.signal);
362325
+ } catch (callError) {
362326
+ const errName = callError.name;
362327
+ return errName === "AbortError" ? { ok: false, reason: "timeout" } : { ok: false, reason: "error", error: String(callError) };
362328
+ } finally {
362329
+ clearTimeout(timeout);
362330
+ }
362331
+ }
362332
+ var DEFAULT_GATE_PROVIDER = "gemini", DEFAULT_GATE_MODEL_GEMINI = "gemini-3.5-flash-lite", DEFAULT_GATE_MODEL_OPENAI = "gpt-5.6-luna", GATE_TIMEOUT_MS = 3000, GATE_MAX_TOKENS = 256, GEMINI_GENERATE_URL2 = "https://generativelanguage.googleapis.com/v1beta/models", DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
362333
+
362228
362334
  // ../api/src/services/turn-events.ts
362229
362335
  function getTurnEventsConnection() {
362230
362336
  return nc && !nc.isClosed() ? nc : null;
@@ -367174,7 +367280,8 @@ async function shouldRespondViaGate(instance4, messages4, chatType, settings) {
367174
367280
  if (!inst.agentGateEnabled)
367175
367281
  return true;
367176
367282
  const agentName = instance4.name ?? "assistant";
367177
- const model = inst.agentGateModel ?? DEFAULT_GATE_MODEL;
367283
+ const provider = await resolveGateProvider(settings);
367284
+ const model = await resolveGateModel(provider, inst.agentGateModel, settings);
367178
367285
  const basePrompt = await resolveGatePrompt(inst.agentGatePrompt, settings);
367179
367286
  const messagesText = messages4.map((m2) => {
367180
367287
  const name = m2.payload.rawPayload?.pushName ?? m2.payload.from ?? "Unknown";
@@ -367185,52 +367292,31 @@ async function shouldRespondViaGate(instance4, messages4, chatType, settings) {
367185
367292
  const traceId = messages4[0]?.metadata.traceId ?? "unknown";
367186
367293
  const startMs = Date.now();
367187
367294
  try {
367188
- const apiKey = await settings.getSecret("gemini.api_key", "GEMINI_API_KEY");
367189
- if (!apiKey) {
367190
- log94.warn("Gate: no Gemini API key, fail-open", { traceId });
367191
- return true;
367192
- }
367193
- const controller = new AbortController;
367194
- const timeout = setTimeout(() => controller.abort(), GATE_TIMEOUT_MS);
367195
- try {
367196
- const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;
367197
- const res = await fetch(url, {
367198
- method: "POST",
367199
- headers: { "Content-Type": "application/json" },
367200
- body: JSON.stringify({
367201
- contents: [{ parts: [{ text: prompt }] }],
367202
- generationConfig: { maxOutputTokens: 10, temperature: 0 }
367203
- }),
367204
- signal: controller.signal
367205
- });
367206
- clearTimeout(timeout);
367207
- if (!res.ok) {
367208
- log94.warn("Gate: API error, fail-open", { traceId, status: res.status, durationMs: Date.now() - startMs });
367209
- return true;
367210
- }
367211
- const data = await res.json();
367212
- const answer = data.candidates?.[0]?.content?.parts?.[0]?.text?.trim().toLowerCase() ?? "";
367213
- const shouldRespond = !answer.startsWith("skip");
367214
- log94.info("Gate decision", {
367295
+ const result = await runGateCall(provider, prompt, model, settings);
367296
+ if (!result.ok) {
367297
+ log94.warn("Gate: call failed, fail-open", {
367215
367298
  traceId,
367216
- decision: shouldRespond ? "respond" : "skip",
367217
- rawAnswer: answer,
367299
+ provider,
367218
367300
  model,
367219
- chatType,
367220
- messageCount: messages4.length,
367301
+ reason: result.reason,
367302
+ status: result.status,
367303
+ error: result.error,
367221
367304
  durationMs: Date.now() - startMs
367222
367305
  });
367223
- return shouldRespond;
367224
- } catch (fetchError) {
367225
- clearTimeout(timeout);
367226
- const errName = fetchError.name;
367227
- if (errName === "AbortError") {
367228
- log94.warn("Gate: timeout, fail-open", { traceId, durationMs: Date.now() - startMs });
367229
- } else {
367230
- log94.warn("Gate: fetch error, fail-open", { traceId, error: String(fetchError) });
367231
- }
367232
367306
  return true;
367233
367307
  }
367308
+ const shouldRespond = !result.answer.startsWith("skip");
367309
+ log94.info("Gate decision", {
367310
+ traceId,
367311
+ decision: shouldRespond ? "respond" : "skip",
367312
+ rawAnswer: result.answer,
367313
+ provider,
367314
+ model,
367315
+ chatType,
367316
+ messageCount: messages4.length,
367317
+ durationMs: Date.now() - startMs
367318
+ });
367319
+ return shouldRespond;
367234
367320
  } catch (error3) {
367235
367321
  log94.warn("Gate: unexpected error, fail-open", { traceId, error: String(error3) });
367236
367322
  return true;
@@ -367543,7 +367629,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
367543
367629
  log94.info("Agent dispatcher shutdown complete");
367544
367630
  };
367545
367631
  }
367546
- var import_api31, log94, agentDispatchLimiter, _natsGenieProviderCtor, QUOTED_MESSAGE_MAX_CHARS = 4000, DM_HISTORY_LIMIT = 20, LIFECYCLE_PREVIEW_MAX_CHARS = 160, LIFECYCLE_SENSITIVE_KEY_PARTS, PRESENCE_DEFAULT_MIN_MS = 5000, PRESENCE_DEFAULT_MAX_WAIT_MS = 30000, activeMessageDebouncer = null, DEFAULT_DISPATCH_ERROR_MESSAGE = "Opa, tive um probleminha aqui \uD83D\uDE05 Pode mandar de novo?", DEFAULT_ERROR_HANDOFF_MESSAGE = "T\xF4 com um probleminha t\xE9cnico aqui agora. Logo algu\xE9m do time vai entrar em contato com voc\xEA.", TRANSIENT_DISPATCH_ERROR_PATTERNS, TRANSIENT_DISPATCH_RETRY_DELAYS_MS, CHANNEL_MESSAGE_LIMITS, DEFAULT_MESSAGE_LIMIT = 4000, MEDIA_BASE_PATH3, NON_DISPATCHABLE_CONTENT_TYPES, MEDIA_ICONS, MEDIA_WAIT_NULL, mediaCompletions, mediaResultCache, MEDIA_WAIT_TIMEOUT_MS = 30000, DEFAULT_SEND_MEDIA_PATH_TYPES, BOT_PREFIX = "\uD83E\uDD16 ", activeStreams, activeRunAborts, CancelThreadPayloadSchema, sessionActivityStore, PROC_REACT_START, PROC_REACT_DONE = "\u2705", queuedMessageAcks, QUEUED_ACK_TIMEOUT_MS = 120000, providerCache, openclawClientPool, _openClawClientCtor, nullFilterWarnedInstances, ACTIVE_OWNER_IDENTIFIER_CACHE_TTL_MS = 1e4, cachedActiveOwnerIdentifiers = null, cachedActiveOwnerIdentifiersAt = 0, tenantCachedActiveOwnerIdentifiers, DEFAULT_GATE_MODEL = "gemini-3-flash-preview", GATE_TIMEOUT_MS = 3000, setupAgentResponder;
367632
+ var import_api31, log94, agentDispatchLimiter, _natsGenieProviderCtor, QUOTED_MESSAGE_MAX_CHARS = 4000, DM_HISTORY_LIMIT = 20, LIFECYCLE_PREVIEW_MAX_CHARS = 160, LIFECYCLE_SENSITIVE_KEY_PARTS, PRESENCE_DEFAULT_MIN_MS = 5000, PRESENCE_DEFAULT_MAX_WAIT_MS = 30000, activeMessageDebouncer = null, DEFAULT_DISPATCH_ERROR_MESSAGE = "Opa, tive um probleminha aqui \uD83D\uDE05 Pode mandar de novo?", DEFAULT_ERROR_HANDOFF_MESSAGE = "T\xF4 com um probleminha t\xE9cnico aqui agora. Logo algu\xE9m do time vai entrar em contato com voc\xEA.", TRANSIENT_DISPATCH_ERROR_PATTERNS, TRANSIENT_DISPATCH_RETRY_DELAYS_MS, CHANNEL_MESSAGE_LIMITS, DEFAULT_MESSAGE_LIMIT = 4000, MEDIA_BASE_PATH3, NON_DISPATCHABLE_CONTENT_TYPES, MEDIA_ICONS, MEDIA_WAIT_NULL, mediaCompletions, mediaResultCache, MEDIA_WAIT_TIMEOUT_MS = 30000, DEFAULT_SEND_MEDIA_PATH_TYPES, BOT_PREFIX = "\uD83E\uDD16 ", activeStreams, activeRunAborts, CancelThreadPayloadSchema, sessionActivityStore, PROC_REACT_START, PROC_REACT_DONE = "\u2705", queuedMessageAcks, QUEUED_ACK_TIMEOUT_MS = 120000, providerCache, openclawClientPool, _openClawClientCtor, nullFilterWarnedInstances, ACTIVE_OWNER_IDENTIFIER_CACHE_TTL_MS = 1e4, cachedActiveOwnerIdentifiers = null, cachedActiveOwnerIdentifiersAt = 0, tenantCachedActiveOwnerIdentifiers, setupAgentResponder;
367547
367633
  var init_agent_dispatcher = __esm(() => {
367548
367634
  init_src2();
367549
367635
  init_src();
@@ -373904,6 +373990,14 @@ var init_settings = __esm(() => {
373904
373990
  description: "Default DeepSeek vision/text model for vision provider dogfood",
373905
373991
  defaultValue: "deepseek-v4-flash"
373906
373992
  },
373993
+ {
373994
+ key: "vision.model",
373995
+ category: "vision",
373996
+ valueType: "string",
373997
+ isSecret: false,
373998
+ description: "Default Gemini vision model for `omni see` (default: gemini-3.5-flash-lite)",
373999
+ defaultValue: "gemini-3.5-flash-lite"
374000
+ },
373907
374001
  {
373908
374002
  key: "deepseek.anthropic_url",
373909
374003
  category: "media",
@@ -373920,6 +374014,22 @@ var init_settings = __esm(() => {
373920
374014
  description: "Default language for media processing",
373921
374015
  defaultValue: "pt"
373922
374016
  },
374017
+ {
374018
+ key: "media.gemini.model",
374019
+ category: "media",
374020
+ valueType: "string",
374021
+ isSecret: false,
374022
+ description: "Gemini model for inbound image description, video analysis and document OCR (default: gemini-3.5-flash-lite)",
374023
+ defaultValue: "gemini-3.5-flash-lite"
374024
+ },
374025
+ {
374026
+ key: "media.openai.vision_model",
374027
+ category: "media",
374028
+ valueType: "string",
374029
+ isSecret: false,
374030
+ description: "OpenAI vision model used when the Gemini vision lane is unavailable (default: gpt-5.6-luna)",
374031
+ defaultValue: "gpt-5.6-luna"
374032
+ },
373923
374033
  {
373924
374034
  key: "prompt.image_description",
373925
374035
  category: "prompts",
@@ -373955,6 +374065,37 @@ var init_settings = __esm(() => {
373955
374065
  isSecret: false,
373956
374066
  description: "Override prompt for response gate (null = code default)"
373957
374067
  },
374068
+ {
374069
+ key: "gate.provider",
374070
+ category: "providers",
374071
+ valueType: "string",
374072
+ isSecret: false,
374073
+ description: 'Response gate provider: "gemini" (default) or "openai".',
374074
+ defaultValue: "gemini"
374075
+ },
374076
+ {
374077
+ key: "gate.gemini.model",
374078
+ category: "providers",
374079
+ valueType: "string",
374080
+ isSecret: false,
374081
+ description: "Default Gemini model for the response gate.",
374082
+ defaultValue: "gemini-3.5-flash-lite"
374083
+ },
374084
+ {
374085
+ key: "gate.openai.model",
374086
+ category: "providers",
374087
+ valueType: "string",
374088
+ isSecret: false,
374089
+ description: "Default OpenAI model for the response gate.",
374090
+ defaultValue: "gpt-5.6-luna"
374091
+ },
374092
+ {
374093
+ key: "gate.openai.base_url",
374094
+ category: "providers",
374095
+ valueType: "string",
374096
+ isSecret: false,
374097
+ description: "OpenAI-compatible base URL for the response gate (default: https://api.openai.com/v1). Set it to route the gate through a gateway."
374098
+ },
373958
374099
  {
373959
374100
  key: "tts.provider",
373960
374101
  category: "providers",
@@ -374031,8 +374172,8 @@ var init_settings = __esm(() => {
374031
374172
  category: "providers",
374032
374173
  valueType: "string",
374033
374174
  isSecret: false,
374034
- description: "Default OpenAI STT model. Primary: gpt-4o-transcribe (dedicated STT); gpt-audio-* models use the chat lane, whose output is validated with a transcriptions-endpoint fallback.",
374035
- defaultValue: "gpt-4o-transcribe"
374175
+ description: "Default OpenAI STT model. Primary: gpt-transcribe (dedicated STT); gpt-audio-* models use the chat lane, whose output is validated with a transcriptions-endpoint fallback.",
374176
+ defaultValue: "gpt-transcribe"
374036
374177
  },
374037
374178
  {
374038
374179
  key: "stt.gemini.model",
@@ -374040,7 +374181,7 @@ var init_settings = __esm(() => {
374040
374181
  valueType: "string",
374041
374182
  isSecret: false,
374042
374183
  description: "Default Gemini direct-audio STT model.",
374043
- defaultValue: "gemini-3.1-flash-lite"
374184
+ defaultValue: "gemini-3.5-flash-lite"
374044
374185
  },
374045
374186
  {
374046
374187
  key: "videogen.gemini.model",
@@ -375304,8 +375445,10 @@ var init_tts3 = __esm(() => {
375304
375445
  }
375305
375446
  async synthesize(text3, options) {
375306
375447
  const apiKey = await this.getApiKey();
375307
- const defaultVoice = await this.settings.getString("elevenlabs.default_voice", "ELEVENLABS_DEFAULT_VOICE", "JBFqnCBsd6RMkjVDRZzb");
375308
- const defaultModel = await this.settings.getString("elevenlabs.default_model", undefined, "eleven_v3");
375448
+ const configuredVoice = await this.settings.getString("elevenlabs.default_voice", "ELEVENLABS_DEFAULT_VOICE", "JBFqnCBsd6RMkjVDRZzb");
375449
+ const defaultVoice = !configuredVoice || configuredVoice === "undefined" ? undefined : configuredVoice;
375450
+ const configuredModel = await this.settings.getString("elevenlabs.default_model", undefined, "eleven_v3");
375451
+ const defaultModel = !configuredModel || configuredModel === "undefined" ? undefined : configuredModel;
375309
375452
  const voiceId = options?.voiceId || defaultVoice || "JBFqnCBsd6RMkjVDRZzb";
375310
375453
  const modelId = options?.modelId || defaultModel || "eleven_v3";
375311
375454
  const stability = options?.stability ?? 0.5;
@@ -389665,7 +389808,7 @@ var init_instances3 = __esm(() => {
389665
389808
  messageSplitDelayMinMs: exports_external.number().int().min(0).default(300).describe('Minimum delay between split chunks in milliseconds (used when messageSplitDelayMode="randomized")'),
389666
389809
  messageSplitDelayMaxMs: exports_external.number().int().min(0).default(1000).describe('Maximum delay between split chunks in milliseconds (used when messageSplitDelayMode="randomized")'),
389667
389810
  agentGateEnabled: exports_external.boolean().default(false).describe("Enable LLM response gate (pre-filter before agent dispatch)"),
389668
- agentGateModel: exports_external.string().nullable().default(null).describe("Model for response gate (default: gemini-3-flash-preview)"),
389811
+ agentGateModel: exports_external.string().nullable().default(null).describe("Model for response gate (default: gate.gemini.model / gemini-3.5-flash-lite). Must match the provider selected by the gate.provider setting."),
389669
389812
  agentGatePrompt: exports_external.string().nullable().default(null).describe("Custom prompt for response gate (null = use default)"),
389670
389813
  telegramBotToken: exports_external.string().optional().nullable().describe("Telegram bot token (persisted for reconnection)"),
389671
389814
  discordBotToken: exports_external.string().optional().nullable().describe("Discord bot token (persisted for reconnection)"),
@@ -399414,19 +399557,23 @@ async function setupMediaProcessor(eventBus, db2, services) {
399414
399557
  audioPrompt,
399415
399558
  imagePrompt,
399416
399559
  videoPrompt,
399417
- documentPrompt
399560
+ documentPrompt,
399561
+ geminiVisionModel,
399562
+ openaiVisionModel
399418
399563
  ] = await Promise.all([
399419
399564
  services.settings.getSecret("groq.api_key", "GROQ_API_KEY"),
399420
399565
  services.settings.getSecret("openai.api_key", "OPENAI_API_KEY"),
399421
399566
  services.settings.getSecret("gemini.api_key", "GEMINI_API_KEY"),
399422
399567
  services.settings.getString("media.default_language", "DEFAULT_LANGUAGE", "pt"),
399423
399568
  services.settings.getString("stt.provider", "STT_PROVIDER", "openai"),
399424
- services.settings.getString("stt.openai.model", "OPENAI_STT_MODEL", "gpt-4o-transcribe"),
399569
+ services.settings.getString("stt.openai.model", "OPENAI_STT_MODEL", OPENAI_TRANSCRIBE_MODEL),
399425
399570
  services.settings.getString("stt.gemini.model", "GEMINI_STT_MODEL", GEMINI_AUDIO_MODEL),
399426
399571
  services.settings.getString("prompt.audio_transcription"),
399427
399572
  services.settings.getString("prompt.image_description"),
399428
399573
  services.settings.getString("prompt.video_description"),
399429
- services.settings.getString("prompt.document_ocr")
399574
+ services.settings.getString("prompt.document_ocr"),
399575
+ services.settings.getString("media.gemini.model", "GEMINI_MEDIA_MODEL", GEMINI_MODEL),
399576
+ services.settings.getString("media.openai.vision_model", "OPENAI_VISION_MODEL", OPENAI_VISION_MODEL)
399430
399577
  ]);
399431
399578
  const mediaService = createMediaProcessingService({
399432
399579
  groqApiKey,
@@ -399434,8 +399581,10 @@ async function setupMediaProcessor(eventBus, db2, services) {
399434
399581
  geminiApiKey,
399435
399582
  defaultLanguage,
399436
399583
  audioProvider: audioProvider ?? "openai",
399437
- audioModel: audioModel ?? "gpt-4o-transcribe",
399584
+ audioModel: audioModel ?? OPENAI_TRANSCRIBE_MODEL,
399438
399585
  geminiAudioModel: geminiAudioModel ?? GEMINI_AUDIO_MODEL,
399586
+ geminiVisionModel: geminiVisionModel ?? GEMINI_MODEL,
399587
+ openaiVisionModel: openaiVisionModel ?? OPENAI_VISION_MODEL,
399439
399588
  audioPrompt: audioPrompt ?? undefined
399440
399589
  });
399441
399590
  const mediaStorage2 = new MediaStorageService(db2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260916.11",
3
+ "version": "2.260921.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",