@tritard/waterbrother 0.16.75 → 0.16.76

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/gateway.js +119 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.75",
3
+ "version": "0.16.76",
4
4
  "description": "Waterbrother: bring-your-own-model coding CLI with local tools, sessions, operator modes, and approval controls",
5
5
  "type": "module",
6
6
  "bin": {
package/src/gateway.js CHANGED
@@ -1850,6 +1850,74 @@ class TelegramGateway {
1850
1850
  }
1851
1851
  };
1852
1852
  }
1853
+ if (continuation.kind === "executor-handoff-override") {
1854
+ const reply = this.stripBotMention(String(message?.text || "").trim()).toLowerCase();
1855
+ const actorId = String(message?.from?.id || "").trim();
1856
+ const actorName = peer?.username || [message?.from?.first_name, message?.from?.last_name].filter(Boolean).join(" ").trim() || actorId;
1857
+ const session = await loadSession(sessionId);
1858
+ if (/\boverride\b/.test(reply)) {
1859
+ await addSharedRoomNote(session.cwd || this.cwd, `${continuation.context?.selectedOwnerName || "Selected executor"} handoff overridden; current terminal may execute`, {
1860
+ actorId,
1861
+ actorName,
1862
+ type: "executor-handoff-override",
1863
+ meta: {
1864
+ selectedAgentId: String(continuation.context?.selectedAgentId || "").trim(),
1865
+ currentOwnerId: String(continuation.context?.currentOwnerId || "").trim()
1866
+ }
1867
+ });
1868
+ return {
1869
+ markup: [
1870
+ "<b>Executor handoff overridden</b>",
1871
+ `selected executor: <code>${escapeTelegramHtml(continuation.context?.selectedOwnerName || "unknown")}</code>`,
1872
+ "Execution can proceed on the current terminal for now."
1873
+ ].join("\n")
1874
+ };
1875
+ }
1876
+ if (/\buse this terminal\b/.test(reply) || /\bthis terminal\b/.test(reply) || /\buse current\b/.test(reply)) {
1877
+ await upsertSharedAgent(session.cwd || this.cwd, {
1878
+ id: String(continuation.context?.currentAgentId || "").trim(),
1879
+ ownerId: String(continuation.context?.currentOwnerId || "").trim(),
1880
+ ownerName: String(continuation.context?.currentOwnerName || "").trim(),
1881
+ label: String(continuation.context?.currentLabel || "").trim(),
1882
+ surface: String(continuation.context?.currentSurface || "live-tui").trim(),
1883
+ role: "executor",
1884
+ provider: String(continuation.context?.currentProvider || "").trim(),
1885
+ model: String(continuation.context?.currentModel || "").trim(),
1886
+ runtimeProfile: String(continuation.context?.currentRuntimeProfile || "").trim(),
1887
+ sessionId: String(continuation.context?.currentSessionId || "").trim(),
1888
+ cwd: String(session.cwd || this.cwd).trim(),
1889
+ chatId: String(message?.chat?.id || "").trim()
1890
+ }, {
1891
+ actorId,
1892
+ actorName
1893
+ });
1894
+ await addSharedRoomNote(session.cwd || this.cwd, `${continuation.context?.currentOwnerName || "Current terminal"} is now the selected executor`, {
1895
+ actorId,
1896
+ actorName,
1897
+ type: "executor-handoff-reassigned",
1898
+ meta: {
1899
+ currentAgentId: String(continuation.context?.currentAgentId || "").trim()
1900
+ }
1901
+ });
1902
+ return {
1903
+ markup: [
1904
+ "<b>Executor reassigned</b>",
1905
+ `executor: <code>${escapeTelegramHtml(continuation.context?.currentOwnerName || "current terminal")}</code>`,
1906
+ "Execution can proceed on this terminal."
1907
+ ].join("\n")
1908
+ };
1909
+ }
1910
+ return {
1911
+ markup: "Reply with <code>override</code> to proceed anyway, or <code>use this terminal</code> to make the current terminal the executor.",
1912
+ remember: {
1913
+ text: String(continuation.lastPrompt || "").trim() || "Reply with override or use this terminal.",
1914
+ kind: continuation.kind,
1915
+ source: continuation.source,
1916
+ context: continuation.context || {},
1917
+ force: true
1918
+ }
1919
+ };
1920
+ }
1853
1921
  return null;
