@automagik/omni 2.260901.1 → 2.260901.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -1
- package/dist/server/index.js +396 -67
- 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.2",
|
|
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.2",
|
|
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;
|
|
@@ -385208,6 +385376,23 @@ async function checkBoltHealth(connection) {
|
|
|
385208
385376
|
}
|
|
385209
385377
|
}
|
|
385210
385378
|
|
|
385379
|
+
// ../channel-slack/src/handlers/agent-sessions.ts
|
|
385380
|
+
function setupAgentSessionHandlers(app, instanceId, callbacks, logger5) {
|
|
385381
|
+
app.event("agent_session_stopped", async ({ event }) => {
|
|
385382
|
+
const evt = event;
|
|
385383
|
+
const channelId = evt.channel;
|
|
385384
|
+
if (!channelId)
|
|
385385
|
+
return;
|
|
385386
|
+
const threadTs = evt.thread_ts;
|
|
385387
|
+
const userId = evt.user;
|
|
385388
|
+
const eventTs = evt.event_ts;
|
|
385389
|
+
const streamingMessageTs = Array.isArray(evt.streaming_message_ts) ? evt.streaming_message_ts : [];
|
|
385390
|
+
logger5.info("Agent session stopped by user", { instanceId, channelId, threadTs, userId, streamingMessageTs });
|
|
385391
|
+
await callbacks.onSessionStopped(instanceId, { channelId, threadTs, userId, streamingMessageTs, eventTs });
|
|
385392
|
+
});
|
|
385393
|
+
logger5.info("Agent session handlers registered", { instanceId });
|
|
385394
|
+
}
|
|
385395
|
+
|
|
385211
385396
|
// ../channel-slack/src/handlers/commands.ts
|
|
385212
385397
|
function setupCommandHandlers(app, instanceId, commandNames, callbacks, logger5) {
|
|
385213
385398
|
for (const commandName of commandNames) {
|
|
@@ -385687,10 +385872,62 @@ function setupReactionHandlers2(app, instanceId, botUserId, callbacks, logger5)
|
|
|
385687
385872
|
|
|
385688
385873
|
// ../channel-slack/src/handlers/typing.ts
|
|
385689
385874
|
var CLEAR_STATUS = "";
|
|
385875
|
+
var AGENT_API_UNAVAILABLE_ERRORS = new Set([
|
|
385876
|
+
"unknown_method",
|
|
385877
|
+
"feature_disabled",
|
|
385878
|
+
"method_deprecated",
|
|
385879
|
+
"missing_scope",
|
|
385880
|
+
"not_allowed_token_type"
|
|
385881
|
+
]);
|
|
385882
|
+
var agentApiUnavailable = new WeakSet;
|
|
385883
|
+
function slackErrorCode(err2) {
|
|
385884
|
+
return err2?.data?.error;
|
|
385885
|
+
}
|
|
385690
385886
|
async function setSlackThreadStatus(params) {
|
|
385691
385887
|
const { client, channelId, threadTs, status, loadingMessages, logger: logger5, instanceId } = params;
|
|
385692
|
-
if (!threadTs)
|
|
385693
|
-
|
|
385888
|
+
if (!threadTs) {
|
|
385889
|
+
logger5.debug("setSlackThreadStatus: skipped, no thread timestamp", {
|
|
385890
|
+
instanceId,
|
|
385891
|
+
channelId,
|
|
385892
|
+
reason: "no_thread_ts",
|
|
385893
|
+
clearing: status.length === 0
|
|
385894
|
+
});
|
|
385895
|
+
return { delivered: false };
|
|
385896
|
+
}
|
|
385897
|
+
const clearing = status.length === 0;
|
|
385898
|
+
const logContext = {
|
|
385899
|
+
instanceId,
|
|
385900
|
+
channelId,
|
|
385901
|
+
threadTs,
|
|
385902
|
+
clearing,
|
|
385903
|
+
statusLength: status.length,
|
|
385904
|
+
loadingMessageCount: loadingMessages?.length ?? 0
|
|
385905
|
+
};
|
|
385906
|
+
if (typeof client.apiCall === "function" && !agentApiUnavailable.has(client)) {
|
|
385907
|
+
try {
|
|
385908
|
+
await client.apiCall("agents.sessions.setStatus", {
|
|
385909
|
+
channel_id: channelId,
|
|
385910
|
+
thread_ts: threadTs,
|
|
385911
|
+
status: clearing ? "active" : "processing"
|
|
385912
|
+
});
|
|
385913
|
+
return { delivered: true, method: "agents.sessions.setStatus" };
|
|
385914
|
+
} catch (err2) {
|
|
385915
|
+
const code = slackErrorCode(err2);
|
|
385916
|
+
if (code && AGENT_API_UNAVAILABLE_ERRORS.has(code)) {
|
|
385917
|
+
agentApiUnavailable.add(client);
|
|
385918
|
+
logger5.info("agents.sessions.setStatus unavailable, falling back to assistant.threads.setStatus", {
|
|
385919
|
+
instanceId,
|
|
385920
|
+
channelId,
|
|
385921
|
+
error: code
|
|
385922
|
+
});
|
|
385923
|
+
} else {
|
|
385924
|
+
logger5.warn("agents.sessions.setStatus failed, trying legacy fallback", {
|
|
385925
|
+
...logContext,
|
|
385926
|
+
error: String(err2)
|
|
385927
|
+
});
|
|
385928
|
+
}
|
|
385929
|
+
}
|
|
385930
|
+
}
|
|
385694
385931
|
const payload = {
|
|
385695
385932
|
channel_id: channelId,
|
|
385696
385933
|
thread_ts: threadTs,
|
|
@@ -385698,27 +385935,19 @@ async function setSlackThreadStatus(params) {
|
|
|
385698
385935
|
...loadingMessages?.length ? { loading_messages: loadingMessages } : {}
|
|
385699
385936
|
};
|
|
385700
385937
|
try {
|
|
385701
|
-
const
|
|
385702
|
-
if (typeof
|
|
385703
|
-
await
|
|
385704
|
-
return true;
|
|
385938
|
+
const legacyClient = client;
|
|
385939
|
+
if (typeof legacyClient.assistant?.threads?.setStatus === "function") {
|
|
385940
|
+
await legacyClient.assistant.threads.setStatus(payload);
|
|
385941
|
+
return { delivered: true, method: "assistant.threads.setStatus" };
|
|
385705
385942
|
}
|
|
385706
|
-
if (typeof
|
|
385707
|
-
await
|
|
385708
|
-
return true;
|
|
385943
|
+
if (typeof legacyClient.apiCall === "function") {
|
|
385944
|
+
await legacyClient.apiCall("assistant.threads.setStatus", payload);
|
|
385945
|
+
return { delivered: true, method: "assistant.threads.setStatus" };
|
|
385709
385946
|
}
|
|
385710
385947
|
} 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
|
-
});
|
|
385948
|
+
logger5.warn("setSlackThreadStatus: failed", { ...logContext, error: String(err2) });
|
|
385720
385949
|
}
|
|
385721
|
-
return false;
|
|
385950
|
+
return { delivered: false, method: "assistant.threads.setStatus" };
|
|
385722
385951
|
}
|
|
385723
385952
|
async function clearTypingStatus(params) {
|
|
385724
385953
|
return setSlackThreadStatus({ ...params, status: CLEAR_STATUS });
|
|
@@ -385893,6 +386122,7 @@ function createSlackStreamSender(options) {
|
|
|
385893
386122
|
let finalized = false;
|
|
385894
386123
|
let pendingContent;
|
|
385895
386124
|
let throttleTimer;
|
|
386125
|
+
let lastContent = "";
|
|
385896
386126
|
function formatText(text) {
|
|
385897
386127
|
return formatMode === "passthrough" ? text : markdownToMrkdwn(text);
|
|
385898
386128
|
}
|
|
@@ -385951,6 +386181,8 @@ function createSlackStreamSender(options) {
|
|
|
385951
386181
|
}
|
|
385952
386182
|
}
|
|
385953
386183
|
async function finalize(text) {
|
|
386184
|
+
if (finalized)
|
|
386185
|
+
return;
|
|
385954
386186
|
finalized = true;
|
|
385955
386187
|
if (throttleTimer) {
|
|
385956
386188
|
clearTimeout(throttleTimer);
|
|
@@ -385976,31 +386208,60 @@ function createSlackStreamSender(options) {
|
|
|
385976
386208
|
await sendInitial(chunk);
|
|
385977
386209
|
}
|
|
385978
386210
|
}
|
|
386211
|
+
async function deleteDraft() {
|
|
386212
|
+
if (draftTs && !finalized) {
|
|
386213
|
+
try {
|
|
386214
|
+
await client.chat.delete({ channel: channelId, ts: draftTs });
|
|
386215
|
+
} catch {}
|
|
386216
|
+
}
|
|
386217
|
+
finalized = true;
|
|
386218
|
+
}
|
|
386219
|
+
async function cancelKeepingPartial() {
|
|
386220
|
+
if (finalized)
|
|
386221
|
+
return;
|
|
386222
|
+
if (lastContent.trim()) {
|
|
386223
|
+
await finalize(lastContent);
|
|
386224
|
+
return;
|
|
386225
|
+
}
|
|
386226
|
+
await deleteDraft();
|
|
386227
|
+
}
|
|
385979
386228
|
if (streamMode === "off") {
|
|
385980
386229
|
return {
|
|
385981
386230
|
async onThinkingDelta(_delta) {},
|
|
385982
386231
|
async onContentDelta(_delta) {},
|
|
385983
386232
|
async onFinal(delta) {
|
|
385984
|
-
|
|
386233
|
+
if (finalized)
|
|
386234
|
+
return;
|
|
385985
386235
|
finalized = true;
|
|
386236
|
+
await sendInitial(delta.content);
|
|
385986
386237
|
},
|
|
385987
386238
|
async onError(delta) {
|
|
385988
|
-
|
|
386239
|
+
if (finalized)
|
|
386240
|
+
return;
|
|
385989
386241
|
finalized = true;
|
|
386242
|
+
await sendInitial(`Error: ${delta.error}`);
|
|
385990
386243
|
},
|
|
385991
386244
|
async abort() {
|
|
385992
386245
|
finalized = true;
|
|
386246
|
+
},
|
|
386247
|
+
async cancel() {
|
|
386248
|
+
finalized = true;
|
|
385993
386249
|
}
|
|
385994
386250
|
};
|
|
385995
386251
|
}
|
|
385996
386252
|
if (streamMode === "status_final") {
|
|
385997
386253
|
return {
|
|
385998
386254
|
async onThinkingDelta(_delta) {
|
|
386255
|
+
if (finalized)
|
|
386256
|
+
return;
|
|
385999
386257
|
if (!draftTs) {
|
|
386000
386258
|
await sendInitial("_Thinking..._");
|
|
386001
386259
|
}
|
|
386002
386260
|
},
|
|
386003
|
-
async onContentDelta(
|
|
386261
|
+
async onContentDelta(delta) {
|
|
386262
|
+
if (finalized)
|
|
386263
|
+
return;
|
|
386264
|
+
lastContent = delta.content;
|
|
386004
386265
|
if (!draftTs) {
|
|
386005
386266
|
await sendInitial("_Thinking..._");
|
|
386006
386267
|
}
|
|
@@ -386012,17 +386273,17 @@ function createSlackStreamSender(options) {
|
|
|
386012
386273
|
await finalize(`Error: ${delta.error}`);
|
|
386013
386274
|
},
|
|
386014
386275
|
async abort() {
|
|
386015
|
-
|
|
386016
|
-
|
|
386017
|
-
|
|
386018
|
-
|
|
386019
|
-
}
|
|
386020
|
-
finalized = true;
|
|
386276
|
+
await deleteDraft();
|
|
386277
|
+
},
|
|
386278
|
+
async cancel() {
|
|
386279
|
+
await cancelKeepingPartial();
|
|
386021
386280
|
}
|
|
386022
386281
|
};
|
|
386023
386282
|
}
|
|
386024
386283
|
return {
|
|
386025
386284
|
async onThinkingDelta(delta) {
|
|
386285
|
+
if (finalized)
|
|
386286
|
+
return;
|
|
386026
386287
|
const text = `_${delta.thinking}_`;
|
|
386027
386288
|
if (!draftTs) {
|
|
386028
386289
|
await sendInitial(text);
|
|
@@ -386031,7 +386292,10 @@ function createSlackStreamSender(options) {
|
|
|
386031
386292
|
}
|
|
386032
386293
|
},
|
|
386033
386294
|
async onContentDelta(delta) {
|
|
386295
|
+
if (finalized)
|
|
386296
|
+
return;
|
|
386034
386297
|
const text = delta.content;
|
|
386298
|
+
lastContent = text;
|
|
386035
386299
|
if (!draftTs) {
|
|
386036
386300
|
await sendInitial(text);
|
|
386037
386301
|
} else {
|
|
@@ -386045,12 +386309,10 @@ function createSlackStreamSender(options) {
|
|
|
386045
386309
|
await finalize(`Error: ${delta.error}`);
|
|
386046
386310
|
},
|
|
386047
386311
|
async abort() {
|
|
386048
|
-
|
|
386049
|
-
|
|
386050
|
-
|
|
386051
|
-
|
|
386052
|
-
}
|
|
386053
|
-
finalized = true;
|
|
386312
|
+
await deleteDraft();
|
|
386313
|
+
},
|
|
386314
|
+
async cancel() {
|
|
386315
|
+
await cancelKeepingPartial();
|
|
386054
386316
|
}
|
|
386055
386317
|
};
|
|
386056
386318
|
}
|
|
@@ -386142,6 +386404,8 @@ function createNativeStreamSender(options) {
|
|
|
386142
386404
|
async onContentDelta(delta) {
|
|
386143
386405
|
if (fallback)
|
|
386144
386406
|
return fallback.onContentDelta(delta);
|
|
386407
|
+
if (stopped)
|
|
386408
|
+
return;
|
|
386145
386409
|
const content = delta.content;
|
|
386146
386410
|
if (!content)
|
|
386147
386411
|
return;
|
|
@@ -386168,6 +386432,11 @@ function createNativeStreamSender(options) {
|
|
|
386168
386432
|
if (fallback)
|
|
386169
386433
|
return fallback.abort();
|
|
386170
386434
|
await stopStream();
|
|
386435
|
+
},
|
|
386436
|
+
async cancel() {
|
|
386437
|
+
if (fallback)
|
|
386438
|
+
return fallback.cancel ? fallback.cancel() : fallback.abort();
|
|
386439
|
+
await stopStream();
|
|
386171
386440
|
}
|
|
386172
386441
|
};
|
|
386173
386442
|
}
|
|
@@ -386561,6 +386830,10 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386561
386830
|
async abort() {
|
|
386562
386831
|
await base2.abort();
|
|
386563
386832
|
cleanup();
|
|
386833
|
+
},
|
|
386834
|
+
async cancel() {
|
|
386835
|
+
await (base2.cancel ? base2.cancel() : base2.abort());
|
|
386836
|
+
cleanup();
|
|
386564
386837
|
}
|
|
386565
386838
|
};
|
|
386566
386839
|
}
|
|
@@ -386568,29 +386841,43 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386568
386841
|
await this.sendPresenceStatus(instanceId, chatId, duration === 0 ? "paused" : "typing", duration);
|
|
386569
386842
|
}
|
|
386570
386843
|
async sendPresenceStatus(instanceId, chatId, type, duration, options) {
|
|
386571
|
-
const
|
|
386844
|
+
const nominalMethod = "agents.sessions.setStatus";
|
|
386572
386845
|
const connection = this.connections.get(instanceId);
|
|
386573
386846
|
if (!connection)
|
|
386574
|
-
return { delivered: false, method, reason: "not_connected" };
|
|
386847
|
+
return { delivered: false, method: nominalMethod, reason: "not_connected" };
|
|
386575
386848
|
const threadTs = options?.threadId ?? this.activeThreads.get(`${instanceId}:${chatId}`);
|
|
386576
|
-
if (!threadTs)
|
|
386577
|
-
|
|
386849
|
+
if (!threadTs) {
|
|
386850
|
+
this.logger.debug("Slack presence status skipped", {
|
|
386851
|
+
instanceId,
|
|
386852
|
+
chatId,
|
|
386853
|
+
type,
|
|
386854
|
+
reason: "no_active_thread"
|
|
386855
|
+
});
|
|
386856
|
+
return { delivered: false, method: nominalMethod, reason: "no_active_thread" };
|
|
386857
|
+
}
|
|
386578
386858
|
const shouldClear = type === "paused";
|
|
386579
386859
|
const status = shouldClear ? "" : options?.status ?? (type === "recording" ? "is recording..." : "is typing...");
|
|
386580
386860
|
const timerKey = this.presenceStatusTimerKey(instanceId, chatId, threadTs);
|
|
386581
|
-
const
|
|
386861
|
+
const statusResult = status === "" ? await clearTypingStatus({
|
|
386582
386862
|
client: connection.actingClient,
|
|
386583
386863
|
channelId: chatId,
|
|
386584
386864
|
threadTs,
|
|
386585
|
-
logger: this.logger
|
|
386865
|
+
logger: this.logger,
|
|
386866
|
+
instanceId
|
|
386586
386867
|
}) : await setSlackThreadStatus({
|
|
386587
386868
|
client: connection.actingClient,
|
|
386588
386869
|
channelId: chatId,
|
|
386589
386870
|
threadTs,
|
|
386590
386871
|
status,
|
|
386591
386872
|
loadingMessages: options?.loadingMessages,
|
|
386592
|
-
logger: this.logger
|
|
386873
|
+
logger: this.logger,
|
|
386874
|
+
instanceId
|
|
386593
386875
|
});
|
|
386876
|
+
const { delivered, method } = statusResult;
|
|
386877
|
+
const usedLegacy = method === "assistant.threads.setStatus";
|
|
386878
|
+
const sessionStatus = shouldClear ? "active" : "processing";
|
|
386879
|
+
const appliedStatus = !delivered || usedLegacy ? status : sessionStatus;
|
|
386880
|
+
const appliedLoadingMessages = !delivered || usedLegacy ? options?.loadingMessages : undefined;
|
|
386594
386881
|
if (delivered) {
|
|
386595
386882
|
this.clearPresenceStatusTimer(timerKey);
|
|
386596
386883
|
}
|
|
@@ -386616,12 +386903,18 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386616
386903
|
this.presenceStatusTimers.set(timerKey, timer);
|
|
386617
386904
|
timer.unref?.();
|
|
386618
386905
|
}
|
|
386619
|
-
return delivered ? {
|
|
386620
|
-
delivered:
|
|
386906
|
+
return delivered ? {
|
|
386907
|
+
delivered: true,
|
|
386621
386908
|
method,
|
|
386622
386909
|
threadId: threadTs,
|
|
386623
|
-
status,
|
|
386624
|
-
loadingMessages:
|
|
386910
|
+
status: appliedStatus,
|
|
386911
|
+
loadingMessages: appliedLoadingMessages
|
|
386912
|
+
} : {
|
|
386913
|
+
delivered: false,
|
|
386914
|
+
method: method ?? nominalMethod,
|
|
386915
|
+
threadId: threadTs,
|
|
386916
|
+
status: appliedStatus,
|
|
386917
|
+
loadingMessages: appliedLoadingMessages,
|
|
386625
386918
|
reason: "slack_status_failed"
|
|
386626
386919
|
};
|
|
386627
386920
|
}
|
|
@@ -386942,6 +387235,37 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
386942
387235
|
break;
|
|
386943
387236
|
}
|
|
386944
387237
|
}
|
|
387238
|
+
async handleAgentSessionStopped(instanceId, connection, args) {
|
|
387239
|
+
const parsedEventTs = args.eventTs ? Number.parseFloat(args.eventTs) : Number.NaN;
|
|
387240
|
+
const requestedAt = Number.isFinite(parsedEventTs) ? Math.round(parsedEventTs * 1000) : Date.now();
|
|
387241
|
+
try {
|
|
387242
|
+
await this.eventBus.publish("agent.run.cancel_requested", {
|
|
387243
|
+
instanceId,
|
|
387244
|
+
chatId: args.channelId,
|
|
387245
|
+
threadId: args.threadTs,
|
|
387246
|
+
requestedBy: args.userId,
|
|
387247
|
+
requestedAt,
|
|
387248
|
+
reason: "user_stop"
|
|
387249
|
+
}, {
|
|
387250
|
+
instanceId,
|
|
387251
|
+
channelType: this.id,
|
|
387252
|
+
source: `channel:${this.id}`
|
|
387253
|
+
});
|
|
387254
|
+
} catch (err2) {
|
|
387255
|
+
this.logger.error("Failed to publish agent.run.cancel_requested", {
|
|
387256
|
+
instanceId,
|
|
387257
|
+
chatId: args.channelId,
|
|
387258
|
+
error: String(err2)
|
|
387259
|
+
});
|
|
387260
|
+
}
|
|
387261
|
+
await clearTypingStatus({
|
|
387262
|
+
client: connection.actingClient,
|
|
387263
|
+
channelId: args.channelId,
|
|
387264
|
+
threadTs: args.threadTs ?? this.activeThreads.get(`${instanceId}:${args.channelId}`),
|
|
387265
|
+
logger: this.logger,
|
|
387266
|
+
instanceId
|
|
387267
|
+
});
|
|
387268
|
+
}
|
|
386945
387269
|
trackActiveThread(instanceId, channelId, threadTs) {
|
|
386946
387270
|
this.activeThreads.set(`${instanceId}:${channelId}`, threadTs);
|
|
386947
387271
|
}
|
|
@@ -387059,6 +387383,11 @@ class SlackPlugin extends BaseChannelPlugin {
|
|
|
387059
387383
|
await this.handleReactionReceived(instId, messageId, chatId, userId, emoji, action);
|
|
387060
387384
|
}
|
|
387061
387385
|
}, this.logger);
|
|
387386
|
+
setupAgentSessionHandlers(connection.app, instanceId, {
|
|
387387
|
+
onSessionStopped: async (instId, args) => {
|
|
387388
|
+
await this.handleAgentSessionStopped(instId, connection, args);
|
|
387389
|
+
}
|
|
387390
|
+
}, this.logger);
|
|
387062
387391
|
setupInteractionHandlers2(connection.app, instanceId, {
|
|
387063
387392
|
onInteraction: async (_instId, payload) => {
|
|
387064
387393
|
await this.handleInteraction(payload);
|