发布

  • [OPIK-7042] [FE] feat: Optimization Studio new-run sidebar (#7291)

    frostbyte_neo 发布于 2026-07-09 09:25:30 +00:00

    • [OPIK-7042] [FE] feat: Optimization new-run sidebar + metric/schema cleanup

    First slice (verified, typecheck + lint clean):

    • Fix the Equals metric default to read reference_key from
      DEFAULT_EQUALS_METRIC_CONFIGS (was wrongly pulling the JSON-schema
      validator constant; harmless today since both are "", but incorrect).
    • Widen StudioLlmModel.model off the legacy PROVIDER_MODEL_TYPE enum to
      string (model ids come from the dynamic registry); drop the now-
      redundant cast in the v2 studio-config converter.

    Sidebar conversion + god-hook split + dataset-picker pagination follow
    on this branch. Part of OPIK_6528.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • feat(optimizations): new-run form as a sidebar over the runs list

    Convert the new-run wizard from the full-page /optimizations/new route into
    a right ResizableSidePanel opened over the runs list (Figma 548:27872):

    • NewRunSidebar hosts the form logic + 2-column body with a "New optimization
      run" top bar and an Optimize/Cancel footer; mounted only while open.
    • The list opens it via ?new (+ ?template/?rerun to pre-fill); the
      studio-templates row, empty state and the single-run header now set those
      params instead of navigating to /new.
    • Remove the /optimizations/new route + its guard usage; delete the orphaned
      OptimizationsNewPage / OptimizationsNewHeader.

    Routing/open-close behavior is not runtime-verified (no app run); typecheck,
    lint and the optimization test suites are green.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • refactor(optimizations): on-demand dataset name lookup + clean schema arms
    • Replace the silent 1000-dataset list (used only to resolve the selected
      dataset's name on submit) with a single useDatasetById; the picker itself
      was already the searchable DatasetSelectBox.
    • Remove the dead commented-out Evolutionary optimizer params schema
      (Evolutionary isn't offered in OPTIMIZER_OPTIONS).
    • Add the Code metric to OPTIMIZATION_METRIC_OPTIONS (it already has a full
      schema arm, config component and submit handling, just wasn't selectable).

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • refactor(optimizations): split new-run god-hook into per-section hooks

    Break useOptimizationsNewFormHandlers (~305 lines) into cohesive hooks under
    formHandlers/: useOptimizerFormHandlers, useMetricFormHandlers,
    useModelFormHandlers and useSubmitOptimization. The main hook (~108 lines)
    now just composes them plus the watches, selected-dataset lookup, and the
    dataset/name handlers.

    Also drop the dead code the sidebar conversion left behind: the unused
    handleCancel and the breadcrumb wiring for the removed /optimizations/new
    route.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] feat: new-run sidebar — non-blocking dataset prep, input alignment & variable validation
    • Render the form during demo-dataset prep instead of a full-panel spinner; the item-source field shows a local "Preparing dataset..." state and submit stays disabled until ready.
    • Align the Name input to 32px (dimension="sm") to match the right-rail controls and Figma.
    • Block submit when {{variables}} in the prompt or G-Eval metric aren't columns in the selected item source, with an inline reason (prevents runs that fail at evaluation time).
    • Metric settings / config-field cleanup (field cards, GEval & reference-key fields, dataset-variable hints).

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix: address Baz review on new-run sidebar
    • Variable check uses the dataset's server-side column schema (datasetItemsData.columns) instead of one sampled row, so optional columns absent from row 1 no longer falsely block submit (Baz: false missing-column block).
    • Submit is disabled while the selected-dataset lookup is loading and surfaces an error if it fails, closing the silent no-op window (Baz: silent no-op on unresolved dataset).
    • Spinner: wrap Loader2 in an animate-spin span so the SVG isn't animated in place (perf guideline).
    • Dataset icon uses the --chart-yellow theme token instead of a hard-coded hex.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix: address Baz re-review (round 2) on new-run sidebar
    • Flatten structured (array) message content via extractMessageContent before pulling {{vars}}, so prompts with multipart parts are still checked by the missing-variable gate.
    • Gate submit while the dataset's columns are still loading (areColumnsLoading), so the missing-variable check can't be bypassed in the window before columns arrive.
    • Restore legacy /optimizations/new -> /optimizations?new=true redirect so old deep links open the new-run sidebar instead of hitting the /$optimizationId detail route.
    • Extract a shared ReferenceKeyField used by the Equals/JSON Schema/Levenshtein/Numerical Similarity metric configs (was duplicated 4x).

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] refactor: move optimization icon accents to theme tokens

    Replaces hard-coded hex on the algorithm/metric icon maps with named --optimizer-icon-* / --metric-icon-* CSS variables in main.scss (matching the existing --template-icon-* / --chart-* convention), so the icons follow the theme system instead of bypassing it. Colors are unchanged. Addresses the last Baz review comment.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix: validate new-run form on submit + align reference-key field
    • Validation is now lazy (mode: onSubmit + reValidateMode: onChange): RHF field errors and the {{variable}} mismatch no longer appear while editing, switching metrics, or before a dataset is picked. The 'Optimize prompt' button stays clickable and reveals what's missing on click (still won't submit with errors / missing variables).
    • Reference-key input aligned to 32px (dimension="sm") to match the Algorithm/Item source/Metric controls.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix(new-run): drive submit + lazy validation through RHF

    Address Baz round-2 findings on the new-run sidebar form:

    • #10 Lazy gate missed RHF field errors: change handlers still forced
      shouldValidate: true, so field errors surfaced eagerly while editing
      despite mode: "onSubmit". Dropped it everywhere (dataset/metric/
      optimizer/prompt/demo-dataset setValue) so field errors and the
      variable-mismatch footer both surface only after a submit attempt.
    • #11 Submit + busy state now flow through form.handleSubmit(onValid)
      and form.formState.isSubmitting/isSubmitted, instead of a manual
      trigger() + local isSubmitting state and a submitAttempted flag.
      useSubmitOptimization no longer re-validates or owns a busy flag.

    Enter-key submit is intentionally not wired: the form is a rich
    multi-field panel with nested untyped buttons (prompt library menu,
    metric-config popovers, model settings), so a <form> wrapper would
    make Enter/stray buttons submit. Submit stays an explicit button click.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix(new-run): swallow already-toasted submit rejection

    RHF's handleSubmit re-throws when the submit handler rejects, and the
    create mutation uses mutateAsync (rejects on error). The mutation already
    surfaces API errors via its onError toast, so the re-thrown rejection was
    only producing an unhandled promise rejection in the console. Catch it at
    the onClick call site; RHF has already reset isSubmitting before re-throwing.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] refactor(new-run): use idiomatic submit

    Adopt the shadcn/RHF form pattern from forms.md instead of calling
    form.handleSubmit from an onClick handler:

    • Wrap the new-run content in ,
      submit button type="submit", cancel type="button". Enter now submits.
    • A without an explicit type inside a defaults to submit,
      so add type="button" to the non-submit buttons that render inside this
      form's DOM: LoadedPromptDisplay (detach), LLMPromptMessageActions (save),
      LLMPromptMessage (show more/less), AlgorithmConfigs (use prompt model),
      DatasetVariablesHint (variable chips). Pure correctness fixes — these
      should never submit any form. Buttons in portaled Dialog/Dropdown content
      are outside the form DOM and were left as-is.

    RHF still owns validation and busy state (form.formState.isSubmitting /
    isSubmitted); the submit handler swallows the settled rejection since the
    create mutation already toasts API errors via its onError.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] chore(optimizations): drop untested custom-code metric from new-run options

    Removes the "Custom code" (METRIC_TYPE.CODE) entry from
    OPTIMIZATION_METRIC_OPTIONS so it is no longer selectable in the new-run
    sidebar. The backend exec path exists (OPIK-3932 / #4817) but was never
    exercised live here and has FE validation / error-surfacing gaps, so
    exposing it now risks silent "Initialized" hangs on bad code. OPIK-7042's
    scope also explicitly excludes the code metric from options.

    Re-exposing it (with pre-submit syntax validation, dataset-column checks,
    and surfaced run errors) is tracked in OPIK-7172. The CODE type, schema arm,
    and CodeMetricConfigs component are left in place for that follow-up.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] refactor(new-run): prune over-explanatory comments and simplify prompt helper

    Delete comments that restate the code, keeping only ticket/Figma refs and
    genuine gotchas; trim the rest to their essential rationale. Also rewrite
    safelyGetPromptVariables to reuse getPromptMustacheTags and drop its dead
    !== "." filter.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] refactor(new-run): move optimizer/metric icon maps to constants

    Static ALGORITHM_ICON_MAP / METRIC_ICON_MAP lookup tables don't belong in a
    component file — move them (and the IconConfig type) into constants/optimizations
    next to the existing option lists so they're reusable. Also folds in the
    new-run sidebar shell/form split.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix(new-run): stop form buttons from submitting; metric title above box

    The new-run form wrapped its whole body in a , so every native
    inside (dropdowns, settings, prompt actions) defaulted to type="submit" and
    submitted on click. Move the body outside a standalone and link only
    the "Optimize prompt" button via form={id}, so nothing else can submit it.

    Also move the "Metric settings" heading above its card (out of the box header)
    to match the Figma.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix(new-run): algorithm-model inheritance, metric defaults, compact selectors

    Address code-review findings on the new optimization run sidebar:

    • Algorithm model represents 'follow prompt model' as unset (picker shows
      'Same as prompt · '). Stop force-seeding/syncing it to the prompt
      model on change and on rerun, which discarded explicit choices and could
      submit a stale/unavailable model behind an 'inherited' label.
    • 'Use prompt model' now clears the explicit algorithm model and works even
      when no prompt model is selected.
    • Merge metric defaults on load so required params the saved config omitted
      (e.g. EQUALS case_sensitive) are present — otherwise Zod rejects a field
      with no inline error and Create silently no-ops.
    • Extract shared MetricParamErrors type (was copy-pasted across 7 files).
    • Compact model dropdown rows (h-8) + small search; align explainer icon
      sizes; shorten G-Eval placeholders.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] revert(new-run): drop SelectItem size prop (to be done separately)

    Remove this branch's only ui/select.tsx change (the SelectItem 'size' compact
    variant) and its two usages in the new-run sidebar. The select sizing work is
    being done separately, and this was the sole conflict with main's SelectItem
    refactor — reverting it lets select.tsx merge cleanly from main.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • [OPIK-7042] [FE] fix(optimizations): per-field message errors + Algorithm model clear

    New-run sidebar:

    • Prompt messages: surface empty-content errors per message (red border +
      inline "Message is required") instead of one general banner — per-index
      superRefine emits issues at [index, "content"] and validationErrors is
      passed through to LLMPromptMessages.
    • Algorithm model: replace the "Use prompt model" link with an inline x clear
      button on the field, and simplify the placeholder to "Same as prompt".

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com


    Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com

    下载附件