switchroom 0.16.23 → 0.16.27
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 +80 -80
- package/dist/cli/autoaccept-poll.js +8 -8
- package/dist/cli/drive-write-pretool.mjs +10 -10
- package/dist/cli/notion-write-pretool.mjs +82 -82
- package/dist/cli/self-improve-apply-guard-pretool.mjs +6 -0
- package/dist/cli/skill-validate-pretool.mjs +2936 -119
- package/dist/cli/switchroom.js +804 -465
- package/dist/host-control/main.js +169 -163
- package/dist/vault/approvals/kernel-server.js +82 -82
- package/dist/vault/broker/server.js +83 -83
- package/package.json +4 -4
- package/telegram-plugin/answer-stream.ts +20 -49
- package/telegram-plugin/auth-snapshot-format.ts +27 -30
- package/telegram-plugin/auto-fallback-fleet.ts +6 -11
- package/telegram-plugin/bridge/bridge.ts +1 -1
- package/telegram-plugin/card-format.ts +28 -25
- package/telegram-plugin/credits-watch.ts +5 -10
- package/telegram-plugin/dist/bridge/bridge.js +113 -113
- package/telegram-plugin/dist/gateway/gateway.js +2085 -2102
- package/telegram-plugin/dist/server.js +161 -161
- package/telegram-plugin/draft-stream.ts +4 -4
- package/telegram-plugin/format.ts +427 -680
- package/telegram-plugin/gateway/approval-callback.ts +2 -3
- package/telegram-plugin/gateway/approval-card.test.ts +17 -4
- package/telegram-plugin/gateway/approval-card.ts +16 -6
- package/telegram-plugin/gateway/approvals-commands.ts +18 -24
- package/telegram-plugin/gateway/auth-command.ts +74 -74
- package/telegram-plugin/gateway/auth-line.ts +5 -15
- package/telegram-plugin/gateway/boot-card.ts +20 -22
- package/telegram-plugin/gateway/boot-version.ts +3 -2
- package/telegram-plugin/gateway/config-approval-handler.test.ts +35 -33
- package/telegram-plugin/gateway/config-approval-handler.ts +24 -24
- package/telegram-plugin/gateway/config-snapshot.ts +9 -9
- package/telegram-plugin/gateway/diff-preview-card.test.ts +8 -8
- package/telegram-plugin/gateway/diff-preview-card.ts +2 -5
- package/telegram-plugin/gateway/disconnect-flush.ts +0 -4
- package/telegram-plugin/gateway/drive-write-approval.test.ts +10 -10
- package/telegram-plugin/gateway/drive-write-approval.ts +14 -8
- package/telegram-plugin/gateway/effort-command.ts +17 -17
- package/telegram-plugin/gateway/folder-picker-handler.test.ts +8 -2
- package/telegram-plugin/gateway/folder-picker-handler.ts +3 -4
- package/telegram-plugin/gateway/gateway.ts +881 -633
- package/telegram-plugin/gateway/inject-handler.test.ts +15 -13
- package/telegram-plugin/gateway/inject-handler.ts +5 -5
- package/telegram-plugin/gateway/ipc-protocol.ts +33 -1
- package/telegram-plugin/gateway/ipc-server.ts +39 -6
- package/telegram-plugin/gateway/linear-activity.ts +16 -14
- package/telegram-plugin/gateway/linear-setup.ts +1 -1
- package/telegram-plugin/gateway/model-command.ts +25 -25
- package/telegram-plugin/gateway/oversize-card-body.ts +6 -7
- package/telegram-plugin/gateway/permission-timeout.ts +76 -0
- package/telegram-plugin/gateway/skill-proposal-card.ts +167 -0
- package/telegram-plugin/inline-keyboard-callbacks.ts +19 -13
- package/telegram-plugin/issues-card.ts +6 -7
- package/telegram-plugin/model-unavailable.ts +8 -12
- package/telegram-plugin/operator-events-history.ts +1 -1
- package/telegram-plugin/operator-events.ts +24 -28
- package/telegram-plugin/package.json +1 -1
- package/telegram-plugin/pending-work-progress.ts +36 -36
- package/telegram-plugin/permission-title.ts +39 -20
- package/telegram-plugin/pty-partial-handler.ts +5 -13
- package/telegram-plugin/quota-check.ts +5 -5
- package/telegram-plugin/quota-watch.ts +13 -18
- package/telegram-plugin/recent-outbound-dedup.ts +5 -5
- package/telegram-plugin/registry/turns-schema.ts +43 -3
- package/telegram-plugin/retry-api-call.ts +42 -7
- package/telegram-plugin/rich-send.ts +86 -0
- package/telegram-plugin/secret-detect/vault-error.test.ts +6 -6
- package/telegram-plugin/secret-detect/vault-error.ts +29 -22
- package/telegram-plugin/shared/bot-runtime.ts +29 -7
- package/telegram-plugin/silence-poke.ts +26 -69
- package/telegram-plugin/silent-reply-anchor.ts +9 -2
- package/telegram-plugin/slot-banner-driver.ts +9 -6
- package/telegram-plugin/slot-banner.ts +5 -8
- package/telegram-plugin/status-no-truncate.ts +11 -5
- package/telegram-plugin/steering.ts +0 -4
- package/telegram-plugin/stream-controller.ts +59 -62
- package/telegram-plugin/stream-reply-handler.ts +49 -98
- package/telegram-plugin/subagent-watcher.ts +2 -2
- package/telegram-plugin/tests/answer-stream-silent-markers.test.ts +5 -2
- package/telegram-plugin/tests/answer-stream.test.ts +54 -63
- package/telegram-plugin/tests/auth-command-format2.test.ts +4 -4
- package/telegram-plugin/tests/auth-command-vernacular.test.ts +3 -2
- package/telegram-plugin/tests/auth-snapshot-format.test.ts +19 -18
- package/telegram-plugin/tests/auto-fallback-fleet.test.ts +15 -13
- package/telegram-plugin/tests/boot-card-reason-to-render.test.ts +27 -12
- package/telegram-plugin/tests/boot-card-render.test.ts +59 -48
- package/telegram-plugin/tests/boot-version-string.test.ts +0 -0
- package/telegram-plugin/tests/bot-api.harness.ts +23 -1
- package/telegram-plugin/tests/bot-runtime.test.ts +23 -18
- package/telegram-plugin/tests/card-format.test.ts +6 -4
- package/telegram-plugin/tests/config-snapshot.test.ts +1 -1
- package/telegram-plugin/tests/credits-watch.test.ts +5 -5
- package/telegram-plugin/tests/fake-bot-api.ts +58 -4
- package/telegram-plugin/tests/finalize-callback.test.ts +11 -9
- package/telegram-plugin/tests/foreground-nesting.test.ts +1 -1
- package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +3 -13
- package/telegram-plugin/tests/ipc-server-validate-send-outbound.test.ts +6 -2
- package/telegram-plugin/tests/issues-card.test.ts +15 -12
- package/telegram-plugin/tests/length-error-classify.test.ts +131 -0
- package/telegram-plugin/tests/linear-agent-activity.test.ts +8 -5
- package/telegram-plugin/tests/model-command.test.ts +2 -2
- package/telegram-plugin/tests/model-unavailable.test.ts +13 -13
- package/telegram-plugin/tests/multi-turn-continuity.test.ts +6 -10
- package/telegram-plugin/tests/operator-events.test.ts +7 -9
- package/telegram-plugin/tests/paragraph-normalizer.test.ts +273 -0
- package/telegram-plugin/tests/pending-work-progress.test.ts +20 -21
- package/telegram-plugin/tests/permission-no-repeat-wiring.test.ts +12 -2
- package/telegram-plugin/tests/permission-timeout.test.ts +77 -0
- package/telegram-plugin/tests/permission-title.test.ts +88 -41
- package/telegram-plugin/tests/pty-partial-handler.test.ts +8 -8
- package/telegram-plugin/tests/quota-check.test.ts +3 -3
- package/telegram-plugin/tests/quota-watch.test.ts +8 -4
- package/telegram-plugin/tests/secret-detect-delete-must-surface-failures.test.ts +4 -3
- package/telegram-plugin/tests/silence-poke.test.ts +75 -112
- package/telegram-plugin/tests/single-mode-stream-reply.test.ts +137 -0
- package/telegram-plugin/tests/skill-proposal-card.test.ts +103 -0
- package/telegram-plugin/tests/slot-banner-driver.e2e.test.ts +36 -24
- package/telegram-plugin/tests/slot-banner.test.ts +9 -6
- package/telegram-plugin/tests/status-accent.test.ts +29 -32
- package/telegram-plugin/tests/{stream-controller-html-fallback.test.ts → stream-controller-parse-fallback.test.ts} +40 -42
- package/telegram-plugin/tests/stream-controller.test.ts +63 -52
- package/telegram-plugin/tests/stream-reply-error-paths.test.ts +43 -38
- package/telegram-plugin/tests/stream-reply-handler.test.ts +122 -249
- package/telegram-plugin/tests/streaming-e2e.test.ts +35 -30
- package/telegram-plugin/tests/streaming-orchestration.test.ts +29 -28
- package/telegram-plugin/tests/telegram-format.test.ts +120 -1083
- package/telegram-plugin/tests/tool-activity-summary.test.ts +144 -145
- package/telegram-plugin/tests/welcome-text.test.ts +72 -65
- package/telegram-plugin/tests/worker-activity-feed.test.ts +119 -137
- package/telegram-plugin/text-voice-scrub.ts +8 -11
- package/telegram-plugin/tool-activity-summary.ts +29 -29
- package/telegram-plugin/welcome-text.ts +82 -83
- package/telegram-plugin/worker-activity-feed.ts +2 -3
- package/telegram-plugin/html-sanitize.ts +0 -244
- package/telegram-plugin/tests/html-sanitize.test.ts +0 -146
- package/telegram-plugin/tests/parse-mode-rotation.test.ts +0 -162
|
@@ -95,17 +95,17 @@ export interface EffortCommandReply {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
const PERSIST_NOTE =
|
|
98
|
-
'
|
|
98
|
+
'_Session-only — reverts to the configured default on restart. To change the default, set \`thinking_effort:\` in switchroom.yaml and restart._'
|
|
99
99
|
|
|
100
|
-
const LEVELS_INLINE = EFFORT_LEVELS.map(l =>
|
|
100
|
+
const LEVELS_INLINE = EFFORT_LEVELS.map(l => `\`${l}\``).join(' · ')
|
|
101
101
|
|
|
102
102
|
function helpText(deps: EffortCommandDeps, reason?: string): EffortCommandReply {
|
|
103
103
|
const lines: string[] = []
|
|
104
104
|
if (reason) lines.push(`⚠️ ${deps.escapeHtml(reason)}`)
|
|
105
105
|
lines.push(
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
|
|
106
|
+
'**/effort** — show or switch the reasoning effort (faster→smarter)',
|
|
107
|
+
'\`/effort\` — show the configured effort + a tap menu',
|
|
108
|
+
`\`/effort <level>\` — switch the live session (${LEVELS_INLINE})`,
|
|
109
109
|
PERSIST_NOTE,
|
|
110
110
|
)
|
|
111
111
|
return { text: lines.join('\n'), html: true }
|
|
@@ -122,9 +122,9 @@ export async function handleEffortCommand(
|
|
|
122
122
|
const shown = configured && configured.length > 0 ? configured : 'low'
|
|
123
123
|
return {
|
|
124
124
|
text: [
|
|
125
|
-
|
|
126
|
-
`Configured default:
|
|
127
|
-
`Switch the live session: ${EFFORT_LEVELS.map(l =>
|
|
125
|
+
`**Effort — ${deps.escapeHtml(deps.getAgentName())}**`,
|
|
126
|
+
`Configured default: \`${deps.escapeHtml(shown)}\``,
|
|
127
|
+
`Switch the live session: ${EFFORT_LEVELS.map(l => `\`/effort ${l}\``).join(' · ')}`,
|
|
128
128
|
PERSIST_NOTE,
|
|
129
129
|
].join('\n'),
|
|
130
130
|
html: true,
|
|
@@ -136,7 +136,7 @@ export async function handleEffortCommand(
|
|
|
136
136
|
if (!isValidEffortArg(parsed.level)) {
|
|
137
137
|
return helpText(deps, `not a valid effort level: ${parsed.level}`)
|
|
138
138
|
}
|
|
139
|
-
const verbHtml =
|
|
139
|
+
const verbHtml = `\`/effort ${deps.escapeHtml(parsed.level)}\``
|
|
140
140
|
let result: EffortApplyResult
|
|
141
141
|
try {
|
|
142
142
|
result = await deps.applyEffort(deps.getAgentName(), parsed.level)
|
|
@@ -153,17 +153,17 @@ export async function handleEffortCommand(
|
|
|
153
153
|
* say so honestly rather than just claiming success.
|
|
154
154
|
*/
|
|
155
155
|
function applyResultText(level: string, result: EffortApplyResult, deps: EffortCommandDeps): string {
|
|
156
|
-
const verbHtml =
|
|
156
|
+
const verbHtml = `\`/effort ${deps.escapeHtml(level)}\``
|
|
157
157
|
if (result.ok) {
|
|
158
158
|
const lines = [`✅ ${verbHtml} — ${deps.escapeHtml(result.output)}`]
|
|
159
159
|
if (result.confirmed) {
|
|
160
|
-
lines.push('
|
|
160
|
+
lines.push('_Switched mid-conversation — your next turn re-reads the cached history (slower, one time)._')
|
|
161
161
|
}
|
|
162
162
|
lines.push(PERSIST_NOTE)
|
|
163
163
|
return lines.join('\n')
|
|
164
164
|
}
|
|
165
165
|
if (result.reason === 'session_missing') {
|
|
166
|
-
return '❌ tmux session not found — the agent must be running under the tmux supervisor (the default). Remove
|
|
166
|
+
return '❌ tmux session not found — the agent must be running under the tmux supervisor (the default). Remove \`experimental.legacy_pty: true\` if set.'
|
|
167
167
|
}
|
|
168
168
|
if (result.reason === 'confirm_failed') {
|
|
169
169
|
const wedged = result.wedged
|
|
@@ -172,7 +172,7 @@ function applyResultText(level: string, result: EffortApplyResult, deps: EffortC
|
|
|
172
172
|
return `❌ ${verbHtml} — couldn't confirm the switch.${wedged}`
|
|
173
173
|
}
|
|
174
174
|
// apply_unverified
|
|
175
|
-
return `❌ ${verbHtml} — sent, but couldn't confirm it applied. The agent may be mid-turn; check
|
|
175
|
+
return `❌ ${verbHtml} — sent, but couldn't confirm it applied. The agent may be mid-turn; check \`/inject /status\`.`
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// ---------------------------------------------------------------------------
|
|
@@ -220,8 +220,8 @@ export function buildEffortMenu(deps: EffortCommandDeps, highlight?: string): Ef
|
|
|
220
220
|
const live = highlight ?? configured
|
|
221
221
|
return {
|
|
222
222
|
text: [
|
|
223
|
-
|
|
224
|
-
`Default:
|
|
223
|
+
`**Effort — ${deps.escapeHtml(deps.getAgentName())}**`,
|
|
224
|
+
`Default: \`${deps.escapeHtml(configured)}\` · faster → smarter: ${LEVELS_INLINE}`,
|
|
225
225
|
'Tap to switch the live session:',
|
|
226
226
|
PERSIST_NOTE,
|
|
227
227
|
].join('\n'),
|
|
@@ -260,8 +260,8 @@ export async function handleEffortMenuCallback(
|
|
|
260
260
|
const result = await deps.applyEffort(deps.getAgentName(), level)
|
|
261
261
|
if (result.ok) {
|
|
262
262
|
banner = result.confirmed
|
|
263
|
-
? `✅ Effort →
|
|
264
|
-
: `✅ Effort →
|
|
263
|
+
? `✅ Effort → \`${deps.escapeHtml(level)}\` (mid-conversation: next turn re-reads history)`
|
|
264
|
+
: `✅ Effort → \`${deps.escapeHtml(level)}\` for this session`
|
|
265
265
|
selected = level
|
|
266
266
|
} else if (result.reason === 'session_missing') {
|
|
267
267
|
banner = '❌ tmux session not found — is the agent running under the supervisor?'
|
|
@@ -42,12 +42,18 @@ function fakeCtx(userId = 12345): { ctx: Context; spy: FakeCtx } {
|
|
|
42
42
|
});
|
|
43
43
|
return { message_id: 1 };
|
|
44
44
|
},
|
|
45
|
-
editMessageText: async (
|
|
45
|
+
editMessageText: async (
|
|
46
|
+
text: string | { markdown: string },
|
|
47
|
+
opts?: { reply_markup?: { inline_keyboard?: unknown[][] } },
|
|
48
|
+
) => {
|
|
46
49
|
const rows = (opts?.reply_markup?.inline_keyboard ?? []) as Array<
|
|
47
50
|
Array<{ text: string }>
|
|
48
51
|
>;
|
|
52
|
+
// #2669: the rich path passes `{ markdown }`; normalize to the body
|
|
53
|
+
// string so the substring assertions keep working.
|
|
54
|
+
const body = typeof text === "object" && text != null ? text.markdown : text;
|
|
49
55
|
spy.edits.push({
|
|
50
|
-
text,
|
|
56
|
+
text: body,
|
|
51
57
|
keyboardRows: opts?.reply_markup
|
|
52
58
|
? rows.map((r) => r.map((b) => b.text))
|
|
53
59
|
: undefined,
|
|
@@ -302,8 +302,8 @@ async function recordGrantAndConfirm(
|
|
|
302
302
|
|
|
303
303
|
const confirmText =
|
|
304
304
|
`✅ Granted ${deps.agentName} access to folder ${parsed.folder_id}\n` +
|
|
305
|
-
`Scope:
|
|
306
|
-
`Revoke with:
|
|
305
|
+
`Scope: \`${scope}\`\n` +
|
|
306
|
+
`Revoke with: \`/approvals revoke ${decisionId}\``;
|
|
307
307
|
|
|
308
308
|
// Keep an [Open in Drive] URL button on the confirmation so the
|
|
309
309
|
// operator can verify which folder they granted.
|
|
@@ -312,8 +312,7 @@ async function recordGrantAndConfirm(
|
|
|
312
312
|
`https://drive.google.com/drive/folders/${parsed.folder_id}`,
|
|
313
313
|
);
|
|
314
314
|
try {
|
|
315
|
-
await ctx.editMessageText(confirmText, {
|
|
316
|
-
parse_mode: "HTML",
|
|
315
|
+
await ctx.editMessageText({ markdown: confirmText }, {
|
|
317
316
|
reply_markup: kb,
|
|
318
317
|
});
|
|
319
318
|
} catch {
|