fix: prefer streamed remote node progress in ui

This commit is contained in:
Ken Simpson
2026-04-17 19:50:19 -07:00
parent 9653c9f347
commit d466e23990
2 changed files with 29 additions and 8 deletions
+9
View File
@@ -44,6 +44,7 @@ def test_remote_modal_status_tracks_active_node_ids() -> None:
source = _modal_toggle_source()
assert "activeNodeId: null" in source
assert "hasStreamedProgress: false" in source
assert "function setPromptActiveNode(promptId, activeNodeId)" in source
assert "detail.active_node_id" in source
assert "clearPromptRemoteStates(promptId)" in source
@@ -59,3 +60,11 @@ def test_remote_modal_uses_distinct_ready_active_and_complete_colors() -> None:
assert 'const STATE_READY = "ready";' in source
assert 'const STATE_ACTIVE = "active";' in source
assert 'detail.phase === "execution_success"' in source
def test_streamed_modal_progress_takes_precedence_over_proxy_events() -> None:
"""Once streamed node progress starts, coarse proxy execution events should stop overriding it."""
source = _modal_toggle_source()
assert "promptState.hasStreamedProgress = true;" in source
assert "if (promptState.hasStreamedProgress && phase !== STATE_ERROR)" in source
+20 -8
View File
@@ -248,6 +248,7 @@ function ensurePromptState(promptId) {
remoteNodeIds: [],
componentsByRepresentative: new Map(),
activeNodeId: null,
hasStreamedProgress: false,
});
}
return modalPromptStates.get(promptId);
@@ -371,14 +372,19 @@ function setNodesPhase(nodeIds, phase, promptId, errorMessage) {
*/
function registerPromptComponents(promptId, remoteNodeIds, components) {
const promptState = ensurePromptState(promptId);
promptState.remoteNodeIds = [...remoteNodeIds];
promptState.componentsByRepresentative.clear();
promptState.activeNodeId = null;
for (const component of components) {
promptState.componentsByRepresentative.set(
String(component.representative_node_id),
component.node_ids.map((nodeIdValue) => String(nodeIdValue)),
);
if (remoteNodeIds.length > 0) {
promptState.remoteNodeIds = [...remoteNodeIds];
}
if (components.length > 0) {
promptState.componentsByRepresentative.clear();
promptState.activeNodeId = null;
promptState.hasStreamedProgress = false;
for (const component of components) {
promptState.componentsByRepresentative.set(
String(component.representative_node_id),
component.node_ids.map((nodeIdValue) => String(nodeIdValue)),
);
}
}
}
@@ -595,6 +601,7 @@ function handleModalStatus(event) {
const nextActiveNodeId =
detail.active_node_id != null ? String(detail.active_node_id) : null;
const previousActiveNodeId = promptState.activeNodeId;
promptState.hasStreamedProgress = true;
setGlobalStatusPhase(promptId, EXECUTION_PHASE, nodeIds.length);
setNodesPhase(nodeIds, STATE_READY, promptId);
if (previousActiveNodeId && previousActiveNodeId !== nextActiveNodeId) {
@@ -608,6 +615,7 @@ function handleModalStatus(event) {
}
if (detail.phase === "execution_success") {
promptState.hasStreamedProgress = true;
if (promptState.activeNodeId) {
setNodesPhase([promptState.activeNodeId], STATE_COMPLETE, promptId);
}
@@ -634,6 +642,10 @@ function handleExecutionPhase(event, phase) {
if (!componentNodeIds) {
return;
}
const promptState = ensurePromptState(promptId);
if (promptState.hasStreamedProgress && phase !== STATE_ERROR) {
return;
}
if (phase === EXECUTION_PHASE) {
setGlobalStatusPhase(promptId, EXECUTION_PHASE, componentNodeIds.length);
setNodesPhase(componentNodeIds, STATE_READY, promptId, detail.exception_message);