From 52c196c723aa8a79a661fcae82052284fd827361 Mon Sep 17 00:00:00 2001 From: Simon Klee Date: Fri, 17 Apr 2026 15:49:52 +0200 Subject: [PATCH] run: prewarm interactive transport in background --- .../src/cli/cmd/run/runtime.lifecycle.ts | 2 +- packages/opencode/src/cli/cmd/run/runtime.ts | 81 +++++++++++++++---- 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/packages/opencode/src/cli/cmd/run/runtime.lifecycle.ts b/packages/opencode/src/cli/cmd/run/runtime.lifecycle.ts index 3c538aea2d..4b5f3d4f4a 100644 --- a/packages/opencode/src/cli/cmd/run/runtime.lifecycle.ts +++ b/packages/opencode/src/cli/cmd/run/runtime.lifecycle.ts @@ -221,7 +221,7 @@ export async function createRuntimeLifecycle(input: LifecycleInput): Promise { + const close = async (next: { showExit: boolean; sessionTitle?: string; sessionID?: string }) => { if (closed) { return } diff --git a/packages/opencode/src/cli/cmd/run/runtime.ts b/packages/opencode/src/cli/cmd/run/runtime.ts index 2632d70c75..2700f94bc9 100644 --- a/packages/opencode/src/cli/cmd/run/runtime.ts +++ b/packages/opencode/src/cli/cmd/run/runtime.ts @@ -272,24 +272,65 @@ async function runInteractiveRuntime(input: RunRuntimeInput): Promise { handle: Awaited["createSessionTransport"]>> } | undefined - const ensureStream = async () => { + let loading: + | Promise<{ + mod: Awaited + handle: Awaited["createSessionTransport"]>> + }> + | undefined + const ensureStream = () => { if (stream) { - return stream + return Promise.resolve(stream) } - await ensureSession() - const mod = await streamTask - const handle = await mod.createSessionTransport({ - sdk: ctx.sdk, - sessionID, - thinking: input.thinking, - limits: () => limits, - footer, - trace: log, - }) - selectSubagent = handle.selectSubagent - stream = { mod, handle } - return stream + if (loading) { + return loading + } + + const task = (async () => { + await ensureSession() + if (footer.isClosed) { + throw new Error("runtime closed") + } + + const mod = await streamTask + if (footer.isClosed) { + throw new Error("runtime closed") + } + + const handle = await mod.createSessionTransport({ + sdk: ctx.sdk, + sessionID, + thinking: input.thinking, + limits: () => limits, + footer, + trace: log, + }) + if (footer.isClosed) { + await handle.close() + throw new Error("runtime closed") + } + + selectSubagent = handle.selectSubagent + const next = { mod, handle } + stream = next + return next + })() + + loading = task + task.then( + () => { + if (loading === task) { + loading = undefined + } + }, + () => { + if (loading === task) { + loading = undefined + } + }, + ) + return task } try { @@ -299,6 +340,16 @@ async function runInteractiveRuntime(input: RunRuntimeInput): Promise { await ensureStream() } + if (!eager && input.resolveSession) { + queueMicrotask(() => { + if (footer.isClosed) { + return + } + + void ensureStream().catch(() => {}) + }) + } + try { if (demo) { await demo.start()