Skip to content

fix(ai-studio): re-adapt visualization when the render format changes - #65

Merged
librowski merged 4 commits into
mainfrom
visualize-adapt-per-format
Jul 15, 2026
Merged

fix(ai-studio): re-adapt visualization when the render format changes#65
librowski merged 4 commits into
mainfrom
visualize-adapt-per-format

Conversation

@librowski

Copy link
Copy Markdown
Collaborator

What

"Adapt with AI" in the Visualize node ran at most once per output. The adapted content was cached in bare component state and reset only when the source text changed, so switching Render as to another format fed the previous format's adaptation to the new renderer - e.g. the chart renderer received the stat-cards JSON and displayed it as raw text - and the AI was never called again. Failures were also silently swallowed, which made the whole thing look randomly broken.

The adaptation is now an async derived value keyed by (renderer, text), extracted into a useAdaptedVisualization hook. A stale adaptation is ignored by the key check instead of being reset by an effect, so every format change triggers a fresh adapt for that format, and the two-effect choreography in VisualizeCard is gone.

Verification

Exercised in the browser with an instrumented fetch against the local stack: first adaptation fires once and renders (chart with proper axes), switching to Stat cards fires a second /api/visualize/adapt request and renders real stat cards instead of raw JSON. pnpm lint and pnpm typecheck (ai-studio) are green.

The adapted content was cached in bare state and reset only when the
source text changed, so switching the render format kept feeding the
previous format's adaptation to the new renderer (raw JSON instead of
a chart) and never called the AI again.

The adaptation is now an async derived value keyed by (renderer, text)
in a useAdaptedVisualization hook: a stale entry is ignored by the key
check instead of being reset by an effect, and each format change
triggers a fresh adapt for that format.
…data

The effect now uses an inner async function with an AbortController:
switching formats mid-flight cancels the HTTP request instead of just
ignoring its result, and the cancelled flag is gone.

A failed adapt is cached as { key, output: null } - the raw-text
fallback derives from data instead of a swallowed exception, so the
catch block has real content and the failure is one selector away
from the UI whenever we want to surface it.
…ation

The hook now owns the raw-text fallback and returns renderText plus an
isAdapted flag, so the caller no longer interprets a null convention
spread across files.
…ation

The hook now owns the raw-text fallback and returns renderText plus an
isAdapted flag, so the caller no longer interprets a null convention
spread across files.
@librowski
librowski merged commit d08c29b into main Jul 15, 2026
2 checks passed
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.

3 participants