Skip to content

Feat/sample data#46

Open
jlee-kitware wants to merge 10 commits into
masterfrom
feat/sample-data
Open

Feat/sample data#46
jlee-kitware wants to merge 10 commits into
masterfrom
feat/sample-data

Conversation

@jlee-kitware

@jlee-kitware jlee-kitware commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #45 (it depends on the vtk-mcp branch), so the base is conversation-history-panel for now; I'll retarget to master once #45 lands. Diff is the six commits below.

Three changes, all from real use:

Sample-data resolution. Example code that reads a file (cow.g, the PLOT3D combustor files) now runs without manual setup. A stdlib-only resolver indexes the .sha512 pointers under VTK_PROMPT_DATA_ROOT, resolves a bare filename to its hash, and fetches from the Kitware data store on first use (cached after). Filename literals are rewritten to local paths only in the executed copy, so the editor keeps the clean names; a chip per dataset shows what was fetched. Deliberately a post-processing step rather than an LLM tool - deterministic, no round-trip. Inert without VTK_PROMPT_DATA_ROOT.

Tool-use nudge, gated on vtk-mcp. A prompt component that tells the model to use the vtk-mcp tools (confirm classes/signatures, check I/O types, validate before finalizing). Added only when a server is reachable, so non-mcp prompts are unchanged.

Execution hardening. execute_vtk_code now catches SystemExit, not just Exception - generated example scripts that call argparse/sys.exit() were taking down the whole server. Run errors also report the failing line, matched by text so it survives the offset between displayed and executed code.

executor test updated for the new return signature.

@jlee-kitware jlee-kitware changed the base branch from conversation-history-panel to master June 30, 2026 23:18
VTK examples reference data files by bare name; the bytes live in VTK's
content-addressed ExternalData store. Add vtk_prompt/data/resolver.py, which
builds a basename -> sha512 index from a local VTK data tree (VTK_PROMPT_DATA_ROOT)
and resolves a name by fetching the blob from data.kitware.com, caching it under
the user cache dir and verifying the checksum. Stdlib only (no new dependency).

resolve(name) returns a local path (or None if unknown / fetch fails);
available_names() and has_data_root() support later UI/prompt hints. Next: stage
resolved files into the exec environment so generated example code runs as-is.
Before executing generated VTK code, rewrite bare data-file references (string
literals that are a known dataset basename, e.g. 'cow.g') to their resolved
local paths via the sample-data resolver. Only the executed copy is rewritten;
the stored/displayed code keeps the bare names, so the editor and Run-state cue
are unaffected. No-op unless a VTK data tree is configured (VTK_PROMPT_DATA_ROOT),
and explicit paths / unrelated strings are left untouched.

Verified end to end: a snippet reading 'cow.g' now resolves, downloads, and
renders (2903 points) instead of failing on a missing file.
Surface the datasets the current code references as small chips in the
"Generated Code" title bar. Each chip shows the dataset name with an icon for
fetched vs not-yet-downloaded, and a hover tooltip with the local cache path,
status, and source. Recomputed on every code change via a pure index lookup
(no download); only shown when the code references known datasets.

resolver.referenced()/artifacts() do the lookup; data_artifacts state drives
the chips.
execute_vtk_code now captures the line where execution failed (handling both
syntax errors and runtime tracebacks) and returns its source text. Because the
executed code differs from what the editor shows (explanation banner prepended,
markdown fence stripped, import added, data literals rewritten), the caller
matches on the line's text rather than its number to find the editor line, then
prefixes the run error with "Line N: <source>". Returns the offending text up
the stack so a later pass can mark the line in the editor.
Add a conditional tool_use prompt component that instructs the model to use the
vtk-mcp reference tools (search/confirm classes and signatures, check input/output
types, validate before finalizing, adapt examples) instead of relying on memory
for uncommon APIs. assemble_vtk_prompt gains an mcp_active flag and the client
passes bool(mcp_client), so the guidance (and its token cost) is included only
when a vtk-mcp server is actually reachable. Without mcp, prompts are unchanged.
VTK example scripts (e.g. the PLOT3D streamlines example) are standalone CLIs:
they define get_program_parameters() with argparse and run via a main() guard.
The executor runs code with __name__ == "__main__", so that main() fires,
parse_args() parses the app's own argv, fails, and calls sys.exit(). SystemExit
is not an Exception subclass, so it escaped execute_vtk_code's handler and tore
down the whole trame app whenever such code was run or revisited.

Trap SystemExit alongside Exception in the executor and report it as a normal
code error with an actionable message (the code is a standalone script using
argparse/sys.exit). The line-pinpointing added earlier correctly flags the
parse_args() line. KeyboardInterrupt is intentionally not caught.
The Settings "Files" tab was a leftover from before the sessions model: it had a
generic upload plus two download buttons wired to JS functions (download_conversation_file
/download_prompt_file) that never existed, so nothing happened on click.

Put the operations where they belong:
- Per-conversation Export in the Recents row menu, via a new export_session trigger
  that returns that session's JSON by id.
- Import in the Recents header (a dialog accepting .json), reusing the existing
  uploaded-files routing.
- The old Files tab becomes Config: import a prompt/config YAML, and a working
  "Download Config File" button. Conversation upload/download removed from here.

Adds the missing client-side download helpers in utils.js (Blob download plus
exportSession/exportConfig that call the server triggers). The "prompt file"
download was always the settings YAML (save_config), so it stays a config concern.
The resolver only read VTK_PROMPT_DATA_ROOT from the environment, so the sample-
data feature was unusable without setting an env var at launch. Make the data
root runtime-settable: resolver.set_data_root() installs an override and clears
the cached index so the next lookup rebuilds against the new tree (env var stays
the fallback).

Wire it through: a "Sample data location" field in the Settings Config tab
(bound to data_root), an initializer default from the env var, a change handler
that repoints the resolver and refreshes the referenced-file chips live, and
config round-tripping (save_config exports data_root; a loaded config applies
it). Like the other settings, the field is session/config-scoped, not auto-saved
to disk.
The dialog read as a stack of competing cards with inconsistent spacing. Fixes:

- Flatten each tab to a single surface with quiet section labels (text-overline)
  and dividers instead of nested cards with bold titles/subtitles.
- Replace free-floating description text (which overlapped the next field's
  floating label) with proper persistent field hints, plus consistent spacing
  between fields. This was the main "looks broken" issue on Model/Advanced.
- Replace emoji (cloud/house tabs, plug, gear, thermometer) with mdi icons to
  match the rest of the app; the Cloud/Local tabs now use mdi-cloud-outline and
  mdi-laptop.
- Temperature slider: recolor orange -> primary, drop the always-on thumb label
  (it collided with the heading) in favor of an inline value, and give it room.
- Config tab: swap the oversized drag-and-drop zone for a compact file input and
  calm the full-width filled download button down to a small outlined one.
- Drop the unaligned per-field prepend icons for a clean left edge.
The Cloud/Local inner tab content sat flush against the tab bar, so the first
field's floating outlined label (Base URL / Provider) was cut off at the top.
Add top padding inside the inner tab window so the label clears the tabs.
This was referenced Jul 12, 2026
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