switchroom 0.12.16 → 0.12.18
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 +82 -81
- package/dist/auth-broker/index.js +82 -81
- package/dist/cli/drive-write-pretool.mjs +10 -10
- package/dist/cli/skill-validate-pretool.mjs +72 -72
- package/dist/cli/switchroom.js +359 -358
- package/dist/host-control/main.js +101 -100
- package/dist/vault/approvals/kernel-server.js +84 -83
- package/dist/vault/broker/server.js +85 -84
- package/package.json +1 -1
- package/telegram-plugin/bridge/bridge.ts +7 -0
- package/telegram-plugin/dist/bridge/bridge.js +115 -113
- package/telegram-plugin/dist/gateway/gateway.js +561 -287
- package/telegram-plugin/dist/server.js +163 -161
- package/telegram-plugin/gateway/compact-notify.ts +94 -0
- package/telegram-plugin/gateway/gateway.ts +261 -4
- package/telegram-plugin/gateway/ipc-protocol.ts +9 -0
- package/telegram-plugin/gateway/proactive-compact.ts +84 -0
- package/telegram-plugin/tests/compact-notify.test.ts +138 -0
- package/telegram-plugin/tests/proactive-compact.test.ts +101 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
decideProactiveCompact,
|
|
4
|
+
initialCompactState,
|
|
5
|
+
COMPACT_COOLDOWN_TURNS,
|
|
6
|
+
COMPACT_REARM_FRACTION,
|
|
7
|
+
type CompactState,
|
|
8
|
+
} from '../gateway/proactive-compact.js'
|
|
9
|
+
|
|
10
|
+
const CAP = 190_000
|
|
11
|
+
|
|
12
|
+
// Drive the state machine over a sequence of occupancy readings,
|
|
13
|
+
// returning the index of every evaluation that fired.
|
|
14
|
+
function run(occ: number[], start: CompactState = initialCompactState()) {
|
|
15
|
+
let state = start
|
|
16
|
+
const fires: number[] = []
|
|
17
|
+
occ.forEach((o, i) => {
|
|
18
|
+
const d = decideProactiveCompact(state, o, CAP)
|
|
19
|
+
state = d.state
|
|
20
|
+
if (d.fire) fires.push(i)
|
|
21
|
+
})
|
|
22
|
+
return { state, fires }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('decideProactiveCompact', () => {
|
|
26
|
+
it('does not fire below the cap', () => {
|
|
27
|
+
const { fires } = run([0, 50_000, 150_000, CAP - 1])
|
|
28
|
+
expect(fires).toEqual([])
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('fires exactly once when occupancy reaches the cap, then disarms', () => {
|
|
32
|
+
// Stays high after the fire (compaction has not landed yet).
|
|
33
|
+
const { fires } = run([CAP, CAP, CAP])
|
|
34
|
+
expect(fires).toEqual([0])
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('fires at occupancy strictly above the cap too', () => {
|
|
38
|
+
const { fires } = run([CAP + 25_000])
|
|
39
|
+
expect(fires).toEqual([0])
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('burns exactly COMPACT_COOLDOWN_TURNS idle evals after a fire before re-considering', () => {
|
|
43
|
+
// Fire at 0, then occupancy stays pegged high. The cooldown must
|
|
44
|
+
// swallow the next COMPACT_COOLDOWN_TURNS evals with no fire, and
|
|
45
|
+
// because it is still above the re-arm band it never re-arms ->
|
|
46
|
+
// never fires again. (Livelock guard.)
|
|
47
|
+
const seq = new Array(1 + COMPACT_COOLDOWN_TURNS + 5).fill(CAP)
|
|
48
|
+
const { fires } = run(seq)
|
|
49
|
+
expect(fires).toEqual([0])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('re-arms only after occupancy falls below REARM_FRACTION × cap, never on the arming pass', () => {
|
|
53
|
+
const lowBand = CAP * COMPACT_REARM_FRACTION
|
|
54
|
+
// fire(0) -> cooldown(1..3) -> still high(4) stays disarmed ->
|
|
55
|
+
// drop just below band(5): arms but does NOT fire same pass ->
|
|
56
|
+
// climb back to cap(6): fires again.
|
|
57
|
+
const seq = [
|
|
58
|
+
CAP, // 0 fire
|
|
59
|
+
CAP, // 1 cooldown
|
|
60
|
+
CAP, // 2 cooldown
|
|
61
|
+
CAP, // 3 cooldown
|
|
62
|
+
CAP, // 4 disarmed, above band -> hold
|
|
63
|
+
lowBand - 1, // 5 re-arm, must NOT fire here
|
|
64
|
+
CAP, // 6 armed + at cap -> fire
|
|
65
|
+
]
|
|
66
|
+
const { fires } = run(seq)
|
|
67
|
+
expect(fires).toEqual([0, 6])
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('does not re-arm if occupancy only drops to the band but not below it', () => {
|
|
71
|
+
const lowBand = CAP * COMPACT_REARM_FRACTION
|
|
72
|
+
// After cooldown, occupancy sits exactly at the band (not strictly
|
|
73
|
+
// below) forever -> never re-arms -> only the first fire.
|
|
74
|
+
const seq = [CAP, CAP, CAP, CAP, lowBand, lowBand, lowBand, CAP, CAP]
|
|
75
|
+
const { fires } = run(seq)
|
|
76
|
+
expect(fires).toEqual([0])
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('full healthy cycle: fire, compaction shrinks context, climbs again, fires again', () => {
|
|
80
|
+
const seq = [
|
|
81
|
+
120_000, // below cap
|
|
82
|
+
CAP, // fire (idx 1)
|
|
83
|
+
30_000, // cooldown 1 (post-compact, small)
|
|
84
|
+
35_000, // cooldown 2
|
|
85
|
+
40_000, // cooldown 3
|
|
86
|
+
45_000, // disarmed, below band -> re-arm (no fire)
|
|
87
|
+
90_000, // armed, below cap -> hold
|
|
88
|
+
CAP + 5_000, // fire again (idx 7)
|
|
89
|
+
]
|
|
90
|
+
const { fires } = run(seq)
|
|
91
|
+
expect(fires).toEqual([1, 7])
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('never fires twice in immediate succession even with no cooldown left if still disarmed', () => {
|
|
95
|
+
// Construct a state that is past cooldown but disarmed, occupancy
|
|
96
|
+
// pegged at cap: must hold (not fire) until it drops below band.
|
|
97
|
+
const stuck: CompactState = { armed: false, cooldownTurns: 0 }
|
|
98
|
+
const { fires } = run([CAP, CAP, CAP, CAP], stuck)
|
|
99
|
+
expect(fires).toEqual([])
|
|
100
|
+
})
|
|
101
|
+
})
|