@automagik/omni 2.260720.2 → 2.260723.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
@@ -125191,7 +125191,7 @@ import { fileURLToPath } from "url";
125191
125191
  // package.json
125192
125192
  var package_default = {
125193
125193
  name: "@automagik/omni",
125194
- version: "2.260720.2",
125194
+ version: "2.260723.1",
125195
125195
  description: "LLM-optimized CLI for Omni",
125196
125196
  type: "module",
125197
125197
  bin: {
@@ -227026,7 +227026,7 @@ var init_sentry_scrub = __esm(() => {
227026
227026
  var require_package7 = __commonJS((exports, module) => {
227027
227027
  module.exports = {
227028
227028
  name: "@omni/api",
227029
- version: "2.260720.2",
227029
+ version: "2.260723.1",
227030
227030
  type: "module",
227031
227031
  exports: {
227032
227032
  ".": {
@@ -337808,6 +337808,19 @@ var init_instances = __esm(() => {
337808
337808
  });
337809
337809
 
337810
337810
  // ../api/src/services/messages.ts
337811
+ function sanitizeMediaText(data) {
337812
+ const out = { ...data };
337813
+ if (typeof out.transcription === "string")
337814
+ out.transcription = sanitizeText(out.transcription) ?? "";
337815
+ if (typeof out.imageDescription === "string")
337816
+ out.imageDescription = sanitizeText(out.imageDescription) ?? "";
337817
+ if (typeof out.videoDescription === "string")
337818
+ out.videoDescription = sanitizeText(out.videoDescription) ?? "";
337819
+ if (typeof out.documentExtraction === "string") {
337820
+ out.documentExtraction = sanitizeText(out.documentExtraction) ?? "";
337821
+ }
337822
+ return out;
337823
+ }
337811
337824
  function buildMessagePreview(options) {
337812
337825
  const sender = options.isFromMe ? "You" : options.senderDisplayName ?? null;
337813
337826
  let content;
@@ -337974,7 +337987,15 @@ class MessageService {
337974
337987
  value -= 2;
337975
337988
  return value;
337976
337989
  };
337977
- return rows.map((message2) => ({ message: message2, score: score(message2) })).sort((a, b3) => b3.score - a.score || b3.message.platformTimestamp.getTime() - a.message.platformTimestamp.getTime())[0]?.message ?? null;
337990
+ const ranked = rows.map((message2) => ({ message: message2, score: score(message2) })).sort((a, b3) => b3.score - a.score || b3.message.platformTimestamp.getTime() - a.message.platformTimestamp.getTime());
337991
+ const AMBIGUOUS_TIE_WINDOW_MS = 5 * 60000;
337992
+ const top = ranked[0];
337993
+ if (!top)
337994
+ return null;
337995
+ const ambiguousTie = top.score > 0 && ranked.some((entry, index2) => index2 > 0 && entry.score === top.score && Math.abs(top.message.platformTimestamp.getTime() - entry.message.platformTimestamp.getTime()) <= AMBIGUOUS_TIE_WINDOW_MS);
337996
+ if (ambiguousTie)
337997
+ return null;
337998
+ return top.message;
337978
337999
  }
337979
338000
  async getByExternalIds(chatId, externalIds) {
337980
338001
  if (externalIds.length === 0)
@@ -338001,10 +338022,10 @@ class MessageService {
338001
338022
  mediaUrl: options.mediaUrl,
338002
338023
  mediaLocalPath: options.mediaLocalPath,
338003
338024
  mediaMetadata: options.mediaMetadata,
338004
- transcription: options.transcription,
338005
- imageDescription: options.imageDescription,
338006
- videoDescription: options.videoDescription,
338007
- documentExtraction: options.documentExtraction,
338025
+ transcription: sanitizeText(options.transcription),
338026
+ imageDescription: sanitizeText(options.imageDescription),
338027
+ videoDescription: sanitizeText(options.videoDescription),
338028
+ documentExtraction: sanitizeText(options.documentExtraction),
338008
338029
  replyToMessageId: options.replyToMessageId,
338009
338030
  replyToExternalId: options.replyToExternalId,
338010
338031
  quotedText: options.quotedText,
@@ -338079,7 +338100,7 @@ class MessageService {
338079
338100
  return { message: message2, created: true };
338080
338101
  }
338081
338102
  async update(id, data) {
338082
- const [updated] = await this.db.update(messages2).set({ ...data, updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338103
+ const [updated] = await this.db.update(messages2).set({ ...sanitizeMediaText(data), updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338083
338104
  if (!updated) {
338084
338105
  throw new NotFoundError("Message", id);
338085
338106
  }
@@ -338183,28 +338204,28 @@ class MessageService {
338183
338204
  return updated;
338184
338205
  }
338185
338206
  async updateTranscription(id, transcription) {
338186
- const [updated] = await this.db.update(messages2).set({ transcription, updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338207
+ const [updated] = await this.db.update(messages2).set({ transcription: sanitizeText(transcription) ?? "", updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338187
338208
  if (!updated) {
338188
338209
  throw new NotFoundError("Message", id);
338189
338210
  }
338190
338211
  return updated;
338191
338212
  }
338192
338213
  async updateImageDescription(id, description) {
338193
- const [updated] = await this.db.update(messages2).set({ imageDescription: description, updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338214
+ const [updated] = await this.db.update(messages2).set({ imageDescription: sanitizeText(description) ?? "", updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338194
338215
  if (!updated) {
338195
338216
  throw new NotFoundError("Message", id);
338196
338217
  }
338197
338218
  return updated;
338198
338219
  }
338199
338220
  async updateVideoDescription(id, description) {
338200
- const [updated] = await this.db.update(messages2).set({ videoDescription: description, updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338221
+ const [updated] = await this.db.update(messages2).set({ videoDescription: sanitizeText(description) ?? "", updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338201
338222
  if (!updated) {
338202
338223
  throw new NotFoundError("Message", id);
338203
338224
  }
338204
338225
  return updated;
338205
338226
  }
338206
338227
  async updateDocumentExtraction(id, extraction) {
338207
- const [updated] = await this.db.update(messages2).set({ documentExtraction: extraction, updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338228
+ const [updated] = await this.db.update(messages2).set({ documentExtraction: sanitizeText(extraction) ?? "", updatedAt: new Date }).where(eq(messages2.id, id)).returning();
338208
338229
  if (!updated) {
338209
338230
  throw new NotFoundError("Message", id);
338210
338231
  }
@@ -369643,6 +369664,69 @@ async function handleGupshupWebhook(request, plugin3, instanceId, webhookVerifyT
369643
369664
  });
369644
369665
  return new Response("OK", { status: 200 });
369645
369666
  }
369667
+ var CROSS_ID_WINDOW_MS = 60000;
369668
+ var FILEMANAGER_URL_RE = /^https:\/\/filemanager\.gupshup\.io\/\S+$/;
369669
+ var recentTextByChat = new Map;
369670
+ var recentMediaByChat = new Map;
369671
+ function pruneExpiredCrossIdEntries(now) {
369672
+ for (const map of [recentTextByChat, recentMediaByChat]) {
369673
+ for (const [key, value] of map) {
369674
+ if (now - value.ts > CROSS_ID_WINDOW_MS * 1.5)
369675
+ map.delete(key);
369676
+ }
369677
+ }
369678
+ }
369679
+ function isRelayMediaEcho(chatKey, messageId, bodyText, now) {
369680
+ if (!messageId.startsWith("gs-entry-") || !FILEMANAGER_URL_RE.test(bodyText))
369681
+ return null;
369682
+ const lastMedia = recentMediaByChat.get(chatKey);
369683
+ if (lastMedia && now - lastMedia.ts <= CROSS_ID_WINDOW_MS)
369684
+ return lastMedia.id;
369685
+ return null;
369686
+ }
369687
+ function isDuplicateTextRedelivery(chatKey, messageId, bodyText, now) {
369688
+ const normalized = bodyText.toLowerCase().replace(/\s+/g, " ");
369689
+ if (normalized.length <= 3)
369690
+ return null;
369691
+ const textKey = `${chatKey}:${normalized}`;
369692
+ const prev = recentTextByChat.get(textKey);
369693
+ if (prev && prev.id !== messageId && now - prev.ts <= CROSS_ID_WINDOW_MS)
369694
+ return prev.id;
369695
+ if (!prev || prev.id === messageId)
369696
+ recentTextByChat.set(textKey, { ts: now, id: messageId });
369697
+ return null;
369698
+ }
369699
+ function isCrossIdDuplicate(instanceId, msg, from, logger5) {
369700
+ const now = Date.now();
369701
+ pruneExpiredCrossIdEntries(now);
369702
+ const chatKey = `${instanceId}:${from.trim()}`;
369703
+ const rawType = msg.type ?? msg.raw?.type ?? "";
369704
+ const bodyText = (msg.text ?? "").trim();
369705
+ if (rawType !== "text" || !bodyText) {
369706
+ if (rawType && rawType !== "text")
369707
+ recentMediaByChat.set(chatKey, { ts: now, id: msg.id });
369708
+ return false;
369709
+ }
369710
+ const echoOf = isRelayMediaEcho(chatKey, msg.id, bodyText, now);
369711
+ if (echoOf) {
369712
+ logger5.info("gupshup cross-id dedupe: relay media echo dropped", {
369713
+ instanceId,
369714
+ messageId: msg.id,
369715
+ mediaMessageId: echoOf
369716
+ });
369717
+ return true;
369718
+ }
369719
+ const duplicateOf = isDuplicateTextRedelivery(chatKey, msg.id, bodyText, now);
369720
+ if (duplicateOf) {
369721
+ logger5.info("gupshup cross-id dedupe: duplicate content dropped", {
369722
+ instanceId,
369723
+ messageId: msg.id,
369724
+ firstMessageId: duplicateOf
369725
+ });
369726
+ return true;
369727
+ }
369728
+ return false;
369729
+ }
369646
369730
  async function processInboundMessage(plugin3, instanceId, webhook, dedupeCache, options = {}) {
369647
369731
  const msg = webhook.messageobj;
369648
369732
  const from = webhook.sender;
@@ -369650,6 +369734,9 @@ async function processInboundMessage(plugin3, instanceId, webhook, dedupeCache,
369650
369734
  if (dedupeCache.isDuplicate(instanceId, dedupeKey, "gupshup", plugin3.getLogger())) {
369651
369735
  return false;
369652
369736
  }
369737
+ if (isCrossIdDuplicate(instanceId, msg, from, plugin3.getLogger())) {
369738
+ return false;
369739
+ }
369653
369740
  const content = extractContent2(msg);
369654
369741
  if (!content)
369655
369742
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260720.2",
3
+ "version": "2.260723.1",
4
4
  "description": "LLM-optimized CLI for Omni",
5
5
  "type": "module",
6
6
  "bin": {