import { type Span } from "@opentelemetry/api"; import type { ExecutorTraceContext } from "../executor/types.js"; import type { StimulusGradeResult } from "../pipeline/grading.js"; import type { Trajectory } from "../trajectory/types.js"; export declare const VALLY_TRACER_NAME = "@microsoft/vally"; export declare const VALLY_TRIAL_SPAN_NAME = "vally.trial"; export declare const VALLY_ATTEMPT_SPAN_NAME = "vally.attempt"; export interface TrialSpanOptions { evalName: string; evalFilePath: string; variant: string; stimulusName: string; trialId: string; model?: string; trialIndex?: number; totalTrials?: number; } export interface AttemptSpanOptions { /** Zero-based retry attempt index; omitted for non-retry-eligible trials. */ attemptIndex?: number; } /** Controls a single `vally.attempt` child span. */ export interface AttemptSpanController { readonly span: Span; /** Trace context of the attempt span, propagated to the executor subprocess. */ readonly traceContext: ExecutorTraceContext; /** * Stamp `gen_ai.conversation.id` up front so failed attempts still carry it; * success later overwrites this with the executor-reported id via setTrajectory. */ setConversationId(conversationId: string): void; /** * Record this attempt's trajectory id and `gen_ai.conversation.id` (the * executor session for this attempt) on the attempt span. Each attempt is a * distinct conversation, so the conversation id lives here, not on the trial. */ setTrajectory(trajectory: Trajectory): void; /** * Mark this attempt as errored without throwing. The trial runner settles * graceful (non-throwing) failures as data, so error status must be recorded * explicitly rather than relying on an exception propagating out of the span. */ setError(error: { message: string; }): void; } /** * Controls the per-trial `vally.trial` parent span and spawns child * `vally.attempt` spans (one per retry attempt) beneath it. */ export interface TrialSpanController { readonly span: Span; /** * Record the winning attempt's result trajectory id on the trial span. * `gen_ai.conversation.id` is deliberately omitted here (see * {@link AttemptSpanController.setTrajectory}). */ setTrajectory(trajectory: Trajectory): void; /** Record the trial's grade on the trial span. */ setGrade(grade: StimulusGradeResult | null): void; /** * Mark the trial as errored without throwing. Called only when the trial * finally settles to an error outcome (a retried failure that later succeeds * keeps a success trial span). */ setError(error: { message: string; }): void; /** * Run a single attempt under a child `vally.attempt` span. The attempt span is * parented explicitly to the trial span, so the hierarchy holds regardless of * whether an async context manager is installed. */ runAttempt(options: AttemptSpanOptions, run: (attempt: AttemptSpanController) => Promise): Promise; } /** * Run a logical trial under a single `vally.trial` span, exposing * {@link TrialSpanController.runAttempt} to nest each retry attempt as a child * `vally.attempt` span. One trace per trial: every attempt (and the executor * runtime spans beneath it) shares the trial's trace id. * * The trial span is started manually (not via `startActiveSpan`) so retry/ * rate-limit orchestration in `run` is not captured as the active span; child * attempt spans are parented through an explicit context instead. */ export declare function runWithTrialSpan(options: TrialSpanOptions, run: (trial: TrialSpanController) => Promise): Promise; //# sourceMappingURL=trial-tracing.d.ts.map