@songsid/agend 2.1.4-beta.47 → 2.1.4-beta.48
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/channel/types.d.ts +1 -1
- package/dist/fleet-context.d.ts +7 -0
- package/dist/fleet-manager.d.ts +22 -0
- package/dist/fleet-manager.js +67 -3
- package/dist/fleet-manager.js.map +1 -1
- package/dist/locale.js +6 -0
- package/dist/locale.js.map +1 -1
- package/dist/topic-commands.js +11 -0
- package/dist/topic-commands.js.map +1 -1
- package/package.json +1 -1
package/dist/channel/types.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface InstanceStatusData {
|
|
|
10
10
|
costCents: number;
|
|
11
11
|
}
|
|
12
12
|
export interface AlertData {
|
|
13
|
-
type: "hang" | "cost_warn" | "cost_limit" | "schedule_deferred" | "rotation" | "cancel" | "interactive_prompt" | "exit_restart" | "clear_confirm" | "tip" | "login";
|
|
13
|
+
type: "hang" | "cost_warn" | "cost_limit" | "schedule_deferred" | "rotation" | "cancel" | "interactive_prompt" | "exit_restart" | "clear_confirm" | "tip" | "login" | "install";
|
|
14
14
|
instanceName: string;
|
|
15
15
|
message: string;
|
|
16
16
|
choices?: Choice[];
|
package/dist/fleet-context.d.ts
CHANGED
|
@@ -93,6 +93,13 @@ export interface FleetContext {
|
|
|
93
93
|
promptTip?(generalName: string, adapter: import("./channel/types.js").ChannelAdapter, chatId: string, threadId?: string): Promise<"posted" | "empty" | "unavailable">;
|
|
94
94
|
/** Persistently enable advanced tips without waiting for the dismissal threshold. */
|
|
95
95
|
unlockAdvancedTips?(userId: string): boolean;
|
|
96
|
+
/** `/install-cli` backend chooser buttons. Caller enforces fleet-admin. */
|
|
97
|
+
promptInstallBackends?(chat: {
|
|
98
|
+
adapter: import("./channel/types.js").ChannelAdapter;
|
|
99
|
+
adapterId: string;
|
|
100
|
+
chatId: string;
|
|
101
|
+
threadId?: string;
|
|
102
|
+
}): Promise<void>;
|
|
96
103
|
/** `/login` backend chooser buttons. Caller enforces fleet-admin. */
|
|
97
104
|
promptLoginBackends?(chat: {
|
|
98
105
|
adapter: import("./channel/types.js").ChannelAdapter;
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -832,6 +832,28 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
832
832
|
chatId: string;
|
|
833
833
|
threadId?: string;
|
|
834
834
|
}): Promise<void>;
|
|
835
|
+
/**
|
|
836
|
+
* Backend chooser for a bare `/install-cli`, mirroring promptLoginBackends so
|
|
837
|
+
* both commands feel the same. Built on postNonceButtonPrompt rather than the
|
|
838
|
+
* `/model` selection coordinator: that is the mechanism `/login` already uses,
|
|
839
|
+
* and the one whose canonical-address binding (#682) makes the buttons answer
|
|
840
|
+
* in a Telegram General topic.
|
|
841
|
+
*
|
|
842
|
+
* Unlike the login chooser this does NOT filter to backends the fleet already
|
|
843
|
+
* runs. Installing is how you get a backend you do not have yet, so filtering
|
|
844
|
+
* by configured backends would hide the only entry the admin came for.
|
|
845
|
+
*
|
|
846
|
+
* gemini-cli is omitted: it is deprecated (see backend/factory.ts). Typing
|
|
847
|
+
* `/install-cli gemini-cli` still works — this only stops recommending it.
|
|
848
|
+
*/
|
|
849
|
+
promptInstallBackends(chat: {
|
|
850
|
+
adapter: ChannelAdapter;
|
|
851
|
+
adapterId: string;
|
|
852
|
+
chatId: string;
|
|
853
|
+
threadId?: string;
|
|
854
|
+
}): Promise<void>;
|
|
855
|
+
/** Backend chooser button → start that backend's install session. */
|
|
856
|
+
private handleInstallBackendSelect;
|
|
835
857
|
/**
|
|
836
858
|
* Start a login session for one backend. Caller enforces admin.
|
|
837
859
|
* Returns a status line to post, or null when a confirmation prompt was
|
package/dist/fleet-manager.js
CHANGED
|
@@ -216,6 +216,7 @@ const CLEAR_CONFIRM_CALLBACK_PREFIX = "clear-confirm:";
|
|
|
216
216
|
const TIP_DISMISS_CALLBACK_PREFIX = "tip-dismiss:";
|
|
217
217
|
const TIP_UNLOCK_CALLBACK_PREFIX = "tip-unlock:";
|
|
218
218
|
const LOGIN_CALLBACK_PREFIX = "login:";
|
|
219
|
+
const INSTALL_CALLBACK_PREFIX = "install-select:";
|
|
219
220
|
const LOGIN_MENU_CALLBACK_PREFIX = "login-menu:";
|
|
220
221
|
const LOGIN_CONFIRM_CALLBACK_PREFIX = "login-confirm:";
|
|
221
222
|
const INSTALL_LOGIN_CALLBACK_PREFIX = "install-login:";
|
|
@@ -2419,6 +2420,8 @@ export class FleetManager {
|
|
|
2419
2420
|
return;
|
|
2420
2421
|
if (await this.handleLoginBackendSelect(data, adapterId, this.adapter ?? undefined))
|
|
2421
2422
|
return;
|
|
2423
|
+
if (await this.handleInstallBackendSelect(data, adapterId, this.adapter ?? undefined))
|
|
2424
|
+
return;
|
|
2422
2425
|
if (await this.handleLoginMenuSelect(data, adapterId, this.adapter ?? undefined))
|
|
2423
2426
|
return;
|
|
2424
2427
|
if (await this.handleLoginConfirm(data, adapterId, this.adapter ?? undefined))
|
|
@@ -2813,6 +2816,8 @@ export class FleetManager {
|
|
|
2813
2816
|
return;
|
|
2814
2817
|
if (await this.handleLoginBackendSelect(data, adapterId, adapter))
|
|
2815
2818
|
return;
|
|
2819
|
+
if (await this.handleInstallBackendSelect(data, adapterId, adapter))
|
|
2820
|
+
return;
|
|
2816
2821
|
if (await this.handleLoginMenuSelect(data, adapterId, adapter))
|
|
2817
2822
|
return;
|
|
2818
2823
|
if (await this.handleLoginConfirm(data, adapterId, adapter))
|
|
@@ -5170,8 +5175,13 @@ export class FleetManager {
|
|
|
5170
5175
|
*/
|
|
5171
5176
|
async postNonceButtonPrompt(opts) {
|
|
5172
5177
|
// 16 bytes = the 128-bit capability the design claims. Telegram's 64-byte
|
|
5173
|
-
// callback_data cap still holds
|
|
5174
|
-
// + 32 hex + ":confirm" (8) = 59
|
|
5178
|
+
// callback_data cap still holds, with two prefixes tied at the longest:
|
|
5179
|
+
// "interactive-assist:" (19) + 32 hex + ":confirm" (8) = 59, and
|
|
5180
|
+
// "install-select:" (15) + 32 hex + ":" + the longest backend name
|
|
5181
|
+
// ("claude-code"/"antigravity", 11) = 59. Only 5 bytes of headroom: a
|
|
5182
|
+
// backend name of 17+ characters, or a longer prefix, would be silently
|
|
5183
|
+
// rejected by Telegram — see the callback_data assertion in
|
|
5184
|
+
// install-backend-menu.test.ts.
|
|
5175
5185
|
const nonce = randomBytes(16).toString("hex");
|
|
5176
5186
|
const entry = {
|
|
5177
5187
|
prefix: opts.prefix,
|
|
@@ -6410,6 +6420,56 @@ export class FleetManager {
|
|
|
6410
6420
|
expiredText: t("buttons.stale"),
|
|
6411
6421
|
});
|
|
6412
6422
|
}
|
|
6423
|
+
/**
|
|
6424
|
+
* Backend chooser for a bare `/install-cli`, mirroring promptLoginBackends so
|
|
6425
|
+
* both commands feel the same. Built on postNonceButtonPrompt rather than the
|
|
6426
|
+
* `/model` selection coordinator: that is the mechanism `/login` already uses,
|
|
6427
|
+
* and the one whose canonical-address binding (#682) makes the buttons answer
|
|
6428
|
+
* in a Telegram General topic.
|
|
6429
|
+
*
|
|
6430
|
+
* Unlike the login chooser this does NOT filter to backends the fleet already
|
|
6431
|
+
* runs. Installing is how you get a backend you do not have yet, so filtering
|
|
6432
|
+
* by configured backends would hide the only entry the admin came for.
|
|
6433
|
+
*
|
|
6434
|
+
* gemini-cli is omitted: it is deprecated (see backend/factory.ts). Typing
|
|
6435
|
+
* `/install-cli gemini-cli` still works — this only stops recommending it.
|
|
6436
|
+
*/
|
|
6437
|
+
async promptInstallBackends(chat) {
|
|
6438
|
+
const choices = Object.keys(BACKEND_INSTALLATION_INFO)
|
|
6439
|
+
.filter(backend => backend !== "gemini-cli")
|
|
6440
|
+
.map(backend => ({ action: backend, label: backend }));
|
|
6441
|
+
await this.postNonceButtonPrompt({
|
|
6442
|
+
prefix: INSTALL_CALLBACK_PREFIX,
|
|
6443
|
+
alertType: "install",
|
|
6444
|
+
instanceName: "install",
|
|
6445
|
+
adapter: chat.adapter,
|
|
6446
|
+
adapterId: chat.adapterId,
|
|
6447
|
+
chatId: chat.chatId,
|
|
6448
|
+
threadId: chat.threadId,
|
|
6449
|
+
message: t("install.choose_backend"),
|
|
6450
|
+
choices,
|
|
6451
|
+
expiredText: t("buttons.stale"),
|
|
6452
|
+
});
|
|
6453
|
+
}
|
|
6454
|
+
/** Backend chooser button → start that backend's install session. */
|
|
6455
|
+
async handleInstallBackendSelect(data, callbackAdapterId, receivingAdapter) {
|
|
6456
|
+
const claimed = this.consumeNonceCallback(INSTALL_CALLBACK_PREFIX, /^install-select:([0-9a-f]+):([a-z][a-z-]*)$/, data, callbackAdapterId, receivingAdapter);
|
|
6457
|
+
if (claimed === null)
|
|
6458
|
+
return false;
|
|
6459
|
+
if (claimed === "consumed")
|
|
6460
|
+
return true;
|
|
6461
|
+
const { entry, action: backend } = claimed;
|
|
6462
|
+
await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("install.starting_backend", backend));
|
|
6463
|
+
const text = await this.startInstallSession(backend, {
|
|
6464
|
+
adapter: entry.adapter,
|
|
6465
|
+
adapterId: entry.adapterId,
|
|
6466
|
+
chatId: entry.chatId,
|
|
6467
|
+
threadId: entry.threadId,
|
|
6468
|
+
});
|
|
6469
|
+
if (text)
|
|
6470
|
+
await entry.adapter.sendText(entry.chatId, text, { threadId: entry.threadId }).catch(() => { });
|
|
6471
|
+
return true;
|
|
6472
|
+
}
|
|
6413
6473
|
/**
|
|
6414
6474
|
* Start a login session for one backend. Caller enforces admin.
|
|
6415
6475
|
* Returns a status line to post, or null when a confirmation prompt was
|
|
@@ -6801,7 +6861,11 @@ export class FleetManager {
|
|
|
6801
6861
|
}
|
|
6802
6862
|
const backend = String(data.options?.backend ?? "").trim();
|
|
6803
6863
|
if (!backend) {
|
|
6804
|
-
|
|
6864
|
+
// Bare call: offer the backends instead of printing a usage line the user
|
|
6865
|
+
// then has to retype. A Discord slash that DID pick the native `backend`
|
|
6866
|
+
// choice never lands here, so the two paths cannot both fire.
|
|
6867
|
+
await this.promptInstallBackends({ adapter, adapterId, chatId: data.channelId });
|
|
6868
|
+
await data.respond(t("install.chooser_posted"));
|
|
6805
6869
|
return;
|
|
6806
6870
|
}
|
|
6807
6871
|
await data.respond(await this.startInstallSession(backend, { adapter, adapterId, chatId: data.channelId }));
|