@songsid/agend 2.1.4-beta.53 → 2.1.4-beta.55
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.
|
@@ -10,7 +10,7 @@ All commands output JSON.
|
|
|
10
10
|
Reply: `agend-agent reply "your response"`
|
|
11
11
|
|
|
12
12
|
2. **`[from:INSTANCE-NAME] text`** — Another agent sent you a message.
|
|
13
|
-
Reply: `agend-agent send INSTANCE-NAME "your response"`
|
|
13
|
+
Reply to the sending agent: `agend-agent send INSTANCE-NAME "your response"`
|
|
14
14
|
|
|
15
15
|
3. **`[delegate_task] ...`** — You've been assigned a task.
|
|
16
16
|
When done: `agend-agent report REQUESTER "summary of results"`
|
|
@@ -46,7 +46,7 @@ agend-agent decision-list # List decisions
|
|
|
46
46
|
## Rules
|
|
47
47
|
|
|
48
48
|
- `[user:... via telegram]` → use `agend-agent reply` (NOT `agend-agent send`)
|
|
49
|
-
- `[from:INSTANCE]` → use `agend-agent send`
|
|
49
|
+
- `[from:INSTANCE]` → use `agend-agent send` or `agend-agent report` to answer the sending agent; AgEnD appends the runtime-specific rule for any requested channel-facing action.
|
|
50
50
|
- Everything for a human user goes inside the `agend-agent reply` command. Your final
|
|
51
51
|
terminal text is NOT delivered to their chat — it only reaches local logs and
|
|
52
52
|
`/view`. After the command succeeds, end the turn with final text of exactly `.`
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -700,7 +700,17 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
700
700
|
notifyFleetError(text: string): void;
|
|
701
701
|
private static readonly FLEET_ERROR_THROTTLE_MS;
|
|
702
702
|
private fleetErrorNotices;
|
|
703
|
-
|
|
703
|
+
/**
|
|
704
|
+
* Post into an instance's topic. Returns whether a send was DISPATCHED — a
|
|
705
|
+
* target was resolved and sendText was called — so a caller that must not
|
|
706
|
+
* lose the message (notifyFleetError, which spends a throttle key) can tell
|
|
707
|
+
* that from silence. Existing callers ignore the result and are unaffected.
|
|
708
|
+
*
|
|
709
|
+
* Not a delivery guarantee: sendText is fire-and-forget, and a platform-side
|
|
710
|
+
* rejection surfaces only as a warn in its .catch. True delivery confirmation
|
|
711
|
+
* would have to make this async and change every caller.
|
|
712
|
+
*/
|
|
713
|
+
notifyInstanceTopic(instanceName: string, text: string, extraOpts?: import("./channel/types.js").SendOpts): boolean;
|
|
704
714
|
/**
|
|
705
715
|
* Post decision buttons whose callback ids are `<prefix><nonce>:<action>`.
|
|
706
716
|
* The entry is registered before the send and rolled back if the send
|
package/dist/fleet-manager.js
CHANGED
|
@@ -5441,14 +5441,6 @@ export class FleetManager {
|
|
|
5441
5441
|
return;
|
|
5442
5442
|
}
|
|
5443
5443
|
const suppressed = seen?.suppressed ?? 0;
|
|
5444
|
-
this.fleetErrorNotices.set(key, { at: now, suppressed: 0 });
|
|
5445
|
-
// Bound the map: it is keyed by message text, and a message with a varying
|
|
5446
|
-
// suffix (a path, an id) would otherwise grow it without limit.
|
|
5447
|
-
if (this.fleetErrorNotices.size > 100) {
|
|
5448
|
-
const oldest = this.fleetErrorNotices.keys().next().value;
|
|
5449
|
-
if (oldest !== undefined)
|
|
5450
|
-
this.fleetErrorNotices.delete(oldest);
|
|
5451
|
-
}
|
|
5452
5444
|
const body = suppressed > 0
|
|
5453
5445
|
? `${text}\n${t("fleet.error_suppressed", suppressed, Math.round(FleetManager.FLEET_ERROR_THROTTLE_MS / 60_000))}`
|
|
5454
5446
|
: text;
|
|
@@ -5458,26 +5450,60 @@ export class FleetManager {
|
|
|
5458
5450
|
// topic_id to post into it.
|
|
5459
5451
|
const general = Object.entries(this.fleetConfig?.instances ?? {})
|
|
5460
5452
|
.find(([, config]) => config.general_topic === true)?.[0];
|
|
5453
|
+
// "dispatched", not "delivered": see notifyInstanceTopic. A platform that
|
|
5454
|
+
// rejects the message afterwards still consumes the throttle window, which
|
|
5455
|
+
// is the pre-existing semantic and not something this change alters.
|
|
5456
|
+
let dispatched = false;
|
|
5461
5457
|
if (general) {
|
|
5462
|
-
this.notifyInstanceTopic(general, body);
|
|
5463
|
-
return;
|
|
5458
|
+
dispatched = this.notifyInstanceTopic(general, body);
|
|
5464
5459
|
}
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5460
|
+
else {
|
|
5461
|
+
// No General instance — fall back to the primary channel's group.
|
|
5462
|
+
const groupId = this.getChannelConfig()?.group_id;
|
|
5463
|
+
if (this.adapter && groupId) {
|
|
5464
|
+
this.adapter.sendText(String(groupId), body)
|
|
5465
|
+
.catch(err => this.logger.warn({ err }, "Failed to send fleet error notification"));
|
|
5466
|
+
dispatched = true;
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
if (!dispatched) {
|
|
5470
|
+
// Do NOT record the throttle key. It used to be claimed before delivery
|
|
5471
|
+
// was attempted, so a message nobody could receive — every fleet error
|
|
5472
|
+
// raised before adapters exist, which is when startup faults happen —
|
|
5473
|
+
// also suppressed the next ten minutes of identical ones. Leaving the key
|
|
5474
|
+
// unspent lets the next caller, once an adapter is up, actually get
|
|
5475
|
+
// through. The counter is not reset either: nothing was shown.
|
|
5476
|
+
this.logger.warn({ text: body }, "Fleet error could not be delivered (no adapter or no target yet) — not consuming the throttle window");
|
|
5471
5477
|
return;
|
|
5472
5478
|
}
|
|
5473
|
-
this.
|
|
5479
|
+
this.fleetErrorNotices.set(key, { at: now, suppressed: 0 });
|
|
5480
|
+
// Bound the map: it is keyed by message text, and a message with a varying
|
|
5481
|
+
// suffix (a path, an id) would otherwise grow it without limit.
|
|
5482
|
+
if (this.fleetErrorNotices.size > 100) {
|
|
5483
|
+
const oldest = this.fleetErrorNotices.keys().next().value;
|
|
5484
|
+
if (oldest !== undefined)
|
|
5485
|
+
this.fleetErrorNotices.delete(oldest);
|
|
5486
|
+
}
|
|
5474
5487
|
}
|
|
5475
5488
|
static FLEET_ERROR_THROTTLE_MS = 10 * 60_000;
|
|
5476
5489
|
fleetErrorNotices = new Map();
|
|
5490
|
+
/**
|
|
5491
|
+
* Post into an instance's topic. Returns whether a send was DISPATCHED — a
|
|
5492
|
+
* target was resolved and sendText was called — so a caller that must not
|
|
5493
|
+
* lose the message (notifyFleetError, which spends a throttle key) can tell
|
|
5494
|
+
* that from silence. Existing callers ignore the result and are unaffected.
|
|
5495
|
+
*
|
|
5496
|
+
* Not a delivery guarantee: sendText is fire-and-forget, and a platform-side
|
|
5497
|
+
* rejection surfaces only as a warn in its .catch. True delivery confirmation
|
|
5498
|
+
* would have to make this async and change every caller.
|
|
5499
|
+
*/
|
|
5477
5500
|
notifyInstanceTopic(instanceName, text, extraOpts) {
|
|
5478
5501
|
const adapter = this.getAdapterForInstance(instanceName) ?? this.adapter;
|
|
5479
|
-
if (!adapter)
|
|
5480
|
-
|
|
5502
|
+
if (!adapter) {
|
|
5503
|
+
// Early startup: adapters are created well after the fleet object exists.
|
|
5504
|
+
this.logger.warn({ instanceName }, "No adapter yet — instance topic notification not sent");
|
|
5505
|
+
return false;
|
|
5506
|
+
}
|
|
5481
5507
|
const channelCfg = this.getChannelConfig(this.getInstanceAdapterId(instanceName));
|
|
5482
5508
|
const groupId = channelCfg?.group_id;
|
|
5483
5509
|
// Fleet topic instance
|
|
@@ -5485,20 +5511,23 @@ export class FleetManager {
|
|
|
5485
5511
|
if (threadId != null && groupId) {
|
|
5486
5512
|
adapter.sendText(String(groupId), text, { threadId: String(threadId), ...extraOpts })
|
|
5487
5513
|
.catch(e => this.logger.warn({ err: e, instanceName }, "Failed to send instance topic notification"));
|
|
5488
|
-
return;
|
|
5514
|
+
return true;
|
|
5489
5515
|
}
|
|
5490
5516
|
// Classic instance: find its channelId from the classic manager
|
|
5491
5517
|
const classicChatId = this.classicChannels?.getChannelIdByInstance(instanceName);
|
|
5492
5518
|
if (classicChatId) {
|
|
5493
5519
|
adapter.sendText(classicChatId, text, extraOpts)
|
|
5494
5520
|
.catch(e => this.logger.warn({ err: e, instanceName }, "Failed to send classic notification"));
|
|
5495
|
-
return;
|
|
5521
|
+
return true;
|
|
5496
5522
|
}
|
|
5497
5523
|
// Fallback: send to group without threadId
|
|
5498
5524
|
if (groupId) {
|
|
5499
5525
|
adapter.sendText(String(groupId), text, extraOpts)
|
|
5500
5526
|
.catch(e => this.logger.warn({ err: e, instanceName }, "Failed to send notification (no topic)"));
|
|
5527
|
+
return true;
|
|
5501
5528
|
}
|
|
5529
|
+
this.logger.warn({ instanceName }, "No group id — instance topic notification not sent");
|
|
5530
|
+
return false;
|
|
5502
5531
|
}
|
|
5503
5532
|
// ── Nonce-armed button prompts (hang / assist / exit / clear) ──
|
|
5504
5533
|
//
|