switchroom 0.18.11 → 0.18.13
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/agent-scheduler/index.js +37 -5
- package/dist/auth-broker/index.js +116 -78
- package/dist/cli/hindsight-mental-model-pretool.mjs +39 -0
- package/dist/cli/ms-365-write-pretool.mjs +31 -8
- package/dist/cli/notion-write-pretool.mjs +38 -6
- package/dist/cli/skill-validate-pretool.mjs +144 -2847
- package/dist/cli/switchroom.js +3529 -4543
- package/dist/cli/ui/index.html +163 -17
- package/dist/host-control/main.js +605 -2847
- package/dist/vault/approvals/kernel-server.js +120 -13
- package/dist/vault/broker/server.js +259 -157
- package/package.json +3 -4
- package/profiles/_base/start.sh.hbs +65 -0
- package/profiles/_shared/vault-protocol.md.hbs +3 -1
- package/profiles/coding/CLAUDE.md.hbs +1 -1
- package/profiles/default/CLAUDE.md.hbs +2 -2
- package/profiles/executive-assistant/CLAUDE.md.hbs +1 -1
- package/profiles/health-coach/CLAUDE.md.hbs +1 -1
- package/telegram-plugin/bridge/bridge.ts +37 -0
- package/telegram-plugin/bridge/inbound-dedup.ts +101 -0
- package/telegram-plugin/dist/bridge/bridge.js +122 -4
- package/telegram-plugin/dist/gateway/gateway.js +4213 -3288
- package/telegram-plugin/dist/server.js +139 -5
- package/telegram-plugin/flood-circuit-breaker.ts +493 -21
- package/telegram-plugin/format.ts +19 -0
- package/telegram-plugin/gateway/approval-hold.ts +602 -0
- package/telegram-plugin/gateway/auth-command.ts +92 -2
- package/telegram-plugin/gateway/auth-loopback-relay.ts +670 -0
- package/telegram-plugin/gateway/boot-card.ts +12 -5
- package/telegram-plugin/gateway/callback-query-handlers.ts +88 -1
- package/telegram-plugin/gateway/config-approval-handler.ts +6 -1
- package/telegram-plugin/gateway/disconnect-flush.ts +19 -0
- package/telegram-plugin/gateway/dm-pin-sweep.test.ts +251 -0
- package/telegram-plugin/gateway/dm-pin-sweep.ts +178 -0
- package/telegram-plugin/gateway/gateway.ts +1695 -230
- package/telegram-plugin/gateway/hostd-dispatch.ts +23 -0
- package/telegram-plugin/gateway/idle-clear.ts +90 -6
- package/telegram-plugin/gateway/inbound-delivery-machine-shadow.ts +26 -5
- package/telegram-plugin/gateway/inject-handler.ts +8 -0
- package/telegram-plugin/gateway/ipc-protocol.ts +46 -3
- package/telegram-plugin/gateway/ipc-server.ts +43 -0
- package/telegram-plugin/gateway/mental-model-propose-resolve.ts +145 -37
- package/telegram-plugin/gateway/model-command.ts +9 -3
- package/telegram-plugin/gateway/pending-session-command.ts +13 -1
- package/telegram-plugin/gateway/permission-ttl-sweep.ts +66 -0
- package/telegram-plugin/gateway/pre-approval-check.ts +74 -0
- package/telegram-plugin/gateway/queued-card-store.ts +217 -0
- package/telegram-plugin/gateway/session-model-file.ts +26 -1
- package/telegram-plugin/gateway/turn-end-gate-backstop.ts +59 -0
- package/telegram-plugin/gateway/turn-end-gate.ts +95 -0
- package/telegram-plugin/gateway/turn-typing-loop.ts +10 -2
- package/telegram-plugin/gateway/unhandled-rejection-policy.ts +13 -0
- package/telegram-plugin/history.ts +51 -0
- package/telegram-plugin/hooks/dispatch-claim-scan.mjs +259 -0
- package/telegram-plugin/hooks/dispatch-claim-stop.mjs +129 -0
- package/telegram-plugin/hooks/hooks.json +9 -0
- package/telegram-plugin/inline-keyboard-callbacks.ts +303 -2
- package/telegram-plugin/model-unavailable.ts +41 -11
- package/telegram-plugin/operator-events.ts +23 -0
- package/telegram-plugin/outbound-field-redact.ts +69 -0
- package/telegram-plugin/package.json +0 -1
- package/telegram-plugin/permission-rule.ts +1 -0
- package/telegram-plugin/permission-title.ts +1 -0
- package/telegram-plugin/render/render.ts +32 -14
- package/telegram-plugin/retry-api-call.ts +212 -2
- package/telegram-plugin/scoped-approval.ts +11 -2
- package/telegram-plugin/secret-detect/chunker.ts +18 -4
- package/telegram-plugin/secret-detect/index.ts +12 -56
- package/telegram-plugin/send-gate-degraded.test.ts +574 -0
- package/telegram-plugin/send-gate-observability.test.ts +470 -0
- package/telegram-plugin/send-gate-observability.ts +355 -0
- package/telegram-plugin/send-gate.test.ts +717 -0
- package/telegram-plugin/send-gate.ts +1056 -0
- package/telegram-plugin/session-tail.ts +82 -7
- package/telegram-plugin/shared/bot-runtime.ts +17 -5
- package/telegram-plugin/shared/gw-trace-gate.ts +105 -0
- package/telegram-plugin/status-pin-driver.ts +52 -7
- package/telegram-plugin/status-pin.ts +81 -0
- package/telegram-plugin/subagent-watcher.ts +173 -18
- package/telegram-plugin/tests/activity-card-wiring.test.ts +18 -5
- package/telegram-plugin/tests/approval-hold-harness.ts +425 -0
- package/telegram-plugin/tests/approval-hold-outcome.test.ts +327 -0
- package/telegram-plugin/tests/approval-hold-record.test.ts +531 -0
- package/telegram-plugin/tests/approval-hold-redeliver.test.ts +602 -0
- package/telegram-plugin/tests/auth-loopback-relay.test.ts +533 -0
- package/telegram-plugin/tests/boot-card-flood-suppress.test.ts +53 -7
- package/telegram-plugin/tests/busy-key-reaper.test.ts +1 -0
- package/telegram-plugin/tests/callback-query-handlers.test.ts +65 -0
- package/telegram-plugin/tests/dispatch-claim-scan.test.ts +250 -0
- package/telegram-plugin/tests/flood-breaker-blindness.test.ts +213 -0
- package/telegram-plugin/tests/flood-windows-persistence.test.ts +224 -0
- package/telegram-plugin/tests/gateway-boot-marker-clear.test.ts +3 -3
- package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +29 -1
- package/telegram-plugin/tests/gateway-loopback-paste-redact.test.ts +66 -0
- package/telegram-plugin/tests/gateway-outbound-redact.test.ts +57 -0
- package/telegram-plugin/tests/gw-trace-gate.test.ts +105 -0
- package/telegram-plugin/tests/history.test.ts +115 -0
- package/telegram-plugin/tests/idle-clear.test.ts +233 -3
- package/telegram-plugin/tests/inbound-dedup.test.ts +93 -0
- package/telegram-plugin/tests/inbound-message-types.test.ts +5 -1
- package/telegram-plugin/tests/inline-keyboard-callbacks.test.ts +448 -0
- package/telegram-plugin/tests/ipc-server-check-pre-approved.test.ts +194 -0
- package/telegram-plugin/tests/mental-model-propose-resolve.test.ts +123 -0
- package/telegram-plugin/tests/missed-approvals-wiring.test.ts +1 -1
- package/telegram-plugin/tests/model-command.test.ts +14 -0
- package/telegram-plugin/tests/operator-events-session-tail.test.ts +74 -0
- package/telegram-plugin/tests/outbound-field-redact.test.ts +107 -0
- package/telegram-plugin/tests/pending-session-command.test.ts +21 -0
- package/telegram-plugin/tests/permission-card-routing.test.ts +30 -5
- package/telegram-plugin/tests/permission-no-repeat-wiring.test.ts +8 -7
- package/telegram-plugin/tests/permission-rearm-wiring.test.ts +1 -1
- package/telegram-plugin/tests/pre-approval-check.test.ts +148 -0
- package/telegram-plugin/tests/queued-card-store.test.ts +232 -0
- package/telegram-plugin/tests/reaction-flush-turn-gated.test.ts +100 -0
- package/telegram-plugin/tests/reaction-gate-routing.test.ts +173 -0
- package/telegram-plugin/tests/render/render.test.ts +88 -0
- package/telegram-plugin/tests/retry-api-call.test.ts +398 -0
- package/telegram-plugin/tests/scoped-approval.test.ts +27 -0
- package/telegram-plugin/tests/secret-detect-chunk-overlap.test.ts +65 -0
- package/telegram-plugin/tests/secret-detect-oauth-code.test.ts +5 -4
- package/telegram-plugin/tests/session-model-file.test.ts +50 -0
- package/telegram-plugin/tests/session-tail-sidecar-reap.test.ts +268 -0
- package/telegram-plugin/tests/status-pin-boot-recovery.test.ts +35 -14
- package/telegram-plugin/tests/status-pin.test.ts +275 -1
- package/telegram-plugin/tests/subagent-watcher-deferral-log-ratelimit.test.ts +316 -0
- package/telegram-plugin/tests/subagent-watcher-fd-leak.test.ts +275 -0
- package/telegram-plugin/tests/turn-end-gate-backstop.test.ts +92 -0
- package/telegram-plugin/tests/turn-end-gate.test.ts +137 -0
- package/telegram-plugin/tests/typing-emitter.test.ts +586 -0
- package/telegram-plugin/tests/unhandled-rejection-policy.test.ts +20 -0
- package/telegram-plugin/tests/worktree-watch-cwds.test.ts +215 -1
- package/telegram-plugin/typing-emitter.ts +224 -0
- package/telegram-plugin/uat/scenarios/jtbd-feel-like-a-colleague-dm.test.ts +136 -0
- package/telegram-plugin/welcome-text.ts +42 -0
- package/telegram-plugin/worktree-watch-cwds.ts +194 -5
- package/vendor/hindsight-memory/scripts/drain_pending.py +22 -6
- package/vendor/hindsight-memory/scripts/lib/client.py +12 -5
- package/vendor/hindsight-memory/scripts/lib/directives.py +38 -3
- package/vendor/hindsight-memory/scripts/lib/pending.py +36 -9
- package/vendor/hindsight-memory/scripts/session_end.py +14 -3
- package/vendor/hindsight-memory/scripts/session_start.py +21 -0
- package/vendor/hindsight-memory/scripts/tests/test_directives.py +38 -0
- package/vendor/hindsight-memory/tests/test_drain_pending.py +68 -0
- package/vendor/hindsight-memory/tests/test_pending.py +44 -0
- package/vendor/hindsight-memory/tests/test_session_end_pending.py +38 -0
- package/vendor/hindsight-memory/tests/test_session_start_drain.py +155 -0
- package/telegram-plugin/channel-envelope-safety.test.ts +0 -56
- package/telegram-plugin/channel-envelope-safety.ts +0 -56
- package/telegram-plugin/secret-detect/secretlint-source.ts +0 -95
- package/telegram-plugin/tests/secret-detect-secretlint.test.ts +0 -105
|
@@ -17062,6 +17062,48 @@ var init_operator_events = __esm(() => {
|
|
|
17062
17062
|
cooldownMap = new Map;
|
|
17063
17063
|
});
|
|
17064
17064
|
|
|
17065
|
+
// quota-check.ts
|
|
17066
|
+
var init_quota_check = () => {};
|
|
17067
|
+
|
|
17068
|
+
// text-voice-scrub.ts
|
|
17069
|
+
var NULL = "\x00", FENCE_PH, INLINE_PH, HTML_CODE_PH, HTML_PRE_PH, URL_PH;
|
|
17070
|
+
var init_text_voice_scrub = __esm(() => {
|
|
17071
|
+
FENCE_PH = `${NULL}VS_FENCE`;
|
|
17072
|
+
INLINE_PH = `${NULL}VS_INLINE`;
|
|
17073
|
+
HTML_CODE_PH = `${NULL}VS_HTMLCODE`;
|
|
17074
|
+
HTML_PRE_PH = `${NULL}VS_HTMLPRE`;
|
|
17075
|
+
URL_PH = `${NULL}VS_URL`;
|
|
17076
|
+
});
|
|
17077
|
+
|
|
17078
|
+
// card-format.ts
|
|
17079
|
+
var init_card_format = __esm(() => {
|
|
17080
|
+
init_text_voice_scrub();
|
|
17081
|
+
});
|
|
17082
|
+
|
|
17083
|
+
// model-unavailable.ts
|
|
17084
|
+
function isTransientUpstreamSignal(text) {
|
|
17085
|
+
if (typeof text !== "string" || text.length === 0)
|
|
17086
|
+
return false;
|
|
17087
|
+
const sample = text.length > 16384 ? text.slice(0, 16384) : text;
|
|
17088
|
+
const lower = sample.toLowerCase();
|
|
17089
|
+
return transientUpstreamSignals.some((s) => lower.includes(s));
|
|
17090
|
+
}
|
|
17091
|
+
var transientUpstreamSignals;
|
|
17092
|
+
var init_model_unavailable = __esm(() => {
|
|
17093
|
+
init_quota_check();
|
|
17094
|
+
init_card_format();
|
|
17095
|
+
transientUpstreamSignals = [
|
|
17096
|
+
"not your usage limit",
|
|
17097
|
+
"not your account",
|
|
17098
|
+
"not your account's",
|
|
17099
|
+
"temporarily limiting requests",
|
|
17100
|
+
"temporarily rate",
|
|
17101
|
+
"server is temporarily",
|
|
17102
|
+
"would exceed your account\u2019s rate limit",
|
|
17103
|
+
"would exceed your account's rate limit"
|
|
17104
|
+
];
|
|
17105
|
+
});
|
|
17106
|
+
|
|
17065
17107
|
// tool-label-sidecar.ts
|
|
17066
17108
|
import { existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync3 } from "node:fs";
|
|
17067
17109
|
import { join as join3 } from "node:path";
|
|
@@ -17491,7 +17533,8 @@ function detectErrorInTranscriptLine(line) {
|
|
|
17491
17533
|
const status = typeof obj.apiErrorStatus === "number" ? obj.apiErrorStatus : null;
|
|
17492
17534
|
const errStr = typeof obj.error === "string" ? obj.error : "";
|
|
17493
17535
|
const text = extractAssistantText(obj);
|
|
17494
|
-
const kind2 = status === 429 ?
|
|
17536
|
+
const kind2 = status === 429 ? isTransientUpstreamSignal(`${text}
|
|
17537
|
+
${errStr}`) ? "rate-limited" : "quota-exhausted" : classifyClaudeError({ type: errStr, status, message: text });
|
|
17495
17538
|
return {
|
|
17496
17539
|
kind: kind2,
|
|
17497
17540
|
raw: obj,
|
|
@@ -17585,6 +17628,7 @@ function startSessionTail(config2) {
|
|
|
17585
17628
|
const onOperatorEvent = config2.onOperatorEvent;
|
|
17586
17629
|
log?.(`session-tail: projectsDir=${projectsDir}`);
|
|
17587
17630
|
const sidecars = new Map;
|
|
17631
|
+
const createSidecar = config2.createSidecar ?? createToolLabelSidecar;
|
|
17588
17632
|
const stateDirForSidecar = process.env.TELEGRAM_STATE_DIR ?? null;
|
|
17589
17633
|
function sessionIdForFile(file) {
|
|
17590
17634
|
if (!file)
|
|
@@ -17599,7 +17643,7 @@ function startSessionTail(config2) {
|
|
|
17599
17643
|
if (existing)
|
|
17600
17644
|
return existing;
|
|
17601
17645
|
try {
|
|
17602
|
-
const s =
|
|
17646
|
+
const s = createSidecar({ stateDir: stateDirForSidecar, sessionId });
|
|
17603
17647
|
sidecars.set(sessionId, s);
|
|
17604
17648
|
s.onLabel((toolUseId, label, toolName) => {
|
|
17605
17649
|
rawOnEvent({ kind: "tool_label", toolUseId, label, toolName });
|
|
@@ -17610,6 +17654,17 @@ function startSessionTail(config2) {
|
|
|
17610
17654
|
return null;
|
|
17611
17655
|
}
|
|
17612
17656
|
}
|
|
17657
|
+
function stopSidecar(sessionId) {
|
|
17658
|
+
if (!sessionId)
|
|
17659
|
+
return;
|
|
17660
|
+
const s = sidecars.get(sessionId);
|
|
17661
|
+
if (!s)
|
|
17662
|
+
return;
|
|
17663
|
+
try {
|
|
17664
|
+
s.stop();
|
|
17665
|
+
} catch {}
|
|
17666
|
+
sidecars.delete(sessionId);
|
|
17667
|
+
}
|
|
17613
17668
|
function decorate(ev, sessionId) {
|
|
17614
17669
|
if (!sessionId)
|
|
17615
17670
|
return ev;
|
|
@@ -17702,6 +17757,11 @@ function startSessionTail(config2) {
|
|
|
17702
17757
|
} catch {}
|
|
17703
17758
|
watcher = null;
|
|
17704
17759
|
}
|
|
17760
|
+
const rotatedAwaySid = sessionIdForFile(currentFile);
|
|
17761
|
+
const nextSid = sessionIdForFile(file);
|
|
17762
|
+
if (rotatedAwaySid != null && rotatedAwaySid !== nextSid) {
|
|
17763
|
+
stopSidecar(rotatedAwaySid);
|
|
17764
|
+
}
|
|
17705
17765
|
currentFile = file;
|
|
17706
17766
|
const prior = fileCursors.get(file);
|
|
17707
17767
|
if (prior != null) {
|
|
@@ -17734,7 +17794,7 @@ function startSessionTail(config2) {
|
|
|
17734
17794
|
const multiAgent = isMultiAgentEnabled();
|
|
17735
17795
|
const CAP_TOOL_USE_THRESHOLD = 30;
|
|
17736
17796
|
const subTails = new Map;
|
|
17737
|
-
const IDLE_FSWATCH_TTL_MS = 5 * 60 * 1000;
|
|
17797
|
+
const IDLE_FSWATCH_TTL_MS = Math.max(1000, config2.subTailIdleReapMs ?? 5 * 60 * 1000);
|
|
17738
17798
|
function readSub(t) {
|
|
17739
17799
|
if (stopped)
|
|
17740
17800
|
return;
|
|
@@ -17841,6 +17901,7 @@ function startSessionTail(config2) {
|
|
|
17841
17901
|
} catch {}
|
|
17842
17902
|
t.watcher = null;
|
|
17843
17903
|
}
|
|
17904
|
+
stopSidecar(sessionIdForFile(t.file));
|
|
17844
17905
|
subTails.delete(file);
|
|
17845
17906
|
log?.(`session-tail: reaped idle sub ${t.agentId} (${file})`);
|
|
17846
17907
|
}
|
|
@@ -17925,6 +17986,7 @@ function startSessionTail(config2) {
|
|
|
17925
17986
|
var MAX_JSONL_LINE_BYTES, MAX_ERROR_TEXT_CHARS = 500;
|
|
17926
17987
|
var init_session_tail = __esm(() => {
|
|
17927
17988
|
init_operator_events();
|
|
17989
|
+
init_model_unavailable();
|
|
17928
17990
|
init_tool_label_sidecar();
|
|
17929
17991
|
init_model_label();
|
|
17930
17992
|
MAX_JSONL_LINE_BYTES = 2 * 1024 * 1024;
|
|
@@ -24259,6 +24321,7 @@ var init_permission_rule = __esm(() => {
|
|
|
24259
24321
|
"WebSearch",
|
|
24260
24322
|
"Task",
|
|
24261
24323
|
"Agent",
|
|
24324
|
+
"Workflow",
|
|
24262
24325
|
"TodoWrite",
|
|
24263
24326
|
"ExitPlanMode"
|
|
24264
24327
|
]);
|
|
@@ -24305,6 +24368,60 @@ var init_crash_breadcrumb = __esm(() => {
|
|
|
24305
24368
|
MAX_LOG_BYTES = 1024 * 1024;
|
|
24306
24369
|
});
|
|
24307
24370
|
|
|
24371
|
+
// bridge/inbound-dedup.ts
|
|
24372
|
+
function shouldDedupInbound(msg) {
|
|
24373
|
+
if (!Number.isFinite(msg.messageId) || msg.messageId <= 0)
|
|
24374
|
+
return false;
|
|
24375
|
+
const m = msg.meta ?? {};
|
|
24376
|
+
if (m.source != null)
|
|
24377
|
+
return false;
|
|
24378
|
+
if (m.button_callback != null)
|
|
24379
|
+
return false;
|
|
24380
|
+
if (m.kind != null)
|
|
24381
|
+
return false;
|
|
24382
|
+
if (m.event != null)
|
|
24383
|
+
return false;
|
|
24384
|
+
return true;
|
|
24385
|
+
}
|
|
24386
|
+
|
|
24387
|
+
class InboundDedup {
|
|
24388
|
+
maxPerChat;
|
|
24389
|
+
byChat = new Map;
|
|
24390
|
+
constructor(maxPerChat = INBOUND_DEDUP_MAX_PER_CHAT) {
|
|
24391
|
+
this.maxPerChat = maxPerChat;
|
|
24392
|
+
}
|
|
24393
|
+
checkAndRecord(chatKey, messageId) {
|
|
24394
|
+
let set2 = this.byChat.get(chatKey);
|
|
24395
|
+
if (set2 == null) {
|
|
24396
|
+
set2 = new Set;
|
|
24397
|
+
this.byChat.set(chatKey, set2);
|
|
24398
|
+
}
|
|
24399
|
+
if (set2.has(messageId))
|
|
24400
|
+
return "duplicate";
|
|
24401
|
+
if (set2.size >= this.maxPerChat) {
|
|
24402
|
+
const oldest = set2.values().next().value;
|
|
24403
|
+
if (oldest !== undefined)
|
|
24404
|
+
set2.delete(oldest);
|
|
24405
|
+
}
|
|
24406
|
+
set2.add(messageId);
|
|
24407
|
+
return "fresh";
|
|
24408
|
+
}
|
|
24409
|
+
clearChat(chatId) {
|
|
24410
|
+
const prefix = `${chatId}:`;
|
|
24411
|
+
for (const key of this.byChat.keys()) {
|
|
24412
|
+
if (key === chatId || key.startsWith(prefix))
|
|
24413
|
+
this.byChat.delete(key);
|
|
24414
|
+
}
|
|
24415
|
+
}
|
|
24416
|
+
size(chatKey) {
|
|
24417
|
+
return this.byChat.get(chatKey)?.size ?? 0;
|
|
24418
|
+
}
|
|
24419
|
+
}
|
|
24420
|
+
function dedupChatKey(chatId, threadId) {
|
|
24421
|
+
return `${chatId}:${threadId == null || threadId === 0 ? "_" : threadId}`;
|
|
24422
|
+
}
|
|
24423
|
+
var INBOUND_DEDUP_MAX_PER_CHAT = 512;
|
|
24424
|
+
|
|
24308
24425
|
// bridge/bridge.ts
|
|
24309
24426
|
var exports_bridge = {};
|
|
24310
24427
|
import { dirname as dirname3, join as join5 } from "path";
|
|
@@ -24330,6 +24447,14 @@ function flushOutstandingPermissionRequests() {
|
|
|
24330
24447
|
}
|
|
24331
24448
|
}
|
|
24332
24449
|
function onInbound(msg) {
|
|
24450
|
+
if (inboundDedupEnabled && shouldDedupInbound(msg)) {
|
|
24451
|
+
const chatKey = dedupChatKey(msg.chatId, msg.threadId);
|
|
24452
|
+
if (inboundDedup.checkAndRecord(chatKey, msg.messageId) === "duplicate") {
|
|
24453
|
+
process.stderr.write(`telegram bridge: dropping duplicate inbound messageId=${msg.messageId} ` + `chat=${chatKey} (already forwarded this turn \u2014 sweep re-delivery, #2094)
|
|
24454
|
+
`);
|
|
24455
|
+
return;
|
|
24456
|
+
}
|
|
24457
|
+
}
|
|
24333
24458
|
mcp.notification({
|
|
24334
24459
|
method: "notifications/claude/channel",
|
|
24335
24460
|
params: {
|
|
@@ -24413,7 +24538,7 @@ async function main() {
|
|
|
24413
24538
|
}
|
|
24414
24539
|
await mcp.connect(new StdioServerTransport);
|
|
24415
24540
|
}
|
|
24416
|
-
var STATE_DIR, SOCKET_PATH, TOPIC_ID, AGENT_NAME, mcp, TOOL_SCHEMAS, EFFECTIVE_TOOL_SCHEMAS, sessionAllowRules, outstandingPermissions, permissionRearmEnabled, ipc = null, sessionTailEnabled, sessionTailHandle = null, ptyTailEnabled, ptyTailHandle = null, CRASH_LOG_PATH;
|
|
24541
|
+
var STATE_DIR, SOCKET_PATH, TOPIC_ID, AGENT_NAME, mcp, TOOL_SCHEMAS, EFFECTIVE_TOOL_SCHEMAS, sessionAllowRules, outstandingPermissions, permissionRearmEnabled, ipc = null, inboundDedup, inboundDedupEnabled, sessionTailEnabled, sessionTailHandle = null, ptyTailEnabled, ptyTailHandle = null, CRASH_LOG_PATH;
|
|
24417
24542
|
var init_bridge = __esm(async () => {
|
|
24418
24543
|
init_server2();
|
|
24419
24544
|
init_stdio2();
|
|
@@ -24492,7 +24617,8 @@ var init_bridge = __esm(async () => {
|
|
|
24492
24617
|
url: { type: "string", description: "Open this URL when tapped. Mutually exclusive with callback_data." },
|
|
24493
24618
|
callback_data: { type: "string", description: "Opaque tag delivered back to the agent on tap. Max 58 chars (gateway prepends an `agent:` prefix to the 64-byte Telegram limit). Mutually exclusive with url." },
|
|
24494
24619
|
ack_text: { type: "string", description: 'Toast text shown to the user the instant they tap this button (#710). Default "\u2713 received". Max ~200 chars (Telegram answerCallbackQuery limit). Has no effect on URL buttons.' },
|
|
24495
|
-
single_use: { type: "boolean", description: `When true (default) tapping any single_use button on the message removes the entire keyboard so the user can't double-fire. Set false on buttons that should stay tappable (e.g. a "Refresh" button). If ANY button on the message has single_use:false the keyboard is preserved on tap.` }
|
|
24620
|
+
single_use: { type: "boolean", description: `When true (default) tapping any single_use button on the message removes the entire keyboard so the user can't double-fire. Set false on buttons that should stay tappable (e.g. a "Refresh" button). If ANY button on the message has single_use:false the keyboard is preserved on tap.` },
|
|
24621
|
+
inline_keyboard_confirm: { type: "boolean", description: `Per-message override for the "\u2705 You chose: <label> \u00b7 HH:MM" body annotation on tap (#789). true forces the annotation even if the agent default is off; false skips it even if the agent default is on; omit to use the agent default. Only applies to single-use keyboards and requires the agent parseMode to be the default html. Has no effect on URL buttons. Note: annotation rebuilds the body from the message's plain text, so formatting entities on the original message are lost.` }
|
|
24496
24622
|
},
|
|
24497
24623
|
required: ["text"]
|
|
24498
24624
|
}
|
|
@@ -24903,6 +25029,12 @@ var init_bridge = __esm(async () => {
|
|
|
24903
25029
|
isError: true
|
|
24904
25030
|
};
|
|
24905
25031
|
}
|
|
25032
|
+
if (inboundDedupEnabled && (tool === "reply" || tool === "stream_reply")) {
|
|
25033
|
+
const replyChatId = args.chat_id;
|
|
25034
|
+
if (typeof replyChatId === "string" && replyChatId.length > 0) {
|
|
25035
|
+
inboundDedup.clearChat(replyChatId);
|
|
25036
|
+
}
|
|
25037
|
+
}
|
|
24906
25038
|
if (result.result && typeof result.result === "object" && "content" in result.result) {
|
|
24907
25039
|
return result.result;
|
|
24908
25040
|
}
|
|
@@ -24966,6 +25098,8 @@ var init_bridge = __esm(async () => {
|
|
|
24966
25098
|
inputPreview: params.input_preview
|
|
24967
25099
|
});
|
|
24968
25100
|
});
|
|
25101
|
+
inboundDedup = new InboundDedup;
|
|
25102
|
+
inboundDedupEnabled = process.env.SWITCHROOM_INBOUND_DEDUP !== "0";
|
|
24969
25103
|
sessionTailEnabled = process.env.SWITCHROOM_SESSION_TAIL !== "off";
|
|
24970
25104
|
if (sessionTailEnabled) {
|
|
24971
25105
|
try {
|