thinkpool-pair 0.7.200 → 0.7.201
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/bridge.mjs +15 -12
- package/claude-session.mjs +4 -1
- package/package.json +1 -1
package/bridge.mjs
CHANGED
|
@@ -844,15 +844,16 @@ const sessions = new Map()
|
|
|
844
844
|
let attachedId = null
|
|
845
845
|
let shuttingDown = false
|
|
846
846
|
|
|
847
|
-
// Background
|
|
848
|
-
//
|
|
849
|
-
//
|
|
850
|
-
//
|
|
851
|
-
//
|
|
852
|
-
//
|
|
847
|
+
// Background warming is OPT-IN. Even a per-room cap multiplies under the account
|
|
848
|
+
// supervisor: four rooms at concurrency 3 launched twelve Claude SDK cold boots at once,
|
|
849
|
+
// stretching measured readiness from ~15s to 40–66s and leaving every idle process
|
|
850
|
+
// resident. Restored transcripts already paint immediately and sendTurn boots a cold lane
|
|
851
|
+
// on demand, so the safe default is zero speculative runtimes. TP_BACKGROUND_WARM=1 keeps
|
|
852
|
+
// the old behaviour available for a deliberately single-room host.
|
|
853
853
|
const warmQueue = []
|
|
854
854
|
let warmingCount = 0
|
|
855
855
|
const WARM_CONCURRENCY = 3
|
|
856
|
+
const BACKGROUND_WARM_ENABLED = process.env.TP_BACKGROUND_WARM === '1'
|
|
856
857
|
function pumpWarm() {
|
|
857
858
|
while (warmingCount < WARM_CONCURRENCY && warmQueue.length) {
|
|
858
859
|
const e = warmQueue.shift()
|
|
@@ -2693,7 +2694,10 @@ channel
|
|
|
2693
2694
|
// through to the SDK default when absent. Stamped on the entry so the announce
|
|
2694
2695
|
// carries it at open (chip shows the model immediately, not the branch).
|
|
2695
2696
|
const runtime = structuredRuntime(payload.cmd)
|
|
2696
|
-
|
|
2697
|
+
// Opening a tab is not work. Paint and announce it immediately, then cold-boot the
|
|
2698
|
+
// expensive Claude/Codex runtime on its first real turn. This keeps a fresh terminal
|
|
2699
|
+
// instant and prevents abandoned tabs from becoming permanent resident processes.
|
|
2700
|
+
openStructured({ id: payload.id, runtime, mode: payload.mode, model: payload.model || undefined, provider: runtime === 'codex' ? undefined : payload.provider || undefined, defer: true })
|
|
2697
2701
|
process.stderr.write(`\n ◆ web opened a structured "${payload.cmd}" session (${payload.mode || 'default'}${payload.model ? `, model ${payload.model}` : ''}).\n`)
|
|
2698
2702
|
return
|
|
2699
2703
|
}
|
|
@@ -2829,7 +2833,7 @@ channel
|
|
|
2829
2833
|
// ── structured-session control (Phase 2) ──
|
|
2830
2834
|
.on('broadcast', { event: 'code-open' }, ({ payload }) => {
|
|
2831
2835
|
if (payload?.host && payload.host !== name) return
|
|
2832
|
-
openStructured({ id: payload?.id || randomUUID(), runtime: payload?.runtime, model: payload?.model, provider: payload?.runtime === 'codex' ? undefined : payload?.provider, resume: payload?.resume, mode: payload?.mode })
|
|
2836
|
+
openStructured({ id: payload?.id || randomUUID(), runtime: payload?.runtime, model: payload?.model, provider: payload?.runtime === 'codex' ? undefined : payload?.provider, resume: payload?.resume, mode: payload?.mode, defer: true })
|
|
2833
2837
|
})
|
|
2834
2838
|
.on('broadcast', { event: 'code-turn' }, async ({ payload }) => {
|
|
2835
2839
|
const s = payload?.term && sessions.get(payload.term)
|
|
@@ -3220,10 +3224,9 @@ channel
|
|
|
3220
3224
|
// saved-session restore above still runs unconditionally, so a bridge
|
|
3221
3225
|
// restart resumes backgrounded sessions regardless of this guard.
|
|
3222
3226
|
else if (attachedCmd) openStructured({ id: randomUUID(), runtime: structuredRuntime(attachedCmd) })
|
|
3223
|
-
//
|
|
3224
|
-
//
|
|
3225
|
-
|
|
3226
|
-
setTimeout(() => {
|
|
3227
|
+
// Optional compatibility lever for deliberately single-room hosts. Account-mode
|
|
3228
|
+
// and normal standalone launches leave restored idle lanes truly lazy by default.
|
|
3229
|
+
if (BACKGROUND_WARM_ENABLED) setTimeout(() => {
|
|
3227
3230
|
for (const [, e] of sessions) if (e.deferred && !e.warmed && !e.warming && !e.session?.started) warmQueue.push(e)
|
|
3228
3231
|
if (warmQueue.length) { process.stderr.write(`\n ◆ background-warming ${warmQueue.length} idle terminal(s) (≤${WARM_CONCURRENCY} at a time)…\n`); pumpWarm() }
|
|
3229
3232
|
}, 6000)
|
package/claude-session.mjs
CHANGED
|
@@ -239,7 +239,9 @@ export function startClaudeSession({ cwd, model, effort: initialEffort = 'high',
|
|
|
239
239
|
// long time"; settingSources:['user','project','local'] boots every host MCP
|
|
240
240
|
// server + SessionStart hook + plugin before init. This is the A-side baseline;
|
|
241
241
|
// open a terminal with TP_MCP_STRICT=1 (below) for the B-side to isolate MCP's share.
|
|
242
|
-
|
|
242
|
+
// A lazy lane may sit unopened for hours. Start the latency clock when query() really
|
|
243
|
+
// launches, not when the lightweight tab/session wrapper is created.
|
|
244
|
+
let spawnT0 = null
|
|
243
245
|
let readyLogged = false
|
|
244
246
|
let modelsSent = false // one-shot: emit the SDK's supported-model list on first init
|
|
245
247
|
let sdkToolsChecked = false // one-shot: run the AskUserQuestion regression guard on the first init carrying tools[]
|
|
@@ -804,6 +806,7 @@ export function startClaudeSession({ cwd, model, effort: initialEffort = 'high',
|
|
|
804
806
|
}
|
|
805
807
|
|
|
806
808
|
const runQuery = async () => {
|
|
809
|
+
if (spawnT0 == null) spawnT0 = Date.now()
|
|
807
810
|
started = true
|
|
808
811
|
// Per-query AbortController (child of the session `ac`): lets a model switch kill
|
|
809
812
|
// just this query. Resolve the previous qDone in case it's still pending.
|