@songsid/agend 2.1.4-beta.31 → 2.1.4-beta.33
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/backend/kiro.d.ts +1 -0
- package/dist/backend/kiro.js +7 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +8 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +15 -7
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +6 -0
- package/dist/channel/adapters/telegram.js +10 -0
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +2 -1
- package/dist/channel/ipc-bridge.js +33 -4
- package/dist/channel/ipc-bridge.js.map +1 -1
- package/dist/channel/mcp-server.js +11 -2
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/types.d.ts +2 -0
- package/dist/daemon.d.ts +14 -0
- package/dist/daemon.js +138 -52
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.js +44 -10
- package/dist/fleet-manager.js.map +1 -1
- package/dist/locale.js +2 -0
- package/dist/locale.js.map +1 -1
- package/dist/reply-dedup.d.ts +7 -8
- package/dist/reply-dedup.js +0 -0
- package/dist/reply-dedup.js.map +1 -1
- package/dist/topic-commands.js +5 -1
- package/dist/topic-commands.js.map +1 -1
- package/package.json +2 -2
package/dist/fleet-manager.js
CHANGED
|
@@ -3932,8 +3932,6 @@ export class FleetManager {
|
|
|
3932
3932
|
}
|
|
3933
3933
|
/** Handle outbound tool calls from a daemon instance */
|
|
3934
3934
|
async handleOutboundFromInstance(instanceName, msg) {
|
|
3935
|
-
if (this.worlds.size === 0)
|
|
3936
|
-
return;
|
|
3937
3935
|
this.touchActivity(instanceName);
|
|
3938
3936
|
this.setTopicIcon(instanceName, "green");
|
|
3939
3937
|
const tool = msg.tool;
|
|
@@ -3943,13 +3941,21 @@ export class FleetManager {
|
|
|
3943
3941
|
const senderSessionName = msg.senderSessionName;
|
|
3944
3942
|
const respond = (result, error) => {
|
|
3945
3943
|
const ipc = this.instanceIpcClients.get(instanceName);
|
|
3944
|
+
let sent = false;
|
|
3946
3945
|
if (fleetRequestId) {
|
|
3947
|
-
ipc?.send({ type: "fleet_outbound_response", fleetRequestId, result, error });
|
|
3946
|
+
sent = ipc?.send({ type: "fleet_outbound_response", fleetRequestId, result, error }) ?? false;
|
|
3948
3947
|
}
|
|
3949
3948
|
else {
|
|
3950
|
-
ipc?.send({ type: "fleet_outbound_response", requestId, result, error });
|
|
3949
|
+
sent = ipc?.send({ type: "fleet_outbound_response", requestId, result, error }) ?? false;
|
|
3950
|
+
}
|
|
3951
|
+
if (!sent) {
|
|
3952
|
+
this.logger.warn({ instanceName, tool, requestId, fleetRequestId, error }, "Fleet outbound result could not be returned — instance IPC is disconnected");
|
|
3951
3953
|
}
|
|
3952
3954
|
};
|
|
3955
|
+
if (this.worlds.size === 0) {
|
|
3956
|
+
respond(null, "Channel adapters are not ready — retry shortly");
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3953
3959
|
// Resolve threadId: use sender's topic_id if sender is a known fleet instance,
|
|
3954
3960
|
// fall back to general topic if sender is unknown, or IPC owner if no sender.
|
|
3955
3961
|
const senderInstanceName = senderSessionName && this.fleetConfig?.instances[senderSessionName]
|
|
@@ -3994,17 +4000,30 @@ export class FleetManager {
|
|
|
3994
4000
|
if (tool === "reply") {
|
|
3995
4001
|
const ticket = this.replyDeduper.begin(instanceName, String(args.text ?? ""), Array.isArray(args.files) ? args.files : []);
|
|
3996
4002
|
if (ticket.duplicate) {
|
|
3997
|
-
this.logger.info({ instanceName }, "
|
|
4003
|
+
this.logger.info({ instanceName }, "Concurrent duplicate reply joined — awaiting the original send's outcome");
|
|
3998
4004
|
ticket.subscribe(respond);
|
|
3999
4005
|
return;
|
|
4000
4006
|
}
|
|
4001
4007
|
const original = respond;
|
|
4002
4008
|
const respondAndRecord = (result, error) => {
|
|
4003
4009
|
ticket.complete(result, error);
|
|
4010
|
+
// Return the platform outcome first. Bookkeeping below must never turn
|
|
4011
|
+
// a confirmed Discord/Telegram POST into a tool error if a secondary
|
|
4012
|
+
// log/button side effect happens to throw.
|
|
4004
4013
|
original(result, error);
|
|
4014
|
+
// The adapter resolves only after the platform POST returns. Keep
|
|
4015
|
+
// outward-facing logs/cancel state on the same confirmation boundary:
|
|
4016
|
+
// a routed-but-failed reply is not a delivered reply.
|
|
4017
|
+
if (!error && result != null) {
|
|
4018
|
+
try {
|
|
4019
|
+
this.afterReplyRouted(instanceName, args, senderSessionName);
|
|
4020
|
+
}
|
|
4021
|
+
catch (err) {
|
|
4022
|
+
this.logger.warn({ err, instanceName }, "Reply delivered but post-delivery bookkeeping failed");
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4005
4025
|
};
|
|
4006
4026
|
if (routeToolCall(outAdapter, tool, args, threadId, respondAndRecord)) {
|
|
4007
|
-
this.afterReplyRouted(instanceName, args, senderSessionName);
|
|
4008
4027
|
return;
|
|
4009
4028
|
}
|
|
4010
4029
|
// routeToolCall knows "reply"; not handling it means the world changed.
|
|
@@ -5109,7 +5128,7 @@ export class FleetManager {
|
|
|
5109
5128
|
* longer parses) collapses the clicked message so the dead button stops
|
|
5110
5129
|
* inviting clicks — the same courtesy the cancel button extends.
|
|
5111
5130
|
*/
|
|
5112
|
-
consumeNonceCallback(prefix, actionRe, data, callbackAdapterId, receivingAdapter) {
|
|
5131
|
+
consumeNonceCallback(prefix, actionRe, data, callbackAdapterId, receivingAdapter, staleHandling) {
|
|
5113
5132
|
if (!data.callbackData.startsWith(prefix))
|
|
5114
5133
|
return null;
|
|
5115
5134
|
const match = data.callbackData.match(actionRe);
|
|
@@ -5121,7 +5140,17 @@ export class FleetManager {
|
|
|
5121
5140
|
pending = undefined;
|
|
5122
5141
|
if (!match || !pending) {
|
|
5123
5142
|
const adapter = receivingAdapter ?? this.adapter;
|
|
5124
|
-
|
|
5143
|
+
if (staleHandling?.keepText && adapter?.removeMessageButtons) {
|
|
5144
|
+
adapter.removeMessageButtons(data.chatId, data.messageId, data.threadId)
|
|
5145
|
+
.catch(() => { });
|
|
5146
|
+
}
|
|
5147
|
+
else {
|
|
5148
|
+
adapter?.editMessageRemoveButtons?.(data.chatId, data.messageId, t("buttons.stale"), data.threadId).catch(() => { });
|
|
5149
|
+
}
|
|
5150
|
+
if (staleHandling?.notice) {
|
|
5151
|
+
adapter?.sendText(data.chatId, staleHandling.notice, { threadId: data.threadId })
|
|
5152
|
+
.catch(() => { });
|
|
5153
|
+
}
|
|
5125
5154
|
return "consumed";
|
|
5126
5155
|
}
|
|
5127
5156
|
// Bind the capability to the exact message/world that created it. Telegram
|
|
@@ -5294,7 +5323,12 @@ export class FleetManager {
|
|
|
5294
5323
|
}
|
|
5295
5324
|
}
|
|
5296
5325
|
async handleTipDismiss(data, callbackAdapterId, receivingAdapter) {
|
|
5297
|
-
const claimed = this.consumeNonceCallback(TIP_DISMISS_CALLBACK_PREFIX, /^tip-dismiss:([0-9a-f]+):(dismiss|confused)$/, data, callbackAdapterId, receivingAdapter
|
|
5326
|
+
const claimed = this.consumeNonceCallback(TIP_DISMISS_CALLBACK_PREFIX, /^tip-dismiss:([0-9a-f]+):(dismiss|confused)$/, data, callbackAdapterId, receivingAdapter,
|
|
5327
|
+
// A restart orphans the expiry timer, so tip buttons can outlive their
|
|
5328
|
+
// nonce by days. Keep the tip text readable and always tell the clicker
|
|
5329
|
+
// what to do next (the keyboard edit itself can be refused: Telegram
|
|
5330
|
+
// rejects edits on messages older than 48h).
|
|
5331
|
+
{ keepText: true, notice: t("tips.expired_use_tips") });
|
|
5298
5332
|
if (claimed === null)
|
|
5299
5333
|
return false;
|
|
5300
5334
|
if (claimed === "consumed")
|
|
@@ -5363,7 +5397,7 @@ export class FleetManager {
|
|
|
5363
5397
|
return true;
|
|
5364
5398
|
}
|
|
5365
5399
|
async handleTipUnlock(data, callbackAdapterId, receivingAdapter) {
|
|
5366
|
-
const claimed = this.consumeNonceCallback(TIP_UNLOCK_CALLBACK_PREFIX, /^tip-unlock:([0-9a-f]+):(unlock)$/, data, callbackAdapterId, receivingAdapter);
|
|
5400
|
+
const claimed = this.consumeNonceCallback(TIP_UNLOCK_CALLBACK_PREFIX, /^tip-unlock:([0-9a-f]+):(unlock)$/, data, callbackAdapterId, receivingAdapter, { keepText: true, notice: t("tips.expired_use_tips") });
|
|
5367
5401
|
if (claimed === null)
|
|
5368
5402
|
return false;
|
|
5369
5403
|
if (claimed === "consumed")
|