# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal, TypeAlias

from pydantic import Field as FieldInfo

from .._models import BaseModel
from .eval_definition import EvalDefinition

__all__ = [
    "Trace",
    "Eval",
    "EvalResults",
    "EvalResultsUnionMember0",
    "EvalResultsUnionMember1",
    "EvalResultsUnionMember2",
    "EvalResultsUnionMember2AnswerRelevancy",
    "EvalResultsUnionMember2AnswerRelevancyMetadata",
    "EvalResultsUnionMember2AnswerRelevancyMetadataQuestion",
    "EvalResultsUnionMember2AnswerRelevancyMetadataSimilarity",
    "EvalResultsUnionMember2ContextPrecision",
    "EvalResultsUnionMember2ContextPrecisionMetadata",
    "EvalResultsUnionMember2ContextRelevancy",
    "EvalResultsUnionMember2ContextRelevancyMetadata",
    "EvalResultsUnionMember2ContextRelevancyMetadataRelevantSentence",
    "EvalResultsUnionMember2Faithfulness",
    "EvalResultsUnionMember2FaithfulnessMetadata",
    "EvalResultsUnionMember2FaithfulnessMetadataFaithfulness",
    "EvalResultsUnionMember3",
    "EvalResultsUnionMember3Metadata",
    "EvalResultsUnionMember4",
    "EvalResultsUnionMember4Classification",
    "EvalResultsUnionMember5",
    "EvalResultsUnionMember5Missing",
    "Step",
    "StepLlmStartStepOutput",
    "StepLlmEndStepOutput",
    "StepLlmEndStepOutputUsage",
    "StepToolStepOutput",
    "StepRetrieverStepOutput",
    "StepLogStepOutput",
    "StepGroupStepOutput",
    "StepResponseStepOutput",
    "StepRequestStepOutput",
]


class EvalResultsUnionMember0(BaseModel):
    analysis: str

    clarity: float

    coherence: float

    engagingness: float

    naturalness: float

    relevance: float


class EvalResultsUnionMember1(BaseModel):
    analysis: str
    """
    A brief explanation for your rating, referring to specific aspects of the
    response and the query. Make sure that the explanation is formatted as markdown,
    and that it is easy to read and understand.
    """

    score: float
    """The score of the response based on the style guide from 1-5"""


class EvalResultsUnionMember2AnswerRelevancyMetadataQuestion(BaseModel):
    question: str


class EvalResultsUnionMember2AnswerRelevancyMetadataSimilarity(BaseModel):
    question: str

    score: float


class EvalResultsUnionMember2AnswerRelevancyMetadata(BaseModel):
    questions: List[EvalResultsUnionMember2AnswerRelevancyMetadataQuestion]

    similarity: List[EvalResultsUnionMember2AnswerRelevancyMetadataSimilarity]


class EvalResultsUnionMember2AnswerRelevancy(BaseModel):
    name: str

    score: float

    error: Optional[str] = None

    metadata: Optional[EvalResultsUnionMember2AnswerRelevancyMetadata] = None


class EvalResultsUnionMember2ContextPrecisionMetadata(BaseModel):
    reason: str

    verdict: int


class EvalResultsUnionMember2ContextPrecision(BaseModel):
    name: str

    score: float

    error: Optional[str] = None

    metadata: Optional[EvalResultsUnionMember2ContextPrecisionMetadata] = None


class EvalResultsUnionMember2ContextRelevancyMetadataRelevantSentence(BaseModel):
    reasons: List[str]

    sentence: str


class EvalResultsUnionMember2ContextRelevancyMetadata(BaseModel):
    relevant_sentences: List[EvalResultsUnionMember2ContextRelevancyMetadataRelevantSentence] = FieldInfo(
        alias="relevantSentences"
    )


class EvalResultsUnionMember2ContextRelevancy(BaseModel):
    name: str

    score: float

    error: Optional[str] = None

    metadata: Optional[EvalResultsUnionMember2ContextRelevancyMetadata] = None


class EvalResultsUnionMember2FaithfulnessMetadataFaithfulness(BaseModel):
    reason: str

    statement: str

    verdict: int

    classification: Optional[Literal["UNSUPPORTED_CLAIM", "CONTRADICTION", "PARTIAL_HALLUCINATION", "SCOPE_DRIFT"]] = (
        None
    )
    """Classification of the hallucination type (only present when verdict is 0)"""


class EvalResultsUnionMember2FaithfulnessMetadata(BaseModel):
    faithfulness: List[EvalResultsUnionMember2FaithfulnessMetadataFaithfulness]

    statements: List[str]


class EvalResultsUnionMember2Faithfulness(BaseModel):
    name: str

    score: float

    error: Optional[str] = None

    metadata: Optional[EvalResultsUnionMember2FaithfulnessMetadata] = None


