@tritard/waterbrother 0.16.83 → 0.16.84

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 +47 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tritard/waterbrother",
3
- "version": "0.16.83",
3
+ "version": "0.16.84",
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
@@ -488,6 +488,21 @@ function chooseReviewerAgent(project) {
488
488
  return agents.find((agent) => String(agent?.role || "").trim() === "reviewer") || null;
489
489
  }
490
490
 
491
+ function summarizeExecutorReviewerArbitration(project, fallbackExecutor = {}) {
492
+ const executorAgent = chooseExecutorAgent(project, fallbackExecutor);
493
+ const reviewerAgent = chooseReviewerAgent(project);
494
+ const executorRuntime = getAgentRuntimeKey(executorAgent || fallbackExecutor);
495
+ const reviewerRuntime = getAgentRuntimeKey(reviewerAgent);
496
+ return {
497
+ executorAgent,
498
+ reviewerAgent,
499
+ executorRuntime,
500
+ reviewerRuntime,
501
+ aligned: Boolean(executorRuntime && reviewerRuntime && executorRuntime === reviewerRuntime),
502
+ split: Boolean(executorRuntime && reviewerRuntime && executorRuntime !== reviewerRuntime)
503
+ };
504
+ }
505
+
491
506
  function parseReviewerOutcome(text = "") {
492
507
  const value = String(text || "").trim();
493
508
  const lower = value.toLowerCase();
@@ -773,6 +788,9 @@ function parseTelegramStateIntent(text = "") {
773
788
  if (/\bmodel conflict\b/.test(lower) || /\bruntime conflict\b/.test(lower) || /\bmodel split\b/.test(lower) || /\bruntime split\b/.test(lower) || /\bcompare models\b/.test(lower) || /\bcompare bots\b/.test(lower)) {
774
789
  return { action: "model-conflict" };
775
790
  }
791
+ if (/\bcompare (?:executor|reviewer)\b/.test(lower) || /\bcompare reviewer and executor\b/.test(lower) || /\bcompare executor and reviewer\b/.test(lower) || /\bdo the reviewer and executor agree\b/.test(lower)) {
792
+ return { action: "executor-reviewer-compare" };
793
+ }
776
794
  if (/\bwhich (?:bot|agent|terminal) should take this\b/.test(lower) || /\bwho should take this\b/.test(lower) || /\bwho should handle this\b/.test(lower)) {
777
795
  return { action: "executor-recommendation" };
778
796
  }
@@ -2233,6 +2251,35 @@ class TelegramGateway {
2233
2251
  return lines.join("\n");
2234
2252
  }
2235
2253
 
2254
+ if (intent.action === "executor-reviewer-compare") {
2255
+ if (!project?.enabled) {
2256
+ return "This project is not shared.";
2257
+ }
2258
+ const comparison = summarizeExecutorReviewerArbitration(project, executor);
2259
+ if (!comparison.executorAgent && !comparison.reviewerAgent) {
2260
+ return "<b>Executor vs reviewer</b>\nNo executor or reviewer is assigned yet.";
2261
+ }
2262
+ if (!comparison.executorAgent) {
2263
+ return "<b>Executor vs reviewer</b>\nNo executor is assigned yet.";
2264
+ }
2265
+ if (!comparison.reviewerAgent) {
2266
+ return "<b>Executor vs reviewer</b>\nNo reviewer is assigned yet.";
2267
+ }
2268
+ return [
2269
+ "<b>Executor vs reviewer</b>",
2270
+ `executor: <code>${escapeTelegramHtml(comparison.executorAgent.ownerName || comparison.executorAgent.label || comparison.executorAgent.ownerId || comparison.executorAgent.id || "unknown")}</code>`,
2271
+ `executor runtime: <code>${escapeTelegramHtml(comparison.executorRuntime || "unknown")}</code>`,
2272
+ `reviewer: <code>${escapeTelegramHtml(comparison.reviewerAgent.ownerName || comparison.reviewerAgent.label || comparison.reviewerAgent.ownerId || comparison.reviewerAgent.id || "unknown")}</code>`,
2273
+ `reviewer runtime: <code>${escapeTelegramHtml(comparison.reviewerRuntime || "unknown")}</code>`,
2274
+ `alignment: <code>${escapeTelegramHtml(comparison.aligned ? "aligned" : comparison.split ? "split" : "unknown")}</code>`,
2275
+ comparison.split
2276
+ ? "These terminals are on different runtimes. Expect different opinions and use the reviewer outcome to arbitrate."
2277
+ : comparison.aligned
2278
+ ? "These terminals are on the same runtime. Disagreement is still possible, but it is less likely to come from model differences alone."
2279
+ : "One side is missing runtime identity, so Waterbrother cannot compare them yet."
2280
+ ].join("\n");
2281
+ }
2282
+
2236
2283
  if (intent.action === "agent-perspective") {
2237
2284
  if (!project?.enabled) {
2238
2285
  return "This project is not shared.";