@automagik/omni 2.260914.13 → 2.260915.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
@@ -137289,7 +137289,7 @@ import { fileURLToPath } from "url";
137289
137289
  // package.json
137290
137290
  var package_default = {
137291
137291
  name: "@automagik/omni",
137292
- version: "2.260914.13",
137292
+ version: "2.260915.1",
137293
137293
  repository: {
137294
137294
  type: "git",
137295
137295
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -44933,7 +44933,7 @@ class BaseChannelPlugin {
44933
44933
  return correlationId;
44934
44934
  }
44935
44935
  async emitMessageReceived(params) {
44936
- const { instanceId, timings, isHistorySync, ...payload } = params;
44936
+ const { instanceId, timings, isHistorySync, onDuplicate, ...payload } = params;
44937
44937
  const options = {
44938
44938
  timings,
44939
44939
  ingestMode: isHistorySync ? "history-sync" : "realtime"
@@ -44941,14 +44941,15 @@ class BaseChannelPlugin {
44941
44941
  return this.publishClaimed("message.received", payload, instanceId, {
44942
44942
  idempotencyKey: `${this.id}:${instanceId}:${this.ingressKeyId(payload.chatId, payload.externalId)}:${payload.content.type}`,
44943
44943
  externalId: payload.externalId,
44944
- options
44944
+ options,
44945
+ onDuplicate
44945
44946
  });
44946
44947
  }
44947
44948
  ingressKeyId(_chatId, id) {
44948
44949
  return id;
44949
44950
  }
44950
44951
  async publishClaimed(type, payload, instanceId, params) {
44951
- const { idempotencyKey, externalId, options = {} } = params;
44952
+ const { idempotencyKey, externalId, options = {}, onDuplicate } = params;
44952
44953
  if (!this.ingressClaim) {
44953
44954
  return this.publishEventInternal(type, payload, instanceId, options);
44954
44955
  }
@@ -44964,6 +44965,7 @@ class BaseChannelPlugin {
44964
44965
  instanceId,
44965
44966
  idempotencyKey
44966
44967
  });
44968
+ onDuplicate?.();
44967
44969
  return generateCorrelationId("evt");
44968
44970
  }
44969
44971
  try {
@@ -250984,7 +250986,7 @@ var init_sentry_scrub = __esm(() => {
250984
250986
  var require_package7 = __commonJS((exports, module) => {
250985
250987
  module.exports = {
250986
250988
  name: "@omni/api",
250987
- version: "2.260914.13",
250989
+ version: "2.260915.1",
250988
250990
  private: true,
250989
250991
  type: "module",
250990
250992
  exports: {
@@ -403409,7 +403411,9 @@ async function handleAscFlowWebhookRequest(request, plugin3, instanceId, verifyT
403409
403411
  if (isRedelivery) {
403410
403412
  return pending();
403411
403413
  }
403412
- await plugin3.handleInboundTurn(instanceId, turn);
403414
+ if (!await plugin3.handleInboundTurn(instanceId, turn)) {
403415
+ return pending();
403416
+ }
403413
403417
  const holdMs = holdTimeoutMs();
403414
403418
  if (holdMs <= 0)
403415
403419
  return pending();
@@ -403778,7 +403782,7 @@ function buildReplyField(replyTo) {
403778
403782
  }
403779
403783
 
403780
403784
  // ../channel-asc-flow/src/utils/turn-freshness.ts
403781
- async function latestInboundText(client, codAtendimento) {
403785
+ async function latestInbound(client, codAtendimento) {
403782
403786
  const { status, body } = await client.get("/atendimento", { codigo_atendimento: codAtendimento });
403783
403787
  if (status !== 200 || typeof body !== "object" || body === null)
403784
403788
  return null;
@@ -403790,15 +403794,15 @@ async function latestInboundText(client, codAtendimento) {
403790
403794
  continue;
403791
403795
  const text = decodeAscEmoji(String(raw.descricao_msg ?? "").trim());
403792
403796
  if (text)
403793
- return text;
403797
+ return { id: raw.id_mensagem == null ? null : String(raw.id_mensagem), text };
403794
403798
  }
403795
403799
  return null;
403796
403800
  }
403797
403801
  async function isStaleFlowReplay(params) {
403798
- const { client, instanceId, codAtendimento, text, logger: logger5 } = params;
403802
+ const { client, instanceId, codAtendimento, text, messageId, logger: logger5 } = params;
403799
403803
  let latest;
403800
403804
  try {
403801
- latest = await latestInboundText(client, codAtendimento);
403805
+ latest = await latestInbound(client, codAtendimento);
403802
403806
  } catch (err2) {
403803
403807
  logger5.warn("[asc-flow] could not read the atendimento to date this turn \u2014 processing it", {
403804
403808
  instanceId,
@@ -403809,8 +403813,12 @@ async function isStaleFlowReplay(params) {
403809
403813
  }
403810
403814
  if (latest === null)
403811
403815
  return false;
403812
- if (latest === text.trim())
403816
+ if (messageId && latest.id) {
403817
+ if (latest.id === messageId)
403818
+ return false;
403819
+ } else if (latest.text === text.trim()) {
403813
403820
  return false;
403821
+ }
403814
403822
  logger5.info("[asc-flow] flow restarted with a stale input variable \u2014 dropping the replay", {
403815
403823
  instanceId,
403816
403824
  codAtendimento
@@ -404285,7 +404293,7 @@ class AscFlowPlugin extends BaseChannelPlugin {
404285
404293
  async handleInboundTurn(instanceId, turn) {
404286
404294
  const sanitized = sanitizeMessage(turn.text, this.logger, { instanceId, messageId: turn.messageId });
404287
404295
  if (!sanitized.ok)
404288
- return;
404296
+ return false;
404289
404297
  const inboundState = this.ascFlowInstances.get(instanceId);
404290
404298
  if (inboundState) {
404291
404299
  this.sweepInFlight(instanceId, inboundState);
@@ -404310,7 +404318,11 @@ class AscFlowPlugin extends BaseChannelPlugin {
404310
404318
  logger: this.logger
404311
404319
  }) : null;
404312
404320
  const timings = this.captureInboundTimings(Date.now());
404321
+ let duplicate = false;
404313
404322
  const correlationId = await this.emitMessageReceived({
404323
+ onDuplicate: () => {
404324
+ duplicate = true;
404325
+ },
404314
404326
  instanceId,
404315
404327
  externalId,
404316
404328
  chatId: turn.codAtendimento,
@@ -404335,10 +404347,28 @@ class AscFlowPlugin extends BaseChannelPlugin {
404335
404347
  timings
404336
404348
  });
404337
404349
  const stamped = this.ascFlowInstances.get(instanceId)?.inFlight.get(turn.codAtendimento);
404350
+ if (duplicate) {
404351
+ this.dropRepublishedTurn(instanceId, turn);
404352
+ return false;
404353
+ }
404338
404354
  if (stamped && stamped.text === turn.text && !stamped.correlationId)
404339
404355
  stamped.correlationId = correlationId;
404340
404356
  if (timings)
404341
404357
  this.captureT2(correlationId, timings);
404358
+ return true;
404359
+ }
404360
+ dropRepublishedTurn(instanceId, turn) {
404361
+ const inFlight = this.ascFlowInstances.get(instanceId)?.inFlight;
404362
+ const stamped = inFlight?.get(turn.codAtendimento);
404363
+ if (stamped && stamped.text === turn.text && !stamped.correlationId)
404364
+ inFlight?.delete(turn.codAtendimento);
404365
+ this.logger.info("[asc-flow] messageId already published for this atendimento \u2014 dropping the re-send", {
404366
+ instanceId,
404367
+ codAtendimento: turn.codAtendimento
404368
+ });
404369
+ }
404370
+ ingressKeyId(chatId, id) {
404371
+ return `${chatId}:${id}`;
404342
404372
  }
404343
404373
  getLogger() {
404344
404374
  return this.logger;
@@ -404422,6 +404452,7 @@ class AscFlowPlugin extends BaseChannelPlugin {
404422
404452
  instanceId,
404423
404453
  codAtendimento: turn.codAtendimento,
404424
404454
  text: turn.text,
404455
+ messageId: turn.messageId,
404425
404456
  logger: this.logger
404426
404457
  });
404427
404458
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260914.13",
3
+ "version": "2.260915.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",