class EvalResultsUnionMember2(BaseModel):
    answer_relevancy: EvalResultsUnionMember2AnswerRelevancy = FieldInfo(alias="AnswerRelevancy")

    context_precision: EvalResultsUnionMember2ContextPrecision = FieldInfo(alias="ContextPrecision")

    context_relevancy: EvalResultsUnionMember2ContextRelevancy = FieldInfo(alias="ContextRelevancy")

    faithfulness: EvalResultsUnionMember2Faithfulness = FieldInfo(alias="Faithfulness")


class EvalResultsUnionMember3Metadata(BaseModel):
    rationale: str


class EvalResultsUnionMember3(BaseModel):
    name: str

    score: int

    error: Optional[str] = None

    metadata: Optional[EvalResultsUnionMember3Metadata] = None


class EvalResultsUnionMember4Classification(BaseModel):
    fn: List[str] = FieldInfo(alias="FN")
    """False negatives: Statements found in the ground truth but omitted in the answer"""

    fp: List[str] = FieldInfo(alias="FP")
    """
    False positives: Statements present in the answer but not found in the ground
    truth
    """

    tp: List[str] = FieldInfo(alias="TP")
    """
    True positives: Statements that are present in both the answer and the ground
    truth
    """


class EvalResultsUnionMember4(BaseModel):
    classification: EvalResultsUnionMember4Classification

    score: float
    """The F1 score of the response based on the fact checker (0-1)"""

    error: Optional[str] = None

    metadata: Optional[object] = None


class EvalResultsUnionMember5Missing(BaseModel):
    have: float

    need: float

    value: str


class EvalResultsUnionMember5(BaseModel):
    reason: str

    score: float

    expected: Optional[str] = None

    expected_list: Optional[List[str]] = FieldInfo(alias="expectedList", default=None)

    f1: Optional[float] = None

    got: Optional[str] = None

    got_list: Optional[List[str]] = FieldInfo(alias="gotList", default=None)

    match_mode: Optional[Literal["exact_unordered", "contains"]] = FieldInfo(alias="matchMode", default=None)

    missing: Optional[List[EvalResultsUnionMember5Missing]] = None

    precision: Optional[float] = None

    recall: Optional[float] = None

    score_metric: Optional[Literal["f1", "precision", "recall"]] = FieldInfo(alias="scoreMetric", default=None)

    tp: Optional[float] = None


EvalResults: TypeAlias = Union[
    EvalResultsUnionMember0,
    EvalResultsUnionMember1,
    EvalResultsUnionMember2,
    EvalResultsUnionMember3,
    EvalResultsUnionMember4,
    EvalResultsUnionMember5,
]


class Eval(BaseModel):
    """Complete evaluation information"""

    id: str
    """Unique identifier of the evaluation"""

    created_at: datetime = FieldInfo(alias="createdAt")
    """When the evaluation was created"""

    definition: EvalDefinition

    modified_at: datetime = FieldInfo(alias="modifiedAt")
    """When the evaluation was last modified"""

    org_id: str = FieldInfo(alias="orgId")
    """Organization ID that owns this evaluation"""

    status: Literal["PENDING", "IN_PROGRESS", "COMPLETED", "FAILED"]
    """Status of the evaluation/test"""

    passed: Optional[bool] = None
    """Whether the evaluation passed"""

    results: Optional[EvalResults] = None
    """Results of the evaluation (structure depends on eval type)."""

    score: Optional[float] = None
    """Overall score of the evaluation"""


class StepLlmStartStepOutput(BaseModel):
    """Start of an LLM trace."""

    id: str
    """UUID for the step."""

    event: Literal["start"]

    input: str
    """JSON input for this LLM trace event (e.g., the prompt)."""

    api_model_id: str = FieldInfo(alias="modelId")
    """Model ID or name used for the LLM call."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["llm"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


class StepLlmEndStepOutputUsage(BaseModel):
    """Number of input and output tokens used by the LLM."""

    completion_tokens: int = FieldInfo(alias="completionTokens")
    """Number of completion tokens used by the LLM."""

    prompt_tokens: int = FieldInfo(alias="promptTokens")
    """Number of prompt tokens used by the LLM."""


class StepLlmEndStepOutput(BaseModel):
    """End of an LLM trace."""

    id: str
    """UUID for the step."""

    event: Literal["end"]

    api_model_id: str = FieldInfo(alias="modelId")
    """Model ID or name used for the LLM call."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["llm"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    finish_reason: Optional[str] = FieldInfo(alias="finishReason", default=None)
    """
    The reason the LLM stopped generating, extracted from
    gen_ai.response.finish_reasons.
    """

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    output: Optional[str] = None
    """JSON describing the output.

    String inputs are parsed or wrapped in { message: val }.
    """

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """

    usage: Optional[StepLlmEndStepOutputUsage] = None
    """Number of input and output tokens used by the LLM."""


class StepToolStepOutput(BaseModel):
    """Track all tool calls using the Tool Step event"""

    id: str
    """UUID for the step."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["tool"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """

    tool_call_id: Optional[str] = FieldInfo(alias="toolCallId", default=None)
    """
    Correlation ID from the LLM's tool_calls response (e.g., OpenAI's call_abc123 or
    Claude's toolu_01A09q). Links tool execution to the originating LLM request in
    parallel tool call scenarios.
    """

    tool_input: Optional[str] = FieldInfo(alias="toolInput", default=None)
    """JSON input for the tool call."""

    tool_output: Optional[str] = FieldInfo(alias="toolOutput", default=None)
    """JSON output from the tool call."""


