发布

  • [OPIK-5793] [FE][BE] feat: playground experiment UX improvements for test suites (#6361)

    frostbyte_neo 发布于 2026-04-23 17:09:29 +00:00

    • [OPIK-5793] [FE][BE] feat: playground experiment UX improvements for test suites
    • Add test suite pass/fail status display in playground output columns
    • Show assertion breakdown tooltips with pass rates per prompt
    • Add winner/loser badge coloring for prompt headers based on pass rate
    • Fix regression: resolve null selectedRuleIds to actual IDs for online scoring
    • Add progress indicator polling for test suite experiment completion
    • Extract useTestSuitePromptResults hook with tests for scoring logic
    • Extract usePromptBadgeColor hook for clean badge color computation
    • Remove dead stale prop from PlaygroundOutputAssertionStatus
    • Add dark theme support for --click-blue CSS variable
    • Return assertion_results and status in experiment item compare API

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix: address code review feedback
    • Extract isItemScored helper, reuse in polling and per-cell scoring
    • Extract usePromptResultStatus hook for shared winner/loser/default state
    • Move animate-spin off SVG onto wrapper span for GPU acceleration
    • Fix BE test assertions for empty evaluators list ([] vs null)

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(tests): update dataset and experiment test assertions
    • Set evaluators default to List.of() in DatasetItemTypeManufacturer
      so PODAM-generated items match new API behavior
    • Fix explicit .evaluators(null) -> .evaluators(List.of()) in DatasetsResourceTest
    • Add executionPolicy to ignored fields in ExperimentTestAssertions

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(tests): add executionPolicy to ignored fields and fix evaluator assertions

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(sdk): access assertion_results directly instead of via model_extra

    The BE now returns executionPolicy in experiment item Compare responses,
    which Pydantic stores in model_extra. The _extract_extra_field helper
    checked model_extra first, so it looked for assertion_results there
    (returning None) instead of reading the proper model field. Remove the
    helper and access value.assertion_results directly, matching the pattern
    already used for feedback_scores.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • WIP: add SKIPPED status for experiment items without assertions

    Backend: add RunStatus.SKIPPED, set status to SKIPPED for items with
    empty assertions in enrichWithAssertions, handle SKIPPED in
    computeRunSummaries. Frontend: simplify isItemScored, handle SKIPPED
    in polling and display logic. Revert winner logic change. Still needs
    backend fix for timing issue (items get SKIPPED before evaluation starts).

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • [OPIK-5793] [BE][FE] feat: delay experiment completion until assertions finish

    BE: Add per-experiment assertion counter via Redis so test suite
    experiments only complete after all assertion evaluations finish.
    Pass experimentId through the scoring pipeline. Revert BE SKIPPED
    status logic from AssertionResultMapper.

    FE: Check all experiment statuses with .every() for multi-prompt
    runs. Show SKIPPED immediately for items without evaluators. Remove
    dead SKIPPED status check since BE no longer returns it.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): extract assertion counter logic into AssertionCounterService

    Centralizes all assertion counter operations (set, decrement, adjust,
    delete, finish-on-complete) into a single service, removing duplicated
    Redis counter logic from OnlineScoringBaseScorer, ExperimentItemPublisher,
    ExperimentItemProcessingSubscriber, and TestSuiteAssertionSampler.

    Fixes race condition where failure-path decrement reaching 0 could mark
    an experiment COMPLETED while the batch failure path marks it CANCELLED,
    by deleting assertion counter keys before marking experiments as failed.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • Revert "refactor(backend): extract assertion counter logic into AssertionCounterService"

    This reverts commit 18b422113d.

    • refactor(backend): extract AssertionCounterService, scope to LLM scorer only

    Extract Redis assertion counter operations into a dedicated
    AssertionCounterService. Keep ExperimentService and counter logic only in
    OnlineScoringLlmAsJudgeScorer — the sole scorer that processes test suite
    assertion messages — instead of polluting the base class and all 6 subclasses.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(backend): finish experiment when no evaluators, extract metadata keys
    • Fix stuck experiments when no assertions exist: TestSuiteAssertionSampler
      now checks counter return value and finishes the experiment when it
      reaches zero
    • Extract TestSuiteMetadataKeys shared constants to prevent contract drift
      between ExperimentTracePersistence (writer) and TestSuiteAssertionSampler
      (reader)
    • Revert formatting-only changes in 5 scorer files

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(fe+be): progress bar skipped items, faster polling, fix test assertions
    • Fix evaluators undefined check in progress bar (was always false for null)
    • Poll assertion status immediately on step 2 start, reduce interval to 1s
    • Remove invalid SKIPPED-status tests (backend never returns SKIPPED)
    • Add executionPolicy to expected ExperimentItem objects in integration tests
    • Refactor assertion counter: rename to TestSuiteAssertionCounterService,
      scope to LLM scorer only, extract metadata keys

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(backend): harden assertion sampler error handling and fix test executionPolicy assertions

    Remove error-swallowing in TestSuiteAssertionSampler (fetchDatasetEvaluators/fetchItemEvaluators),
    add per-trace try/catch to ensure assertion counter always decrements on failure, extract
    decrementAssertionCounterForTrace helper. Fix DatasetsResourceTest executionPolicy mismatches
    by adding ExecutionPolicy.DEFAULT to all expected ExperimentItem builders in Compare view tests.
    Add unit tests for TestSuiteAssertionCounterService.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(test): add executionPolicy to StreamExperimentItems expected items

    The stream endpoint has no @JsonView so executionPolicy is always
    returned. Add ExecutionPolicy.DEFAULT to the two expected-item
    builders in streamByExperimentNameAndProjectName test.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(backend): demote evaluator fetch log to DEBUG

    The log inside computeIfAbsent fires once per cache miss but
    can still be noisy at INFO when many datasets are involved.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): scope assertion counter Redis key by workspace with opik prefix

    Add workspaceId to all TestSuiteAssertionCounterService methods and include
    it in the Redis key to enforce workspace isolation. Update key prefix from
    "experiment:assertion:" to "opik:experiment:assertion:{workspaceId}:{experimentId}".

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): harden assertion counter service
    • Use Optional chain in fetchItemEvaluators instead of null checks
    • Renew TTL on decrement and adjust via withExpiryRenewal helper
    • Guard decrementAndFinishIfComplete with exists check to prevent
      phantom key creation on expired counters
    • Propagate finishExperiment errors to callers instead of swallowing

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): remove unused deleteCounters and narrow catch blocks

    Remove unused deleteCounters method from TestSuiteAssertionCounterService
    and narrow catch(Exception) to catch(RuntimeException) in
    TestSuiteAssertionSampler to avoid silently swallowing checked exceptions.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • test(backend): add tests for TracesCreated trace partition logic

    Document that TracesCreated fires only on insert (not update) so each
    trace is processed exactly once. Add tests verifying incomplete traces
    decrement the assertion counter immediately while complete traces
    proceed to scoring.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): convert TestSuiteAssertionSampler to reactive chain

    Eliminate scattered .block() calls inside helper methods and stream
    lambdas by composing a proper Flux/Mono pipeline with a single .block()
    at the EventBus entry point. Extract per-trace processing into a
    reactive processTrace() method. Use Mono.cache() for lazy dataset
    evaluator caching. Add TODO comments for finishExperiment deduplication.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • refactor(backend): address PR review — null-safe collections, whole-object assertions, static imports

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(backend): decrement assertion counter when dataset_id is missing from trace metadata

    The missing-dataset-id early-return path was not decrementing the assertion
    counter, which could cause experiments to hang indefinitely.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(fe): address PR review comments - DRY PassedCell, tighten types, fix column labels
    • Extract resolveSkippedStatus() to DRY repeated hasEvaluators/experimentFinished logic
    • Remove dead status = undefined no-op assignments
    • Drop | string from isExperimentTerminal, cast at call sites
    • Revert PlaygroundOutputTable column label to "Prompt" (not "Result"/"Output")

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

    • fix(backend,fe): null-safe assertion counter grouping and accurate skipped message

    Filter out null experimentIds before grouping in setAssertionCounters to
    prevent NPE for non-test-suite items. Show "Scoring failed" instead of
    "No assertions defined" when evaluators exist but scoring produced no result.

    Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


    Co-authored-by: Claude Opus 4.6 noreply@anthropic.com

    下载附件