@automagik/omni 2.260904.1 → 2.260906.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
@@ -128298,7 +128298,7 @@ import { fileURLToPath } from "url";
128298
128298
  // package.json
128299
128299
  var package_default = {
128300
128300
  name: "@automagik/omni",
128301
- version: "2.260904.1",
128301
+ version: "2.260906.1",
128302
128302
  repository: {
128303
128303
  type: "git",
128304
128304
  url: "git+https://github.com/automagik-dev/omni.git",
@@ -242910,7 +242910,7 @@ var init_sentry_scrub = __esm(() => {
242910
242910
  var require_package7 = __commonJS((exports, module) => {
242911
242911
  module.exports = {
242912
242912
  name: "@omni/api",
242913
- version: "2.260904.1",
242913
+ version: "2.260906.1",
242914
242914
  type: "module",
242915
242915
  exports: {
242916
242916
  ".": {
@@ -344750,7 +344750,7 @@ async function sendTypingPresence(channel5, instanceId, chatId, state) {
344750
344750
  log91.debug("Failed to send typing presence", { error: String(error3) });
344751
344751
  }
344752
344752
  }
344753
- async function sendTextMessage5(channel5, instanceId, chatId, text3, messageFormatMode = "convert", replyTo, correlationId, senderAgentId, systemNotice) {
344753
+ async function sendTextMessage5(channel5, instanceId, chatId, text3, messageFormatMode = "convert", replyTo, correlationId, senderAgentId, systemNotice, part) {
344754
344754
  const plugin11 = await getPlugin(channel5);
344755
344755
  if (!plugin11)
344756
344756
  throw new Error(`Channel plugin not found: ${channel5}`);
@@ -344761,7 +344761,13 @@ async function sendTextMessage5(channel5, instanceId, chatId, text3, messageForm
344761
344761
  to: chatId,
344762
344762
  content: { type: "text", text: sanitized },
344763
344763
  replyTo,
344764
- metadata: { messageFormatMode, correlationId, senderAgentId, systemNotice }
344764
+ metadata: {
344765
+ messageFormatMode,
344766
+ correlationId,
344767
+ senderAgentId,
344768
+ systemNotice,
344769
+ ...part ? { partIndex: part.index, partCount: part.count } : {}
344770
+ }
344765
344771
  });
344766
344772
  }
344767
344773
  function resolveDispatchErrorMessage(instanceErrorMessages, env2 = process.env, random = Math.random) {
@@ -345223,14 +345229,15 @@ function isSelfChat(chatId, ownerIdentifier) {
345223
345229
  }
345224
345230
  async function sendResponseParts(channel5, instanceId, chatId, parts, splitConfig, messageFormatMode = "convert", replyTo, correlationId, senderAgentId) {
345225
345231
  const messageLimit = getMessageLimit(channel5);
345226
- const allChunks = [];
345232
+ const chunked = [];
345227
345233
  for (const part of parts) {
345228
- allChunks.push(...chunkText(part, messageLimit));
345234
+ chunked.push(...chunkText(part, messageLimit));
345229
345235
  }
345236
+ const allChunks = chunked.map((chunk2) => sanitizeOutboundText(chunk2)).filter(Boolean);
345230
345237
  const isSlack = channel5 === "slack";
345231
345238
  for (const [index2, chunk2] of allChunks.entries()) {
345232
345239
  const chunkReplyTo = isSlack || index2 === 0 ? replyTo : undefined;
345233
- await sendTextMessage5(channel5, instanceId, chatId, chunk2, messageFormatMode, chunkReplyTo, correlationId, senderAgentId);
345240
+ await sendTextMessage5(channel5, instanceId, chatId, chunk2, messageFormatMode, chunkReplyTo, correlationId, senderAgentId, undefined, { index: index2, count: allChunks.length });
345234
345241
  const isLastChunk = index2 === allChunks.length - 1;
345235
345242
  if (!isLastChunk) {
345236
345243
  const delay2 = calculateSplitDelay(splitConfig);
@@ -380150,11 +380157,28 @@ function decodeAscEmoji(text) {
380150
380157
  }
380151
380158
  });
380152
380159
  }
380160
+ var TRANSLITERATIONS = [
380161
+ [/[\u2014\u2013\u2212]/g, "-"],
380162
+ [/\u2026/g, "..."],
380163
+ [/[\u201C\u201D\u201E]/g, '"'],
380164
+ [/[\u2018\u2019\u201A]/g, "'"],
380165
+ [/\u2192/g, "->"],
380166
+ [/\u2190/g, "<-"],
380167
+ [/\u2265/g, ">="],
380168
+ [/\u2264/g, "<="],
380169
+ [/\u00A0/g, " "],
380170
+ [/[\u2022\u00B7]/g, "-"]
380171
+ ];
380172
+ function nonLatin1Left(text) {
380173
+ return [...new Set([...text].filter((ch) => (ch.codePointAt(0) ?? 0) > 255))];
380174
+ }
380153
380175
  function encodeAscEmoji(text) {
380154
- return text.replace(EMOJI_RUN, (run) => `##${[...run].map((ch) => (ch.codePointAt(0) ?? 0).toString(16)).join("-")}##`);
380176
+ const withMarkers = text.replace(EMOJI_RUN, (run) => `##${[...run].map((ch) => (ch.codePointAt(0) ?? 0).toString(16)).join("-")}##`);
380177
+ return TRANSLITERATIONS.reduce((acc, [pattern, ascii]) => acc.replace(pattern, ascii), withMarkers);
380155
380178
  }
380156
380179
 
380157
380180
  // ../channel-asc-flow/src/handlers/webhook.ts
380181
+ var holdTimeoutMs = () => Number(process.env.ASC_FLOW_HOLD_MS ?? 40000);
380158
380182
  var MAX_BODY_BYTES = 64 * 1024;
380159
380183
  function json(body, status = 200) {
380160
380184
  return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" } });
@@ -380171,13 +380195,16 @@ function firstString(...values) {
380171
380195
  }
380172
380196
  function parseInboundTurn(body) {
380173
380197
  const codAtendimento = firstString(body.codAtendimento, body.cod_atendimento);
380174
- const text = decodeAscEmoji(firstString(body.chatInput, body.message));
380198
+ const typed = decodeAscEmoji(firstString(body.chatInput));
380199
+ const fallback = decodeAscEmoji(firstString(body.message));
380200
+ const text = typed || fallback;
380175
380201
  if (!codAtendimento || !text)
380176
380202
  return null;
380177
380203
  const messageId = firstString(body.messageId, body.idMensagem);
380178
380204
  return {
380179
380205
  codAtendimento,
380180
380206
  text,
380207
+ fromFallback: !typed,
380181
380208
  phone: firstString(body.phone, body.telefone),
380182
380209
  ...messageId ? { messageId } : {}
380183
380210
  };
@@ -380225,12 +380252,26 @@ async function handleAscFlowWebhookRequest(request, plugin2, instanceId, verifyT
380225
380252
  if (ready) {
380226
380253
  return json(ready);
380227
380254
  }
380255
+ if (turn.fromFallback && plugin2.hasSeenCod(instanceId, turn.codAtendimento)) {
380256
+ logger5.debug("[asc-flow] loop-back with no chatInput \u2014 treating as a poll", {
380257
+ instanceId,
380258
+ codAtendimento: turn.codAtendimento
380259
+ });
380260
+ return pending();
380261
+ }
380262
+ if (await plugin2.isStaleFlowReplay(instanceId, turn)) {
380263
+ return pending();
380264
+ }
380228
380265
  const isRedelivery = turn.messageId ? dedupeCache.isDuplicate(instanceId, turn.messageId, "asc-flow", logger5) : plugin2.isRedeliveryOfTurnInFlight(instanceId, turn);
380229
380266
  if (isRedelivery) {
380230
380267
  return pending();
380231
380268
  }
380232
380269
  await plugin2.handleInboundTurn(instanceId, turn);
380233
- return pending();
380270
+ const holdMs = holdTimeoutMs();
380271
+ if (holdMs <= 0)
380272
+ return pending();
380273
+ const held = await plugin2.waitForTurn(instanceId, turn.codAtendimento, turn.text, holdMs);
380274
+ return held ? json(held) : pending();
380234
380275
  }
380235
380276
 
380236
380277
  // ../channel-asc-flow/src/utils/handoff.ts
@@ -380306,6 +380347,16 @@ function buildGenesysFields(read, logger5, mode) {
380306
380347
  init_src2();
380307
380348
  var MAX_OPTIONS = 10;
380308
380349
  var MAX_BODY_TEXT = 1024;
380350
+ var MAX_BUTTONS = 3;
380351
+ var BUTTON_TITLE_MAX = 20;
380352
+ function shortenTitle(title) {
380353
+ const value = title.trim();
380354
+ if (value.length <= BUTTON_TITLE_MAX)
380355
+ return value;
380356
+ const head = value.slice(0, BUTTON_TITLE_MAX);
380357
+ const boundary = head.lastIndexOf(" ");
380358
+ return (boundary >= 8 ? head.slice(0, boundary) : head).trim();
380359
+ }
380309
380360
  function foldTitle(value) {
380310
380361
  return value.normalize("NFD").replace(/\p{Mn}/gu, "").toLocaleLowerCase().split(/\s+/).filter(Boolean).join(" ");
380311
380362
  }
@@ -380331,14 +380382,19 @@ function buildUra(body, buttons, listOptions = {}) {
380331
380382
  const type = plan.interactive.type;
380332
380383
  if (type !== "button" && type !== "list")
380333
380384
  return null;
380334
- const titles = titlesOf(plan.interactive);
380385
+ let titles = titlesOf(plan.interactive);
380386
+ let asButtons = type === "button";
380387
+ if (!asButtons && replyButtons.length <= MAX_BUTTONS) {
380388
+ titles = replyButtons.map((b2) => shortenTitle(b2.text ?? ""));
380389
+ asButtons = true;
380390
+ }
380335
380391
  if (titles.length !== replyButtons.length || titles.some((t) => !t))
380336
380392
  return null;
380337
380393
  if (new Set(titles.map(foldTitle)).size !== titles.length)
380338
380394
  return null;
380339
380395
  return {
380340
380396
  ura_opcoes: Object.fromEntries(titles.map((title, i) => [String(i + 1), title])),
380341
- forcar_botoes: type === "button"
380397
+ forcar_botoes: asButtons
380342
380398
  };
380343
380399
  }
380344
380400
  function splitBubbles(text) {
@@ -380557,6 +380613,47 @@ function buildReplyField(replyTo) {
380557
380613
  return /^\d+$/.test(trimmed) ? { id_mensagem_resposta: Number(trimmed) } : {};
380558
380614
  }
380559
380615
 
380616
+ // ../channel-asc-flow/src/utils/turn-freshness.ts
380617
+ async function latestInboundText(client, codAtendimento) {
380618
+ const { status, body } = await client.get("/atendimento", { codigo_atendimento: codAtendimento });
380619
+ if (status !== 200 || typeof body !== "object" || body === null)
380620
+ return null;
380621
+ const list = body.mensagens;
380622
+ if (!Array.isArray(list))
380623
+ return null;
380624
+ for (const raw of [...list].reverse()) {
380625
+ if (String(raw.boleano_entrante ?? "") !== "1")
380626
+ continue;
380627
+ const text = decodeAscEmoji(String(raw.descricao_msg ?? "").trim());
380628
+ if (text)
380629
+ return text;
380630
+ }
380631
+ return null;
380632
+ }
380633
+ async function isStaleFlowReplay(params) {
380634
+ const { client, instanceId, codAtendimento, text, logger: logger5 } = params;
380635
+ let latest;
380636
+ try {
380637
+ latest = await latestInboundText(client, codAtendimento);
380638
+ } catch (err2) {
380639
+ logger5.warn("[asc-flow] could not read the atendimento to date this turn \u2014 processing it", {
380640
+ instanceId,
380641
+ codAtendimento,
380642
+ err: String(err2)
380643
+ });
380644
+ return false;
380645
+ }
380646
+ if (latest === null)
380647
+ return false;
380648
+ if (latest === text.trim())
380649
+ return false;
380650
+ logger5.info("[asc-flow] flow restarted with a stale input variable \u2014 dropping the replay", {
380651
+ instanceId,
380652
+ codAtendimento
380653
+ });
380654
+ return true;
380655
+ }
380656
+
380560
380657
  // ../channel-asc-flow/src/plugin.ts
380561
380658
  var DEFAULT_ASC_FLOW_BASE_URL = "https://sac-notredame.ascbrazil.com.br";
380562
380659
  var REST_PREFIX = "/rest/v2";
@@ -380566,11 +380663,36 @@ var UNDELIVERABLE_ERROR = "no ASC flow turn is polling this cod_atendimento \u20
380566
380663
  var HANDOFF_REFUSED_ERROR = "handoff refused: the transfer never held, so the turn answers without it";
380567
380664
  var IN_FLIGHT_SWEEP_MS = 60000;
380568
380665
  var IN_FLIGHT_MAX_ENTRIES = 5000;
380569
- function resolveOutboundText(message2) {
380666
+ function resolveOutboundText(message2, logger5) {
380570
380667
  const formatMode = message2.metadata?.messageFormatMode ?? "convert";
380571
380668
  const text = message2.content.text ?? message2.content.caption ?? "";
380572
380669
  const formatted = formatMode === "passthrough" ? text : markdownToWhatsApp(text);
380573
- return encodeAscEmoji(formatted);
380670
+ const encoded = encodeAscEmoji(formatted);
380671
+ const restante = nonLatin1Left(encoded);
380672
+ if (restante.length > 0) {
380673
+ logger5?.warn('[asc-flow] characters the platform cannot carry \u2014 they will arrive as "?"', {
380674
+ chars: restante.join(" "),
380675
+ codepoints: restante.map((c) => (c.codePointAt(0) ?? 0).toString(16)).join(" ")
380676
+ });
380677
+ }
380678
+ return encoded;
380679
+ }
380680
+ function collectTurnParts(message2, turn) {
380681
+ const meta = message2.metadata ?? {};
380682
+ const partCount = Number(meta.partCount ?? 1);
380683
+ const partIndex = Number(meta.partIndex ?? 0);
380684
+ if (!turn || message2.content.type !== "text" || !(partCount > 1) || !(partIndex >= 0))
380685
+ return message2;
380686
+ const part = message2.content.text ?? "";
380687
+ if (partIndex < partCount - 1) {
380688
+ turn.parts = [...turn.parts ?? [], part];
380689
+ return null;
380690
+ }
380691
+ const text = [...turn.parts ?? [], part].join(`
380692
+
380693
+ `);
380694
+ turn.parts = undefined;
380695
+ return { ...message2, content: { ...message2.content, text } };
380574
380696
  }
380575
380697
  function listOptionsOf(content) {
380576
380698
  return {
@@ -380594,6 +380716,8 @@ function buildReadyBody(turn) {
380594
380716
  resposta: turn.delivered ? "" : turn.lastBubble || OUTBOUND_MEDIA_FALLBACK_TEXT,
380595
380717
  hand_off: turn.handoff ? "sim" : "nao",
380596
380718
  bolhas: turn.bubbles,
380719
+ fila_vq: "",
380720
+ motivo_transf_vq: "",
380597
380721
  ...turn.handoff ?? {},
380598
380722
  ...turn.ura ?? {}
380599
380723
  };
@@ -380646,7 +380770,9 @@ class AscFlowPlugin extends BaseChannelPlugin {
380646
380770
  config: ascFlowConfig,
380647
380771
  dedupeCache: createInboundDedupeCache(),
380648
380772
  inFlight: new Map,
380649
- lastSweepAt: Date.now()
380773
+ lastSweepAt: Date.now(),
380774
+ seenCods: new Set,
380775
+ lastAnswered: new Map
380650
380776
  });
380651
380777
  await this.updateInstanceStatus(instanceId, config2, {
380652
380778
  state: "connected",
@@ -380688,9 +380814,8 @@ class AscFlowPlugin extends BaseChannelPlugin {
380688
380814
  if (!state) {
380689
380815
  return { success: false, error: "ASC Flow instance not connected", retryable: false, timestamp: Date.now() };
380690
380816
  }
380691
- const { content, to } = message2;
380817
+ const { to } = message2;
380692
380818
  const meta = message2.metadata ?? {};
380693
- const text = resolveOutboundText(message2);
380694
380819
  const correlationId = meta.correlationId;
380695
380820
  if (correlationId)
380696
380821
  this.captureT10(correlationId);
@@ -380698,12 +380823,24 @@ class AscFlowPlugin extends BaseChannelPlugin {
380698
380823
  const cod = toCodAtendimento(to);
380699
380824
  const answering = state.inFlight.get(to.trim());
380700
380825
  const polling = answering !== undefined && answering.text !== "";
380701
- const { rich, bubbles } = await this.prepareTurn(message2, text);
380826
+ const turnMessage = collectTurnParts(message2, polling ? answering : undefined);
380827
+ if (!turnMessage)
380828
+ return { success: true, timestamp: Date.now() };
380829
+ const content = turnMessage.content;
380830
+ const text = resolveOutboundText(turnMessage, this.logger);
380831
+ const { rich, bubbles } = await this.prepareTurn(turnMessage, text);
380702
380832
  const lastBubble = bubbles[bubbles.length - 1] ?? "";
380703
380833
  const ura = rich ? null : buildUra(lastBubble, content.buttons, listOptionsOf(content));
380704
- if (!rich && !ura && !polling)
380834
+ const { delivered } = await this.deliver(state, cod, {
380835
+ text,
380836
+ bubbles,
380837
+ lastBubble,
380838
+ rich,
380839
+ ura,
380840
+ message: turnMessage
380841
+ });
380842
+ if (!delivered && !polling)
380705
380843
  return this.refuseUndeliverable(instanceId, to, content.type);
380706
- const { delivered } = await this.deliver(state, cod, { text, bubbles, lastBubble, rich, ura, message: message2 });
380707
380844
  const handoff = meta.isHandoff === true ? await this.runHandoff(state, instanceId, cod, meta, delivered ? "" : lastBubble) : null;
380708
380845
  const handoffRefused = meta.isHandoff === true && handoff === null;
380709
380846
  this.resolveTurn(state, to, buildReadyBody({ delivered, lastBubble, bubbles, handoff, ura }), answering, correlationId);
@@ -380712,7 +380849,7 @@ class AscFlowPlugin extends BaseChannelPlugin {
380712
380849
  if (correlationId)
380713
380850
  this.captureT11(correlationId);
380714
380851
  const messageId = crypto.randomUUID();
380715
- await this.emitTurnSent(instanceId, message2, messageId, {
380852
+ await this.emitTurnSent(instanceId, turnMessage, messageId, {
380716
380853
  cod,
380717
380854
  bubbles: bubbles.length,
380718
380855
  ura,
@@ -380858,13 +380995,19 @@ class AscFlowPlugin extends BaseChannelPlugin {
380858
380995
  async deliver(state, cod, turn) {
380859
380996
  const reply = buildReplyField(turn.message.replyTo);
380860
380997
  if (turn.rich) {
380861
- return { delivered: await this.sendMensagem(state, cod, turn.text, { ...turn.rich, ...reply }) };
380998
+ if (await this.sendMensagem(state, cod, turn.text, { ...turn.rich, ...reply }))
380999
+ return { delivered: true };
381000
+ const texto = turn.bubbles.length > 0 ? turn.bubbles : [OUTBOUND_MEDIA_FALLBACK_TEXT];
381001
+ return { delivered: await this.pushBubbles(state, cod, texto) > 0 };
380862
381002
  }
380863
- await this.pushLeadingBubbles(state, cod, turn.bubbles);
380864
381003
  if (turn.ura) {
380865
- return { delivered: await this.sendMensagem(state, cod, turn.lastBubble, { ...turn.ura, ...reply }) };
381004
+ await this.pushBubbles(state, cod, turn.bubbles.slice(0, -1));
381005
+ if (await this.sendMensagem(state, cod, turn.lastBubble, { ...turn.ura, ...reply }))
381006
+ return { delivered: true };
381007
+ return { delivered: await this.pushBubbles(state, cod, [turn.lastBubble]) > 0 };
380866
381008
  }
380867
- return { delivered: false };
381009
+ const pushed = await this.pushBubbles(state, cod, turn.bubbles);
381010
+ return { delivered: pushed > 0 };
380868
381011
  }
380869
381012
  async sendMensagem(state, cod, text, extra) {
380870
381013
  try {
@@ -380885,8 +381028,9 @@ class AscFlowPlugin extends BaseChannelPlugin {
380885
381028
  return false;
380886
381029
  }
380887
381030
  }
380888
- async pushLeadingBubbles(state, cod, bubbles) {
380889
- for (const bubble of bubbles.slice(0, -1)) {
381031
+ async pushBubbles(state, cod, bubbles) {
381032
+ let enviadas = 0;
381033
+ for (const bubble of bubbles) {
380890
381034
  try {
380891
381035
  await state.client.call("/callbackFlowMsg", {
380892
381036
  cod_atendimento: cod,
@@ -380894,15 +381038,21 @@ class AscFlowPlugin extends BaseChannelPlugin {
380894
381038
  msg_usuario: bubble,
380895
381039
  entrante: 0
380896
381040
  });
380897
- await state.client.call("/sendIndicador", { cod, tipo: 1 });
381041
+ enviadas++;
381042
+ if (enviadas < bubbles.length) {
381043
+ await state.client.call("/sendIndicador", { cod, tipo: 1 });
381044
+ }
380898
381045
  } catch (err2) {
380899
- this.logger.warn("[asc-flow] leading bubble push failed \u2014 degrading to resposta", {
381046
+ this.logger.warn("[asc-flow] bubble push failed \u2014 stopping so the rest do not arrive out of order", {
380900
381047
  cod,
381048
+ enviadas,
381049
+ total: bubbles.length,
380901
381050
  err: String(err2)
380902
381051
  });
380903
- return;
381052
+ return enviadas;
380904
381053
  }
380905
381054
  }
381055
+ return enviadas;
380906
381056
  }
380907
381057
  async handleWebhook(request) {
380908
381058
  const url = new URL(request.url);
@@ -380922,6 +381072,12 @@ class AscFlowPlugin extends BaseChannelPlugin {
380922
381072
  if (inboundState) {
380923
381073
  this.sweepInFlight(instanceId, inboundState);
380924
381074
  inboundState.inFlight.set(turn.codAtendimento, { text: turn.text, at: Date.now() });
381075
+ if (inboundState.seenCods.size >= IN_FLIGHT_MAX_ENTRIES) {
381076
+ const oldest = inboundState.seenCods.values().next().value;
381077
+ if (oldest !== undefined)
381078
+ inboundState.seenCods.delete(oldest);
381079
+ }
381080
+ inboundState.seenCods.add(turn.codAtendimento);
380925
381081
  }
380926
381082
  await this.sendTyping(instanceId, turn.codAtendimento);
380927
381083
  const externalId = turn.messageId ?? crypto.randomUUID();
@@ -380969,6 +381125,9 @@ class AscFlowPlugin extends BaseChannelPlugin {
380969
381125
  getLogger() {
380970
381126
  return this.logger;
380971
381127
  }
381128
+ hasSeenCod(instanceId, codAtendimento) {
381129
+ return this.ascFlowInstances.get(instanceId)?.seenCods.has(codAtendimento) ?? false;
381130
+ }
380972
381131
  sweepInFlight(instanceId, state) {
380973
381132
  const now = Date.now();
380974
381133
  if (now - state.lastSweepAt < IN_FLIGHT_SWEEP_MS && state.inFlight.size < IN_FLIGHT_MAX_ENTRIES)
@@ -381026,8 +381185,45 @@ class AscFlowPlugin extends BaseChannelPlugin {
381026
381185
  ageMs
381027
381186
  });
381028
381187
  }
381188
+ if (state.lastAnswered.size >= IN_FLIGHT_MAX_ENTRIES) {
381189
+ const oldest = state.lastAnswered.keys().next().value;
381190
+ if (oldest !== undefined)
381191
+ state.lastAnswered.delete(oldest);
381192
+ }
381193
+ state.lastAnswered.set(codAtendimento, text.trim());
381029
381194
  return entry.ready;
381030
381195
  }
381196
+ async isStaleFlowReplay(instanceId, turn) {
381197
+ const state = this.ascFlowInstances.get(instanceId);
381198
+ if (!state)
381199
+ return false;
381200
+ if (state.lastAnswered.get(turn.codAtendimento) !== turn.text.trim())
381201
+ return false;
381202
+ return isStaleFlowReplay({
381203
+ client: state.client,
381204
+ instanceId,
381205
+ codAtendimento: turn.codAtendimento,
381206
+ text: turn.text,
381207
+ logger: this.logger
381208
+ });
381209
+ }
381210
+ async waitForTurn(instanceId, codAtendimento, text, timeoutMs) {
381211
+ const deadline = Date.now() + timeoutMs;
381212
+ while (Date.now() < deadline) {
381213
+ await new Promise((resolve2) => setTimeout(resolve2, 250));
381214
+ if (!this.ascFlowInstances.has(instanceId))
381215
+ return null;
381216
+ const ready = this.takeReadyTurn(instanceId, codAtendimento, text);
381217
+ if (ready)
381218
+ return ready;
381219
+ }
381220
+ this.logger.warn("[asc-flow] held the request to its deadline with no agent answer", {
381221
+ instanceId,
381222
+ codAtendimento,
381223
+ timeoutMs
381224
+ });
381225
+ return null;
381226
+ }
381031
381227
  isRedeliveryOfTurnInFlight(instanceId, turn) {
381032
381228
  const state = this.ascFlowInstances.get(instanceId);
381033
381229
  const entry = state?.inFlight.get(turn.codAtendimento);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automagik/omni",
3
- "version": "2.260904.1",
3
+ "version": "2.260906.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/automagik-dev/omni.git",