@automagik/omni 2.260910.1 → 2.260910.2

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
@@ -137139,7 +137139,7 @@ import { fileURLToPath } from "url";
137139
137139
  // package.json
137140
137140
  var package_default = {
137141
137141
  name: "@automagik/omni",
137142
- version: "2.260910.1",
137142
+ version: "2.260910.2",
137143
137143
  repository: {
137144
137144
  type: "git",
137145
137145
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -44693,6 +44693,7 @@ class InstanceManager {
44693
44693
  // ../channel-sdk/src/base/BaseChannelPlugin.ts
44694
44694
  class BaseChannelPlugin {
44695
44695
  eventBus;
44696
+ ingressClaim;
44696
44697
  logger;
44697
44698
  storage;
44698
44699
  config;
@@ -44704,6 +44705,7 @@ class BaseChannelPlugin {
44704
44705
  this.storage = context2.storage;
44705
44706
  this.config = context2.config;
44706
44707
  this.db = context2.db;
44708
+ this.ingressClaim = context2.ingressClaim;
44707
44709
  await this.onInitialize(context2);
44708
44710
  }
44709
44711
  async onInitialize(_context) {}
@@ -44829,10 +44831,34 @@ class BaseChannelPlugin {
44829
44831
  }
44830
44832
  async emitMessageReceived(params) {
44831
44833
  const { instanceId, timings, isHistorySync, ...payload } = params;
44832
- return this.publishEventInternal("message.received", payload, instanceId, {
44834
+ const options = {
44833
44835
  timings,
44834
44836
  ingestMode: isHistorySync ? "history-sync" : "realtime"
44835
- });
44837
+ };
44838
+ if (this.ingressClaim) {
44839
+ const idempotencyKey = `${this.id}:${instanceId}:${payload.externalId}:${payload.content.type}`;
44840
+ const eventId = await this.ingressClaim.claim({
44841
+ idempotencyKey,
44842
+ instanceId,
44843
+ channelType: this.id,
44844
+ externalId: payload.externalId
44845
+ });
44846
+ if (eventId === null) {
44847
+ this.logger.info("Skipping duplicate inbound message (idempotency key already journaled)", {
44848
+ instanceId,
44849
+ idempotencyKey
44850
+ });
44851
+ return generateCorrelationId("evt");
44852
+ }
44853
+ options.publishEventId = eventId;
44854
+ try {
44855
+ return await this.publishEventInternal("message.received", payload, instanceId, options);
44856
+ } catch (error) {
44857
+ await this.ingressClaim.release(eventId).catch(() => {});
44858
+ throw error;
44859
+ }
44860
+ }
44861
+ return this.publishEventInternal("message.received", payload, instanceId, options);
44836
44862
  }
44837
44863
  async emitMessageSent(params) {
44838
44864
  const { instanceId, ...payload } = params;
@@ -251569,7 +251595,7 @@ var init_sentry_scrub = __esm(() => {
251569
251595
  var require_package7 = __commonJS((exports, module) => {
251570
251596
  module.exports = {
251571
251597
  name: "@omni/api",
251572
- version: "2.260910.1",
251598
+ version: "2.260910.2",
251573
251599
  private: true,
251574
251600
  type: "module",
251575
251601
  exports: {
@@ -363041,6 +363067,7 @@ var init_storage = __esm(() => {
363041
363067
  });
363042
363068
 
363043
363069
  // ../api/src/plugins/context.ts
363070
+ import { randomUUID as randomUUID2 } from "crypto";
363044
363071
  function createPluginDatabase(db2) {
363045
363072
  return {
363046
363073
  async execute(_sql, _params) {
@@ -363052,6 +363079,38 @@ function createPluginDatabase(db2) {
363052
363079
  }
363053
363080
  };
363054
363081
  }
363082
+ function createIngressClaim(db2) {
363083
+ return {
363084
+ async claim({ idempotencyKey, instanceId, channelType, externalId }) {
363085
+ const id = randomUUID2();
363086
+ try {
363087
+ const claimed = await db2.insert(omniEvents).values({
363088
+ id,
363089
+ externalId,
363090
+ channel: channelTypes.includes(channelType) ? channelType : "discord",
363091
+ instanceId,
363092
+ eventType: "message.received",
363093
+ direction: "inbound",
363094
+ status: "received",
363095
+ idempotencyKey,
363096
+ receivedAt: new Date,
363097
+ metadata: { correlationId: id, source: `channel:${channelType}`, idempotencyKey },
363098
+ tenantId: resolvePublishTenantId(undefined, instanceId)
363099
+ }).onConflictDoNothing({ target: omniEvents.idempotencyKey }).returning({ id: omniEvents.id });
363100
+ return claimed.length > 0 ? id : null;
363101
+ } catch (error3) {
363102
+ log88.warn("Ingress idempotency claim failed; publishing without dedup", {
363103
+ idempotencyKey,
363104
+ error: String(error3)
363105
+ });
363106
+ return id;
363107
+ }
363108
+ },
363109
+ async release(eventId) {
363110
+ await db2.delete(omniEvents).where(eq(omniEvents.id, eventId));
363111
+ }
363112
+ };
363113
+ }
363055
363114
  function createPluginContext(options) {
363056
363115
  const { pluginId, eventBus, db: db2 } = options;
363057
363116
  const env2 = "development";
@@ -363070,12 +363129,15 @@ function createPluginContext(options) {
363070
363129
  basePath: process.env.MEDIA_STORAGE_PATH ?? "./data/media"
363071
363130
  }
363072
363131
  },
363073
- db: createPluginDatabase(db2)
363132
+ db: createPluginDatabase(db2),
363133
+ ingressClaim: createIngressClaim(db2)
363074
363134
  };
363075
363135
  }
363076
363136
  var log88;
363077
363137
  var init_context3 = __esm(() => {
363078
363138
  init_src();
363139
+ init_src5();
363140
+ init_drizzle_orm();
363079
363141
  init_logger4();
363080
363142
  init_storage();
363081
363143
  log88 = createLogger("api:plugin-context");
@@ -367135,10 +367197,11 @@ async function shouldProcessMessage3(agentRunner, accessService, chatsService, m
367135
367197
  if (await isAgentOutboundEcho(chatsService, messagesService, db2, payload, metadata.instanceId, trustedTenantId)) {
367136
367198
  return null;
367137
367199
  }
367138
- if (payload.content?.type === "reaction") {
367139
- log91.debug("Skipping reaction dual-emit on message path (reaction.received owns dispatch)", {
367200
+ if (payload.content?.type && NON_DISPATCHABLE_CONTENT_TYPES.has(payload.content.type)) {
367201
+ log91.debug("Skipping non-conversational content type on message path", {
367140
367202
  instanceId: metadata.instanceId,
367141
- chatId: payload.chatId
367203
+ chatId: payload.chatId,
367204
+ contentType: payload.content.type
367142
367205
  });
367143
367206
  return null;
367144
367207
  }
@@ -367671,7 +367734,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
367671
367734
  log91.info("Agent dispatcher shutdown complete");
367672
367735
  };
367673
367736
  }
367674
- var import_api31, log91, 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, 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;
367737
+ var import_api31, log91, 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;
367675
367738
  var init_agent_dispatcher = __esm(() => {
367676
367739
  init_src2();
367677
367740
  init_src();
@@ -367718,6 +367781,7 @@ var init_agent_dispatcher = __esm(() => {
367718
367781
  telegram: 4096
367719
367782
  };
367720
367783
  MEDIA_BASE_PATH3 = process.env.MEDIA_STORAGE_PATH || "./data/media";
367784
+ NON_DISPATCHABLE_CONTENT_TYPES = new Set(["reaction", "delete", "unknown"]);
367721
367785
  MEDIA_ICONS = {
367722
367786
  audio: "\uD83C\uDFB5",
367723
367787
  image: "\uD83D\uDDBC\uFE0F",
@@ -368486,7 +368550,7 @@ var init_batch_pricing = __esm(() => {
368486
368550
  });
368487
368551
 
368488
368552
  // ../api/src/services/media-storage.ts
368489
- import { randomUUID as randomUUID2 } from "crypto";
368553
+ import { randomUUID as randomUUID3 } from "crypto";
368490
368554
  import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
368491
368555
  import { rm as rm3, writeFile as writeFile5 } from "fs/promises";
368492
368556
  import { tmpdir as tmpdir12 } from "os";
@@ -368720,7 +368784,7 @@ class MediaStorageService {
368720
368784
  }
368721
368785
  const buffer3 = await this.backend.read(reference);
368722
368786
  const ext = extname2(reference) || ".bin";
368723
- const tempPath = join23(tmpdir12(), `omni-media-${randomUUID2()}${ext}`);
368787
+ const tempPath = join23(tmpdir12(), `omni-media-${randomUUID3()}${ext}`);
368724
368788
  try {
368725
368789
  await writeFile5(tempPath, buffer3);
368726
368790
  } catch (error3) {
@@ -395917,7 +395981,7 @@ var init_webhooks3 = __esm(() => {
395917
395981
  });
395918
395982
 
395919
395983
  // ../api/src/lib/oauth-token-cache.ts
395920
- import { randomUUID as randomUUID3 } from "crypto";
395984
+ import { randomUUID as randomUUID4 } from "crypto";
395921
395985
  function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
395922
395986
  if (!accessToken)
395923
395987
  throw new Error("oauth-token-cache: accessToken is required");
@@ -395926,7 +395990,7 @@ function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
395926
395990
  if (oldest)
395927
395991
  store.delete(oldest);
395928
395992
  }
395929
- const handle = `eshandle_${randomUUID3()}`;
395993
+ const handle = `eshandle_${randomUUID4()}`;
395930
395994
  store.set(handle, { accessToken, expiresAt: Date.now() + ttlMs });
395931
395995
  return handle;
395932
395996
  }
@@ -397679,8 +397743,7 @@ async function setupEventPersistence(eventBus, db2) {
397679
397743
  await runConsumerInTenantContext(db2, event, async () => {
397680
397744
  const sdb = scopedHandle(db2);
397681
397745
  const chatUuid = await resolveChatUuid(sdb, metadata.instanceId, payload.chatId);
397682
- const newEvent = {
397683
- ...eventIdInsert(event.id),
397746
+ const columns2 = {
397684
397747
  externalId: payload.externalId,
397685
397748
  channel: mapChannelType(metadata.channelType),
397686
397749
  instanceId: metadata.instanceId,
@@ -397706,7 +397769,7 @@ async function setupEventPersistence(eventBus, db2) {
397706
397769
  conversationId: null,
397707
397770
  chatUuid
397708
397771
  };
397709
- await sdb.insert(omniEvents).values(newEvent).onConflictDoNothing({ target: omniEvents.id });
397772
+ await sdb.insert(omniEvents).values({ ...eventIdInsert(event.id), ...columns2 }).onConflictDoUpdate({ target: omniEvents.id, set: columns2 });
397710
397773
  });
397711
397774
  if (metadata.timings && metadata.correlationId) {
397712
397775
  const tracker = getJourneyTracker();
@@ -407437,10 +407500,7 @@ class DiscordPlugin extends BaseChannelPlugin {
407437
407500
  externalId: `${messageId}-delete-${Date.now()}`,
407438
407501
  chatId,
407439
407502
  from: chatId,
407440
- content: {
407441
- type: "delete",
407442
- text: fromMe ? "Message deleted by bot" : "Message deleted"
407443
- },
407503
+ content: { type: "delete" },
407444
407504
  rawPayload: {
407445
407505
  deletedMessageId: messageId,
407446
407506
  deletedAt: Date.now(),
@@ -528091,10 +528151,7 @@ function extractUnknownContent(message2) {
528091
528151
  return null;
528092
528152
  }
528093
528153
  log52.debug("Unknown message type", { keys: messageKeys });
528094
- return {
528095
- type: "unknown",
528096
- text: `Unknown message type: ${messageKeys.join(", ")}`
528097
- };
528154
+ return { type: "unknown" };
528098
528155
  }
528099
528156
  function extractContent3(msg) {
528100
528157
  const message2 = msg.message;
@@ -531336,10 +531393,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531336
531393
  externalId: `${externalId}-delete-${Date.now()}`,
531337
531394
  chatId,
531338
531395
  from: chatId,
531339
- content: {
531340
- type: "delete",
531341
- text: fromMe ? "Message deleted by sender" : "Message deleted"
531342
- },
531396
+ content: { type: "delete" },
531343
531397
  rawPayload: {
531344
531398
  deletedMessageId: externalId,
531345
531399
  deletedAt: Date.now(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260910.1",
3
+ "version": "2.260910.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",