mirror of
https://github.com/stablyai/orca.git
synced 2026-10-13 00:02:54 +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.
|
// Absent → hydration has not been considered yet for this PTY.
|
||||||
// See docs/mobile-prefer-renderer-scrollback.md.
|
// See docs/mobile-prefer-renderer-scrollback.md.
|
||||||
protected headlessHydrationState = new Map<string, 'pending' | 'done'>()
|
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
|
// 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 —
|
// 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)
|
return state.writeChain.then(() => seeded)
|
||||||
this.rendererSeedsByPtyId.set(ptyId, seed)
|
|
||||||
return seed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Public: a phone fit resizes the PTY, but an idle TUI sends no byte to hydrate on. Resolves
|
/** 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. */
|
* true once the model holds the pane's screen reflowed onto the PTY's current grid. */
|
||||||
hydrateHeadlessTerminalFromRenderer(ptyId: string): Promise<boolean> {
|
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 (
|
return (
|
||||||
this.maybeHydrateHeadlessFromRenderer(ptyId) ??
|
this.headlessHydrationState.get(ptyId) === 'done' &&
|
||||||
this.rendererSeedsByPtyId.get(ptyId) ??
|
this.headlessTerminals.get(ptyId) === state &&
|
||||||
Promise.resolve(false)
|
!this.providerSnapshotPreferredPtys.has(ptyId)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ export class OrcaRuntimeWithSerializeHeadlessTerminalBuffer extends OrcaRuntimeW
|
|||||||
|
|
||||||
protected disposeHeadlessTerminal(ptyId: string): void {
|
protected disposeHeadlessTerminal(ptyId: string): void {
|
||||||
this.headlessHydrationState.delete(ptyId)
|
this.headlessHydrationState.delete(ptyId)
|
||||||
this.rendererSeedsByPtyId.delete(ptyId)
|
|
||||||
const state = this.headlessTerminals.get(ptyId)
|
const state = this.headlessTerminals.get(ptyId)
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ const CLEARED_BY_REAPER_HELPER: Record<string, { helper: string; module: string
|
|||||||
agentPromptPermissionSequenceByPtyId: {
|
agentPromptPermissionSequenceByPtyId: {
|
||||||
helper: 'advancePtyLifecycleGeneration',
|
helper: 'advancePtyLifecycleGeneration',
|
||||||
module: 'src/main/runtime/orca-runtime-record-agent-prompt-lifecycle-state.ts'
|
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