switchroom 0.13.51 → 0.13.53
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 +317 -132
- package/dist/auth-broker/index.js +494 -156
- package/dist/cli/drive-write-pretool.mjs +18 -3
- package/dist/cli/switchroom.js +2452 -1114
- package/dist/host-control/main.js +246 -127
- package/dist/vault/approvals/kernel-server.js +8269 -8146
- package/dist/vault/broker/server.js +2811 -2688
- package/package.json +1 -1
- package/profiles/_base/start.sh.hbs +17 -4
- package/profiles/_shared/agent-self-service.md.hbs +12 -22
- package/profiles/coding/CLAUDE.md.hbs +1 -1
- package/profiles/default/CLAUDE.md.hbs +8 -1
- package/profiles/executive-assistant/CLAUDE.md.hbs +1 -1
- package/profiles/health-coach/CLAUDE.md.hbs +1 -1
- package/skills/switchroom-status/SKILL.md +8 -6
- package/telegram-plugin/chat-lock.ts +87 -19
- package/telegram-plugin/dist/gateway/gateway.js +752 -120
- package/telegram-plugin/gateway/disconnect-flush.ts +32 -0
- package/telegram-plugin/gateway/gateway.ts +258 -55
- package/telegram-plugin/gateway/inbound-coalesce.ts +19 -6
- package/telegram-plugin/stream-reply-handler.ts +10 -8
- package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +116 -0
- package/telegram-plugin/tests/inbound-coalesce.test.ts +20 -4
- package/telegram-plugin/tests/outbound-ordering.test.ts +228 -0
- package/telegram-plugin/tests/parallel-turns-deadlock-fix.test.ts +217 -0
- package/telegram-plugin/tests/typing-wrap.test.ts +65 -8
- package/telegram-plugin/typing-wrap.ts +43 -21
|
@@ -37,6 +37,11 @@ export interface DisconnectFlushDeps<Ctrl extends { finalize: (reason?: 'done' |
|
|
|
37
37
|
activeReactionMsgIds: Map<string, { chatId: string; messageId: number }>
|
|
38
38
|
/** Mirror map: same keys → turn-start timestamps. */
|
|
39
39
|
activeTurnStartedAt: Map<string, number>
|
|
40
|
+
/** PR3b: keys claude has actually been handed (delivered, not just
|
|
41
|
+
* received). Cleared on disconnect for the same reason as
|
|
42
|
+
* activeTurnStartedAt — the bridge just died, every turn it
|
|
43
|
+
* was handed is dead by definition. */
|
|
44
|
+
claudeBusyKeys: Set<string>
|
|
40
45
|
|
|
41
46
|
/** Open draft-stream handles keyed by chat:thread:replyId. */
|
|
42
47
|
activeDraftStreams: Map<string, Stream>
|
|
@@ -78,6 +83,7 @@ export function flushOnAgentDisconnect<
|
|
|
78
83
|
activeStatusReactions,
|
|
79
84
|
activeReactionMsgIds,
|
|
80
85
|
activeTurnStartedAt,
|
|
86
|
+
claudeBusyKeys,
|
|
81
87
|
activeDraftStreams,
|
|
82
88
|
activeDraftParseModes,
|
|
83
89
|
clearActiveReactions,
|
|
@@ -105,6 +111,7 @@ export function flushOnAgentDisconnect<
|
|
|
105
111
|
activeStatusReactions.delete(key)
|
|
106
112
|
activeReactionMsgIds.delete(key)
|
|
107
113
|
activeTurnStartedAt.delete(key)
|
|
114
|
+
claudeBusyKeys.delete(key)
|
|
108
115
|
}
|
|
109
116
|
clearActiveReactions()
|
|
110
117
|
|
|
@@ -124,6 +131,7 @@ export function flushOnAgentDisconnect<
|
|
|
124
131
|
for (const k of danglingKeys) {
|
|
125
132
|
activeTurnStartedAt.delete(k)
|
|
126
133
|
activeReactionMsgIds.delete(k)
|
|
134
|
+
claudeBusyKeys.delete(k)
|
|
127
135
|
}
|
|
128
136
|
log(
|
|
129
137
|
`telegram gateway: disconnect-flush swept ${danglingKeys.length} dangling turn key(s) ` +
|
|
@@ -132,6 +140,30 @@ export function flushOnAgentDisconnect<
|
|
|
132
140
|
onDanglingTurnsSwept?.(danglingKeys)
|
|
133
141
|
}
|
|
134
142
|
|
|
143
|
+
// PR3b orphan-sweep (#1880 follow-up): claudeBusyKeys can hold keys
|
|
144
|
+
// that activeTurnStartedAt does NOT — specifically when a synthetic
|
|
145
|
+
// inbound (cron via onInjectInbound, reaction dispatch, vault
|
|
146
|
+
// grant-approved / -denied / save-discarded / -failed / -completed,
|
|
147
|
+
// button-callback) was delivered. Those paths bypass handleInbound's
|
|
148
|
+
// fresh-turn branch (which is what would set activeTurnStartedAt),
|
|
149
|
+
// so the sweep loop above wouldn't notice them. Pre-PR3b this was
|
|
150
|
+
// invisible because the fleet gate read activeTurnStartedAt.size —
|
|
151
|
+
// synthetic-only turns never registered. PR3b's claudeBusyKeys.add
|
|
152
|
+
// is the more-accurate "claude is busy on this" gate, which means
|
|
153
|
+
// a synthetic-delivered turn that dies WITHOUT turn_end leaves an
|
|
154
|
+
// orphan that the activeTurnStartedAt-keyed sweep can't see.
|
|
155
|
+
// Cure: clear any leftover busy keys here. Bridge died → every
|
|
156
|
+
// busy key is dead by definition. Same justification as the
|
|
157
|
+
// dangling-sweep above for activeTurnStartedAt.
|
|
158
|
+
if (claudeBusyKeys.size > 0) {
|
|
159
|
+
const orphanCount = claudeBusyKeys.size
|
|
160
|
+
claudeBusyKeys.clear()
|
|
161
|
+
log(
|
|
162
|
+
`telegram gateway: disconnect-flush cleared ${orphanCount} orphan claudeBusyKeys ` +
|
|
163
|
+
`entr${orphanCount === 1 ? 'y' : 'ies'} (synthetic-inbound deliveries that never turn_ended)`,
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
135
167
|
// Stop coalesce timers that could emit into a finalized draft stream, but
|
|
136
168
|
// preserve chats with pendingCompletion=true — those have background
|
|
137
169
|
// sub-agents that legitimately outlive the parent bridge disconnect. The
|