@automagik/omni 2.260423.9 → 2.260424.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
@@ -113929,7 +113929,7 @@ import { fileURLToPath } from "url";
113929
113929
  // package.json
113930
113930
  var package_default = {
113931
113931
  name: "@automagik/omni",
113932
- version: "2.260423.9",
113932
+ version: "2.260424.1",
113933
113933
  description: "LLM-optimized CLI for Omni",
113934
113934
  type: "module",
113935
113935
  bin: {
@@ -22659,6 +22659,10 @@ function generateCorrelationId(prefix = "corr") {
22659
22659
  const random = Math.random().toString(36).substring(2, 10);
22660
22660
  return `${prefix}-${timestamp}-${random}`;
22661
22661
  }
22662
+ function isValidUuid(id) {
22663
+ const uuidRegex2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
22664
+ return uuidRegex2.test(id);
22665
+ }
22662
22666
  var init_ids = () => {};
22663
22667
 
22664
22668
  // ../../node_modules/.bun/croner@9.1.0/node_modules/croner/dist/croner.js
@@ -224550,7 +224554,7 @@ var init_sentry_scrub = __esm(() => {
224550
224554
  var require_package8 = __commonJS((exports, module) => {
224551
224555
  module.exports = {
224552
224556
  name: "@omni/api",
224553
- version: "2.260423.9",
224557
+ version: "2.260424.1",
224554
224558
  type: "module",
224555
224559
  exports: {
224556
224560
  ".": {
@@ -280781,7 +280785,7 @@ class FollowUpSweeperService {
280781
280785
  lastInboundCustomerMessageAt: chatFollowUpState.lastInboundCustomerMessageAt,
280782
280786
  chatName: chats.name,
280783
280787
  channelType: instances.channel
280784
- }).from(chatFollowUpState).leftJoin(chats, eq(chatFollowUpState.chatId, chats.id)).leftJoin(instances, eq(chatFollowUpState.instanceId, instances.id)).where(and2(isNull2(chatFollowUpState.disarmReason), lte(chatFollowUpState.nextFireAt, now))).orderBy(chatFollowUpState.nextFireAt).limit(limit2).for("update", { of: chatFollowUpState, skipLocked: true });
280788
+ }).from(chatFollowUpState).leftJoin(chats, eq(chatFollowUpState.chatId, chats.id)).leftJoin(instances, eq(chatFollowUpState.instanceId, instances.id)).where(and2(isNull2(chatFollowUpState.disarmReason), lte(chatFollowUpState.nextFireAt, now), sql`(${chats.settings}->>'agentPaused')::boolean IS DISTINCT FROM true`)).orderBy(chatFollowUpState.nextFireAt).limit(limit2).for("update", { of: chatFollowUpState, skipLocked: true });
280785
280789
  return claimed;
280786
280790
  });
280787
280791
  return rows.map((r) => ({
@@ -300724,6 +300728,11 @@ var init_messages5 = __esm(() => {
300724
300728
  await services.chats.update(data.chatId, {
300725
300729
  settings: { agentPaused: true }
300726
300730
  });
300731
+ await services.followUpLifecycle.disarm({
300732
+ chatId: data.chatId,
300733
+ instanceId: data.instanceId,
300734
+ reason: "handoff"
300735
+ });
300727
300736
  db2.insert(handoffLogs).values({
300728
300737
  instanceId: data.instanceId,
300729
300738
  chatUuid: data.chatId,
@@ -302860,6 +302869,9 @@ function mapContentType2(contentType) {
302860
302869
  }
302861
302870
  return null;
302862
302871
  }
302872
+ function eventIdInsert(eventId) {
302873
+ return eventId && isValidUuid(eventId) ? { id: eventId } : {};
302874
+ }
302863
302875
  async function resolveChatUuid(db2, instanceId, chatId) {
302864
302876
  if (!instanceId || !chatId)
302865
302877
  return null;
@@ -302883,6 +302895,7 @@ async function setupEventPersistence(eventBus, db2) {
302883
302895
  try {
302884
302896
  const chatUuid = await resolveChatUuid(db2, metadata.instanceId, payload.chatId);
302885
302897
  const newEvent = {
302898
+ ...eventIdInsert(event.id),
302886
302899
  externalId: payload.externalId,
302887
302900
  channel: mapChannelType(metadata.channelType),
302888
302901
  instanceId: metadata.instanceId,
@@ -302907,7 +302920,7 @@ async function setupEventPersistence(eventBus, db2) {
302907
302920
  conversationId: null,
302908
302921
  chatUuid
302909
302922
  };
302910
- await db2.insert(omniEvents).values(newEvent);
302923
+ await db2.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
302911
302924
  if (metadata.timings && metadata.correlationId) {
302912
302925
  const tracker = getJourneyTracker();
302913
302926
  tracker.recordCheckpoint(metadata.correlationId, "T4", JOURNEY_STAGES.T4);
@@ -302929,6 +302942,7 @@ async function setupEventPersistence(eventBus, db2) {
302929
302942
  try {
302930
302943
  const chatUuid = await resolveChatUuid(db2, metadata.instanceId, payload.chatId);
302931
302944
  const newEvent = {
302945
+ ...eventIdInsert(event.id),
302932
302946
  externalId: payload.externalId,
302933
302947
  channel: mapChannelType(metadata.channelType),
302934
302948
  instanceId: metadata.instanceId,
@@ -302952,7 +302966,7 @@ async function setupEventPersistence(eventBus, db2) {
302952
302966
  conversationId: null,
302953
302967
  chatUuid
302954
302968
  };
302955
- await db2.insert(omniEvents).values(newEvent);
302969
+ await db2.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
302956
302970
  log104.debug("Persisted message.sent", {
302957
302971
  externalId: payload.externalId,
302958
302972
  instanceId: metadata.instanceId
@@ -302975,6 +302989,7 @@ async function setupEventPersistence(eventBus, db2) {
302975
302989
  if (updated.length === 0) {
302976
302990
  const chatUuid = await resolveChatUuid(db2, metadata.instanceId, payload.chatId);
302977
302991
  const newEvent = {
302992
+ ...eventIdInsert(event.id),
302978
302993
  externalId: payload.externalId,
302979
302994
  channel: mapChannelType(metadata.channelType),
302980
302995
  instanceId: metadata.instanceId,
@@ -302988,7 +303003,7 @@ async function setupEventPersistence(eventBus, db2) {
302988
303003
  conversationId: null,
302989
303004
  chatUuid
302990
303005
  };
302991
- await db2.insert(omniEvents).values(newEvent);
303006
+ await db2.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
302992
303007
  }
302993
303008
  log104.debug("Persisted message.delivered", {
302994
303009
  externalId: payload.externalId
@@ -303010,6 +303025,7 @@ async function setupEventPersistence(eventBus, db2) {
303010
303025
  if (updated.length === 0) {
303011
303026
  const chatUuid = await resolveChatUuid(db2, metadata.instanceId, payload.chatId);
303012
303027
  const newEvent = {
303028
+ ...eventIdInsert(event.id),
303013
303029
  externalId: payload.externalId,
303014
303030
  channel: mapChannelType(metadata.channelType),
303015
303031
  instanceId: metadata.instanceId,
@@ -303023,7 +303039,7 @@ async function setupEventPersistence(eventBus, db2) {
303023
303039
  conversationId: null,
303024
303040
  chatUuid
303025
303041
  };
303026
- await db2.insert(omniEvents).values(newEvent);
303042
+ await db2.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
303027
303043
  }
303028
303044
  log104.debug("Persisted message.read", {
303029
303045
  externalId: payload.externalId
@@ -303041,6 +303057,7 @@ async function setupEventPersistence(eventBus, db2) {
303041
303057
  try {
303042
303058
  const chatUuid = await resolveChatUuid(db2, metadata.instanceId, payload.chatId);
303043
303059
  const newEvent = {
303060
+ ...eventIdInsert(event.id),
303044
303061
  externalId: payload.externalId,
303045
303062
  channel: mapChannelType(metadata.channelType),
303046
303063
  instanceId: metadata.instanceId,
@@ -303060,7 +303077,7 @@ async function setupEventPersistence(eventBus, db2) {
303060
303077
  conversationId: null,
303061
303078
  chatUuid
303062
303079
  };
303063
- await db2.insert(omniEvents).values(newEvent);
303080
+ await db2.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
303064
303081
  log104.debug("Persisted message.failed", {
303065
303082
  chatId: payload.chatId,
303066
303083
  error: payload.error
@@ -303125,6 +303142,9 @@ function shouldProcess(contentType) {
303125
303142
  return false;
303126
303143
  return PROCESSABLE_MEDIA_TYPES.has(contentType);
303127
303144
  }
303145
+ function isUuid(value) {
303146
+ return typeof value === "string" && isValidUuid(value);
303147
+ }
303128
303148
  function getMimeType2(content) {
303129
303149
  if (content.mimeType)
303130
303150
  return content.mimeType;
@@ -303203,6 +303223,28 @@ async function resolveMediaPath2(ctx, instanceId, chatId, externalId, content, m
303203
303223
  fullPath: join25(ctx.mediaStorage.getBasePath(), filePath)
303204
303224
  };
303205
303225
  }
303226
+ async function resolveSafeMediaContentEventId(ctx, eventId) {
303227
+ if (!isUuid(eventId))
303228
+ return null;
303229
+ const maxWaitMs = 250;
303230
+ const pollMs = 50;
303231
+ const deadline = Date.now() + maxWaitMs;
303232
+ while (true) {
303233
+ try {
303234
+ const [event] = await ctx.db.select({ id: omniEvents.id }).from(omniEvents).where(eq(omniEvents.id, eventId)).limit(1);
303235
+ if (event)
303236
+ return event.id;
303237
+ } catch (error2) {
303238
+ log105.debug("Failed to validate media_content event FK", { eventId, error: String(error2) });
303239
+ return null;
303240
+ }
303241
+ if (Date.now() >= deadline) {
303242
+ log105.debug("Skipping media_content event FK; omni_event not found", { eventId });
303243
+ return null;
303244
+ }
303245
+ await new Promise((resolve4) => setTimeout(resolve4, pollMs));
303246
+ }
303247
+ }
303206
303248
  async function persistProcessingResult(ctx, messageId, eventId, result, contentType) {
303207
303249
  if (result.content) {
303208
303250
  const updateField = getContentFieldForType(result.processingType, contentType);
@@ -303211,8 +303253,9 @@ async function persistProcessingResult(ctx, messageId, eventId, result, contentT
303211
303253
  }
303212
303254
  }
303213
303255
  try {
303256
+ const safeEventId = await resolveSafeMediaContentEventId(ctx, eventId);
303214
303257
  await ctx.db.insert(mediaContent).values({
303215
- eventId: eventId ?? undefined,
303258
+ eventId: safeEventId,
303216
303259
  mediaId: messageId,
303217
303260
  processingType: result.processingType,
303218
303261
  content: result.content ?? "",
@@ -424351,6 +424394,15 @@ init_src();
424351
424394
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
424352
424395
  import { basename, dirname as dirname2, join as join8 } from "path";
424353
424396
 
424397
+ // ../channel-whatsapp/src/utils/message.ts
424398
+ function getDocumentMessage(message2) {
424399
+ return message2?.documentMessage ?? message2?.documentWithCaptionMessage?.message?.documentMessage;
424400
+ }
424401
+ function getMessageContextInfo(msg) {
424402
+ const message2 = msg.message;
424403
+ return message2?.extendedTextMessage?.contextInfo ?? message2?.imageMessage?.contextInfo ?? message2?.videoMessage?.contextInfo ?? getDocumentMessage(message2)?.contextInfo;
424404
+ }
424405
+
424354
424406
  // ../channel-whatsapp/src/utils/download.ts
424355
424407
  function detectMediaType(msg) {
424356
424408
  const message2 = msg.message;
@@ -424377,11 +424429,12 @@ function detectMediaType(msg) {
424377
424429
  duration: message2.videoMessage.seconds || undefined
424378
424430
  };
424379
424431
  }
424380
- if (message2.documentMessage) {
424432
+ const documentMessage = getDocumentMessage(message2);
424433
+ if (documentMessage) {
424381
424434
  return {
424382
424435
  type: "document",
424383
- mimeType: message2.documentMessage.mimetype || "application/octet-stream",
424384
- filename: message2.documentMessage.fileName || undefined
424436
+ mimeType: documentMessage.mimetype || "application/octet-stream",
424437
+ filename: documentMessage.fileName || undefined
424385
424438
  };
424386
424439
  }
424387
424440
  if (message2.stickerMessage) {
@@ -424472,8 +424525,9 @@ function getMediaSize(msg) {
424472
424525
  if (message2.videoMessage?.fileLength) {
424473
424526
  return Number(message2.videoMessage.fileLength);
424474
424527
  }
424475
- if (message2.documentMessage?.fileLength) {
424476
- return Number(message2.documentMessage.fileLength);
424528
+ const documentMessage = getDocumentMessage(message2);
424529
+ if (documentMessage?.fileLength) {
424530
+ return Number(documentMessage.fileLength);
424477
424531
  }
424478
424532
  if (message2.stickerMessage?.fileLength) {
424479
424533
  return Number(message2.stickerMessage.fileLength);
@@ -424521,14 +424575,17 @@ var contentExtractors = [
424521
424575
  })
424522
424576
  },
424523
424577
  {
424524
- check: (m2) => !!m2.documentMessage,
424525
- extract: (m2) => ({
424526
- type: "document",
424527
- filename: m2.documentMessage?.fileName ?? undefined,
424528
- mimeType: m2.documentMessage?.mimetype ?? "application/octet-stream",
424529
- caption: m2.documentMessage?.caption ?? undefined,
424530
- mediaUrl: m2.documentMessage?.url ?? undefined
424531
- })
424578
+ check: (m2) => !!getDocumentMessage(m2),
424579
+ extract: (m2) => {
424580
+ const document2 = getDocumentMessage(m2);
424581
+ return {
424582
+ type: "document",
424583
+ filename: document2?.fileName ?? undefined,
424584
+ mimeType: document2?.mimetype ?? "application/octet-stream",
424585
+ caption: document2?.caption ?? undefined,
424586
+ mediaUrl: document2?.url ?? undefined
424587
+ };
424588
+ }
424532
424589
  },
424533
424590
  {
424534
424591
  check: (m2) => !!m2.stickerMessage,
@@ -424781,10 +424838,6 @@ function extractPhoneFromVcard(vcard) {
424781
424838
  }
424782
424839
  return;
424783
424840
  }
424784
- function getMessageContextInfo(msg) {
424785
- const message2 = msg.message;
424786
- return message2?.extendedTextMessage?.contextInfo ?? message2?.imageMessage?.contextInfo ?? message2?.videoMessage?.contextInfo ?? message2?.documentMessage?.contextInfo;
424787
- }
424788
424841
  function getReplyToId2(msg) {
424789
424842
  const contextInfo = getMessageContextInfo(msg);
424790
424843
  return contextInfo?.stanzaId || undefined;
@@ -427573,10 +427626,6 @@ class WhatsAppPlugin extends BaseChannelPlugin {
427573
427626
  }
427574
427627
  }
427575
427628
  }
427576
- getMessageContextInfo(rawMessage) {
427577
- const message2 = rawMessage.message;
427578
- return message2?.extendedTextMessage?.contextInfo ?? message2?.imageMessage?.contextInfo ?? message2?.videoMessage?.contextInfo ?? message2?.documentMessage?.contextInfo;
427579
- }
427580
427629
  async handleMessageReceived(instanceId, externalId, chatId, from, content, replyToId, rawMessage, isFromMe2, platformTimestamp) {
427581
427630
  if (externalId && rawMessage.key) {
427582
427631
  const cacheKey = `${instanceId}:${externalId}`;
@@ -427601,7 +427650,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
427601
427650
  ...rawMessage,
427602
427651
  isFromMe: isFromMe2
427603
427652
  };
427604
- const contextInfo = this.getMessageContextInfo(rawMessage);
427653
+ const contextInfo = getMessageContextInfo(rawMessage);
427605
427654
  if (contextInfo?.mentionedJid && contextInfo.mentionedJid.length > 0) {
427606
427655
  extendedPayload.mentionedJids = contextInfo.mentionedJid;
427607
427656
  this.logger.debug("Processing mentioned JIDs", {
@@ -428185,6 +428234,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
428185
428234
  return null;
428186
428235
  }
428187
428236
  extractMediaContent(message2) {
428237
+ const documentMessage = getDocumentMessage(message2);
428188
428238
  if (message2.imageMessage) {
428189
428239
  return {
428190
428240
  type: "image",
@@ -428202,11 +428252,11 @@ class WhatsAppPlugin extends BaseChannelPlugin {
428202
428252
  caption: message2.videoMessage.caption ?? undefined
428203
428253
  };
428204
428254
  }
428205
- if (message2.documentMessage) {
428255
+ if (documentMessage) {
428206
428256
  return {
428207
428257
  type: "document",
428208
- mimeType: message2.documentMessage.mimetype ?? "application/octet-stream",
428209
- caption: message2.documentMessage.caption ?? undefined
428258
+ mimeType: documentMessage.mimetype ?? "application/octet-stream",
428259
+ caption: documentMessage.caption ?? undefined
428210
428260
  };
428211
428261
  }
428212
428262
  if (message2.stickerMessage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260423.9",
3
+ "version": "2.260424.1",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,15 +39,15 @@
39
39
  "qrcode-terminal": "^0.12.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@omni/api": "2.260423.8",
43
- "@omni/channel-discord": "2.260423.8",
44
- "@omni/channel-gupshup": "2.260423.8",
45
- "@omni/channel-sdk": "2.260423.8",
46
- "@omni/channel-slack": "2.260423.8",
47
- "@omni/channel-telegram": "2.260423.8",
48
- "@omni/channel-whatsapp": "2.260423.8",
49
- "@omni/core": "2.260423.8",
50
- "@omni/sdk": "2.260423.8",
42
+ "@omni/api": "2.260423.10",
43
+ "@omni/channel-discord": "2.260423.10",
44
+ "@omni/channel-gupshup": "2.260423.10",
45
+ "@omni/channel-sdk": "2.260423.10",
46
+ "@omni/channel-slack": "2.260423.10",
47
+ "@omni/channel-telegram": "2.260423.10",
48
+ "@omni/channel-whatsapp": "2.260423.10",
49
+ "@omni/core": "2.260423.10",
50
+ "@omni/sdk": "2.260423.10",
51
51
  "@types/node": "^22.10.3",
52
52
  "@types/qrcode-terminal": "^0.12.2",
53
53
  "typescript": "^5.7.3"