Skip to content

Dataweaver dev#381

Closed
sagrimson wants to merge 5 commits into
mainfrom
dataweaver-dev
Closed

Dataweaver dev#381
sagrimson wants to merge 5 commits into
mainfrom
dataweaver-dev

Conversation

@sagrimson

Copy link
Copy Markdown
Contributor

No description provided.

@sagrimson sagrimson closed this Jun 26, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a disambiguation flow for broad or exploratory queries, updates the streaming query logic to handle skipped places and terminal states more robustly, and adds a 30-second timeout to MCP calls. The review feedback highlights a potential race condition in QueryProvider when handling disambiguation results that could lead to state inconsistency, suggests adding defensive fallbacks for LLM-generated fields in the home page UI, and recommends logging caught errors when tool calls fail or time out to improve production observability.

Comment on lines +102 to +108
if (result.disambiguation) {
// Handle disambiguation if present
queryFail(active.nodeId);
querySetProcessing(false);
querySetStatus(STATUS.idle);
break;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is a race condition and state inconsistency here when handling result.disambiguation.

When a disambiguation is found, queryFail is called, which sets the node status to 'error' and unregisters cards. However, the SSE stream is still active and will eventually emit a STREAM_EVENT.complete event. When STREAM_EVENT.complete is processed, it calls queryComplete which overwrites the node status back to 'complete' and sets cardIds to the stale active.cardIds (which contains card IDs that were already unregistered by queryFail). This leads to state inconsistency and potential UI bugs.

To fix this, we should:

  1. Clean up any remaining loading cards.
  2. Call queryComplete(active.nodeId, []) to cleanly complete the query with no cards.
  3. Set activeQueryRef.current = null to ignore any subsequent stream events (preventing the race condition).
  4. Set querySetStatus(STATUS.complete) so the home page's useEffect (which expects STATUS.complete) is triggered correctly to show the follow-up/disambiguation UI.
        if (result.disambiguation) {
          const { cardUnregister: unregisterOrphan, cards } = store.getState();
          for (const id of active.cardIds) {
            const card = cards[id];
            if (card?.type === 'loading') {
              unregisterOrphan(id);
            }
          }
          queryComplete(active.nodeId, []);
          querySetProcessing(false);
          querySetStatus(STATUS.complete);
          activeQueryRef.current = null;
          break;
        }

Comment on lines +50 to +55
setFollowUp({
question: node.query,
answer: disambiguation.summary,
followUp: disambiguation.question,
prompts: disambiguation.options,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It is safer to add defensive fallbacks when parsing LLM-generated JSON responses. Even though the schema defines these fields as required, LLMs can occasionally return malformed or incomplete objects. Adding default values prevents potential runtime crashes when rendering the follow-up UI.

Suggested change
setFollowUp({
question: node.query,
answer: disambiguation.summary,
followUp: disambiguation.question,
prompts: disambiguation.options,
});
setFollowUp({
question: node.query,
answer: disambiguation.summary || '',
followUp: disambiguation.question || '',
prompts: Array.isArray(disambiguation.options) ? disambiguation.options : [],
});

Comment on lines +166 to +171
} catch (err: unknown) {
// If the caller aborted, re-throw so the outer loop exits cleanly.
if (signal?.aborted) throw err;
// Tool call timed out or failed — return empty so the place is skipped.
return { text: '', resolvedPlaceDcid };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When a tool call fails or times out, the error is caught and the place is silently skipped. This makes debugging in production extremely difficult because there is no server-side log of the failure. We should log the error to console.error before returning.

        } catch (err: unknown) {
          if (signal?.aborted) throw err;
          console.error('[Data Discovery] Tool call "' + fcName + '" failed:', err);
          return { text: '', resolvedPlaceDcid };
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant