mirror of
https://github.com/stablyai/orca.git
synced 2026-10-10 16:02:53 +00:00
fix(runtime): join the resize repaint's seed without per-PTY seed state
Replaces the rendererSeedsByPtyId map with a check over existing state. If an on-data seed was already considered before the subscribe's hydrate, the subscribe awaits the model's write chain and reads the outcome from the hydration state, the installed model and the provider-preferred flag. Claude-Session: lane-host-hydrate
This commit is contained in:
@@ -130,8 +130,6 @@ export class OrcaRuntimeWithFitOverrideListeners extends OrcaRuntimeWithStopRequ
|
||||
// Absent → hydration has not been considered yet for this PTY.
|
||||
// See docs/mobile-prefer-renderer-scrollback.md.
|
||||
protected headlessHydrationState = new Map<string, 'pending' | 'done'>()
|
||||
/** The model's renderer seed, resolving true once written; lives as long as the model. */
|
||||
protected rendererSeedsByPtyId = new Map<string, Promise<boolean>>()
|
||||
|
||||
// Why: mobile-fit overrides are keyed by ptyId (not terminal handle) because
|
||||
// handles can be reissued while the PTY identity is stable. In-memory only —
|
||||
|
||||
@@ -110,19 +110,32 @@ export class OrcaRuntimeWithMaybeHydrateHeadlessFromRenderer extends OrcaRuntime
|
||||
}
|
||||
}
|
||||
})
|
||||
const seed = state.writeChain.then(() => seeded)
|
||||
this.rendererSeedsByPtyId.set(ptyId, seed)
|
||||
return seed
|
||||
return state.writeChain.then(() => seeded)
|
||||
}
|
||||
|
||||
/** Public: a phone fit resizes the PTY, but an idle TUI sends no byte to hydrate on. Resolves
|
||||
* true once the model holds the pane's screen reflowed onto the PTY's current grid. */
|
||||
hydrateHeadlessTerminalFromRenderer(ptyId: string): Promise<boolean> {
|
||||
// Why join: a resize repaint can run the on-data seed first; its result answers this caller too.
|
||||
const priorHydration = this.headlessHydrationState.get(ptyId)
|
||||
const seed = this.maybeHydrateHeadlessFromRenderer(ptyId)
|
||||
if (seed) {
|
||||
return seed
|
||||
}
|
||||
// Why: a resize repaint can run the on-data seed before this call; join its outcome instead.
|
||||
return priorHydration ? this.readRendererSeedOutcome(ptyId) : Promise.resolve(false)
|
||||
}
|
||||
|
||||
private async readRendererSeedOutcome(ptyId: string): Promise<boolean> {
|
||||
const state = this.headlessTerminals.get(ptyId)
|
||||
if (!state) {
|
||||
return false
|
||||
}
|
||||
await state.writeChain
|
||||
// Why: a failed seed also ends 'done'; treated as seeded, since that model is on the PTY grid.
|
||||
return (
|
||||
this.maybeHydrateHeadlessFromRenderer(ptyId) ??
|
||||
this.rendererSeedsByPtyId.get(ptyId) ??
|
||||
Promise.resolve(false)
|
||||
this.headlessHydrationState.get(ptyId) === 'done' &&
|
||||
this.headlessTerminals.get(ptyId) === state &&
|
||||
!this.providerSnapshotPreferredPtys.has(ptyId)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ export class OrcaRuntimeWithSerializeHeadlessTerminalBuffer extends OrcaRuntimeW
|
||||
|
||||
protected disposeHeadlessTerminal(ptyId: string): void {
|
||||
this.headlessHydrationState.delete(ptyId)
|
||||
this.rendererSeedsByPtyId.delete(ptyId)
|
||||
const state = this.headlessTerminals.get(ptyId)
|
||||
if (!state) {
|
||||
return
|
||||
|
||||
@@ -41,10 +41,6 @@ const CLEARED_BY_REAPER_HELPER: Record<string, { helper: string; module: string
|
||||
agentPromptPermissionSequenceByPtyId: {
|
||||
helper: 'advancePtyLifecycleGeneration',
|
||||
module: 'src/main/runtime/orca-runtime-record-agent-prompt-lifecycle-state.ts'
|
||||
},
|
||||
rendererSeedsByPtyId: {
|
||||
helper: 'disposeHeadlessTerminal',
|
||||
module: 'src/main/runtime/orca-runtime-serialize-headless-terminal-buffer.ts'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user