发布

  • [OPIK-7512] [FE] fix: Optimization Studio display cleanups — dead Pass rate column, {{variable}} rendering, Rerun label (#7655)

    frostbyte_neo 发布于 2026-07-30 11:06:39 +00:00

    • [OPIK-7512] [FE] fix: merge dead Pass rate column, restore {{variable}} display, relabel Rerun

    Three Optimization Studio papercuts from dogfooding. v2 only; v1 is deliberately
    left alone (precedent: 4c5ec9a4ca).

    1. Dead "Pass rate" column on the runs list. "Pass rate" and "Accuracy" were
      mutually exclusive — each rendered a literal "-" for the run type it did not
      handle — so every Studio dataset run showed a permanently empty Pass rate
      column. Merged into one objective column rendered per run type.

      The header stays type-neutral ("Best score") rather than using
      getObjectiveLabel like the trials table does: one run has one type, but this
      list can mix test-suite and dataset runs, so no static header can be per-row
      correct. Which metric produced the score is already carried by the sibling
      "Metric" column and by the score tag's own label.

      The merged column keeps id "accuracy" deliberately — it is already in
      existing users' saved selected-columns/order state, so the column stays
      visible and positioned without bumping SELECTED_COLUMNS_KEY and resetting
      everyone's customizations. The now-unused "pass_rate" id no longer matches a
      column and is ignored.

    2. A brace pair disappeared from displayed prompts. The Studio form uses
      {{variable}}; studio/types.py::_convert_template_syntax rewrites it to
      {variable} on ingest, so every view downstream of a run showed a single
      brace, reading as if the user had authored a broken prompt. Added
      restorePromptVariableFormat and applied it at the display boundary only —
      getCandidatePrompt (the single resolver behind both v2 prompt surfaces) and
      the best-prompt card. Nothing is re-sent to the backend in this form.

      The pattern is narrower than the existing convertOptimizationVariableFormat's
      [^{}]+: prompts routinely embed literal braces (JSON examples, code), and
      re-doubling those would corrupt what the user reads, so only
      identifier-shaped tokens are restored. convertOptimizationVariableFormat is
      left untouched because v1 shares it.

      The transform walks the value structurally instead of normalizing it, so
      every prompt wrapper shape survives: bare message array, { messages: [...] },
      the single-prompt { "": [...] } wrapper, and the named multi-prompt map.

    3. "Rerun" never reran. It opens the new-run panel prefilled from the run and
      never launches anything, so it is now "Duplicate run" with a copy icon.

    Two candidatePrompt tests asserted verbatim passthrough, which is the contract
    this changes; updated to express the new one and added a case naming the bug.

    NOT included, split out deliberately: extending the ingest brace conversion in
    studio/types.py to multimodal (list) content. That is a silent run-time
    substitution failure rather than a display issue, needs its own backend test,
    and would be under-reviewed inside a PR titled "display cleanups".

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

    • [OPIK-7512] [FE] fix: drop run-type column filtering that hid the merged score column

    Self-review catch on the previous commit. OptimizationsPage filtered the
    "accuracy" column out of the table whenever the page held no dataset run
    (hasOldTypeOptimizations === false), so that Accuracy's all-"-" cells would not
    show for a pure test-suite workspace.

    That filter predates this change and was only ever half a fix: it hid the dead
    column in one direction while leaving the reported bug — a Studio-only workspace
    showing a permanently empty "Pass rate" — untouched. After merging the pair into
    a single column that carries id "accuracy", the filter became actively harmful:
    on a page with only test-suite runs it stripped the ONLY score column, leaving no
    score at all.

    The merged column renders correctly for both run types, so no run-type-dependent
    column filtering is needed. Removed the filter and the now-unused
    hasOldTypeOptimizations memo.

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

    • [OPIK-7512] [FE] fix: restore {{variable}} in the trials-table prompt column too

    Caught by driving the real UI, not by any test. TrialPromptCell carries its own
    getPromptFromExperiment — a single-experiment duplicate of getCandidatePrompt's
    lookup — so the trials table kept rendering the optimizer's single-brace form
    while the overview's best-trial panel had switched to the authored double-brace
    form. Two surfaces on the same run page disagreed, which is worse than the
    original papercut: before this PR both were consistently wrong.

    That helper feeds both the cell preview and the "Diff vs baseline" hover card, so
    one call site fixes both. Verified in the browser: trials table, best-trial panel
    and the diff popover now all render {{question}}.

    There are exactly three prompt read sites in v2 (grep for prompt_messages /
    OPTIMIZATION_PROMPT_KEY): candidatePrompt.ts, BestPrompt.tsx and this one. All
    three now restore. Left the duplication in place rather than extracting a shared
    single-experiment resolver — that refactor is wider than this PR — but documented
    the sibling relationship so the next reader finds both.

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

    • [OPIK-7512] [FE] test: guard both regressions this PR shipped and fixed

    Review finding: the two defects in this PR were caught by reading code and by
    driving the UI, and nothing in CI would have caught their return. Both files
    involved had no test at all.

    TrialPromptCell.test.ts — exports getPromptFromExperiment and covers the restore
    for both the prompt and legacy prompt_messages keys. The important case is the
    agreement with getCandidatePrompt block: two near-identical resolvers read a
    trial's prompt, and that duplication is exactly why the trials table drifted from
    the overview panel. The tests pin them to the same output across five payload
    shapes (message array, legacy key, single-prompt named wrapper, multimodal parts,
    literal JSON braces) until one shared resolver replaces both.

    OptimizationsColumns.test.ts — asserts a single objective-score column rather than
    the Pass rate / Accuracy pair, that the retired pass_rate id is gone from the
    default selection and order, and that the accessor produces a value for BOTH run
    types (the property that makes run-type column filtering unnecessary — that filter
    stripped the only score column from a test-suite-only page). It also pins the
    column's id to "accuracy": renaming it for semantic tidiness would leave the id
    absent from existing users' saved selected-columns state and render the column
    hidden for all of them, so the test states why the odd name stays.

    Both suites were mutation-checked rather than assumed: reverting the
    TrialPromptCell restore fails 7 of its 8 tests, and re-adding the dead pass_rate
    column fails the columns test. 14 tests added, 2286 passing overall.

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


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

    下载附件