class StepRetrieverStepOutput(BaseModel):
    """Track all retriever (RAG) calls using the Retriever Step event."""

    id: str
    """UUID for the step."""

    query: str
    """Query used for RAG."""

    result: str
    """Retrieved text"""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["retriever"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


class StepLogStepOutput(BaseModel):
    """Track all logs using the Log Step event."""

    id: str
    """UUID for the step."""

    content: str
    """The actual log message for this trace."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["log"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


class StepGroupStepOutput(BaseModel):
    """
    Use this to group multiple steps together, for example a log, llm start, and llm end.
    """

    id: str
    """UUID for the step."""

    key: str
    """
    A unique identifier for the grouping, which must be appended to the
    corresponding steps
    """

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["group"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


class StepResponseStepOutput(BaseModel):
    """Track AI responses to users using the Response Step event."""

    id: str
    """UUID for the step."""

    content: str
    """The response content from the AI to the user."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["response"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


class StepRequestStepOutput(BaseModel):
    """Track user requests to the AI using the Request Step event."""

    id: str
    """UUID for the step."""

    content: str
    """The request content from the user to the AI."""

    status: Literal["success", "error", "timeout", "pending"]
    """Status of the step indicating success or failure. Defaults to 'success'."""

    timestamp: datetime
    """When the step was created"""

    trace_id: str = FieldInfo(alias="traceId")
    """UUID referencing the parent trace's ID."""

    type: Literal["request"]

    cost_amount: Optional[float] = FieldInfo(alias="costAmount", default=None)
    """Cost of the step in the configured currency (primarily for LLM steps)"""

    duration_ms: Optional[int] = FieldInfo(alias="durationMs", default=None)
    """Duration of the step in milliseconds"""

    end_time: Optional[datetime] = FieldInfo(alias="endTime", default=None)
    """When the step ended (for duration tracking)"""

    error: Optional[str] = None
    """Error message or stack trace if the step failed."""

    group: Optional[str] = None
    """Optionally, the key for a group step to group the step with."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Extra metadata about this trace event.

    String values are parsed as JSON if possible, otherwise wrapped in { raw: val }.
    """

    name: Optional[str] = None
    """The name of the step."""

    params: Union[Dict[str, object], List[object], None] = None
    """Arbitrary params for the step."""

    parent_id: Optional[str] = FieldInfo(alias="parentId", default=None)
    """Parent step ID for hierarchical span relationships.

    Links this step to its parent in the trace tree.
    """

    status_code: Optional[str] = FieldInfo(alias="statusCode", default=None)
    """
    Status code associated with the step (e.g., HTTP status code for API calls, OTEL
    status code for traced spans).
    """


Step: TypeAlias = Union[
    StepLlmStartStepOutput,
    StepLlmEndStepOutput,
    StepToolStepOutput,
    StepRetrieverStepOutput,
    StepLogStepOutput,
    StepGroupStepOutput,
    StepResponseStepOutput,
    StepRequestStepOutput,
]


class Trace(BaseModel):
    """A trace grouping related steps (e.g. a user-agent interaction or conversation)."""

    id: str
    """Unique Trace ID (UUID)."""

    timestamp: datetime
    """When the trace was created"""

    evals: Optional[List[Eval]] = None
    """Evaluation results for this trace, joined through the associated test."""

    has_error: Optional[bool] = FieldInfo(alias="hasError", default=None)
    """Whether any step in this trace has an error status."""

    metadata: Union[Dict[str, object], List[object], None] = None
    """Arbitrary metadata (e.g., userId, source).

    String inputs are parsed as JSON or wrapped in { raw: val }.
    """

    reference_id: Optional[str] = FieldInfo(alias="referenceId", default=None)
    """
    An optional reference ID to link the trace to an existing conversation or
    interaction in your own database.
    """

    step_count: Optional[int] = FieldInfo(alias="stepCount", default=None)
    """Total number of steps in this trace."""

    steps: Optional[List[Step]] = None
    """The steps associated with the trace."""

    test_id: Optional[str] = FieldInfo(alias="testId", default=None)
    """The associated Test if this was triggered by an Avido eval"""

    total_completion_tokens: Optional[int] = FieldInfo(alias="totalCompletionTokens", default=None)
    """Total number of completion tokens used across all LLM steps in this trace."""

    total_cost: Optional[float] = FieldInfo(alias="totalCost", default=None)
    """Total cost of all steps in this trace (sum of step costAmount values)."""

    total_duration_ms: Optional[int] = FieldInfo(alias="totalDurationMs", default=None)
    """Total duration of the trace in milliseconds (sum of all step durations)."""

    total_prompt_tokens: Optional[int] = FieldInfo(alias="totalPromptTokens", default=None)
    """Total number of prompt tokens used across all LLM steps in this trace."""
