@automagik/omni 2.260901.1 → 2.260901.3
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 +2 -1
- package/dist/server/index.js +439 -88
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12312,6 +12312,7 @@ var init_types3 = __esm(() => {
|
|
|
12312
12312
|
"batch-job.cancelled",
|
|
12313
12313
|
"batch-job.failed",
|
|
12314
12314
|
"agent.state.changed",
|
|
12315
|
+
"agent.run.cancel_requested",
|
|
12315
12316
|
"agent.task.created",
|
|
12316
12317
|
"agent.task.updated",
|
|
12317
12318
|
"agent.task.completed",
|
|
@@ -128288,7 +128289,7 @@ import { fileURLToPath } from "url";
|
|
|
128288
128289
|
// package.json
|
|
128289
128290
|
var package_default = {
|
|
128290
128291
|
name: "@automagik/omni",
|
|
128291
|
-
version: "2.260901.
|
|
128292
|
+
version: "2.260901.3",
|
|
128292
128293
|
description: "LLM-optimized CLI for Omni",
|
|
128293
128294
|
type: "module",
|
|
128294
128295
|
bin: {
|
package/dist/server/index.js
CHANGED
|
@@ -174,6 +174,7 @@ var init_types2 = __esm(() => {
|
|
|
174
174
|
"batch-job.cancelled",
|
|
175
175
|
"batch-job.failed",
|
|
176
176
|
"agent.state.changed",
|
|
177
|
+
"agent.run.cancel_requested",
|
|
177
178
|
"agent.task.created",
|
|
178
179
|
"agent.task.updated",
|
|
179
180
|
"agent.task.completed",
|
|
@@ -36795,7 +36796,7 @@ function ensureCleanup() {
|
|
|
36795
36796
|
}
|
|
36796
36797
|
}
|
|
36797
36798
|
function startAck(plugin2, ackProvider, instanceId, chatId, messageId, channel2, config2) {
|
|
36798
|
-
const noopHandle = { remove() {} };
|
|
36799
|
+
const noopHandle = { remove() {}, release() {} };
|
|
36799
36800
|
if (config2.reactionAck !== "on") {
|
|
36800
36801
|
return noopHandle;
|
|
36801
36802
|
}
|
|
@@ -36830,6 +36831,12 @@ function startAck(plugin2, ackProvider, instanceId, chatId, messageId, channel2,
|
|
|
36830
36831
|
if (ackProvider) {
|
|
36831
36832
|
ackProvider.removeAck(instanceId, chatId, messageId, emoji).catch(() => {});
|
|
36832
36833
|
}
|
|
36834
|
+
},
|
|
36835
|
+
release() {
|
|
36836
|
+
if (removed)
|
|
36837
|
+
return;
|
|
36838
|
+
removed = true;
|
|
36839
|
+
clearTimeout(timer);
|
|
36833
36840
|
}
|
|
36834
36841
|
};
|
|
36835
36842
|
}
|
|
@@ -242894,7 +242901,7 @@ var init_sentry_scrub = __esm(() => {
|
|
|
242894
242901
|
var require_package7 = __commonJS((exports, module) => {
|
|
242895
242902
|
module.exports = {
|
|
242896
242903
|
name: "@omni/api",
|
|
242897
|
-
version: "2.260901.
|
|
242904
|
+
version: "2.260901.3",
|
|
242898
242905
|
type: "module",
|
|
242899
242906
|
exports: {
|
|
242900
242907
|
".": {
|
|
@@ -343539,14 +343546,16 @@ var init_loader2 = __esm(() => {
|
|
|
343539
343546
|
class MessageDebouncer {
|
|
343540
343547
|
buffers = new Map;
|
|
343541
343548
|
timers = new Map;
|
|
343542
|
-
inFlight = new
|
|
343549
|
+
inFlight = new Map;
|
|
343543
343550
|
firstBufferedAt = new Map;
|
|
343544
343551
|
lastConfig = new Map;
|
|
343545
343552
|
onFlush;
|
|
343546
343553
|
now;
|
|
343547
|
-
|
|
343554
|
+
options;
|
|
343555
|
+
constructor(onFlush, now = Date.now, options = {}) {
|
|
343548
343556
|
this.onFlush = onFlush;
|
|
343549
343557
|
this.now = now;
|
|
343558
|
+
this.options = options;
|
|
343550
343559
|
}
|
|
343551
343560
|
getChatKey(instanceId, chatId) {
|
|
343552
343561
|
return `${instanceId}:${chatId}`;
|
|
@@ -343559,8 +343568,19 @@ class MessageDebouncer {
|
|
|
343559
343568
|
if (!this.firstBufferedAt.has(chatKey))
|
|
343560
343569
|
this.firstBufferedAt.set(chatKey, this.now());
|
|
343561
343570
|
this.lastConfig.set(chatKey, config4);
|
|
343562
|
-
if (this.inFlight.has(chatKey))
|
|
343571
|
+
if (this.inFlight.has(chatKey)) {
|
|
343572
|
+
const blockingTraceId = this.inFlight.get(chatKey);
|
|
343573
|
+
const queuePosition = buffer3.length;
|
|
343574
|
+
log89.info("agent_dispatch_queued", {
|
|
343575
|
+
instanceId,
|
|
343576
|
+
chatId,
|
|
343577
|
+
traceId: message2.metadata.traceId,
|
|
343578
|
+
queuePosition,
|
|
343579
|
+
blockingTraceId
|
|
343580
|
+
});
|
|
343581
|
+
this.options.onQueuedBehindActiveRun?.({ instanceId, chatId, message: message2, queuePosition, blockingTraceId });
|
|
343563
343582
|
return;
|
|
343583
|
+
}
|
|
343564
343584
|
this.restartTimer(chatKey, config4);
|
|
343565
343585
|
}
|
|
343566
343586
|
hasPending(instanceId, chatId) {
|
|
@@ -343621,7 +343641,7 @@ class MessageDebouncer {
|
|
|
343621
343641
|
clearTimeout(timer2);
|
|
343622
343642
|
if (!messages4?.length)
|
|
343623
343643
|
return;
|
|
343624
|
-
this.inFlight.
|
|
343644
|
+
this.inFlight.set(chatKey, messages4[0]?.metadata.traceId);
|
|
343625
343645
|
try {
|
|
343626
343646
|
await this.onFlush(chatKey, messages4);
|
|
343627
343647
|
} catch (error3) {
|
|
@@ -345473,6 +345493,51 @@ async function fetchChatMetadata(services, instanceId, chatId, chatType, trusted
|
|
|
345473
345493
|
return {};
|
|
345474
345494
|
}
|
|
345475
345495
|
}
|
|
345496
|
+
function runAbortKey(instanceId, chatId, threadId2) {
|
|
345497
|
+
return `${instanceId}:${chatId}:${threadId2 ?? ""}`;
|
|
345498
|
+
}
|
|
345499
|
+
async function cancelActiveAgentRun(instanceId, chatId, reason, opts) {
|
|
345500
|
+
let entry = activeRunAborts.get(runAbortKey(instanceId, chatId, opts?.threadId));
|
|
345501
|
+
if (!entry && opts?.threadId) {
|
|
345502
|
+
entry = activeRunAborts.get(runAbortKey(instanceId, chatId));
|
|
345503
|
+
}
|
|
345504
|
+
if (!entry) {
|
|
345505
|
+
log91.info("Agent run cancel requested but nothing in flight", {
|
|
345506
|
+
instanceId,
|
|
345507
|
+
chatId,
|
|
345508
|
+
threadId: opts?.threadId,
|
|
345509
|
+
reason
|
|
345510
|
+
});
|
|
345511
|
+
return false;
|
|
345512
|
+
}
|
|
345513
|
+
if (opts?.requestedAt !== undefined && entry.startedAt > opts.requestedAt) {
|
|
345514
|
+
log91.info("Agent run cancel ignored \u2014 run started after the stop request", {
|
|
345515
|
+
instanceId,
|
|
345516
|
+
chatId,
|
|
345517
|
+
threadId: opts?.threadId,
|
|
345518
|
+
startedAt: entry.startedAt,
|
|
345519
|
+
requestedAt: opts.requestedAt,
|
|
345520
|
+
reason
|
|
345521
|
+
});
|
|
345522
|
+
return false;
|
|
345523
|
+
}
|
|
345524
|
+
log91.info("Cancelling in-flight agent run", {
|
|
345525
|
+
instanceId,
|
|
345526
|
+
chatId,
|
|
345527
|
+
threadId: opts?.threadId,
|
|
345528
|
+
reason,
|
|
345529
|
+
hasActiveStream: !!entry.sender
|
|
345530
|
+
});
|
|
345531
|
+
entry.controller.abort();
|
|
345532
|
+
if (entry.sender) {
|
|
345533
|
+
try {
|
|
345534
|
+
await (entry.sender.cancel ? entry.sender.cancel() : entry.sender.abort());
|
|
345535
|
+
} catch (err2) {
|
|
345536
|
+
log91.warn("Stream sender cancel failed during run cancellation", { instanceId, chatId, error: String(err2) });
|
|
345537
|
+
}
|
|
345538
|
+
}
|
|
345539
|
+
return true;
|
|
345540
|
+
}
|
|
345476
345541
|
async function routeStreamDelta(sender, delta) {
|
|
345477
345542
|
switch (delta.phase) {
|
|
345478
345543
|
case "thinking":
|
|
@@ -345693,6 +345758,10 @@ async function dispatchViaStreamingProvider(services, instance4, messages4, trig
|
|
|
345693
345758
|
const sender = resolved.createSender(instance4.id, chatId, replyToId, chatType, { formatMode });
|
|
345694
345759
|
const streamKey = `${instance4.id}:${chatId}`;
|
|
345695
345760
|
activeStreams.set(streamKey, sender);
|
|
345761
|
+
const cancelController = new AbortController;
|
|
345762
|
+
const runKey = runAbortKey(instance4.id, chatId, rawThreadId);
|
|
345763
|
+
activeRunAborts.set(runKey, { controller: cancelController, startedAt: Date.now(), sender });
|
|
345764
|
+
trigger.abortSignal = cancelController.signal;
|
|
345696
345765
|
const streamDispatchStart = Date.now();
|
|
345697
345766
|
try {
|
|
345698
345767
|
const generator = resolved.provider.triggerStream(trigger);
|
|
@@ -345707,8 +345776,12 @@ async function dispatchViaStreamingProvider(services, instance4, messages4, trig
|
|
|
345707
345776
|
attributes: { provider_type: resolved.provider.schema }
|
|
345708
345777
|
});
|
|
345709
345778
|
}
|
|
345710
|
-
return streamResult;
|
|
345779
|
+
return cancelController.signal.aborted ? true : streamResult;
|
|
345711
345780
|
} catch (err2) {
|
|
345781
|
+
if (cancelController.signal.aborted) {
|
|
345782
|
+
log91.info("Streaming dispatch cancelled by user", { instanceId: instance4.id, chatId, traceId });
|
|
345783
|
+
return true;
|
|
345784
|
+
}
|
|
345712
345785
|
log91.error("Streaming dispatch failed, falling back", {
|
|
345713
345786
|
instanceId: instance4.id,
|
|
345714
345787
|
chatId,
|
|
@@ -345721,6 +345794,7 @@ async function dispatchViaStreamingProvider(services, instance4, messages4, trig
|
|
|
345721
345794
|
return false;
|
|
345722
345795
|
} finally {
|
|
345723
345796
|
activeStreams.delete(streamKey);
|
|
345797
|
+
activeRunAborts.delete(runKey);
|
|
345724
345798
|
}
|
|
345725
345799
|
}
|
|
345726
345800
|
function formatMediaContent(msg) {
|
|
@@ -345919,6 +345993,38 @@ async function dispatchViaTurnBasedProvider(services, instance4, provider, trigg
|
|
|
345919
345993
|
});
|
|
345920
345994
|
return true;
|
|
345921
345995
|
}
|
|
345996
|
+
function resolveReplySuppression(flags) {
|
|
345997
|
+
if (flags.handoffTriggered)
|
|
345998
|
+
return "handoff_triggered";
|
|
345999
|
+
if (flags.errorHandoffDone)
|
|
346000
|
+
return "error_handoff";
|
|
346001
|
+
if (flags.supersededByNewerInbound)
|
|
346002
|
+
return "superseded_by_newer_inbound";
|
|
346003
|
+
if (flags.runCancelled)
|
|
346004
|
+
return "run_cancelled_by_user";
|
|
346005
|
+
return null;
|
|
346006
|
+
}
|
|
346007
|
+
async function triggerProviderWithCancellation(provider, trigger, spanAttributes, instanceId, chatId, traceId) {
|
|
346008
|
+
const cancelController = new AbortController;
|
|
346009
|
+
const runKey = runAbortKey(instanceId, chatId, trigger.source.threadId);
|
|
346010
|
+
activeRunAborts.set(runKey, { controller: cancelController, startedAt: Date.now() });
|
|
346011
|
+
try {
|
|
346012
|
+
const result = await withLifecycleSpan("omni.dispatch_to_agno", spanAttributes, () => provider.trigger({
|
|
346013
|
+
...trigger,
|
|
346014
|
+
abortSignal: cancelController.signal,
|
|
346015
|
+
traceContext: activeProviderTraceContext() ?? trigger.traceContext
|
|
346016
|
+
}));
|
|
346017
|
+
return { result, cancelled: cancelController.signal.aborted };
|
|
346018
|
+
} catch (err2) {
|
|
346019
|
+
if (cancelController.signal.aborted) {
|
|
346020
|
+
log91.info("Agent run cancelled by user during dispatch", { instanceId, chatId, traceId });
|
|
346021
|
+
return null;
|
|
346022
|
+
}
|
|
346023
|
+
throw err2;
|
|
346024
|
+
} finally {
|
|
346025
|
+
activeRunAborts.delete(runKey);
|
|
346026
|
+
}
|
|
346027
|
+
}
|
|
345922
346028
|
async function dispatchViaProvider(services, instance4, messages4, triggerType, channel5, chatId, senderId, personId, senderName, traceId, rawEvent, db2, extraContextMessages, senderAgentId) {
|
|
345923
346029
|
const provider = await getAgentProvider(services, instance4, db2);
|
|
345924
346030
|
if (!provider)
|
|
@@ -345988,11 +346094,14 @@ async function dispatchViaProvider(services, instance4, messages4, triggerType,
|
|
|
345988
346094
|
}
|
|
345989
346095
|
const correlationId = messages4[0]?.metadata.correlationId;
|
|
345990
346096
|
const dispatchStart = Date.now();
|
|
345991
|
-
const
|
|
346097
|
+
const triggerOutcome = await triggerProviderWithCancellation(provider, trigger, buildLifecycleSpanAttributes({
|
|
345992
346098
|
...lifecycleBase,
|
|
345993
346099
|
stage: "dispatch_to_agno",
|
|
345994
346100
|
extra: { trigger_type: triggerType, provider_id: provider.id, provider_schema: provider.schema }
|
|
345995
|
-
}),
|
|
346101
|
+
}), instance4.id, chatId, traceId);
|
|
346102
|
+
if (!triggerOutcome)
|
|
346103
|
+
return true;
|
|
346104
|
+
const { result, cancelled: runCancelled } = triggerOutcome;
|
|
345996
346105
|
const dispatchDurationMs = Date.now() - dispatchStart;
|
|
345997
346106
|
if (sentryEnabled()) {
|
|
345998
346107
|
exports_public_api2.count("agent.dispatch", 1, { attributes: { provider_type: provider.schema } });
|
|
@@ -346005,7 +346114,13 @@ async function dispatchViaProvider(services, instance4, messages4, triggerType,
|
|
|
346005
346114
|
const handoffTriggered = chatAfterRun?.settings?.agentPaused === true;
|
|
346006
346115
|
const supersededByNewerInbound = !handoffTriggered && isReplySuperseded(instance4, chatId);
|
|
346007
346116
|
const errorHandoffDone = await maybeTriggerErrorHandoff(services, db2, channel5, instance4, chatId, result?.metadata.customerErrorBlocked === true, handoffTriggered, messages4[0]?.metadata.trustedTenantId);
|
|
346008
|
-
|
|
346117
|
+
const suppressReason = resolveReplySuppression({
|
|
346118
|
+
handoffTriggered,
|
|
346119
|
+
errorHandoffDone,
|
|
346120
|
+
supersededByNewerInbound,
|
|
346121
|
+
runCancelled
|
|
346122
|
+
});
|
|
346123
|
+
if (result && result.parts.length > 0 && !suppressReason) {
|
|
346009
346124
|
const selfChat = isSelfChat(chatId, instance4.ownerIdentifier);
|
|
346010
346125
|
const rawParts = selfChat ? result.parts.map((p2) => `${BOT_PREFIX}${p2}`) : result.parts;
|
|
346011
346126
|
const parts = await Promise.all(rawParts.map((part) => executeBeforeMessageWriteHooks(instance4.id, chatId, part)));
|
|
@@ -346021,13 +346136,9 @@ async function dispatchViaProvider(services, instance4, messages4, triggerType,
|
|
|
346021
346136
|
}), () => sendResponseParts(channel5, instance4.id, chatId, parts, getSplitDelayConfig(instance4), _fmtMode, replyTo, correlationId, senderAgentId));
|
|
346022
346137
|
recordJourneyCheckpoint(correlationId, "T9", JOURNEY_STAGES.T9);
|
|
346023
346138
|
await forwardToChainedInstance(instance4, parts, correlationId, messages4);
|
|
346024
|
-
} else if (
|
|
346025
|
-
log91.info("Agent response suppressed
|
|
346026
|
-
|
|
346027
|
-
chatId
|
|
346028
|
-
});
|
|
346029
|
-
} else if (supersededByNewerInbound) {
|
|
346030
|
-
log91.info("Agent response discarded \u2014 superseded by newer inbound", {
|
|
346139
|
+
} else if (suppressReason) {
|
|
346140
|
+
log91.info("Agent response suppressed", {
|
|
346141
|
+
reason: suppressReason,
|
|
346031
346142
|
instanceId: instance4.id,
|
|
346032
346143
|
chatId,
|
|
346033
346144
|
parts: result?.parts.length ?? 0,
|
|
@@ -346370,6 +346481,34 @@ function buildAckConfig(instance4) {
|
|
|
346370
346481
|
ackTimeoutMs: inst.ackTimeoutMs ?? 30000
|
|
346371
346482
|
};
|
|
346372
346483
|
}
|
|
346484
|
+
function takeQueuedAck(chatKey) {
|
|
346485
|
+
const entry = queuedMessageAcks.get(chatKey);
|
|
346486
|
+
queuedMessageAcks.delete(chatKey);
|
|
346487
|
+
return entry?.handle;
|
|
346488
|
+
}
|
|
346489
|
+
async function ackQueuedMessage(info2) {
|
|
346490
|
+
const chatKey = `${info2.instanceId}:${info2.chatId}`;
|
|
346491
|
+
try {
|
|
346492
|
+
const existing = queuedMessageAcks.get(chatKey);
|
|
346493
|
+
if (existing && Date.now() - existing.at < QUEUED_ACK_TIMEOUT_MS)
|
|
346494
|
+
return;
|
|
346495
|
+
const instance4 = info2.message.metadata.resolvedInstance;
|
|
346496
|
+
const messageId = info2.message.payload.externalId;
|
|
346497
|
+
if (!instance4 || !messageId)
|
|
346498
|
+
return;
|
|
346499
|
+
const entry = { at: Date.now() };
|
|
346500
|
+
queuedMessageAcks.set(chatKey, entry);
|
|
346501
|
+
const channel5 = info2.message.metadata.channelType ?? instance4.channel;
|
|
346502
|
+
const plugin10 = await getPlugin(channel5) ?? null;
|
|
346503
|
+
entry.handle = startAck(plugin10, createPluginAckProvider(plugin10), instance4.id, info2.chatId, messageId, channel5, {
|
|
346504
|
+
...buildAckConfig(instance4),
|
|
346505
|
+
ackTimeoutMs: QUEUED_ACK_TIMEOUT_MS
|
|
346506
|
+
});
|
|
346507
|
+
} catch (error3) {
|
|
346508
|
+
queuedMessageAcks.delete(chatKey);
|
|
346509
|
+
log91.debug("Failed to ack queued message", { chatId: info2.chatId, error: String(error3) });
|
|
346510
|
+
}
|
|
346511
|
+
}
|
|
346373
346512
|
async function dispatchToAgent(services, instance4, msgs, triggerType, channel5, chatId, senderId, personId, senderName, traceId, senderAgentId, perThreadExtraContext, db2) {
|
|
346374
346513
|
const firstMsg = msgs[0];
|
|
346375
346514
|
if (!firstMsg)
|
|
@@ -347463,10 +347602,13 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
347463
347602
|
}
|
|
347464
347603
|
}
|
|
347465
347604
|
}, 60000);
|
|
347466
|
-
const
|
|
347605
|
+
const onDebouncedFlush = async (chatKey, messages4) => {
|
|
347606
|
+
const queuedAck = takeQueuedAck(chatKey);
|
|
347467
347607
|
const firstMsg = messages4[0];
|
|
347468
|
-
if (!firstMsg)
|
|
347608
|
+
if (!firstMsg) {
|
|
347609
|
+
queuedAck?.remove();
|
|
347469
347610
|
return;
|
|
347611
|
+
}
|
|
347470
347612
|
const instanceId = firstMsg.metadata.instanceId;
|
|
347471
347613
|
let instance4;
|
|
347472
347614
|
if (firstMsg.metadata.resolvedInstance) {
|
|
@@ -347475,6 +347617,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
347475
347617
|
const baseInstance = await runDispatchDb(db2, firstMsg.metadata.trustedTenantId, () => agentRunner.getInstanceWithProvider(instanceId));
|
|
347476
347618
|
if (!baseInstance) {
|
|
347477
347619
|
log91.warn("Instance not found for debounced messages", { instanceId });
|
|
347620
|
+
queuedAck?.remove();
|
|
347478
347621
|
return;
|
|
347479
347622
|
}
|
|
347480
347623
|
const externalChatId = firstMsg.payload.chatId;
|
|
@@ -347484,13 +347627,19 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
347484
347627
|
}
|
|
347485
347628
|
const msgContext = buildMessageContext(firstMsg.payload, instance4);
|
|
347486
347629
|
const triggerType = classifyMessageTrigger(msgContext);
|
|
347487
|
-
if (await shouldSkipViaGate(triggerType, firstMsg, instance4, messages4, services))
|
|
347630
|
+
if (await shouldSkipViaGate(triggerType, firstMsg, instance4, messages4, services)) {
|
|
347631
|
+
queuedAck?.remove();
|
|
347488
347632
|
return;
|
|
347633
|
+
}
|
|
347489
347634
|
if (firstMsg.metadata.journeyTracked && firstMsg.metadata.correlationId) {
|
|
347490
347635
|
const tracker = getJourneyTracker();
|
|
347491
347636
|
tracker.recordCheckpoint(firstMsg.metadata.correlationId, "T5", JOURNEY_STAGES.T5);
|
|
347492
347637
|
}
|
|
347638
|
+
queuedAck?.release();
|
|
347493
347639
|
await processAgentResponse(services, instance4, messages4, triggerType, db2, eventBus);
|
|
347640
|
+
};
|
|
347641
|
+
const debouncer = new MessageDebouncer(onDebouncedFlush, Date.now, {
|
|
347642
|
+
onQueuedBehindActiveRun: (info2) => void ackQueuedMessage(info2)
|
|
347494
347643
|
});
|
|
347495
347644
|
activeMessageDebouncer = debouncer;
|
|
347496
347645
|
try {
|
|
@@ -347656,7 +347805,24 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
347656
347805
|
queue: "agent-dispatcher-media",
|
|
347657
347806
|
startFrom: "new"
|
|
347658
347807
|
});
|
|
347659
|
-
|
|
347808
|
+
await eventBus.subscribe("agent.run.cancel_requested", async (event) => {
|
|
347809
|
+
const payload = event.payload;
|
|
347810
|
+
try {
|
|
347811
|
+
await cancelActiveAgentRun(payload.instanceId, payload.chatId, payload.reason, {
|
|
347812
|
+
threadId: payload.threadId,
|
|
347813
|
+
requestedAt: payload.requestedAt
|
|
347814
|
+
});
|
|
347815
|
+
} catch (error3) {
|
|
347816
|
+
log91.error("Error cancelling agent run", {
|
|
347817
|
+
instanceId: payload.instanceId,
|
|
347818
|
+
chatId: payload.chatId,
|
|
347819
|
+
error: String(error3)
|
|
347820
|
+
});
|
|
347821
|
+
}
|
|
347822
|
+
}, {
|
|
347823
|
+
startFrom: "new"
|
|
347824
|
+
});
|
|
347825
|
+
log91.info("Agent dispatcher initialized (message + reaction + reaction-removed + media + cancel triggers)");
|
|
347660
347826
|
} catch (error3) {
|
|
347661
347827
|
log91.error("Failed to set up agent dispatcher", { error: String(error3) });
|
|
347662
347828
|
clearInterval(mediaCleanupInterval);
|
|
@@ -347710,7 +347876,7 @@ async function setupAgentDispatcher(eventBus, services, db2) {
|
|
|
347710
347876
|
log91.info("Agent dispatcher shutdown complete");
|
|
347711
347877
|
};
|
|
347712
347878
|
}
|
|
347713
|
-
var import_api32, 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, sessionActivityStore, PROC_REACT_START, PROC_REACT_DONE = "\u2705", 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;
|
|
347879
|
+
var import_api32, 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, 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;
|
|
347714
347880
|
var init_agent_dispatcher = __esm(() => {
|
|
347715
347881
|
init_src2();
|
|
347716
347882
|
init_src();
|
|
@@ -347767,8 +347933,10 @@ var init_agent_dispatcher = __esm(() => {
|
|
|
347767
347933
|
mediaResultCache = new Map;
|
|
347768
347934
|
DEFAULT_SEND_MEDIA_PATH_TYPES = ["image", "video", "document"];
|
|
347769
347935
|
activeStreams = new Map;
|
|
347936
|
+
activeRunAborts = new Map;
|
|
347770
347937
|
sessionActivityStore = new InMemorySessionActivityStore;
|
|
347771
347938
|
PROC_REACT_START = { audio: "\uD83C\uDFA7", image: "\uD83D\uDC40", video: "\uD83D\uDC40", document: "\uD83D\uDC40" };
|
|
347939
|
+
queuedMessageAcks = new Map;
|
|
347772
347940
|
providerCache = new Map;
|
|
347773
347941
|
openclawClientPool = new Map;
|
|
347774
347942
|
_openClawClientCtor = OpenClawClient;
|
|
@@ -365105,6 +365273,27 @@ var init_handoffs = __esm(() => {
|
|
|
365105
365273
|
});
|
|
365106
365274
|
});
|
|
365107
365275
|
|
|
365276
|
+
// ../api/src/lib/whatsapp-business-connection.ts
|
|
365277
|
+
function applyWhatsAppBusinessConnectionOptions(options, input) {
|
|
365278
|
+
if (input.metaAccessToken)
|
|
365279
|
+
options.metaAccessToken = input.metaAccessToken;
|
|
365280
|
+
if (input.metaPhoneNumberId)
|
|
365281
|
+
options.metaPhoneNumberId = input.metaPhoneNumberId;
|
|
365282
|
+
if (input.metaWabaId)
|
|
365283
|
+
options.metaWabaId = input.metaWabaId;
|
|
365284
|
+
if (input.metaAppId)
|
|
365285
|
+
options.metaAppId = input.metaAppId;
|
|
365286
|
+
if (input.metaBusinessId)
|
|
365287
|
+
options.metaBusinessId = input.metaBusinessId;
|
|
365288
|
+
const apiVersion = process.env.META_GRAPH_API_VERSION ?? input.metaApiVersion;
|
|
365289
|
+
if (apiVersion)
|
|
365290
|
+
options.metaApiVersion = apiVersion;
|
|
365291
|
+
if (input.metaDisplayPhoneNumber)
|
|
365292
|
+
options.metaDisplayPhoneNumber = input.metaDisplayPhoneNumber;
|
|
365293
|
+
if (input.metaConnectionMethod)
|
|
365294
|
+
options.metaConnectionMethod = input.metaConnectionMethod;
|
|
365295
|
+
}
|
|
365296
|
+
|
|
365108
365297
|
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMode.js
|
|
365109
365298
|
var require_QRMode = __commonJS((exports, module) => {
|
|
365110
365299
|
module.exports = {
|
|
@@ -366530,6 +366719,9 @@ function applyChannelSpecificConnectionOptions(options, input) {
|
|
|
366530
366719
|
case "hermes":
|
|
366531
366720
|
applyHermesConnectionOptions(options, input);
|
|
366532
366721
|
return;
|
|
366722
|
+
case "whatsapp-business":
|
|
366723
|
+
applyWhatsAppBusinessConnectionOptions(options, input);
|
|
366724
|
+
return;
|
|
366533
366725
|
}
|
|
366534
366726
|
}
|
|
366535
366727
|
function buildInstanceConnectionOptions(input) {
|
|
@@ -366673,7 +366865,15 @@ function buildConnectConnectionOptions(instance4, body, forceNewQr) {
|
|
|
366673
366865
|
hermesUsername: body.hermesUsername ?? instance4.hermesUsername,
|
|
366674
366866
|
hermesPassword: body.hermesPassword ?? instance4.hermesPassword,
|
|
366675
366867
|
hermesMediaId: body.hermesMediaId ?? instance4.hermesMediaId,
|
|
366676
|
-
hermesTemplateNamespace: body.hermesTemplateNamespace ?? instance4.hermesTemplateNamespace
|
|
366868
|
+
hermesTemplateNamespace: body.hermesTemplateNamespace ?? instance4.hermesTemplateNamespace,
|
|
366869
|
+
metaAccessToken: instance4.metaAccessToken,
|
|
366870
|
+
metaPhoneNumberId: instance4.metaPhoneNumberId,
|
|
366871
|
+
metaWabaId: instance4.metaWabaId,
|
|
366872
|
+
metaAppId: instance4.metaAppId,
|
|
366873
|
+
metaBusinessId: instance4.metaBusinessId,
|
|
366874
|
+
metaApiVersion: instance4.metaApiVersion,
|
|
366875
|
+
metaDisplayPhoneNumber: instance4.metaDisplayPhoneNumber,
|
|
366876
|
+
metaConnectionMethod: instance4.metaConnectionMethod
|
|
366677
366877
|
});
|
|
366678
366878
|
}
|
|
366679
366879
|
function hydrateConnectionOptionsForInstance(plugin10, instance4, options) {
|
|
@@ -367411,6 +367611,9 @@ var init_instances3 = __esm(() => {
|
|
|
367411
367611
|
if (instance4.channel === "hermes") {
|
|
367412
367612
|
applyHermesConnectionOptions(restartOptions, instance4);
|
|
367413
367613
|
}
|
|
367614
|
+
if (instance4.channel === "whatsapp-business") {
|
|
367615
|
+
applyWhatsAppBusinessConnectionOptions(restartOptions, instance4);
|
|
367616
|
+
}
|
|
367414
367617
|
if (instance4.channel === "whatsapp-baileys" && instance4.markOnlineOnConnect != null) {
|
|
367415
367618
|
restartOptions.whatsapp = {
|
|
367416
367619
|
...restartOptions.whatsapp,
|
|
@@ -371011,7 +371214,12 @@ var init_messages5 = __esm(() => {
|
|
|
371011
371214
|
...list ? { list } : {}
|
|
371012
371215
|
},
|
|
371013
371216
|
replyTo,
|
|
371014
|
-
metadata: {
|
|
371217
|
+
metadata: {
|
|
371218
|
+
...mentions ? { mentions } : {},
|
|
371219
|
+
...replyContext,
|
|
371220
|
+
...senderAgentId ? { senderAgentId } : {},
|
|
371221
|
+
...instance4.messageFormatMode ? { messageFormatMode: instance4.messageFormatMode } : {}
|
|
371222
|
+
}
|
|
371015
371223
|
};
|
|
371016
371224
|
if (correlationId && tracker.isTracking(correlationId)) {
|
|
371017
371225
|
tracker.recordCheckpoint(correlationId, "T8", JOURNEY_STAGES.T8);
|
|
@@ -377404,7 +377612,7 @@ function buildInstanceConnectOptions(instance4) {
|
|
|
377404
377612
|
applyTwilioWhatsAppOptions(options, instance4);
|
|
377405
377613
|
}
|
|
377406
377614
|
if (instance4.channel === "whatsapp-business") {
|
|
377407
|
-
|
|
377615
|
+
applyWhatsAppBusinessConnectionOptions(options, instance4);
|
|
377408
377616
|
}
|
|
377409
377617
|
if (instance4.channel === "hermes") {
|
|
377410
377618
|
applyHermesOptions(options, instance4);
|
|
@@ -377423,24 +377631,6 @@ function applyHermesOptions(options, instance4) {
|
|
|
377423
377631
|
if (instance4.hermesTemplateNamespace)
|
|
377424
377632
|
options.hermesTemplateNamespace = instance4.hermesTemplateNamespace;
|
|
377425
377633
|
}
|
|
377426
|
-
function applyWhatsAppBusinessOptions(options, instance4) {
|
|
377427
|
-
if (instance4.metaAccessToken)
|
|
377428
|
-
options.metaAccessToken = instance4.metaAccessToken;
|
|
377429
|
-
if (instance4.metaPhoneNumberId)
|
|
377430
|
-
options.metaPhoneNumberId = instance4.metaPhoneNumberId;
|
|
377431
|
-
if (instance4.metaWabaId)
|
|
377432
|
-
options.metaWabaId = instance4.metaWabaId;
|
|
377433
|
-
if (instance4.metaAppId)
|
|
377434
|
-
options.metaAppId = instance4.metaAppId;
|
|
377435
|
-
if (instance4.metaBusinessId)
|
|
377436
|
-
options.metaBusinessId = instance4.metaBusinessId;
|
|
377437
|
-
if (instance4.metaApiVersion)
|
|
377438
|
-
options.metaApiVersion = instance4.metaApiVersion;
|
|
377439
|
-
if (instance4.metaDisplayPhoneNumber)
|
|
377440
|
-
options.metaDisplayPhoneNumber = instance4.metaDisplayPhoneNumber;
|
|
377441
|
-
if (instance4.metaConnectionMethod)
|
|
377442
|
-
options.metaConnectionMethod = instance4.metaConnectionMethod;
|
|
377443
|
-
}
|
|
377444
377634
|
function applyGupshupOptions(options, instance4) {
|
|
377445
377635
|
if (instance4.gupshupCallbackUrl)
|
|
377446
377636
|
options.gupshupCallbackUrl = instance4.gupshupCallbackUrl;
|
|
@@ -385208,6 +385398,23 @@ async function checkBoltHealth(connection) {
|
|
|
385208
385398
|
}
|
|
385209
385399
|
}
|
|
385210
385400
|
|
|
385401
|
+
// ../channel-slack/src/handlers/agent-sessions.ts
|
|
385402
|
+
function setupAgentSessionHandlers(app, instanceId, callbacks, logger5) {
|
|
385403
|
+
app.event("agent_session_stopped", async ({ event }) => {
|
|
385404
|
+
const evt = event;
|
|
385405
|
+
const channelId = evt.channel;
|
|
385406
|
+
if (!channelId)
|
|
385407
|
+
return;
|
|
385408
|
+
const threadTs = evt.thread_ts;
|
|
385409
|
+
const userId = evt.user;
|
|
385410
|
+
const eventTs = evt.event_ts;
|
|
385411
|
+
const streamingMessageTs = Array.isArray(evt.streaming_message_ts) ? evt.streaming_message_ts : [];
|
|
385412
|
+
logger5.info("Agent session stopped by user", { instanceId, channelId, threadTs, userId, streamingMessageTs });
|
|
385413
|
+
await callbacks.onSessionStopped(instanceId, { channelId, threadTs, userId, streamingMessageTs, eventTs });
|
|
385414
|
+
});
|
|
385415
|
+
logger5.info("Agent session handlers registered", { instanceId });
|
|
385416
|
+
}
|
|
385417
|
+
|
|
385211
385418
|
// ../channel-slack/src/handlers/commands.ts
|
|
385212
385419
|
function setupCommandHandlers(app, instanceId, commandNames, callbacks, logger5) {
|
|
385213
385420
|
for (const commandName of commandNames) {
|
|
@@ -385687,10 +385894,62 @@ function setupReactionHandlers2(app, instanceId, botUserId, callbacks, logger5)
|
|
|
385687
385894
|
|
|
385688
385895
|
// ../channel-slack/src/handlers/typing.ts
|
|
385689
385896
|
var CLEAR_STATUS = "";
|
|
385897
|
+
var AGENT_API_UNAVAILABLE_ERRORS = new Set([
|
|
385898
|
+
"unknown_method",
|
|
385899
|
+
"feature_disabled",
|
|
385900
|
+
"method_deprecated",
|
|
385901
|
+
"missing_scope",
|
|
385902
|
+
"not_allowed_token_type"
|
|
385903
|
+
]);
|
|
385904
|
+
var agentApiUnavailable = new WeakSet;
|
|
385905
|
+
function slackErrorCode(err2) {
|
|
385906
|
+
return err2?.data?.error;
|
|
385907
|
+
}
|
|
385690
385908
|
async function setSlackThreadStatus(params) {
|
|
385691
385909
|
const { client, channelId, threadTs, status, loadingMessages, logger: logger5, instanceId } = params;
|
|
385692
|
-
if (!threadTs)
|
|
385693
|
-
|
|
385910
|
+
if (!threadTs) {
|
|
385911
|
+
logger5.debug("setSlackThreadStatus: skipped, no thread timestamp", {
|
|
385912
|
+
instanceId,
|
|
385913
|
+
channelId,
|
|
385914
|
+
reason: "no_thread_ts",
|
|
385915
|
+
clearing: status.length === 0
|
|
385916
|
+
});
|
|
385917
|
+
return { delivered: false };
|
|
385918
|
+
}
|
|
385919
|
+
const clearing = status.length === 0;
|
|
385920
|
+
const logContext = {
|
|
385921
|
+
instanceId,
|
|
385922
|
+
channelId,
|
|
385923
|
+
threadTs,
|
|
385924
|
+
clearing,
|
|
385925
|
+
statusLength: status.length,
|
|
385926
|
+
loadingMessageCount: loadingMessages?.length ?? 0
|
|
385927
|
+
};
|
|
385928
|
+
if (typeof client.apiCall === "function" && !agentApiUnavailable.has(client)) {
|
|
385929
|
+
try {
|
|
385930
|
+
await client.apiCall("agents.sessions.setStatus", {
|
|
385931
|
+
channel_id: channelId,
|
|
385932
|
+
thread_ts: threadTs,
|
|
385933
|
+
status: clearing ? "active" : "processing"
|
|
385934
|
+
});
|
|
385935
|
+
return { delivered: true, method: "agents.sessions.setStatus" };
|
|
385936
|
+
} catch (err2) {
|
|
385937
|
+
const code = slackErrorCode(err2);
|
|
385938
|
+
if (code && AGENT_API_UNAVAILABLE_ERRORS.has(code)) {
|
|
385939
|
+
agentApiUnavailable.add(client);
|
|
385940
|
+
logger5.info("agents.sessions.setStatus unavailable, falling back to assistant.threads.setStatus", {
|
|
385941
|
+
instanceId,
|
|
385942
|
+
channelId,
|
|
385943
|
+
error: code
|
|
385944
|
+
});
|
|
385945
|
+
} else {
|
|
385946
|
+
logger5.warn("agents.sessions.setStatus failed, trying legacy fallback", {
|
|
385947
|
+
...logContext,
|
|
385948
|
+
error: String(err2)
|
|
385949
|
+
});
|
|
385950
|
+
}
|
|
385951
|
+
}
|
|
385952
|
+
}
|
|
385694
385953
|
const payload = {
|
|
385695
385954
|
channel_id: channelId,
|
|
385696
385955
|
thread_ts: threadTs,
|
|
@@ -385698,27 +385957,19 @@ async function setSlackThreadStatus(params) {
|
|
|
385698
385957
|
...loadingMessages?.length ? { loading_messages: loadingMessages } : {}
|
|
385699
385958
|
};
|
|
385700
385959
|
try {
|
|
385701
|
-
const
|
|
385702
|
-
if (typeof
|
|
385703
|
-
await
|
|
385704
|
-
return true;
|
|
385960
|
+
const legacyClient = client;
|
|
385961
|
+
if (typeof legacyClient.assistant?.threads?.setStatus === "function") {
|
|
385962
|
+
await legacyClient.assistant.threads.setStatus(payload);
|
|
385963
|
+
return { delivered: true, method: "assistant.threads.setStatus" };
|
|
385705
385964
|
}
|
|
385706
|
-
if (typeof
|
|
385707
|
-
await
|
|
385708
|
-
return true;
|
|
385965
|
+
if (typeof legacyClient.apiCall === "function") {
|
|
385966
|
+
await legacyClient.apiCall("assistant.threads.setStatus", payload);
|
|
385967
|
+
return { delivered: true, method: "assistant.threads.setStatus" };
|
|
385709
385968
|
}
|
|
385710
385969
|
} catch (err2) {
|
|
385711
|
-
logger5.warn("setSlackThreadStatus: failed", {
|
|
385712
|
-
instanceId,
|
|
385713
|
-
channelId,
|
|
385714
|
-
threadTs,
|
|
385715
|
-
clearing: status.length === 0,
|
|
385716
|
-
statusLength: status.length,
|
|
385717
|
-
loadingMessageCount: loadingMessages?.length ?? 0,
|
|
385718
|
-
error: String(err2)
|
|
385719
|
-
});
|
|
385970
|
+
logger5.warn("setSlackThreadStatus: failed", { ...logContext, error: String(err2) });
|
|
385720
385971
|
}
|
|
385721
|
-
return false;
|
|
385972
|
+
return { delivered: false, method: "assistant.threads.setStatus" };
|
|
385722
385973
|
}
|
|
385723
385974
|
async function clearTypingStatus(params) {
|
|
385724
385975
|
return setSlackThreadStatus({ ...params, status: CLEAR_STATUS });
|
|
@@ -385893,6 +386144,7 @@ function createSlackStreamSender(options) {
|
|
|
385893
386144
|
let finalized = false;
|
|
385894
386145
|
let pendingContent;
|
|
385895
386146
|
let throttleTimer;
|
|
386147
|
+
let lastContent = "";
|
|
385896
386148
|
function formatText(text) {
|
|
385897
386149
|
return formatMode === "passthrough" ? text : markdownToMrkdwn(text);
|
|
385898
386150
|
}
|
|
@@ -385951,6 +386203,8 @@ function createSlackStreamSender(options) {
|
|
|
385951
386203
|
}
|
|
385952
386204
|
}
|
|
385953
386205
|
async function finalize(text) {
|
|
386206
|
+
if (finalized)
|
|
386207
|
+
return;
|
|
385954
386208
|
finalized = true;
|
|
385955
386209
|
if (throttleTimer) {
|
|
385956
386210
|
clearTimeout(throttleTimer);
|
|
@@ -385976,31 +386230,60 @@ function createSlackStreamSender(options) {
|
|
|
385976
386230
|
await sendInitial(chunk);
|
|
385977
386231
|
}
|
|
385978
386232
|
}
|
|
386233
|
+
async function deleteDraft() {
|
|
386234
|
+
if (draftTs && !finalized) {
|
|
386235
|
+
try {
|
|
386236
|
+
await client.chat.delete({ channel: channelId, ts: draftTs });
|
|
386237
|
+
} catch {}
|
|
386238
|
+
}
|
|
386239
|
+
finalized = true;
|
|
386240
|
+
}
|
|
386241
|
+
async function cancelKeepingPartial() {
|
|
386242
|
+
if (finalized)
|
|
386243
|
+
return;
|
|
386244
|
+
if (lastContent.trim()) {
|
|
386245
|
+
await finalize(lastContent);
|
|
386246
|
+
return;
|
|
386247
|
+
}
|
|
386248
|
+
await deleteDraft();
|
|
386249
|
+
}
|
|
385979
386250
|
if (streamMode === "off") {
|
|
385980
386251
|
return {
|
|
385981
386252
|
async onThinkingDelta(_delta) {},
|
|
385982
386253
|
async onContentDelta(_delta) {},
|
|
385983
386254
|
async onFinal(delta) {
|
|
385984
|
-
|
|
386255
|
+
if (finalized)
|
|
386256
|
+
return;
|
|
385985
386257
|
finalized = true;
|
|
386258
|
+
await sendInitial(delta.content);
|
|
385986
386259
|
},
|
|
385987
386260
|
async onError(delta) {
|
|
385988
|
-
|
|
386261
|
+
if (finalized)
|
|
386262
|
+
return;
|
|
385989
386263
|
finalized = true;
|
|
386264
|
+
await sendInitial(`Error: ${delta.error}`);
|
|
385990
386265
|
},
|
|
385991
386266
|
async abort() {
|
|
385992
386267
|
finalized = true;
|
|
386268
|
+
},
|
|
386269
|
+
async cancel() {
|
|
386270
|
+
finalized = true;
|
|
385993
386271
|
}
|
|
385994
386272
|
};
|
|
385995
386273
|
}
|
|
385996
386274
|
if (streamMode === "status_final") {
|
|
385997
386275
|
return {
|
|
385998
386276
|
async onThinkingDelta(_delta) {
|
|
386277
|
+
if (finalized)
|
|
386278
|
+
return;
|
|
385999
386279
|
if (!draftTs) {
|
|
386000
386280
|
await sendInitial("_Thinking..._");
|
|
386001
386281
|
}
|
|
386002
386282
|
},
|
|
386003
|
-
async onContentDelta(
|
|
386283
|
+
async onContentDelta(delta) {
|
|
386284
|
+
if (finalized)
|
|
386285
|
+
return;
|
|
386286
|
+
lastContent = delta.content;
|
|
386004
386287
|
if (!draftTs) {
|
|
386005
386288
|
await sendInitial("_Thinking..._");
|
|
386006
386289
|
}
|
|
@@ -386012,17 +386295,17 @@ function createSlackStreamSender(options) {
|
|
|
386012
386295
|
await finalize(`Error: ${delta.error}`);
|
|
386013
386296
|
},
|
|
386014
386297
|
async abort() {
|
|
386015
|
-
|
|
386016
|
-
|
|
386017
|
-
|
|
386018
|
-
|
|
386019
|
-
}
|
|
386020
|
-
finalized = true;
|
|
386298
|
+
await deleteDraft();
|
|
386299
|
+
},
|
|
386300
|
+
async cancel() {
|
|
386301
|
+
await cancelKeepingPartial();
|
|
386021
386302
|
}
|
|
386022
386303
|
};
|
|
386023
386304
|
}
|
|
386024
386305
|
return {
|
|
386025
386306
|
async onThinkingDelta(delta) {
|
|
386307
|
+
if (finalized)
|
|
386308
|
+
return;
|
|
386026
386309
|
const text = `_${delta.thinking}_`;
|
|
386027
386310
|
if (!draftTs) {
|
|
386028
386311
|
await sendInitial(text);
|
|
@@ -386031,7 +386314,10 @@ function createSlackStreamSender(options) {
|
|
|
386031
386314
|
}
|
|
386032
386315
|
},
|
|
386033
386316
|
async onContentDelta(delta) {
|
|
386317
|
+
if (finalized)
|
|
386318
|
+
return;
|
|
386034
386319
|
const text = delta.content;
|
|
386320
|
+
lastContent = text;
|
|
386035
386321
|
if (!draftTs) {
|
|
386036
386322
|
await sendInitial(text);
|
|
386037
386323
|
} else {
|
|
@@ -386045,12 +386331,10 @@ function createSlackStreamSender(options) {
|
|
|
386045
386331
|
await finalize(`Error: ${delta.error}`);
|
|
386046
386332
|
},
|
|
386047
386333
|
async abort() {
|
|
386048
|
-
|
|
386049
|
-
|
|
386050
|
-
|
|
386051
|
-
|
|
386052
|
-
}
|
|
386053
|
-
finalized = true;
|
|
386334
|
+
await deleteDraft();
|
|
386335
|
+
},
|
|
386336
|
+
async cancel() {
|
|
386337
|
+
await cancelKeepingPartial();
|
|
386054
386338
|
}
|
|
386055
386339
|
};
|
|
386056
386340
|
}
|
|
@@ -386142,6 +386426,8 @@ function createNativeStreamSender(options) {
|
|
|
386142
386426
|
async onContentDelta(delta) {
|
|
386143
386427
|
if (fallback)
|
|
386144
386428
|
return fallback.onContentDelta(delta);
|
|
386429
|
+
if (stopped)
|
|
386430
|
+
return;
|
|
386145
386431
|
const content = delta.content;
|
|
386146
386432
|
if (!content)
|
|
386147
386433
|
return;
|
|
@@ -386168,6 +386454,11 @@ function createNativeStreamSender(options) {
|
|
|
386168
386454
|
if (fallback)
|
|
386169
386455
|
return fallback.abort();
|
|
386170
386456
|
await stopStream();
|
|
386457
|
+
},
|
|
386458
|
+
async cancel() {
|
|
386459
|
+
if (fallback)
|
|
386460
|
+
return fallback.cancel ? fallback.cancel() : fallback.abort();
|
|
386461
|
+
await stopStream();
|
|
386171
386462
|
}
|
|
386172
386463
|
};
|
|
386173
386464
|
}
|
|
@@ -386561,6 +386852,10 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386561
386852
|
async abort() {
|
|
386562
386853
|
await base2.abort();
|
|
386563
386854
|
cleanup();
|
|
386855
|
+
},
|
|
386856
|
+
async cancel() {
|
|
386857
|
+
await (base2.cancel ? base2.cancel() : base2.abort());
|
|
386858
|
+
cleanup();
|
|
386564
386859
|
}
|
|
386565
386860
|
};
|
|
386566
386861
|
}
|
|
@@ -386568,29 +386863,43 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386568
386863
|
await this.sendPresenceStatus(instanceId, chatId, duration === 0 ? "paused" : "typing", duration);
|
|
386569
386864
|
}
|
|
386570
386865
|
async sendPresenceStatus(instanceId, chatId, type, duration, options) {
|
|
386571
|
-
const
|
|
386866
|
+
const nominalMethod = "agents.sessions.setStatus";
|
|
386572
386867
|
const connection = this.connections.get(instanceId);
|
|
386573
386868
|
if (!connection)
|
|
386574
|
-
return { delivered: false, method, reason: "not_connected" };
|
|
386869
|
+
return { delivered: false, method: nominalMethod, reason: "not_connected" };
|
|
386575
386870
|
const threadTs = options?.threadId ?? this.activeThreads.get(`${instanceId}:${chatId}`);
|
|
386576
|
-
if (!threadTs)
|
|
386577
|
-
|
|
386871
|
+
if (!threadTs) {
|
|
386872
|
+
this.logger.debug("Slack presence status skipped", {
|
|
386873
|
+
instanceId,
|
|
386874
|
+
chatId,
|
|
386875
|
+
type,
|
|
386876
|
+
reason: "no_active_thread"
|
|
386877
|
+
});
|
|
386878
|
+
return { delivered: false, method: nominalMethod, reason: "no_active_thread" };
|
|
386879
|
+
}
|
|
386578
386880
|
const shouldClear = type === "paused";
|
|
386579
386881
|
const status = shouldClear ? "" : options?.status ?? (type === "recording" ? "is recording..." : "is typing...");
|
|
386580
386882
|
const timerKey = this.presenceStatusTimerKey(instanceId, chatId, threadTs);
|
|
386581
|
-
const
|
|
386883
|
+
const statusResult = status === "" ? await clearTypingStatus({
|
|
386582
386884
|
client: connection.actingClient,
|
|
386583
386885
|
channelId: chatId,
|
|
386584
386886
|
threadTs,
|
|
386585
|
-
logger: this.logger
|
|
386887
|
+
logger: this.logger,
|
|
386888
|
+
instanceId
|
|
386586
386889
|
}) : await setSlackThreadStatus({
|
|
386587
386890
|
client: connection.actingClient,
|
|
386588
386891
|
channelId: chatId,
|
|
386589
386892
|
threadTs,
|
|
386590
386893
|
status,
|
|
386591
386894
|
loadingMessages: options?.loadingMessages,
|
|
386592
|
-
logger: this.logger
|
|
386895
|
+
logger: this.logger,
|
|
386896
|
+
instanceId
|
|
386593
386897
|
});
|
|
386898
|
+
const { delivered, method } = statusResult;
|
|
386899
|
+
const usedLegacy = method === "assistant.threads.setStatus";
|
|
386900
|
+
const sessionStatus = shouldClear ? "active" : "processing";
|
|
386901
|
+
const appliedStatus = !delivered || usedLegacy ? status : sessionStatus;
|
|
386902
|
+
const appliedLoadingMessages = !delivered || usedLegacy ? options?.loadingMessages : undefined;
|
|
386594
386903
|
if (delivered) {
|
|
386595
386904
|
this.clearPresenceStatusTimer(timerKey);
|
|
386596
386905
|
}
|
|
@@ -386616,12 +386925,18 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386616
386925
|
this.presenceStatusTimers.set(timerKey, timer);
|
|
386617
386926
|
timer.unref?.();
|
|
386618
386927
|
}
|
|
386619
|
-
return delivered ? {
|
|
386620
|
-
delivered:
|
|
386928
|
+
return delivered ? {
|
|
386929
|
+
delivered: true,
|
|
386621
386930
|
method,
|
|
386622
386931
|
threadId: threadTs,
|
|
386623
|
-
status,
|
|
386624
|
-
loadingMessages:
|
|
386932
|
+
status: appliedStatus,
|
|
386933
|
+
loadingMessages: appliedLoadingMessages
|
|
386934
|
+
} : {
|
|
386935
|
+
delivered: false,
|
|
386936
|
+
method: method ?? nominalMethod,
|
|
386937
|
+
threadId: threadTs,
|
|
386938
|
+
status: appliedStatus,
|
|
386939
|
+
loadingMessages: appliedLoadingMessages,
|
|
386625
386940
|
reason: "slack_status_failed"
|
|
386626
386941
|
};
|
|
386627
386942
|
}
|
|
@@ -386942,6 +387257,37 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386942
387257
|
break;
|
|
386943
387258
|
}
|
|
386944
387259
|
}
|
|
387260
|
+
async handleAgentSessionStopped(instanceId, connection, args) {
|
|
387261
|
+
const parsedEventTs = args.eventTs ? Number.parseFloat(args.eventTs) : Number.NaN;
|
|
387262
|
+
const requestedAt = Number.isFinite(parsedEventTs) ? Math.round(parsedEventTs * 1000) : Date.now();
|
|
387263
|
+
try {
|
|
387264
|
+
await this.eventBus.publish("agent.run.cancel_requested", {
|
|
387265
|
+
instanceId,
|
|
387266
|
+
chatId: args.channelId,
|
|
387267
|
+
threadId: args.threadTs,
|
|
387268
|
+
requestedBy: args.userId,
|
|
387269
|
+
requestedAt,
|
|
387270
|
+
reason: "user_stop"
|
|
387271
|
+
}, {
|
|
387272
|
+
instanceId,
|
|
387273
|
+
channelType: this.id,
|
|
387274
|
+
source: `channel:${this.id}`
|
|
387275
|
+
});
|
|
387276
|
+
} catch (err2) {
|
|
387277
|
+
this.logger.error("Failed to publish agent.run.cancel_requested", {
|
|
387278
|
+
instanceId,
|
|
387279
|
+
chatId: args.channelId,
|
|
387280
|
+
error: String(err2)
|
|
387281
|
+
});
|
|
387282
|
+
}
|
|
387283
|
+
await clearTypingStatus({
|
|
387284
|
+
client: connection.actingClient,
|
|
387285
|
+
channelId: args.channelId,
|
|
387286
|
+
threadTs: args.threadTs ?? this.activeThreads.get(`${instanceId}:${args.channelId}`),
|
|
387287
|
+
logger: this.logger,
|
|
387288
|
+
instanceId
|
|
387289
|
+
});
|
|
387290
|
+
}
|
|
386945
387291
|
trackActiveThread(instanceId, channelId, threadTs) {
|
|
386946
387292
|
this.activeThreads.set(`${instanceId}:${channelId}`, threadTs);
|
|
386947
387293
|
}
|
|
@@ -387059,6 +387405,11 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
387059
387405
|
await this.handleReactionReceived(instId, messageId, chatId, userId, emoji, action);
|
|
387060
387406
|
}
|
|
387061
387407
|
}, this.logger);
|
|
387408
|
+
setupAgentSessionHandlers(connection.app, instanceId, {
|
|
387409
|
+
onSessionStopped: async (instId, args) => {
|
|
387410
|
+
await this.handleAgentSessionStopped(instId, connection, args);
|
|
387411
|
+
}
|
|
387412
|
+
}, this.logger);
|
|
387062
387413
|
setupInteractionHandlers2(connection.app, instanceId, {
|
|
387063
387414
|
onInteraction: async (_instId, payload) => {
|
|
387064
387415
|
await this.handleInteraction(payload);
|