1854
1922
  }
1855
1923
 
@@ -3565,6 +3633,57 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
3565
3633
  });
3566
3634
  return;
3567
3635
  }
3636
+ const host = await this.getLiveBridgeHost();
3637
+ const activeExecutor = {
3638
+ surface: host?.surface || (host ? "live-tui" : "telegram-fallback"),
3639
+ provider: host?.provider || this.runtime.provider,
3640
+ model: host?.model || this.runtime.model,
3641
+ runtimeProfile: host?.runtimeProfile || operatorGate.project?.runtimeProfile || this.channel.defaultRuntimeProfile || this.gateway.defaultRuntimeProfile || "",
3642
+ hostSessionId: host?.sessionId || "",
3643
+ ownerId: host?.ownerId || "",
3644
+ ownerName: host?.ownerName || "",
3645
+ label: host?.label || ""
3646
+ };
3647
+ const selectedExecutor = chooseExecutorAgent(operatorGate.project, activeExecutor);
3648
+ if (
3649
+ selectedExecutor?.ownerId
3650
+ && activeExecutor.ownerId
3651
+ && String(selectedExecutor.ownerId).trim() !== String(activeExecutor.ownerId).trim()
3652
+ ) {
3653
+ const selectedName = String(selectedExecutor.ownerName || selectedExecutor.label || selectedExecutor.ownerId || "selected executor").trim();
3654
+ const currentName = String(activeExecutor.ownerName || activeExecutor.label || activeExecutor.ownerId || "current terminal").trim();
3655
+ const followUp = `Selected executor is ${selectedName}. Reply with override to proceed anyway, or use this terminal to make ${currentName} the executor.`;
3656
+ await this.sendMarkup(
3657
+ message.chat.id,
3658
+ [
3659
+ "<b>Executor handoff required</b>",
3660
+ `selected executor: <code>${escapeTelegramHtml(selectedName)}</code>`,
3661
+ `current terminal: <code>${escapeTelegramHtml(currentName)}</code>`,
3662
+ "Execution is paused because this room selected a different terminal as executor.",
3663
+ followUp
3664
+ ].join("\n"),
3665
+ message.message_id
3666
+ );
3667
+ await this.rememberContinuationWithOptions(message, followUp, {
3668
+ kind: "executor-handoff-override",
3669
+ source: "executor-handoff-gate",
3670
+ context: {
3671
+ selectedAgentId: String(selectedExecutor.id || "").trim(),
3672
+ selectedOwnerName: selectedName,
3673
+ currentAgentId: String(host?.sessionId ? `agent:telegram-bridge:${host.sessionId}` : "").trim(),
3674
+ currentOwnerId: String(activeExecutor.ownerId || "").trim(),
3675
+ currentOwnerName: currentName,
3676
+ currentLabel: String(activeExecutor.label || "").trim(),
3677
+ currentSurface: String(activeExecutor.surface || "").trim(),
3678
+ currentProvider: String(activeExecutor.provider || "").trim(),
3679
+ currentModel: String(activeExecutor.model || "").trim(),
3680
+ currentRuntimeProfile: String(activeExecutor.runtimeProfile || "").trim(),
3681
+ currentSessionId: String(activeExecutor.hostSessionId || "").trim()
3682
+ },
3683
+ force: true
3684
+ });
3685
+ return;
3686
+ }
3568
3687
  previewMessage = await this.sendProgressMessage(message.chat.id, message.message_id);
3569
3688
  const content = (await this.runPromptViaBridge(message, sessionId, promptText, { explicitExecution: shouldExecutePrompt }))
3570
3689
  ?? (await this.runPromptFallback(sessionId, promptText));