switchroom 0.13.65 → 0.14.1
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 +80 -80
- package/dist/auth-broker/index.js +96 -81
- package/dist/cli/drive-write-pretool.mjs +10 -10
- package/dist/cli/notion-write-pretool.mjs +82 -82
- package/dist/cli/skill-validate-pretool.mjs +72 -72
- package/dist/cli/switchroom.js +1883 -1479
- package/dist/host-control/main.js +149 -149
- package/dist/vault/approvals/kernel-server.js +82 -82
- package/dist/vault/broker/server.js +83 -83
- package/package.json +1 -1
- package/profiles/_shared/telegram-style.md.hbs +1 -1
- package/telegram-plugin/auth-snapshot-format.ts +47 -1
- package/telegram-plugin/dist/bridge/bridge.js +112 -112
- package/telegram-plugin/dist/gateway/gateway.js +1226 -696
- package/telegram-plugin/dist/server.js +160 -160
- package/telegram-plugin/gateway/boot-card.ts +100 -0
- package/telegram-plugin/gateway/config-snapshot.ts +274 -0
- package/telegram-plugin/gateway/gateway.ts +256 -36
- package/telegram-plugin/operator-events.ts +2 -10
- package/telegram-plugin/quota-watch.ts +276 -0
- package/telegram-plugin/tests/auth-snapshot-format.test.ts +133 -1
- package/telegram-plugin/tests/boot-card-render.test.ts +93 -0
- package/telegram-plugin/tests/config-snapshot.test.ts +409 -0
- package/telegram-plugin/tests/operator-events.test.ts +12 -6
- package/telegram-plugin/tests/quota-watch.test.ts +366 -0
- package/telegram-plugin/tests/tool-activity-summary.test.ts +66 -0
- package/telegram-plugin/tests/turn-flush-safety.test.ts +48 -0
- package/telegram-plugin/tool-activity-summary.ts +137 -0
- package/telegram-plugin/turn-flush-safety.ts +47 -0
- package/telegram-plugin/uat/assertions.ts +4 -4
|
@@ -50,6 +50,48 @@ export function isSilentFlushMarker(text: string | undefined): boolean {
|
|
|
50
50
|
return SILENT_MARKERS.has(trimmed.toUpperCase())
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// Trivial end-of-turn confirmations the model emits as terminal text after
|
|
54
|
+
// calling reply (e.g. "Sent." once the reply tool returns). On their own
|
|
55
|
+
// they're harmless; the danger is when they're glued to silent markers
|
|
56
|
+
// across Stop-hook re-prompt cycles into a composite blob like
|
|
57
|
+
// "Sent.\nNO_REPLY\nNO_REPLY" — which `isSilentFlushMarker` can't match
|
|
58
|
+
// (multi-line, over the length guard) so it leaks to chat. See
|
|
59
|
+
// `isCompositeSilentNoise`.
|
|
60
|
+
const TRIVIAL_CONFIRMATIONS = new Set(['SENT', 'DONE', 'OK', 'OKAY', 'ACK'])
|
|
61
|
+
|
|
62
|
+
function isTrivialConfirmationLine(line: string): boolean {
|
|
63
|
+
let t = line.trim()
|
|
64
|
+
if (t.length === 0 || t.length > 8) return false
|
|
65
|
+
if (/\W$/.test(t)) t = t.slice(0, -1) // strip a single trailing punct ("Sent.")
|
|
66
|
+
return TRIVIAL_CONFIRMATIONS.has(t.toUpperCase())
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Recognise a multi-line composite that is *entirely* silent noise — every
|
|
71
|
+
* non-empty line is a silent marker (NO_REPLY / HEARTBEAT_OK) or a trivial
|
|
72
|
+
* confirmation ("Sent."), AND at least one line is a real silent marker.
|
|
73
|
+
*
|
|
74
|
+
* Backstop for the Stop-hook re-prompt leak: the model replies cleanly,
|
|
75
|
+
* emits a terminal "Sent.", gets re-prompted by the silent-end Stop hook,
|
|
76
|
+
* answers "NO_REPLY" one or more times, and the accumulated `capturedText`
|
|
77
|
+
* ("Sent.\nNO_REPLY\nNO_REPLY") flushes as a visible message because
|
|
78
|
+
* `isSilentFlushMarker` only matches a single sentinel. Requiring ≥1 hard
|
|
79
|
+
* marker keeps this conservative — a standalone "Sent." (no NO_REPLY) is NOT
|
|
80
|
+
* suppressed here, so we never silently drop a turn that wasn't already
|
|
81
|
+
* signalling "nothing to add".
|
|
82
|
+
*/
|
|
83
|
+
export function isCompositeSilentNoise(text: string | undefined): boolean {
|
|
84
|
+
if (typeof text !== 'string') return false
|
|
85
|
+
const lines = text
|
|
86
|
+
.split('\n')
|
|
87
|
+
.map(l => l.trim())
|
|
88
|
+
.filter(l => l.length > 0)
|
|
89
|
+
if (lines.length === 0) return false
|
|
90
|
+
const hasMarker = lines.some(l => isSilentFlushMarker(l))
|
|
91
|
+
if (!hasMarker) return false
|
|
92
|
+
return lines.every(l => isSilentFlushMarker(l) || isTrivialConfirmationLine(l))
|
|
93
|
+
}
|
|
94
|
+
|
|
53
95
|
export type FlushDecision =
|
|
54
96
|
| { kind: 'flush'; text: string }
|
|
55
97
|
| { kind: 'skip'; reason: FlushSkipReason }
|
|
@@ -115,6 +157,11 @@ export function decideTurnFlush(input: FlushDecisionInput): FlushDecision {
|
|
|
115
157
|
const joined = input.capturedText.join('\n').trim()
|
|
116
158
|
if (joined.length === 0) return { kind: 'skip', reason: 'empty-text' }
|
|
117
159
|
if (isSilentFlushMarker(joined)) return { kind: 'skip', reason: 'silent-marker' }
|
|
160
|
+
// Composite silent noise — e.g. "Sent.\nNO_REPLY\nNO_REPLY" accumulated
|
|
161
|
+
// across Stop-hook re-prompt cycles. The single-sentinel check above
|
|
162
|
+
// misses it (multi-line, over the length guard); without this the blob
|
|
163
|
+
// leaks to chat as a visible message.
|
|
164
|
+
if (isCompositeSilentNoise(joined)) return { kind: 'skip', reason: 'silent-marker' }
|
|
118
165
|
return { kind: 'flush', text: joined }
|
|
119
166
|
}
|
|
120
167
|
|
|
@@ -337,10 +337,10 @@ export async function waitForCardPhase(
|
|
|
337
337
|
/**
|
|
338
338
|
* Detect the progress card's phase from its rendered text.
|
|
339
339
|
*
|
|
340
|
-
* The actual card render
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
340
|
+
* The actual card render uses emoji markers in the header: `✅` for
|
|
341
|
+
* done, `❌` for errors, `⚙️` while working (foreground), `🌀` for
|
|
342
|
+
* Background (parent done but fleet still running, see #862 /
|
|
343
|
+
* reference/conversational-pacing.md),
|
|
344
344
|
* and `⏳` during the boot-card window. These markers are stable
|
|
345
345
|
* enough to key on for UAT — finer parsing (checklist items,
|
|
346
346
|
* sub-agent row content) is out of scope.
|