@automagik/omni 2.260909.5 → 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.
@@ -53,6 +53,18 @@ export declare const __testables: {
53
53
  loadSchemaArtifact: typeof loadSchemaArtifact;
54
54
  summarizeSchemaRow: typeof summarizeSchemaRow;
55
55
  };
56
+ /**
57
+ * Table projection for list-shaped event commands. Human-readable output only:
58
+ * JSON mode emits the raw API rows via `rawData` so `eventType` (and every
59
+ * other field) survives intact (#1028).
60
+ */
61
+ export declare function eventListRow(e: Event): {
62
+ id: string;
63
+ type: string;
64
+ instanceId: string;
65
+ direction: string;
66
+ receivedAt: string;
67
+ };
56
68
  /** True when event_type denotes a failure/denial — used by --errors-only. */
57
69
  export declare function isErrorEvent(eventType: string): boolean;
58
70
  /** True when event_type is considered noisy and should be hidden unless --all is set. */
@@ -81,8 +93,40 @@ export interface StreamFilterOptions {
81
93
  * (chat-id, person-id, errors-only, noise suppression).
82
94
  */
83
95
  export declare function passesStreamFilters(event: Event, options: StreamFilterOptions): boolean;
96
+ /**
97
+ * The journal row as GET /events actually returns it (full omni_events row —
98
+ * the SDK `Event` type is a projection). `stream` reads the raw platform
99
+ * chat id (#1036 ask 3) and sender hints out of the extra columns.
100
+ */
101
+ export type StreamEventRow = Event & {
102
+ chatId?: string | null;
103
+ metadata?: {
104
+ from?: string;
105
+ } | null;
106
+ rawPayload?: {
107
+ pushName?: string;
108
+ key?: {
109
+ fromMe?: boolean;
110
+ };
111
+ } | null;
112
+ };
113
+ /** id → display name lookups for `stream` (null = looked up, nothing found). */
114
+ export interface StreamNames {
115
+ instances: Map<string, string | null>;
116
+ chats: Map<string, string | null>;
117
+ persons: Map<string, string | null>;
118
+ }
119
+ export interface FormatLineOptions {
120
+ /** Add sender / fromMe / contentType columns (#1036 ask 1). */
121
+ verbose?: boolean;
122
+ /** Print raw uuid8 ids even when a name is known (#1036 ask 2, `--ids`). */
123
+ ids?: boolean;
124
+ names?: StreamNames;
125
+ }
126
+ /** Sender label: resolved person name, then channel push name, then raw `from`. */
127
+ export declare function senderLabel(event: StreamEventRow, names?: StreamNames): string;
84
128
  /** Format an event as a single human-readable line. */
85
- export declare function formatEventLine(event: Event): string;
129
+ export declare function formatEventLine(event: StreamEventRow, options?: FormatLineOptions): string;
86
130
  /**
87
131
  * The journal row as the API actually returns it: the generated SDK `Event`
88
132
  * type is a projection, but GET /events returns full omni_events rows —
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/commands/events.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -40094,6 +40094,14 @@ function evaluateConditionsWithDetails(conditions, payload, logic = "and") {
40094
40094
  conditions: results
40095
40095
  };
40096
40096
  }
40097
+ function describeUnmatchedConditions(result) {
40098
+ const failed = result.conditions.filter((c2) => !c2.matched).map((c2) => {
40099
+ const expected = c2.operator === "exists" || c2.operator === "not_exists" ? "" : ` ${JSON.stringify(c2.expectedValue)}`;
40100
+ const actual = c2.actualValue === undefined ? "condition_field_unresolved" : `actual: ${JSON.stringify(c2.actualValue)}`;
40101
+ return `${c2.field} ${c2.operator}${expected} (${actual})`;
40102
+ });
40103
+ return `conditions_not_matched: ${failed.join("; ")}`;
40104
+ }
40097
40105
  var logger, MAX_REGEX_INPUT_LENGTH = 1e4, MAX_REGEX_PATTERN_LENGTH = 500, DANGEROUS_REGEX_PATTERN;
40098
40106
  var init_conditions = __esm(() => {
40099
40107
  init_logger();
@@ -41503,6 +41511,7 @@ class AutomationEngine {
41503
41511
  releaseIdleTimeoutClaim: deps.releaseIdleTimeoutClaim,
41504
41512
  claimEmittedEvent: deps.claimEmittedEvent,
41505
41513
  releaseEmittedEventClaim: deps.releaseEmittedEventClaim,
41514
+ claimExecution: deps.claimExecution,
41506
41515
  validateEmitEvent: deps.validateEmitEvent
41507
41516
  };
41508
41517
  this.automations = automations.filter((a) => a.enabled);
@@ -41589,7 +41598,8 @@ class AutomationEngine {
41589
41598
  queue: "automation-engine",
41590
41599
  startFrom: "new",
41591
41600
  maxRetries: 3,
41592
- retryDelayMs: 1000
41601
+ retryDelayMs: 1000,
41602
+ ackWaitMs: 5 * 60 * 1000
41593
41603
  });
41594
41604
  logger4.info(`Subscribed to ${eventType}.*`, { durable });
41595
41605
  return subscription;
@@ -41876,6 +41886,25 @@ class AutomationEngine {
41876
41886
  status: "skipped",
41877
41887
  conditionsMatched: false,
41878
41888
  actionsExecuted: [],
41889
+ error: describeUnmatchedConditions(conditionResult),
41890
+ executionTimeMs: Date.now() - start
41891
+ };
41892
+ await this.logExecution(result2, trustedTenantId);
41893
+ return result2;
41894
+ }
41895
+ if (this.deps.claimExecution && !await this.deps.claimExecution(event.id, automation.id, trustedTenantId)) {
41896
+ logger4.info("Skipping redelivered event: execution already claimed", {
41897
+ automationId: automation.id,
41898
+ eventId: event.id
41899
+ });
41900
+ const result2 = {
41901
+ automationId: automation.id,
41902
+ automationName: automation.name,
41903
+ eventId: event.id,
41904
+ status: "skipped",
41905
+ conditionsMatched: true,
41906
+ actionsExecuted: [],
41907
+ error: "duplicate delivery: execution already claimed for this event",
41879
41908
  executionTimeMs: Date.now() - start
41880
41909
  };
41881
41910
  await this.logExecution(result2, trustedTenantId);
@@ -70700,6 +70729,7 @@ __export(exports_src, {
70700
70729
  enableDefaultMetrics: () => enableDefaultMetrics,
70701
70730
  disarmSequence: () => disarmSequence,
70702
70731
  detectContentFlags: () => detectContentFlags,
70732
+ describeUnmatchedConditions: () => describeUnmatchedConditions,
70703
70733
  deriveFollowUpFromPayload: () => deriveFollowUpFromPayload,
70704
70734
  decompressPayload: () => decompressPayload,
70705
70735
  deadLettersPending: () => deadLettersPending,
@@ -115685,7 +115715,7 @@ var require_client2 = __commonJS((exports) => {
115685
115715
 
115686
115716
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
115687
115717
  var require_esmLoader = __commonJS((exports) => {
115688
- var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115718
+ var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
115689
115719
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
115690
115720
  var core = require_cjs();
115691
115721
  var importInTheMiddle = require_import_in_the_middle();
@@ -137109,7 +137139,7 @@ import { fileURLToPath } from "url";
137109
137139
  // package.json
137110
137140
  var package_default = {
137111
137141
  name: "@automagik/omni",
137112
- version: "2.260909.5",
137142
+ version: "2.260910.2",
137113
137143
  repository: {
137114
137144
  type: "git",
137115
137145
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -144020,6 +144050,9 @@ function createSchemaCommand() {
144020
144050
  });
144021
144051
  return schema;
144022
144052
  }
144053
+ function eventListRow(e10) {
144054
+ return { id: e10.id, type: e10.eventType, instanceId: e10.instanceId, direction: e10.direction, receivedAt: e10.receivedAt };
144055
+ }
144023
144056
  var NOISY_EVENT_TYPES = new Set([
144024
144057
  "presence.typing",
144025
144058
  "presence.online",
@@ -144053,19 +144086,55 @@ function passesStreamFilters(event, options) {
144053
144086
  return false;
144054
144087
  return true;
144055
144088
  }
144056
- function formatEventLine(event) {
144089
+ function labelFor(id, names, ids2) {
144090
+ if (!id)
144091
+ return "";
144092
+ const name = ids2 ? undefined : names?.get(id);
144093
+ return name ? name.slice(0, 16) : id.slice(0, 8);
144094
+ }
144095
+ function senderLabel(event, names) {
144096
+ const person2 = event.personId ? names?.persons.get(event.personId) : undefined;
144097
+ return person2 ?? event.rawPayload?.pushName ?? event.metadata?.from ?? "";
144098
+ }
144099
+ function formatEventLine(event, options = {}) {
144100
+ const ids2 = options.ids === true;
144057
144101
  const time = new Date(event.receivedAt).toISOString().slice(11, 19);
144058
- const instance3 = event.instanceId?.slice(0, 8) ?? "--------";
144059
- const chat = event.chatUuid?.slice(0, 8) ?? "--------";
144102
+ const instance3 = labelFor(event.instanceId, options.names?.instances, ids2) || "--------";
144103
+ const chat = labelFor(event.chatUuid, options.names?.chats, ids2) || event.chatId || "--------";
144060
144104
  const summary = event.textContent ?? event.transcription ?? event.imageDescription ?? "";
144061
144105
  const trimmed = summary.length > 80 ? `${summary.slice(0, 77)}...` : summary;
144062
- return `${time} ${event.eventType.padEnd(28)} ${instance3}/${chat} ${event.direction.padEnd(8)} ${trimmed}`.trimEnd();
144106
+ const cols = [time, event.eventType.padEnd(28), `${instance3}/${chat}`, event.direction.padEnd(8)];
144107
+ if (options.verbose) {
144108
+ const fromMe = event.rawPayload?.key?.fromMe === true || event.direction === "outbound";
144109
+ cols.push(fromMe ? "me" : " ", (event.contentType ?? "-").padEnd(8), senderLabel(event, options.names).padEnd(16));
144110
+ }
144111
+ return `${cols.join(" ")} ${trimmed}`.trimEnd();
144063
144112
  }
144064
- function emitStreamEvent(event, ndjson) {
144113
+ async function warmStreamNames(client, names, events2) {
144114
+ const lookup2 = async (map2, id, fetch2) => {
144115
+ if (map2.has(id))
144116
+ return;
144117
+ map2.set(id, await fetch2().catch(() => null));
144118
+ };
144119
+ if (names.instances.size === 0 && events2.length > 0) {
144120
+ const list2 = await client.instances.list({ limit: 100 }).catch(() => ({ items: [] }));
144121
+ for (const i6 of list2.items)
144122
+ names.instances.set(i6.id, i6.name);
144123
+ }
144124
+ for (const ev2 of events2) {
144125
+ if (ev2.chatUuid) {
144126
+ await lookup2(names.chats, ev2.chatUuid, async () => (await client.chats.get(ev2.chatUuid)).name ?? null);
144127
+ }
144128
+ if (ev2.personId) {
144129
+ await lookup2(names.persons, ev2.personId, async () => (await client.persons.get(ev2.personId)).displayName);
144130
+ }
144131
+ }
144132
+ }
144133
+ function emitStreamEvent(event, ndjson, format) {
144065
144134
  if (ndjson) {
144066
144135
  raw(JSON.stringify(event));
144067
144136
  } else {
144068
- raw(formatEventLine(event));
144137
+ raw(formatEventLine(event, format));
144069
144138
  }
144070
144139
  }
144071
144140
  async function fetchStreamBatch(client, filters, channel2, type, sinceIso) {
@@ -144084,15 +144153,18 @@ async function fetchStreamBatch(client, filters, channel2, type, sinceIso) {
144084
144153
  return [];
144085
144154
  }
144086
144155
  }
144087
- function processStreamBatch(items, filters, state, ndjson) {
144156
+ async function processStreamBatch(client, items, filters, state, ndjson, format) {
144088
144157
  const ascending = [...items].sort((a2, b8) => a2.receivedAt.localeCompare(b8.receivedAt));
144158
+ const fresh = ascending.filter((ev2) => !state.seen.has(ev2.id) && passesStreamFilters(ev2, filters));
144159
+ if (!ndjson && !format.ids && format.names)
144160
+ await warmStreamNames(client, format.names, fresh);
144089
144161
  for (const ev2 of ascending) {
144090
144162
  if (state.seen.has(ev2.id))
144091
144163
  continue;
144092
144164
  state.seen.add(ev2.id);
144093
144165
  if (!passesStreamFilters(ev2, filters))
144094
144166
  continue;
144095
- emitStreamEvent(ev2, ndjson);
144167
+ emitStreamEvent(ev2, ndjson, format);
144096
144168
  if (ev2.receivedAt > state.sinceIso)
144097
144169
  state.sinceIso = ev2.receivedAt;
144098
144170
  }
@@ -144118,6 +144190,11 @@ async function streamEvents(client, options) {
144118
144190
  errorsOnly: options.errorsOnly,
144119
144191
  all: options.all
144120
144192
  };
144193
+ const format = {
144194
+ verbose: options.verbose,
144195
+ ids: options.ids,
144196
+ names: { instances: new Map, chats: new Map, persons: new Map }
144197
+ };
144121
144198
  let stopped = false;
144122
144199
  const shutdown = () => {
144123
144200
  stopped = true;
@@ -144130,7 +144207,7 @@ async function streamEvents(client, options) {
144130
144207
  try {
144131
144208
  while (!stopped) {
144132
144209
  const items = await fetchStreamBatch(client, filters, options.channel, options.type, state.sinceIso);
144133
- processStreamBatch(items, filters, state, ndjson);
144210
+ await processStreamBatch(client, items, filters, state, ndjson, format);
144134
144211
  if (stopped)
144135
144212
  break;
144136
144213
  await new Promise((resolve2) => setTimeout(resolve2, pollMs));
@@ -144317,20 +144394,13 @@ function createEventsCommand() {
144317
144394
  until: options.until,
144318
144395
  limit: options.limit
144319
144396
  });
144320
- const items = result.items.map((e10) => ({
144321
- id: e10.id,
144322
- type: e10.eventType,
144323
- instanceId: e10.instanceId,
144324
- direction: e10.direction,
144325
- receivedAt: e10.receivedAt
144326
- }));
144327
- list(items, { emptyMessage: "No events found." });
144397
+ list(result.items.map(eventListRow), { emptyMessage: "No events found.", rawData: result.items });
144328
144398
  } catch (err2) {
144329
144399
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144330
144400
  error(`Failed to list events: ${message2}`);
144331
144401
  }
144332
144402
  });
144333
- events2.command("stream").description("Stream events in real-time (tail -f style). Ctrl+C to stop.").option("--instance <id>", "Filter by instance ID").option("--channel <type>", "Filter by channel type").option("--type <type>", "Filter by event type (trailing * = prefix glob, e.g. custom.*)").option("--chat-id <id>", "Filter by chat ID").option("--person-id <id>", "Filter by person ID").option("--since <time>", "Start cursor (e.g., 5min, 24h, 7d, or ISO timestamp)").option("--errors-only", "Show only error/failure events").option("--all", "Include noisy event types (presence, delivered, read, progress)").option("--ndjson", "Emit JSON Lines (one event per line) \u2014 same as global --json in stream mode").option("--poll-ms <n>", "Polling interval in milliseconds", (v4) => Number.parseInt(v4, 10), 2000).action(async (options) => {
144403
+ events2.command("stream").description("Stream events in real-time (tail -f style). Ctrl+C to stop.").option("--instance <id>", "Filter by instance ID").option("--channel <type>", "Filter by channel type").option("--type <type>", "Filter by event type (trailing * = prefix glob, e.g. custom.*)").option("--chat-id <id>", "Filter by chat ID").option("--person-id <id>", "Filter by person ID").option("--since <time>", "Start cursor (e.g., 5min, 24h, 7d, or ISO timestamp)").option("--errors-only", "Show only error/failure events").option("--all", "Include noisy event types (presence, delivered, read, progress)").option("--ndjson", "Emit JSON Lines (one event per line) \u2014 same as global --json in stream mode").option("-v, --verbose", "Add sender, fromMe marker and contentType columns").option("--ids", "Print raw ids instead of resolved instance/chat names").option("--poll-ms <n>", "Polling interval in milliseconds", (v4) => Number.parseInt(v4, 10), 2000).action(async (options) => {
144334
144404
  const client = getClient();
144335
144405
  try {
144336
144406
  await streamEvents(client, options);
@@ -144374,7 +144444,7 @@ function createEventsCommand() {
144374
144444
  error(`Failed to wait for event: ${message2}`);
144375
144445
  }
144376
144446
  });
144377
- events2.command("follow").description("Tail the journal through a durable consumer: resumes from its stored cursor, prints JSON lines, acks as it goes.").requiredOption("--consumer <name>", "Durable consumer to follow (create with: omni events consumers create)").option("--limit <n>", "Max journal rows scanned per pull", (v4) => Number.parseInt(v4, 10), 100).option("--wait-ms <n>", "Server-side long-poll window per pull when idle (max 30000)", (v4) => Number.parseInt(v4, 10), 1e4).option("--no-ack", "Peek: print one page without advancing the cursor, then exit").option("--until-idle", "Exit 0 once caught up with the journal instead of tailing forever").action(async (options) => {
144447
+ events2.command("follow").description("Tail the journal through a durable consumer: resumes from its stored cursor, prints JSON lines, acks as it goes.").requiredOption("--consumer <name>", "Durable consumer to follow (create with: omni events consumers create)").option("--limit <n>", "Max journal rows scanned per pull", (v4) => Number.parseInt(v4, 10), 100).option("--wait-ms <n>", "Server-side long-poll window per pull when idle (max 30000)", (v4) => Number.parseInt(v4, 10), 1e4).option("--no-ack", "Peek: print one page without advancing the cursor, then exit").option("--until-idle", "Exit 0 once caught up with the journal instead of tailing forever").option("--ndjson", "Accepted for symmetry with `events stream` \u2014 follow always emits JSON Lines").action(async (options) => {
144378
144448
  let stopped = false;
144379
144449
  const shutdown = () => {
144380
144450
  stopped = true;
@@ -144426,14 +144496,10 @@ function createEventsCommand() {
144426
144496
  since: options.since ? parseSinceTime(options.since) : undefined,
144427
144497
  limit: options.limit
144428
144498
  });
144429
- const items = result.items.map((e10) => ({
144430
- id: e10.id,
144431
- type: e10.eventType,
144432
- instanceId: e10.instanceId,
144433
- direction: e10.direction,
144434
- receivedAt: e10.receivedAt
144435
- }));
144436
- list(items, { emptyMessage: "No matching events found." });
144499
+ list(result.items.map(eventListRow), {
144500
+ emptyMessage: "No matching events found.",
144501
+ rawData: result.items
144502
+ });
144437
144503
  } catch (err2) {
144438
144504
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144439
144505
  error(`Failed to search events: ${message2}`);
@@ -144446,14 +144512,10 @@ function createEventsCommand() {
144446
144512
  search: personId,
144447
144513
  limit: options.limit
144448
144514
  });
144449
- const items = result.items.map((e10) => ({
144450
- id: e10.id,
144451
- type: e10.eventType,
144452
- instanceId: e10.instanceId,
144453
- direction: e10.direction,
144454
- receivedAt: e10.receivedAt
144455
- }));
144456
- list(items, { emptyMessage: `No events found for person: ${personId}` });
144515
+ list(result.items.map(eventListRow), {
144516
+ emptyMessage: `No events found for person: ${personId}`,
144517
+ rawData: result.items
144518
+ });
144457
144519
  } catch (err2) {
144458
144520
  const message2 = err2 instanceof Error ? err2.message : "Unknown error";
144459
144521
  error(`Failed to get timeline: ${message2}`);
@@ -144712,7 +144774,7 @@ function formatTime3(ts) {
144712
144774
  return ts;
144713
144775
  }
144714
144776
  }
144715
- function senderLabel(msg) {
144777
+ function senderLabel2(msg) {
144716
144778
  if (msg.senderDisplayName)
144717
144779
  return msg.senderDisplayName;
144718
144780
  if (msg.isFromMe)
@@ -144774,7 +144836,7 @@ function createHistoryCommand() {
144774
144836
  const rows = messages2.map((msg) => ({
144775
144837
  ID: msg.externalId,
144776
144838
  TIME: formatTime3(msg.platformTimestamp),
144777
- SENDER: senderLabel(msg),
144839
+ SENDER: senderLabel2(msg),
144778
144840
  TYPE: msg.messageType,
144779
144841
  CONTENT: contentPreview(msg, !!options.full)
144780
144842
  }));
@@ -36998,6 +36998,14 @@ function evaluateConditionsWithDetails(conditions, payload, logic = "and") {
36998
36998
  conditions: results
36999
36999
  };
37000
37000
  }
37001
+ function describeUnmatchedConditions(result) {
37002
+ const failed = result.conditions.filter((c) => !c.matched).map((c) => {
37003
+ const expected = c.operator === "exists" || c.operator === "not_exists" ? "" : ` ${JSON.stringify(c.expectedValue)}`;
37004
+ const actual = c.actualValue === undefined ? "condition_field_unresolved" : `actual: ${JSON.stringify(c.actualValue)}`;
37005
+ return `${c.field} ${c.operator}${expected} (${actual})`;
37006
+ });
37007
+ return `conditions_not_matched: ${failed.join("; ")}`;
37008
+ }
37001
37009
  var logger, MAX_REGEX_INPUT_LENGTH = 1e4, MAX_REGEX_PATTERN_LENGTH = 500, DANGEROUS_REGEX_PATTERN;
37002
37010
  var init_conditions = __esm(() => {
37003
37011
  init_logger();
@@ -38407,6 +38415,7 @@ class AutomationEngine {
38407
38415
  releaseIdleTimeoutClaim: deps.releaseIdleTimeoutClaim,
38408
38416
  claimEmittedEvent: deps.claimEmittedEvent,
38409
38417
  releaseEmittedEventClaim: deps.releaseEmittedEventClaim,
38418
+ claimExecution: deps.claimExecution,
38410
38419
  validateEmitEvent: deps.validateEmitEvent
38411
38420
  };
38412
38421
  this.automations = automations.filter((a) => a.enabled);
@@ -38493,7 +38502,8 @@ class AutomationEngine {
38493
38502
  queue: "automation-engine",
38494
38503
  startFrom: "new",
38495
38504
  maxRetries: 3,
38496
- retryDelayMs: 1000
38505
+ retryDelayMs: 1000,
38506
+ ackWaitMs: 5 * 60 * 1000
38497
38507
  });
38498
38508
  logger4.info(`Subscribed to ${eventType}.*`, { durable });
38499
38509
  return subscription;
@@ -38780,6 +38790,25 @@ class AutomationEngine {
38780
38790
  status: "skipped",
38781
38791
  conditionsMatched: false,
38782
38792
  actionsExecuted: [],
38793
+ error: describeUnmatchedConditions(conditionResult),
38794
+ executionTimeMs: Date.now() - start
38795
+ };
38796
+ await this.logExecution(result2, trustedTenantId);
38797
+ return result2;
38798
+ }
38799
+ if (this.deps.claimExecution && !await this.deps.claimExecution(event.id, automation.id, trustedTenantId)) {
38800
+ logger4.info("Skipping redelivered event: execution already claimed", {
38801
+ automationId: automation.id,
38802
+ eventId: event.id
38803
+ });
38804
+ const result2 = {
38805
+ automationId: automation.id,
38806
+ automationName: automation.name,
38807
+ eventId: event.id,
38808
+ status: "skipped",
38809
+ conditionsMatched: true,
38810
+ actionsExecuted: [],
38811
+ error: "duplicate delivery: execution already claimed for this event",
38783
38812
  executionTimeMs: Date.now() - start
38784
38813
  };
38785
38814
  await this.logExecution(result2, trustedTenantId);
@@ -44234,6 +44263,7 @@ __export(exports_src, {
44234
44263
  enableDefaultMetrics: () => enableDefaultMetrics,
44235
44264
  disarmSequence: () => disarmSequence,
44236
44265
  detectContentFlags: () => detectContentFlags,
44266
+ describeUnmatchedConditions: () => describeUnmatchedConditions,
44237
44267
  deriveFollowUpFromPayload: () => deriveFollowUpFromPayload,
44238
44268
  decompressPayload: () => decompressPayload,
44239
44269
  deadLettersPending: () => deadLettersPending,
@@ -44663,6 +44693,7 @@ class InstanceManager {
44663
44693
  // ../channel-sdk/src/base/BaseChannelPlugin.ts
44664
44694
  class BaseChannelPlugin {
44665
44695
  eventBus;
44696
+ ingressClaim;
44666
44697
  logger;
44667
44698
  storage;
44668
44699
  config;
@@ -44674,6 +44705,7 @@ class BaseChannelPlugin {
44674
44705
  this.storage = context2.storage;
44675
44706
  this.config = context2.config;
44676
44707
  this.db = context2.db;
44708
+ this.ingressClaim = context2.ingressClaim;
44677
44709
  await this.onInitialize(context2);
44678
44710
  }
44679
44711
  async onInitialize(_context) {}
@@ -44799,10 +44831,34 @@ class BaseChannelPlugin {
44799
44831
  }
44800
44832
  async emitMessageReceived(params) {
44801
44833
  const { instanceId, timings, isHistorySync, ...payload } = params;
44802
- return this.publishEventInternal("message.received", payload, instanceId, {
44834
+ const options = {
44803
44835
  timings,
44804
44836
  ingestMode: isHistorySync ? "history-sync" : "realtime"
44805
- });
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);
44806
44862
  }
44807
44863
  async emitMessageSent(params) {
44808
44864
  const { instanceId, ...payload } = params;
@@ -76868,7 +76924,7 @@ var require_ClientVoiceManager = __commonJS((exports, module) => {
76868
76924
 
76869
76925
  // ../../node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist/index.js
76870
76926
  var require_dist9 = __commonJS((exports, module) => {
76871
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
76927
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@discordjs+ws@1.2.3/node_modules/@discordjs/ws/dist";
76872
76928
  var __create2 = Object.create;
76873
76929
  var __defProp2 = Object.defineProperty;
76874
76930
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -162148,7 +162204,7 @@ var require_indexes = __commonJS((exports, module) => {
162148
162204
 
162149
162205
  // ../../node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream/index.js
162150
162206
  var require_thread_stream = __commonJS((exports, module) => {
162151
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162207
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/thread-stream@3.1.0/node_modules/thread-stream";
162152
162208
  var { version } = require_package5();
162153
162209
  var { EventEmitter: EventEmitter3 } = __require("events");
162154
162210
  var { Worker } = __require("worker_threads");
@@ -162569,7 +162625,7 @@ var require_thread_stream = __commonJS((exports, module) => {
162569
162625
 
162570
162626
  // ../../node_modules/.bun/pino@9.14.0/node_modules/pino/lib/transport.js
162571
162627
  var require_transport2 = __commonJS((exports, module) => {
162572
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162628
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/pino@9.14.0/node_modules/pino/lib";
162573
162629
  var { createRequire: createRequire2 } = __require("module");
162574
162630
  var getCallers = require_caller();
162575
162631
  var { join: join8, isAbsolute, sep: sep2 } = __require("path");
@@ -244313,7 +244369,7 @@ var require_client3 = __commonJS((exports) => {
244313
244369
 
244314
244370
  // ../../node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js
244315
244371
  var require_esmLoader = __commonJS((exports) => {
244316
- var __filename = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244372
+ var __filename = "/home/runner/work/omni/omni/node_modules/.bun/@sentry+node-core@10.52.0+2c50d7e904f6cfd7/node_modules/@sentry/node-core/build/cjs/sdk/esmLoader.js";
244317
244373
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
244318
244374
  var core3 = require_cjs6();
244319
244375
  var importInTheMiddle = require_import_in_the_middle();
@@ -251539,7 +251595,7 @@ var init_sentry_scrub = __esm(() => {
251539
251595
  var require_package7 = __commonJS((exports, module) => {
251540
251596
  module.exports = {
251541
251597
  name: "@omni/api",
251542
- version: "2.260909.5",
251598
+ version: "2.260910.2",
251543
251599
  private: true,
251544
251600
  type: "module",
251545
251601
  exports: {
@@ -278641,7 +278697,7 @@ var require_src45 = __commonJS((exports) => {
278641
278697
 
278642
278698
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/channelz.js
278643
278699
  var require_channelz = __commonJS((exports) => {
278644
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278700
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
278645
278701
  Object.defineProperty(exports, "__esModule", { value: true });
278646
278702
  exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
278647
278703
  exports.unregisterChannelzRef = unregisterChannelzRef;
@@ -284044,7 +284100,7 @@ var require_duration = __commonJS((exports) => {
284044
284100
 
284045
284101
  // ../../node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src/orca.js
284046
284102
  var require_orca = __commonJS((exports) => {
284047
- var __dirname = "/home/runner/work/omni/omni/.stable-source/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284103
+ var __dirname = "/home/runner/work/omni/omni/node_modules/.bun/@grpc+grpc-js@1.14.3/node_modules/@grpc/grpc-js/build/src";
284048
284104
  Object.defineProperty(exports, "__esModule", { value: true });
284049
284105
  exports.OrcaOobMetricsSubchannelWrapper = exports.GRPC_METRICS_HEADER = exports.ServerMetricRecorder = exports.PerRequestMetricRecorder = undefined;
284050
284106
  exports.createOrcaClient = createOrcaClient;
@@ -313067,6 +313123,7 @@ var init_scopes = __esm(() => {
313067
313123
  "PATCH /access/rules/:id": "access:write",
313068
313124
  "DELETE /access/rules/:id": "access:write",
313069
313125
  "POST /access/check": "access:read",
313126
+ "GET /access": "access:read",
313070
313127
  "GET /instances/:instanceId/routes": "routes:read",
313071
313128
  "GET /instances/:instanceId/routes/:id": "routes:read",
313072
313129
  "POST /instances/:instanceId/routes": "routes:write",
@@ -313087,7 +313144,7 @@ var init_scopes = __esm(() => {
313087
313144
  "PATCH /agents/:id": "agents:write",
313088
313145
  "DELETE /agents/:id": "agents:write",
313089
313146
  "GET /agents/:id/identities": "agents:read",
313090
- "POST /agents/:id/identities": "agents:write",
313147
+ "POST /agents/:id/identities/link": "agents:write",
313091
313148
  "GET /agents/:id/manifest": "agents:read",
313092
313149
  "PUT /agents/:id/manifest": "agents:write",
313093
313150
  "GET /agents/:id/tasks": "agents:read",
@@ -313113,6 +313170,9 @@ var init_scopes = __esm(() => {
313113
313170
  "GET /chats": "chats:read",
313114
313171
  "POST /chats": "chats:write",
313115
313172
  "GET /chats/:id": "chats:read",
313173
+ "PATCH /chats/:id/participants/:platformUserId/role": "chats:write",
313174
+ "POST /chats/:id/reopen-contact": "chats:write",
313175
+ "POST /chats/clear-session": "chats:write",
313116
313176
  "PATCH /chats/:id": "chats:write",
313117
313177
  "DELETE /chats/:id": "chats:write",
313118
313178
  "POST /chats/:id/archive": "chats:write",
@@ -313128,7 +313188,6 @@ var init_scopes = __esm(() => {
313128
313188
  "GET /chats/:id/participants": "chats:read",
313129
313189
  "POST /chats/:id/participants": "chats:write",
313130
313190
  "DELETE /chats/:id/participants/:platformUserId": "chats:write",
313131
- "PATCH /chats/:id/participants/:platformUserId": "chats:write",
313132
313191
  "GET /chats/:id/messages": "chats:read",
313133
313192
  "GET /chats/by-external": "chats:read",
313134
313193
  "POST /chats/:id/read": "chats:write",
@@ -313163,6 +313222,11 @@ var init_scopes = __esm(() => {
313163
313222
  "GET /events/schemas": "events:read",
313164
313223
  "GET /events/schemas/:eventType": "events:read",
313165
313224
  "POST /events/schemas": "events:write",
313225
+ "GET /events/consumers/:name": "events:read",
313226
+ "POST /events/consumers": "events:write",
313227
+ "DELETE /events/consumers/:name": "events:write",
313228
+ "POST /events/consumers/:name/pull": "events:write",
313229
+ "POST /events/consumers/:name/ack": "events:write",
313166
313230
  "GET /events": "events:read",
313167
313231
  "GET /events/analytics": "events:read",
313168
313232
  "GET /events/timeline/:personId": "events:read",
@@ -313219,6 +313283,16 @@ var init_scopes = __esm(() => {
313219
313283
  "POST /instances/:id/groups/:groupJid/invite/revoke": "instances:write",
313220
313284
  "POST /instances/:id/groups/join": "instances:write",
313221
313285
  "PUT /instances/:id/groups/:groupJid/picture": "instances:write",
313286
+ "PUT /instances/:id/groups/:groupJid/subject": "instances:write",
313287
+ "POST /instances/:id/groups/:groupJid/subject": "instances:write",
313288
+ "PUT /instances/:id/groups/:groupJid/description": "instances:write",
313289
+ "POST /instances/:id/groups/:groupJid/description": "instances:write",
313290
+ "POST /instances/:id/groups/:groupJid/settings": "instances:write",
313291
+ "PATCH /instances/:id/groups/:groupJid": "instances:write",
313292
+ "POST /instances/:id/groups/:groupJid/participants": "instances:write",
313293
+ "PATCH /instances/:id/groups/:groupJid/participants": "instances:write",
313294
+ "POST /instances/:id/groups/:groupJid/participants/:action": "instances:write",
313295
+ "POST /instances/:id/groups/:groupJid/leave": "instances:write",
313222
313296
  "GET /instances/:id/privacy": "instances:read",
313223
313297
  "POST /instances/:id/calls/reject": "instances:write",
313224
313298
  "POST /instances/:id/resync": "instances:write",
@@ -313247,12 +313321,14 @@ var init_scopes = __esm(() => {
313247
313321
  "POST /media/imagine": "media:write",
313248
313322
  "POST /media/vision": "media:read",
313249
313323
  "POST /media/film": "media:write",
313324
+ "POST /media/music": "media:write",
313250
313325
  "GET /media/:instanceId/*": "media:read",
313251
313326
  "GET /messages": "messages:read",
313252
313327
  "GET /messages/by-external": "messages:read",
313253
313328
  "POST /messages/media/download": "messages:read",
313254
313329
  "POST /messages": "messages:write",
313255
313330
  "GET /messages/:id": "messages:read",
313331
+ "GET /messages/:id/permalink": "messages:read",
313256
313332
  "PATCH /messages/:id": "messages:write",
313257
313333
  "DELETE /messages/:id": "messages:write",
313258
313334
  "POST /messages/:id/edit": "messages:write",
@@ -313269,6 +313345,8 @@ var init_scopes = __esm(() => {
313269
313345
  "POST /messages/send/sticker": "messages:send",
313270
313346
  "POST /messages/send/contact": "messages:send",
313271
313347
  "POST /messages/send/location": "messages:send",
313348
+ "POST /messages/send/handoff": "messages:send",
313349
+ "POST /messages/send/close-contact": "messages:send",
313272
313350
  "GET /messages/tts/voices": "messages:read",
313273
313351
  "POST /messages/send/tts": "messages:send",
313274
313352
  "POST /messages/send/forward": "messages:send",
@@ -313281,6 +313359,12 @@ var init_scopes = __esm(() => {
313281
313359
  "POST /messages/delete-channel": "messages:send",
313282
313360
  "POST /messages/:id/star": "messages:write",
313283
313361
  "DELETE /messages/:id/star": "messages:write",
313362
+ "GET /scheduled-messages": "messages:read",
313363
+ "GET /scheduled-messages/:id": "messages:read",
313364
+ "POST /scheduled-messages": "messages:send",
313365
+ "DELETE /scheduled-messages/:id": "messages:send",
313366
+ "GET /slack/search": "messages:read",
313367
+ "POST /slack/dm/open": "messages:send",
313284
313368
  "GET /metrics": "metrics:read",
313285
313369
  "GET /events/:eventId/payloads": "payloads:read",
313286
313370
  "GET /events/:eventId/payloads/:stage": "payloads:read",
@@ -313361,6 +313445,7 @@ var init_scopes = __esm(() => {
313361
313445
  "PATCH /webhook-sources/:id": "webhooks:write",
313362
313446
  "DELETE /webhook-sources/:id": "webhooks:write",
313363
313447
  "POST /webhooks/:source": "webhooks:write",
313448
+ "POST /webhooks/:source/heartbeat": "webhooks:write",
313364
313449
  "POST /events/trigger": "events:write"
313365
313450
  };
313366
313451
  });
@@ -362982,6 +363067,7 @@ var init_storage = __esm(() => {
362982
363067
  });
362983
363068
 
362984
363069
  // ../api/src/plugins/context.ts
363070
+ import { randomUUID as randomUUID2 } from "crypto";
362985
363071
  function createPluginDatabase(db2) {
362986
363072
  return {
362987
363073
  async execute(_sql, _params) {
@@ -362993,6 +363079,38 @@ function createPluginDatabase(db2) {
362993
363079
  }
362994
363080
  };
362995
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
+ }
362996
363114
  function createPluginContext(options) {
362997
363115
  const { pluginId, eventBus, db: db2 } = options;
362998
363116
  const env2 = "development";
@@ -363011,12 +363129,15 @@ function createPluginContext(options) {
363011
363129
  basePath: process.env.MEDIA_STORAGE_PATH ?? "./data/media"
363012
363130
  }
363013
363131
  },
363014
- db: createPluginDatabase(db2)
363132
+ db: createPluginDatabase(db2),
363133
+ ingressClaim: createIngressClaim(db2)
363015
363134
  };
363016
363135
  }
363017
363136
  var log88;
363018
363137
  var init_context3 = __esm(() => {
363019
363138
  init_src();
363139
+ init_src5();
363140
+ init_drizzle_orm();
363020
363141
  init_logger4();
363021
363142
  init_storage();
363022
363143
  log88 = createLogger("api:plugin-context");
@@ -363791,6 +363912,39 @@ async function handleMessagePinState(services, event, pinned) {
363791
363912
  });
363792
363913
  }
363793
363914
  }
363915
+ async function handleReactionState(services, event, added) {
363916
+ const payload = event.payload;
363917
+ const metadata = event.metadata;
363918
+ if (!metadata.instanceId)
363919
+ return;
363920
+ const instanceId = metadata.instanceId;
363921
+ try {
363922
+ await runConsumerInTenantContext(services.db, event, async () => {
363923
+ const chat2 = await services.chats.findByExternalIdSmart(instanceId, payload.chatId);
363924
+ const message2 = chat2 ? await services.messages.getByExternalId(chat2.id, payload.messageId) : null;
363925
+ if (!message2) {
363926
+ log90.debug("Target message not found for reaction", { chatId: payload.chatId, messageId: payload.messageId });
363927
+ return;
363928
+ }
363929
+ if (added) {
363930
+ await services.messages.addReaction(message2.id, {
363931
+ emoji: payload.emoji,
363932
+ platformUserId: payload.from,
363933
+ isCustomEmoji: payload.isCustomEmoji,
363934
+ customEmojiId: payload.isCustomEmoji ? payload.emoji : undefined
363935
+ }, event.id);
363936
+ } else {
363937
+ await services.messages.removeReaction(message2.id, payload.from, payload.emoji, event.id);
363938
+ }
363939
+ log90.debug("Updated message reactions", { messageId: message2.id, emoji: payload.emoji, added });
363940
+ });
363941
+ } catch (error3) {
363942
+ log90.error("Failed to update message reactions", {
363943
+ messageId: payload.messageId,
363944
+ error: String(error3)
363945
+ });
363946
+ }
363947
+ }
363794
363948
  async function setupMessagePersistence(eventBus, services) {
363795
363949
  try {
363796
363950
  await eventBus.subscribe("message.received", async (event) => {
@@ -363988,6 +364142,22 @@ async function setupMessagePersistence(eventBus, services) {
363988
364142
  startFrom: "first",
363989
364143
  concurrency: 10
363990
364144
  });
364145
+ await eventBus.subscribe("reaction.received", (event) => handleReactionState(services, event, true), {
364146
+ durable: "message-persistence-reaction-received",
364147
+ queue: "message-persistence",
364148
+ maxRetries: 2,
364149
+ retryDelayMs: 500,
364150
+ startFrom: "first",
364151
+ concurrency: 10
364152
+ });
364153
+ await eventBus.subscribe("reaction.removed", (event) => handleReactionState(services, event, false), {
364154
+ durable: "message-persistence-reaction-removed",
364155
+ queue: "message-persistence",
364156
+ maxRetries: 2,
364157
+ retryDelayMs: 500,
364158
+ startFrom: "first",
364159
+ concurrency: 10
364160
+ });
363991
364161
  await eventBus.subscribe("instance.connected", async (event) => {
363992
364162
  const payload = event.payload;
363993
364163
  const instanceId = payload.instanceId;
@@ -367027,10 +367197,11 @@ async function shouldProcessMessage3(agentRunner, accessService, chatsService, m
367027
367197
  if (await isAgentOutboundEcho(chatsService, messagesService, db2, payload, metadata.instanceId, trustedTenantId)) {
367028
367198
  return null;
367029
367199
  }
367030
- if (payload.content?.type === "reaction") {
367031
- 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", {
367032
367202
  instanceId: metadata.instanceId,
367033
- chatId: payload.chatId
367203
+ chatId: payload.chatId,
367204
+ contentType: payload.content.type
367034
367205
  });
367035
367206
  return null;
367036
367207
  }
@@ -367563,7 +367734,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
367563
367734
  log91.info("Agent dispatcher shutdown complete");
367564
367735
  };
367565
367736
  }
367566
- 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;
367567
367738
  var init_agent_dispatcher = __esm(() => {
367568
367739
  init_src2();
367569
367740
  init_src();
@@ -367610,6 +367781,7 @@ var init_agent_dispatcher = __esm(() => {
367610
367781
  telegram: 4096
367611
367782
  };
367612
367783
  MEDIA_BASE_PATH3 = process.env.MEDIA_STORAGE_PATH || "./data/media";
367784
+ NON_DISPATCHABLE_CONTENT_TYPES = new Set(["reaction", "delete", "unknown"]);
367613
367785
  MEDIA_ICONS = {
367614
367786
  audio: "\uD83C\uDFB5",
367615
367787
  image: "\uD83D\uDDBC\uFE0F",
@@ -368378,7 +368550,7 @@ var init_batch_pricing = __esm(() => {
368378
368550
  });
368379
368551
 
368380
368552
  // ../api/src/services/media-storage.ts
368381
- import { randomUUID as randomUUID2 } from "crypto";
368553
+ import { randomUUID as randomUUID3 } from "crypto";
368382
368554
  import { existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
368383
368555
  import { rm as rm3, writeFile as writeFile5 } from "fs/promises";
368384
368556
  import { tmpdir as tmpdir12 } from "os";
@@ -368612,7 +368784,7 @@ class MediaStorageService {
368612
368784
  }
368613
368785
  const buffer3 = await this.backend.read(reference);
368614
368786
  const ext = extname2(reference) || ".bin";
368615
- const tempPath = join23(tmpdir12(), `omni-media-${randomUUID2()}${ext}`);
368787
+ const tempPath = join23(tmpdir12(), `omni-media-${randomUUID3()}${ext}`);
368616
368788
  try {
368617
368789
  await writeFile5(tempPath, buffer3);
368618
368790
  } catch (error3) {
@@ -372279,13 +372451,15 @@ class MessageService {
372279
372451
  async removeReaction(id, platformUserId, emoji, latestEventId) {
372280
372452
  const message2 = await this.getById(id);
372281
372453
  const currentReactions = message2.reactions ?? [];
372282
- const newReactions = currentReactions.filter((r) => !(r.platformUserId === platformUserId && r.emoji === emoji));
372454
+ const newReactions = currentReactions.filter((r) => !(r.platformUserId === platformUserId && (emoji === "" || r.emoji === emoji)));
372283
372455
  const currentCounts = message2.reactionCounts ?? {};
372284
372456
  const newCounts = { ...currentCounts };
372285
- if (newCounts[emoji]) {
372286
- newCounts[emoji] = Math.max(0, newCounts[emoji] - 1);
372287
- if (newCounts[emoji] === 0) {
372288
- delete newCounts[emoji];
372457
+ for (const removed of currentReactions.filter((r) => !newReactions.includes(r))) {
372458
+ const count3 = (newCounts[removed.emoji] ?? 0) - 1;
372459
+ if (count3 > 0) {
372460
+ newCounts[removed.emoji] = count3;
372461
+ } else {
372462
+ delete newCounts[removed.emoji];
372289
372463
  }
372290
372464
  }
372291
372465
  const [updated] = await this.db.update(messages2).set({
@@ -384599,7 +384773,7 @@ var init_automations4 = __esm(() => {
384599
384773
  init_zod();
384600
384774
  automationsRoutes = new Hono2;
384601
384775
  conditionSchema = exports_external.object({
384602
- field: exports_external.string().min(1).describe("Dot notation field path (e.g., payload.content.type)"),
384776
+ field: exports_external.string().min(1).describe("Dot notation path into the event payload (e.g., content.type, pull_request.merged)"),
384603
384777
  operator: exports_external.enum(["eq", "neq", "gt", "lt", "gte", "lte", "contains", "not_contains", "exists", "not_exists", "regex"]).describe("Comparison operator"),
384604
384778
  value: exports_external.unknown().optional().describe("Value to compare against")
384605
384779
  });
@@ -395807,7 +395981,7 @@ var init_webhooks3 = __esm(() => {
395807
395981
  });
395808
395982
 
395809
395983
  // ../api/src/lib/oauth-token-cache.ts
395810
- import { randomUUID as randomUUID3 } from "crypto";
395984
+ import { randomUUID as randomUUID4 } from "crypto";
395811
395985
  function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
395812
395986
  if (!accessToken)
395813
395987
  throw new Error("oauth-token-cache: accessToken is required");
@@ -395816,7 +395990,7 @@ function put(accessToken, ttlMs = DEFAULT_TTL_MS4) {
395816
395990
  if (oldest)
395817
395991
  store.delete(oldest);
395818
395992
  }
395819
- const handle = `eshandle_${randomUUID3()}`;
395993
+ const handle = `eshandle_${randomUUID4()}`;
395820
395994
  store.set(handle, { accessToken, expiresAt: Date.now() + ttlMs });
395821
395995
  return handle;
395822
395996
  }
@@ -397569,15 +397743,14 @@ async function setupEventPersistence(eventBus, db2) {
397569
397743
  await runConsumerInTenantContext(db2, event, async () => {
397570
397744
  const sdb = scopedHandle(db2);
397571
397745
  const chatUuid = await resolveChatUuid(sdb, metadata.instanceId, payload.chatId);
397572
- const newEvent = {
397573
- ...eventIdInsert(event.id),
397746
+ const columns2 = {
397574
397747
  externalId: payload.externalId,
397575
397748
  channel: mapChannelType(metadata.channelType),
397576
397749
  instanceId: metadata.instanceId,
397577
397750
  personId: metadata.personId,
397578
397751
  platformIdentityId: metadata.platformIdentityId,
397579
397752
  eventType: "message.received",
397580
- direction: "inbound",
397753
+ direction: payload.rawPayload?.isFromMe === true ? "outbound" : "inbound",
397581
397754
  contentType: mapContentType2(payload.content.type),
397582
397755
  textContent: sanitizeText(payload.content.text),
397583
397756
  mediaUrl: payload.content.mediaUrl,
@@ -397596,7 +397769,7 @@ async function setupEventPersistence(eventBus, db2) {
397596
397769
  conversationId: null,
397597
397770
  chatUuid
397598
397771
  };
397599
- 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 });
397600
397773
  });
397601
397774
  if (metadata.timings && metadata.correlationId) {
397602
397775
  const tracker = getJourneyTracker();
@@ -399948,6 +400121,10 @@ function buildAutomationEngineDeps(services, db3, options = {}) {
399948
400121
  return services.followUpLifecycle.evaluateIdleTimeoutFreshness(chatId, instanceId, eventSequenceIndex, trustedTenantId);
399949
400122
  },
399950
400123
  releaseIdleTimeoutClaim: (claimToken) => releaseIdleTimeoutClaim(claimToken),
400124
+ claimExecution: async (eventId, automationId) => {
400125
+ const claim = await db3.insert(processedEvents).values({ eventId, handler: `automation:${automationId}` }).onConflictDoNothing().returning({ eventId: processedEvents.eventId });
400126
+ return claim.length > 0;
400127
+ },
399951
400128
  claimEmittedEvent: async (claim, trustedTenantId = null) => {
399952
400129
  const claimed = await runTenantWorkDb(db3, trustedTenantId, () => scopedHandle(db3).insert(omniEvents).values({
399953
400130
  id: claim.eventId,
@@ -407298,23 +407475,6 @@ class DiscordPlugin extends BaseChannelPlugin {
407298
407475
  isCustomEmoji: false
407299
407476
  });
407300
407477
  }
407301
- if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false") {
407302
- await this.emitMessageReceived({
407303
- instanceId,
407304
- externalId: `${messageId}-reaction-${Date.now()}`,
407305
- chatId,
407306
- from: userId,
407307
- content: {
407308
- type: "reaction",
407309
- text: emoji
407310
- },
407311
- rawPayload: {
407312
- targetMessageId: messageId,
407313
- action,
407314
- emoji
407315
- }
407316
- });
407317
- }
407318
407478
  }
407319
407479
  async handleMessageEdited(instanceId, messageId, chatId, newText) {
407320
407480
  await this.emitMessageReceived({
@@ -407340,10 +407500,7 @@ class DiscordPlugin extends BaseChannelPlugin {
407340
407500
  externalId: `${messageId}-delete-${Date.now()}`,
407341
407501
  chatId,
407342
407502
  from: chatId,
407343
- content: {
407344
- type: "delete",
407345
- text: fromMe ? "Message deleted by bot" : "Message deleted"
407346
- },
407503
+ content: { type: "delete" },
407347
407504
  rawPayload: {
407348
407505
  deletedMessageId: messageId,
407349
407506
  deletedAt: Date.now(),
@@ -527994,10 +528151,7 @@ function extractUnknownContent(message2) {
527994
528151
  return null;
527995
528152
  }
527996
528153
  log52.debug("Unknown message type", { keys: messageKeys });
527997
- return {
527998
- type: "unknown",
527999
- text: `Unknown message type: ${messageKeys.join(", ")}`
528000
- };
528154
+ return { type: "unknown" };
528001
528155
  }
528002
528156
  function extractContent3(msg) {
528003
528157
  const message2 = msg.message;
@@ -529352,6 +529506,14 @@ function summarizeContent(content) {
529352
529506
  }
529353
529507
  return summary;
529354
529508
  }
529509
+ function getOrCreate(outer, key) {
529510
+ let inner = outer.get(key);
529511
+ if (!inner) {
529512
+ inner = new Map;
529513
+ outer.set(key, inner);
529514
+ }
529515
+ return inner;
529516
+ }
529355
529517
 
529356
529518
  class WhatsAppPlugin extends BaseChannelPlugin {
529357
529519
  id = "whatsapp-baileys";
@@ -529455,6 +529617,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
529455
529617
  }
529456
529618
  lidFirstEnabledMap = new Map;
529457
529619
  lidMappingCache = new Map;
529620
+ publishedLidMappings = new Map;
529621
+ publishedContactNames = new Map;
529458
529622
  recentMessageKeys = new Map;
529459
529623
  static MESSAGE_KEY_CACHE_TTL_MS = 60000;
529460
529624
  storeLidMapping(instanceId, lidJid, phoneJid) {
@@ -529831,6 +529995,8 @@ class WhatsAppPlugin extends BaseChannelPlugin {
529831
529995
  this.decryptTrackers.delete(instanceId);
529832
529996
  this.lidFirstEnabledMap.delete(instanceId);
529833
529997
  this.lidMappingCache.delete(instanceId);
529998
+ this.publishedLidMappings.delete(instanceId);
529999
+ this.publishedContactNames.delete(instanceId);
529834
530000
  this.lastActionTime.delete(instanceId);
529835
530001
  this.historyPushFetchCount.delete(instanceId);
529836
530002
  this.dedupeCaches.get(instanceId)?.dispose();
@@ -531176,19 +531342,6 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531176
531342
  emoji: ""
531177
531343
  });
531178
531344
  }
531179
- if (process.env.OMNI_DUAL_EMIT_REACTIONS !== "false" && !isFromMe2) {
531180
- await this.emitMessageReceived({
531181
- instanceId,
531182
- externalId,
531183
- chatId,
531184
- from,
531185
- content: {
531186
- type: "reaction",
531187
- text: emoji
531188
- },
531189
- rawPayload: { targetMessageId, isFromMe: isFromMe2 }
531190
- });
531191
- }
531192
531345
  }
531193
531346
  async handleMessageDelivered(instanceId, externalId, chatId) {
531194
531347
  await this.emitMessageDelivered({
@@ -531240,10 +531393,7 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531240
531393
  externalId: `${externalId}-delete-${Date.now()}`,
531241
531394
  chatId,
531242
531395
  from: chatId,
531243
- content: {
531244
- type: "delete",
531245
- text: fromMe ? "Message deleted by sender" : "Message deleted"
531246
- },
531396
+ content: { type: "delete" },
531247
531397
  rawPayload: {
531248
531398
  deletedMessageId: externalId,
531249
531399
  deletedAt: Date.now(),
@@ -531423,11 +531573,15 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531423
531573
  const contactCache = this.contactsCache.get(instanceId);
531424
531574
  if (!contactCache || contactCache.size === 0)
531425
531575
  return;
531576
+ const published = getOrCreate(this.publishedContactNames, instanceId);
531426
531577
  const names = [];
531427
531578
  for (const [jid, contact] of contactCache) {
531428
- if (contact.name && !jid.includes("@g.us") && !jid.includes("@broadcast")) {
531429
- names.push({ jid, name: contact.name });
531430
- }
531579
+ if (!contact.name || jid.includes("@g.us") || jid.includes("@broadcast"))
531580
+ continue;
531581
+ if (published.get(jid) === contact.name)
531582
+ continue;
531583
+ published.set(jid, contact.name);
531584
+ names.push({ jid, name: contact.name });
531431
531585
  }
531432
531586
  if (names.length === 0)
531433
531587
  return;
@@ -531442,7 +531596,16 @@ class WhatsAppPlugin extends BaseChannelPlugin {
531442
531596
  const lidCache = this.lidMappingCache.get(instanceId);
531443
531597
  if (!lidCache || lidCache.size === 0)
531444
531598
  return;
531445
- const mappings = Array.from(lidCache.entries()).filter(([key]) => isLidJid(key)).map(([lidJid, phoneJid]) => ({ lidJid, phoneJid }));
531599
+ const published = getOrCreate(this.publishedLidMappings, instanceId);
531600
+ const mappings = [];
531601
+ for (const [lidJid, phoneJid] of lidCache) {
531602
+ if (!isLidJid(lidJid) || published.get(lidJid) === phoneJid)
531603
+ continue;
531604
+ published.set(lidJid, phoneJid);
531605
+ mappings.push({ lidJid, phoneJid });
531606
+ }
531607
+ if (mappings.length === 0)
531608
+ return;
531446
531609
  this.eventBus.publishGeneric("custom.lid-mapping.batch", { mappings }, { instanceId, channelType: this.id, source: `channel:${this.id}`, correlationId: `lid-batch-${instanceId}` }).catch((err2) => this.logger.warn("Failed to publish LID mappings", { error: String(err2) }));
531447
531610
  }
531448
531611
  handleContactsUpdate(instanceId, updates) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260909.5",
3
+ "version": "2.260910.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",