Skip to content

Enhance model selection UI and integrate Playground output - #262

Merged
tonythethompson merged 18 commits into
mainfrom
fix/olive-studio-issue-reports
Aug 13, 2026
Merged

tonythethompson merged 18 commits into
mainfrom
fix/olive-studio-issue-reports

Conversation

@tonythethompson

@tonythethompson tonythethompson commented Aug 13, 2026 •

Copy link
Copy Markdown
Owner

Summary by cubic

Blocks Execute until a model is chosen and pipes the exact executed recipe to Playground. Previously “Local checks passed” showed and MCP advisories ran with no model, and Playground rebuilt recipes from edited state; now a critical “No model selected” blocks Execute, diagnostics clear on deselect, and Browser Test only consumes a captured WebGPU run recipe.

  • Validation and diagnostics: export hasSelectedModel; emit critical model-source-not-set; gate trust_remote_code and MCP lookups until a model is set; add clearDiagnostic() to abort in‑flight requests and reset state; reset the issue counter when issues clear.
  • Execute → Playground: capture the submitted recipe via runRecipeJsonRef and store as capturedRunRecipe in playgroundStore; PlaygroundPanel prefers this captured recipe and falls back to current state only when absent; pass to Browser Test only if its provider is WebGpuExecutionProvider (memoized check); show “Test in Playground →” after a successful run; clear on Playground reset.
  • Provider UI and a11y: collapse export/platform targets; collapse undetected local accelerators behind “Show other targets” (auto‑expands for the active selection); add per‑card “Show/Hide details” (collapsed by default, opens for the selected card) with unique per‑provider aria-controls/id; quiet the “Compatible” pill to a slate container with an emerald icon.
  • Hardware detection: make isProviderDetectedLocally("CPUExecutionProvider") always true so CPU fallback isn’t hidden on a null hardwareProbe; do not treat a missing probe as a block.
  • Matrix and nav: make the pass × provider matrix header sticky with vertical scroll; show an amber incomplete indicator and ARIA labels on steps 02–04 until a model is selected.
  • Batch and catalog: preserve existing local files when hydrating UI from batch jobs; show approximate inference memory (“~X GB” or “~min–max GB”) on collapsed model headers.

Written for commit 7b7e8d2. Summary will update on new commits.

Review in cubic

Note

Integrate captured Execute recipe into Playground and improve model selection UI

  • On successful Execute completion, ExecutionWorkspace stores the submitted recipe in the playground store via setCapturedRunRecipe; PlaygroundPanel passes it to the Browser Test only when it targets WebGPU.
  • Sidebar pipeline navigation now shows an amber dot and updated labels on steps that are incomplete due to no model being selected.
  • CPUExecutionProvider is always treated as detected locally in isProviderDetectedLocally, even when probe data is absent; the provider card no longer shows as hardware-blocked in this case.
  • Local accelerators not detected on the host are grouped under a collapsible section in ProviderCardGrid; HardwareProviderCard details are collapsible and expand by default for the selected provider.
  • MCP diagnostics are cleared when no model is selected, and redundant re-fetches are skipped when the critical issue count is unchanged.

Macroscope summarized 7b7e8d2.

tonythethompson and others added 9 commits August 12, 2026 17:06
Deployed size (inferenceGb) was only visible after expanding a model's
target list — the collapsed header showed just device badges and a
target count. Add a compact "~X GB" (or "~min–max GB" when targets vary
in size) label next to the title, reusing the RecipeRow.inferenceGb
already computed for sorting, so it's visible before expanding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…model selected

Nothing validated that a model was actually chosen. With no model,
validation.statusLabel still said "Local checks passed" (green) next to an
enabled-looking Execute Live button, and the panel piled model-specific
tuning advisories (e.g. "NVIDIA prefers AWQ INT4 over PTQ INT8") plus an
MCP diagnostic lookup on top of that — all meaningless without a model to
apply them to.

- pipelineValidation: add a critical "No model selected" issue
  (hasSelectedModel, now exported) so isBlocked/isRunnable correctly go
  false, and gate the trust_remote_code advisory on a model actually being
  set.
- RecipeValidationPanel: when no model is selected, show only that one
  issue instead of merging in pass-parameter/compat/MCP warnings, and skip
  the MCP error-diagnostic fetch entirely (there's no error pattern to
  diagnose yet).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Local accelerators (the actual candidates on this machine) and export/
platform targets (QNN, WebGPU, CoreML, NNAPI, TFLite, WASM, ...) rendered
as ~16 equal-weight cards with no distinction — export-only targets you'll
almost never pick got the same visual weight as CUDA on a machine that has
an NVIDIA GPU, turning step 02 into several screens of scrolling for what's
usually a one-card decision.

Collapse "Export & platform targets" behind a disclosure, showing just the
count and a one-line description by default. Auto-expands if the currently
selected provider happens to be one of them, so switching providers never
hides your own active selection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two dead wires kept step 04 feeling like a separate tool instead of part
of the pipeline:

- PlaygroundPanel hardcoded `recipeJson={undefined}` into Browser Test, so
  the "this test matches your configured recipe" hint could never show,
  regardless of what was actually configured in steps 01-03. Now builds it
  from live pipeline state via buildRecipeJsonFromState.
- Nothing pointed from a finished run back to Playground. Add a
  "Test in Playground ->" button next to the Active Draft "Done" badge
  once executionStatus is "completed", landing on Browser Test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- ProviderCardGrid: sync disclosure state when selected provider changes to prevent hiding active export targets
- RecipeCatalogBrowserList: format memory sizes before comparing to avoid redundant labels like "~1.0 GB–1.0 GB"
- RecipeCatalogBrowserList: fix tooltip wording from "deployed model size" to "inference memory estimate"
- pipelineValidation: add targeted unit tests for hasSelectedModel covering HF empty/whitespace, local files, and Azure paths

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- PlaygroundPanel: gate recipeJson on WebGPU provider to prevent false hints on CPU/QNN/DirectML
- RecipeValidationPanel: reset issue-count ref when model deselected to avoid stale diagnostics

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reset prevIssueCountRef when criticalIssues count is 0 to ensure clean state for next issue detection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- HardwareCompatibilityMatrix: sticky header row + vertical scroll so column headers stay visible while scrolling through the pass x provider matrix
- ProviderCardGrid: collapse undetected local-accelerator cards behind "Show N other targets", mirroring the existing export/platform-targets disclosure pattern
- HardwareProviderCard: add progressive disclosure ("Show/Hide details") for plugin-install logs and hint paragraphs, collapsed by default (expanded for the active selection); quiet detected/compatible badges from emerald container to slate container + emerald icon
- CompatStatus: same slate-container/emerald-icon treatment for the "Compatible" tier pill
- App.tsx: soft incomplete-step indicator (amber dot) on nav items 02-04 when no model is selected yet, without gating navigation — free-scroll behavior is preserved

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
olive-studio Ready Ready Preview Aug 13, 2026 5:04am

@tonythethompson
tonythethompson marked this pull request as ready for review August 13, 2026 03:15
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@tonythethompson, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: abb0f64c-3689-45c2-a929-a8d1bc81123b

📥 Commits

Reviewing files that changed from the base of the PR and between 5417800 and 7b7e8d2.

📒 Files selected for processing (17)
  • src/App.tsx
  • src/components/features/execute/BatchProcessingPanel.tsx
  • src/components/features/execute/ExecutionWorkspace.tsx
  • src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx
  • src/components/features/execute/useOliveStream.ts
  • src/components/features/ihv/HardwareCompatibilityMatrix.tsx
  • src/components/features/ihv/HardwareProviderCard.tsx
  • src/components/features/ihv/ProviderCardGrid.test.tsx
  • src/components/features/ihv/ProviderCardGrid.tsx
  • src/components/features/input/CompatStatus.tsx
  • src/components/features/playground/PlaygroundPanel.test.tsx
  • src/components/features/playground/PlaygroundPanel.tsx
  • src/lib/hardwareProbe.test.ts
  • src/lib/hardwareProbe.ts
  • src/lib/hooks/useMcpDiagnostic.ts
  • src/lib/oliveRecipeHub.ts
  • src/lib/stores/playgroundStore.ts
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/olive-studio-issue-reports
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/olive-studio-issue-reports

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/components/features/ihv/HardwareProviderCard.tsx
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Block runs without a selected model and link Execute output to Playground

🐞 Bug fix ✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add a critical "No model selected" validation issue to correctly block Execute.
• Connect successful Execute runs to Playground Browser Test with WebGPU recipe context.
• Improve provider and catalog UX with collapsible targets and visible VRAM size hints.
Diagram

graph TD
S["pipelineStore (state)"] --> V["pipelineValidation (hasSelectedModel + issues)"] --> R["RecipeValidationPanel"]
S --> D["App Dashboard nav"]
S --> P["PlaygroundPanel"] --> B["InBrowserValidation"]
E["ExecutionWorkspace"] --> N["pipelineNavigation -> Playground"] --> P
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. UI-only gating (disable Execute/sections when model missing)
  • ➕ Simpler mental model for users: buttons/sections just disabled
  • ➕ Avoids adding a new critical issue type
  • ➖ Validation becomes inconsistent across entry points (e.g., deep links, future actions)
  • ➖ Harder to test and reason about than a single validation rule
2. Dedicated 'pipeline readiness' selector in the store
  • ➕ Centralizes derived state (selected model, runnable flags, etc.)
  • ➕ Avoids recomputing readiness logic across components
  • ➖ Adds store surface area and potential coupling
  • ➖ Still likely needs validation-level issues for messaging/autofix hooks

Recommendation: Keep the PR’s approach: a single exported hasSelectedModel() and a critical model-source-not-set issue makes gating consistent and testable, while letting the UI focus on presenting the right message. If buildRecipeJsonFromState becomes expensive, consider narrowing the useMemo dependencies (e.g., to input/provider-related fields) or moving recipeJson construction behind a memoized selector.

Files changed (12) +405 / -103

Enhancement (8) +275 / -97
App.tsxMark steps 02–04 as incomplete until a model is selected +12/-3

Mark steps 02–04 as incomplete until a model is selected

• Uses hasSelectedModel(pipelineState) to add an amber incomplete dot and clearer aria/title text for steps that depend on a chosen model. This nudges users to configure Model source (step 01) before moving deeper into the workflow.

src/App.tsx

ExecutionWorkspace.tsxAdd "Test in Playground" CTA after successful execution +18/-3

Add "Test in Playground" CTA after successful execution

• On completed runs, displays a button that switches Playground to the Browser Test subview and navigates to the Playground pipeline view. This creates a direct path from Execute results to in-browser validation.

src/components/features/execute/ExecutionWorkspace.tsx

HardwareCompatibilityMatrix.tsxMake compatibility matrix header sticky in a scroll container +3/-3

Make compatibility matrix header sticky in a scroll container

• Switches to a max-height scrollable container and makes the table header sticky, improving readability when scanning larger compatibility matrices.

src/components/features/ihv/HardwareCompatibilityMatrix.tsx

HardwareProviderCard.tsxCollapse provider card details with per-card show/hide toggle +96/-70

Collapse provider card details with per-card show/hide toggle

• Introduces an expandable details section on each provider card, defaulting open for the selected card. Also adjusts the "Compatible" badge styling to a neutral container while preserving a green icon indicator.

src/components/features/ihv/HardwareProviderCard.tsx

ProviderCardGrid.tsxCollapse export/platform targets and undetected local accelerators by default +102/-11

Collapse export/platform targets and undetected local accelerators by default

• Splits provider cards into detected local accelerators, optionally revealed undetected targets, and a collapsible export/platform target section. Auto-expands a section when the current selection lives inside it.

src/components/features/ihv/ProviderCardGrid.tsx

CompatStatus.tsxNeutralize Compatible pill container while keeping green icon +8/-4

Neutralize Compatible pill container while keeping green icon

• Updates the Compatible tier badge to use a slate container and adds an optional iconClassName to keep the icon green without the whole pill reading as a success state.

src/components/features/input/CompatStatus.tsx

RecipeCatalogBrowserList.tsxShow approximate inference memory on collapsed recipe group headers +23/-1

Show approximate inference memory on collapsed recipe group headers

• Computes min/max inferenceGb across targets and displays a compact "~X GB" (or range) label next to the model title when the group is collapsed, using the existing per-row inference estimates.

src/components/features/input/RecipeCatalogBrowserList.tsx

PlaygroundPanel.tsxPass WebGPU recipe JSON into Browser Test +13/-2

Pass WebGPU recipe JSON into Browser Test

• Builds recipeJson from the configured pipeline state and passes it to InBrowserValidation, but only when a model is selected and the provider is WebGpuExecutionProvider. This restores recipe context for Browser Test without enabling it for other providers.

src/components/features/playground/PlaygroundPanel.tsx

Bug fix (2) +40 / -5
RecipeValidationPanel.tsxSuppress unrelated advisories/diagnostics when no model is selected +18/-4

Suppress unrelated advisories/diagnostics when no model is selected

• Detects modelSelected and, when false, shows only pipeline validation issues (not pass-parameter/compat/MCP warnings). Also prevents MCP diagnostic auto-fetching and resets diagnostic counters when the model is deselected.

src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx

pipelineValidation.tsIntroduce hasSelectedModel and emit critical "No model selected" issue +22/-1

Introduce hasSelectedModel and emit critical "No model selected" issue

• Adds an exported hasSelectedModel helper and uses it to gate trust_remote_code advisory emission. Emits a critical model-source-not-set issue when no model is configured, ensuring isBlocked/isRunnable reflect reality.

src/lib/pipelineValidation.ts

Tests (1) +89 / -0
pipelineValidation.test.tsAdd unit coverage for model selection detection and blocking issue +89/-0

Add unit coverage for model selection detection and blocking issue

• Introduces tests for hasSelectedModel across Hugging Face/local/Azure sources and verifies the new critical model-source-not-set issue is emitted (and not emitted) in the expected cases.

src/lib/tests/pipelineValidation.test.ts

Other (1) +1 / -1
Cargo.lockBump olive-studio dependency to 0.4.0 +1/-1

Bump olive-studio dependency to 0.4.0

• Updates the locked olive-studio crate version from 0.3.0 to 0.4.0, aligning the Tauri backend dependency set with the new release.

src-tauri/Cargo.lock

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues, and left some high level feedback:

  • In HardwareProviderCard, isExpanded is initialized from isSelected but never updated when the selection changes; consider syncing expansion state with isSelected so the newly active card auto-expands even if the user previously collapsed it.
  • The new undetected-local accelerator grouping in ProviderCardGrid relies on isProviderDetectedLocally and hardwareProbe; it may be worth guarding against a null/undefined probe or stale detection data to avoid misclassifying providers into the detected/undetected groups.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `HardwareProviderCard`, `isExpanded` is initialized from `isSelected` but never updated when the selection changes; consider syncing expansion state with `isSelected` so the newly active card auto-expands even if the user previously collapsed it.
- The new undetected-local accelerator grouping in `ProviderCardGrid` relies on `isProviderDetectedLocally` and `hardwareProbe`; it may be worth guarding against a `null`/undefined probe or stale detection data to avoid misclassifying providers into the detected/undetected groups.

## Individual Comments

### Comment 1
<location path="src/components/features/ihv/HardwareProviderCard.tsx" line_range="856" />
<code_context>
 }: HardwareProviderCardProps) {
   const isSelected = state.ihvProvider === p.id;
+  // Selected card starts open so the active target's details aren't hidden behind a click.
+  const [isExpanded, setIsExpanded] = useState(isSelected);
   const Icon = p.icon;
   const pConflicts = getProviderConflicts(p.id, state.passes);
</code_context>
<issue_to_address>
**question (bug_risk):** The expansion state is only initialized from selection and won’t respond to later selection changes.

`useState(isSelected)` only uses the initial `isSelected` value, so expansion won’t follow later selection changes. This can leave previously selected cards expanded while the newly selected card remains collapsed. If the active card should always be expanded, derive `isExpanded` from `isSelected` (or sync it via `useEffect`) instead of managing it as independent state.
</issue_to_address>

### Comment 2
<location path="src/components/features/ihv/HardwareProviderCard.tsx" line_range="970-977" />
<code_context>
+                  const modelSelected = hasSelectedModel(pipelineState);
+                  const isIncomplete = !modelSelected && id !== "input";
                   return (
                     <button
                       key={id}
                       type="button"
</code_context>
<issue_to_address>
**suggestion:** The details toggle button could be more accessible by tying it to the controlled content region.

The button’s `aria-expanded` is set correctly, but assistive technologies don’t have an explicit link to the content being toggled. Consider giving the collapsible container an `id` and referencing it with `aria-controls`, or using a native `details/summary` pattern so the control–content relationship is clearer for screen readers.

Suggested implementation:

```typescript
          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation();
              setIsExpanded((v) => !v);
            }}
            className="flex items-center gap-1 text-[11px] text-slate-500 hover:text-slate-400 transition-colors cursor-pointer"
            aria-expanded={isExpanded}
            aria-controls="hardware-provider-details"
          >

```

To fully implement the accessibility improvement, the collapsible content container that is shown/hidden based on `isExpanded` should be given a matching `id="hardware-provider-details"` (or another consistent id if you prefer a different name). For example, wherever the expanded content is rendered, update the wrapping element to include this `id` so assistive technologies can correctly associate the toggle button with the controlled region.
</issue_to_address>

Fix all in Cursor


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/components/features/ihv/HardwareProviderCard.tsx
Comment thread src/components/features/ihv/HardwareProviderCard.tsx
@greptile-apps

greptile-apps Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR improves model-selection validation, preserves the submitted execution recipe for Playground, and refines hardware-provider presentation and fallback behavior.

  • Blocks execution and suppresses unrelated diagnostics until a model is selected.
  • Captures successful WebGPU run recipes for Browser Test.
  • Adds collapsible provider details and groups undetected targets.
  • Keeps CPU visible and selectable when hardware probing is unavailable.
  • Preserves local files when restoring batch-job state.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/components/features/ihv/HardwareProviderCard.tsx Synchronizes detail expansion with provider selection and removes the null-probe CPU hardware block, resolving the prior card-state and CPU fallback findings.
src/components/features/ihv/ProviderCardGrid.tsx Groups undetected local providers while preserving all local targets when probe results are unavailable.
src/lib/hardwareProbe.ts Treats CPU as locally detected regardless of probe availability, ensuring the fallback remains visible.
src/components/features/execute/ExecutionWorkspace.tsx Captures the exact recipe from a successfully completed execution for subsequent Playground use.
src/components/features/playground/PlaygroundPanel.tsx Prefers the captured execution recipe and passes it to Browser Test only when it targets WebGPU.
src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx Clears stale diagnostics after model deselection and resets diagnostic issue-count tracking.

Fix All in Greploop

Reviews (6): Last reviewed commit: "perf: memoize captured WebGPU recipe che..." | Re-trigger Greptile

Comment thread src/components/features/ihv/HardwareProviderCard.tsx
Comment thread src/components/features/ihv/ProviderCardGrid.tsx
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

() => (hasSelectedModel(state) && state.ihvProvider === "WebGpuExecutionProvider" ? buildRecipeJsonFromState(state) : undefined),

P2 Badge Preserve the completed run context for Playground

When the user follows the new button immediately after a successful Execute Live run, this condition always produces undefined: getLocalExecutionIssues blocks WebGpuExecutionProvider from Execute Live, so a completed run necessarily used another provider. If the user changes providers first, the value instead describes the newly edited pipeline rather than the completed run. Consequently Browser Test never receives the recipe associated with the output that prompted the link; pass the captured run recipe/output context rather than rebuilding conditionally from the current store state.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…Selected)

When clicking a different already-mounted provider card, isExpanded now
syncs via useEffect so the newly active target opens to show install
controls and hardware details, rather than staying collapsed.

Matches existing pattern in ProviderCardGrid.tsx.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tonythethompson

Copy link
Copy Markdown
Owner Author

Re: macroscope review on HardwareProviderCard.tsx:856 — Added useEffect to sync isExpanded when isSelected changes, so newly selected provider cards auto-open. Matches pattern in ProviderCardGrid.

🤖 Addressed by Claude Code

When an Execute run reaches "completed", ExecutionWorkspace now builds the current recipe JSON and stores it in the playground Zustand store. The store adds `capturedRunRecipe` plus a setter, and clears that field during `resetPlayground` so session-scoped Playground state resets cleanly.
@qodo-code-review

qodo-code-review Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Batch job validation ignores localFiles state ✓ Resolved 🐞 Bug ≡ Correctness
Description
uiStateForBatchJob() only overrides hfModelId/azureModelPath from job.modelIdentifier but never sets
localFiles when job.modelSource is "local"; since the persisted UIState always has localFiles=[]
(see pipelineStore.ts partialize/merge), hasSelectedModel() will return false for any local-source
batch job and getPipelineValidation now emits the new critical "model-source-not-set" issue,
permanently blocking legitimate local-file batch jobs from running.
Code

src/lib/pipelineValidation.ts[R795-805]

+  if (!hasSelectedModel(state)) {
+    issues.push({
+      id: "model-source-not-set",
+      severity: "critical",
+      title: "No model selected",
+      description:
+        "Choose a Hugging Face model, local files, or an Azure ML path in Model source (step 01) before running or exporting this recipe.",
+      affectedTabs: ["input"],
+      affectedPasses: ["input_model"],
+    });
+  }
Relevance

●●● Strong

Likely blocking correctness bug; aligns with new hasSelectedModel gating introduced recently.

PR-#260

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
hasSelectedModel() (pipelineValidation.ts lines 780-786) treats modelSource==="local" as selected
only if state.localFiles.length>0. BatchProcessingPanel.tsx's uiStateForBatchJob() (lines 296-304)
sets modelSource: job.modelSource but does not populate localFiles from the job at all, and
pipelineStore.ts always clears localFiles to [] on persist/merge. Consequently any batch job created
with newSource === "local" (BatchProcessingPanel.tsx line 961) will fail the new hasSelectedModel
check inside getRecipeRuntimeIssues, causing jobValidation.isBlocked to be true and the job to fail
via failQueuedBatchJob (BatchProcessingPanel.tsx lines 359-375), even though the job legitimately
targets local files.

src/lib/pipelineValidation.ts[780-805]
src/components/features/execute/BatchProcessingPanel.tsx[296-304]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
After this PR, `hasSelectedModel()` treats a `local` modelSource as selected only when `state.localFiles.length > 0`. Batch jobs created with `modelSource: "local"` never populate `localFiles`, so `uiStateForBatchJob()` produces a UIState where `hasSelectedModel()` returns false, causing the new `model-source-not-set` critical issue to block every local-source batch job.

## Issue Context
- `hasSelectedModel` was added in this PR in `src/lib/pipelineValidation.ts` and is used by `getRecipeRuntimeIssues` to emit a critical blocking issue when no model is selected.
- `uiStateForBatchJob` in `BatchProcessingPanel.tsx` builds the UIState used for per-job validation before starting a queued batch job, but only maps `hfModelId`/`azureModelPath` from `job.modelIdentifier`, never `localFiles`.
- `BatchJob` (types.ts) stores `modelIdentifier: string`, not a `localFiles` array, so there's no per-job file list to map from.

## Fix Focus Areas
- src/components/features/execute/BatchProcessingPanel.tsx[296-304]
- src/lib/pipelineValidation.ts[780-805]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Selected details stay collapsed ✓ Resolved 🐞 Bug ≡ Correctness
Description
HardwareProviderCard initializes isExpanded from isSelected only when the card mounts, so
selecting a previously unselected card does not open its details. The newly gated installation
controls and hardware guidance therefore remain hidden even though the selected target is intended
to expand automatically.
Code

src/components/features/ihv/HardwareProviderCard.tsx[R855-856]

+  // Selected card starts open so the active target's details aren't hidden behind a click.
+  const [isExpanded, setIsExpanded] = useState(isSelected);
Relevance

●●● Strong

Pattern of syncing derived UI state with selection was accepted; likely they’ll auto-expand when
selected.

PR-#260

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The card stores the mount-time isSelected value as local expansion state, while selection later
changes through the card's parent click handler without updating that state. All provider
installation controls are now conditionally rendered under isExpanded, proving that a newly
selected card can keep those controls hidden.

src/components/features/ihv/HardwareProviderCard.tsx[854-856]
src/components/features/ihv/HardwareProviderCard.tsx[910-914]
src/components/features/ihv/HardwareProviderCard.tsx[984-1017]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`isExpanded` captures only the card's initial selection state. When this card becomes selected later, its details remain collapsed, including provider installation controls and hardware guidance.

## Issue Context
Preserve manual Show/Hide details behavior, but ensure a transition from unselected to selected expands the card as the comment promises. Avoid forcing the card open on every render.

## Fix Focus Areas
- src/components/features/ihv/HardwareProviderCard.tsx[854-856]
- src/components/features/ihv/HardwareProviderCard.tsx[970-1017]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. Stale MCP diagnostic may resurface after reselect ✓ Resolved 🐞 Bug ☼ Reliability
Description
The MCP diagnostic auto-fetch effect resets prevIssueCountRef to 0 when the model is deselected but
never clears the previously fetched mcpDiagnostic value from useMcpDiagnostic(), so once a model is
reselected and re-validated, a diagnostic tied to the prior model/config can still render until a
fresh fetch completes.
Code

src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx[R218-223]

+    // Nothing to diagnose yet — "No model selected" isn't a runtime error pattern.
+    // Reset ref and clear stale diagnostics when model is deselected.
+    if (!modelSelected) {
+      prevIssueCountRef.current = 0;
+      return;
+    }
Relevance

●●● Strong

Team often fixes stale UI state on context changes; leaving old diagnostics visible is confusing.

PR-#161
PR-#107

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
RecipeValidationPanel.tsx lines 218-223 add an early return resetting only prevIssueCountRef.current
on !modelSelected; the mcpDiagnostic state from useMcpDiagnostic() (line 97) is not cleared here or
elsewhere in the effect, so once a model is reselected and issues recur, the UI may briefly show a
diagnostic fetched against a stale model/critical-issue set before fetchDiagnostic resolves again.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When `hasSelectedModel(state)` becomes false, the MCP diagnostic auto-fetch effect in `RecipeValidationPanel.tsx` resets `prevIssueCountRef` but does not clear the `mcpDiagnostic` value already held by the `useMcpDiagnostic()` hook. If the user later reselects a model, the previously-fetched diagnostic (tied to the old model/config) can render again before a new fetch completes.

## Issue Context
- `useMcpDiagnostic()` is defined in `src/lib/hooks/useMcpDiagnostic.ts` and exposes `diagnostic`/`fetchDiagnostic`.
- The new `!modelSelected` guard was added in this PR to skip diagnosing when no model is selected, but it doesn't clear existing diagnostic state.

## Fix Focus Areas
- src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx[213-235]
- src/lib/hooks/useMcpDiagnostic.ts[31-80]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Duplicated collapse condition across UI elements 🐞 Bug ⚙ Maintainability
Description
ProviderCardGrid now derives showExportTargets/showUndetectedLocal via useState+useEffect synced
from selectedIsExportTarget/selectedIsUndetectedLocal, and separately renders a static hint
paragraph gated on the same collapsed condition; this duplicates the expand/collapse condition
across the toggle button, hint text, and card grid, increasing risk of future inconsistency if only
one spot is updated.
Code

src/components/features/ihv/ProviderCardGrid.tsx[R127-133]

+          {!showExportTargets && (
+            <p className="text-xs text-slate-600">
+              Deploy/export targets for other runtimes (mobile, browser, edge) — not local
+              execution providers on this machine.
            </p>
+          )}
+          {showExportTargets && (
Relevance

●● Moderate

Maintainability/DRY refactor is subjective; no strong precedent that they require consolidating
collapse conditions.

PR-#260

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ProviderCardGrid.tsx lines 110-139 add a useState/useEffect pair to sync showExportTargets with
selectedIsExportTarget, plus a separate ternary block rendering either a static hint paragraph or
the card grid; this duplicates the expand/collapse condition across three separate spots (button
label, hint paragraph, and card grid) increasing the chance of future inconsistency.

5. Technical UI copy in IHV 📘 Rule violation ✧ Quality
Description
New user-facing strings include internal implementation terminology (e.g., execution providers,
Python EP, ORT probe hit). This violates the requirement to avoid technical implementation
details in UI copy and can confuse users or leak unnecessary internal concepts.
Code

src/components/features/ihv/ProviderCardGrid.tsx[R128-131]

+            <p className="text-xs text-slate-600">
+              Deploy/export targets for other runtimes (mobile, browser, edge) — not local
+              execution providers on this machine.
            </p>
Relevance

● Weak

Very close precedent: request to remove “execution providers/runtimes” jargon in this exact hint
text was rejected.

PR-#260

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2661574 disallows technical implementation details in user-facing UI copy. The
changed UI text explicitly references internal runtime/provider concepts (e.g., `execution
providers, Python EP, ORT probe hit`), which are implementation details rather than user-task
guidance.

Rule 2661574: Avoid technical implementation details in user-facing UI copy
src/components/features/ihv/ProviderCardGrid.tsx[127-131]
src/components/features/ihv/HardwareProviderCard.tsx[1021-1038]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
User-facing UI copy added/modified in the IHV selection UI contains internal technical implementation details (e.g., mentioning `execution providers`, `Python EP`, `ORT probe hit`). The compliance requirement is to keep user-facing copy task-focused and avoid internal implementation terminology.

## Issue Context
These strings appear in the provider selection UI and are visible to end users.

## Fix Focus Areas
- src/components/features/ihv/ProviderCardGrid.tsx[128-131]
- src/components/features/ihv/HardwareProviderCard.tsx[1022-1038]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 33 rules
Review mode: 🧠 Deep: This PR changes multiple independent behavioral paths—validation gating, execution/playground navigation, provider filtering/expansion, and catalog rendering—across 12 files with 37 hunks, making redundant review materially useful.

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/components/features/ihv/HardwareProviderCard.tsx
Comment thread src/components/features/execute/ExecutionWorkspace.tsx Outdated
Comment thread src/components/features/playground/PlaygroundPanel.tsx Outdated
greptile-apps[bot]
greptile-apps Bot previously approved these changes Aug 13, 2026
Capture the exact recipe submitted for execution by using `runRecipeJsonRef` instead of rebuilding from potentially edited UI state after completion. Add `clearDiagnostic` to `useMcpDiagnostic` (aborts in-flight requests and resets state) and invoke it when no model is selected to prevent stale validation diagnostics. Also stop auto-injecting placeholder local files in batch job UI state hydration.
@greptile-apps
greptile-apps Bot dismissed their stale review August 13, 2026 03:31

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

Comment thread src/components/features/ihv/ProviderCardGrid.tsx
…rowser Test

- Ensure isProviderDetectedLocally always returns true for CPUExecutionProvider, preventing CPU from being marked as hardware-blocked when hardwareProbe is null.
- Validate execution provider in PlaygroundPanel before passing capturedRunRecipe to InBrowserValidation so non-WebGPU run recipes do not trigger the WebGPU hint.
- Export mapExecutionProviderFromRecipe from oliveRecipeHub for recipe provider inspection.
- Add component and unit tests covering null probe CPU detection and PlaygroundPanel recipe provider filtering.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread src/components/features/ihv/HardwareProviderCard.tsx Outdated
greptile-apps[bot]
greptile-apps Bot previously approved these changes Aug 13, 2026
Generate a per-provider details ID in `HardwareProviderCard` and wire both `aria-controls` and the details container `id` to it. This avoids duplicate static IDs across cards and keeps the expand/collapse button’s accessibility relationship accurate.
@greptile-apps
greptile-apps Bot dismissed their stale review August 13, 2026 04:26

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

greptile-apps[bot]
greptile-apps Bot previously approved these changes Aug 13, 2026

Copilot AI 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.

Pull request overview

This PR tightens the “model must be selected” invariant across the app, improves IHV/provider selection UX (including a11y affordances), and ensures the Playground Browser Test consumes the exact recipe that was executed (rather than rebuilding from potentially edited state).

Changes:

  • Captures the submitted Execute recipe and routes it into the Playground store; Browser Test consumes it only when the recipe’s provider is WebGPU.
  • Improves validation/diagnostics lifecycle (including abortable MCP diagnostics) and hardware/provider detection behavior (CPU always treated as locally detected).
  • Enhances IHV UI/UX (collapsible provider cards, detected vs undetected grouping, sticky matrix header) plus nav “incomplete” indicators and batch hydration behavior.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/lib/stores/playgroundStore.ts Adds capturedRunRecipe to persist the last successful Execute recipe for Playground use.
src/lib/oliveRecipeHub.ts Exposes mapExecutionProviderFromRecipe for provider detection from recipe JSON.
src/lib/hooks/useMcpDiagnostic.ts Adds clearDiagnostic() to abort/reset MCP diagnostic state.
src/lib/hardwareProbe.ts Treats CPUExecutionProvider as locally detected even without a probe.
src/lib/hardwareProbe.test.ts Adds unit coverage for isProviderDetectedLocally behavior.
src/components/features/playground/PlaygroundPanel.tsx Prefers captured Execute recipe for Browser Test, with WebGPU-only gating.
src/components/features/playground/PlaygroundPanel.test.tsx Tests captured recipe routing into InBrowserValidation only for WebGPU.
src/components/features/input/CompatStatus.tsx Adjusts compatible pill styling and icon coloring.
src/components/features/ihv/ProviderCardGrid.tsx Splits local providers into detected/undetected groups with a toggle for “other targets”.
src/components/features/ihv/ProviderCardGrid.test.tsx Adds regression test ensuring CPU isn’t shown as hardware-blocked when probe is null.
src/components/features/ihv/HardwareProviderCard.tsx Adds per-card collapsible “Show/Hide details” region with aria-controls.
src/components/features/ihv/HardwareCompatibilityMatrix.tsx Adds vertical scroll with sticky header for the compatibility matrix.
src/components/features/execute/useOliveStream.ts Exposes runRecipeJsonRef so callers can persist the submitted recipe.
src/components/features/execute/recipe-graph/RecipeValidationPanel.tsx Clears MCP diagnostics on model deselect and resets issue counters when issues clear.
src/components/features/execute/ExecutionWorkspace.tsx Captures executed recipe on completion into Playground store.
src/components/features/execute/BatchProcessingPanel.tsx Preserves localFiles when hydrating UI from batch jobs.
src/App.tsx Adds incomplete-step indicators/ARIA labels for steps when no model is selected.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +79 to +84
const recipeJson = useMemo(() => {
if (capturedRunRecipe && isWebGpuRecipe(capturedRunRecipe)) return capturedRunRecipe;
return hasSelectedModel(state) && state.ihvProvider === "WebGpuExecutionProvider"
? buildRecipeJsonFromState(state)
: undefined;
}, [capturedRunRecipe, state]);
Comment on lines +41 to +48
// However, if probe is still loading or failed (null), show all locals together since we
// can't reliably distinguish detected from undetected (e.g., null probe would hide CPU fallback).
const { detectedLocal, undetectedLocal } = useMemo(() => {
const hardwareProbe = providerCardProps.hardwareProbe;
const detected: ProviderCatalogEntry[] = [];
const undetected: ProviderCatalogEntry[] = [];

// Only split if probe data is available; otherwise treat all as detected to avoid hiding CPU.
Co-authored-by: Cursor <cursoragent@cursor.com>
@greptile-apps
greptile-apps Bot dismissed their stale review August 13, 2026 05:04

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@codefactor-io

codefactor-io Bot commented Aug 13, 2026

Copy link
Copy Markdown

CodeFactor found an issue: 'runRecipeJson' is assigned a value but never used. Allowed unused vars must match /^_/u.

It's currently on:
src\components\features\execute\ExecutionWorkspace.tsx:480
Commit 7b7e8d2

@codefactor-io

codefactor-io Bot commented Aug 13, 2026

Copy link
Copy Markdown

CodeFactor found an issue: Complex Method

It's currently on:
src\components\features\execute\useOliveStream.ts:137-180
Commit 46d096e

@codefactor-io

codefactor-io Bot commented Aug 13, 2026

Copy link
Copy Markdown

CodeFactor found an issue: Complex Method

It's currently on:
src\components\features\execute\useOliveStream.ts:225-521
Commit 46d096e

@codefactor-io

codefactor-io Bot commented Aug 13, 2026

Copy link
Copy Markdown

CodeFactor found an issue: Complex Method

It's currently on:
src\components\features\execute\useOliveStream.ts:424-505
Commit 46d096e

@tonythethompson
tonythethompson merged commit 112c1d0 into main Aug 13, 2026
16 of 19 checks passed
@tonythethompson
tonythethompson deleted the fix/olive-studio-issue-reports branch August 13, 2026 05:09
@linear-code

linear-code Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

OLI-98

This branch was successfully deployed

1 active deployment
Preview — 7b7e8d21 Deployed Aug 13, 2026 by vercel[bot]
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.

2 participants