> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutual-dissent.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Types

> ModelResponse, DebateRound, DebateTranscript, and related data structures

All types are defined in `mutual_dissent.models` and `mutual_dissent.types`. Every type is JSON-serializable via `.to_dict()`.

## DebateTranscript

The complete record of a debate session.

```python theme={null}
from mutual_dissent.models import DebateTranscript

transcript.transcript_id    # str — UUID4
transcript.short_id         # str — first 8 characters of transcript_id
transcript.query            # str — original user query
transcript.panel            # list[str] — model aliases
transcript.synthesizer_id   # str — alias of synthesis model
transcript.max_rounds       # int — configured reflection round count
transcript.rounds           # list[DebateRound]
transcript.synthesis        # ModelResponse | None
transcript.created_at       # datetime (UTC)
transcript.metadata         # dict[str, Any]
```

## DebateRound

All responses from one round.

```python theme={null}
round.round_number   # int — 0=initial, 1+=reflection
round.round_type     # str — "initial", "reflection", "synthesis"
round.responses      # list[ModelResponse]
```

## ModelResponse

One model's response in one round.

```python theme={null}
response.model_id       # str — full OpenRouter or vendor model ID
response.model_alias    # str — short alias (e.g. "claude")
response.agent_id       # str — unique agent identity (e.g. "claude-2"), empty if not set
response.display_label  # property — returns agent_id if set, else model_alias
response.round_number   # int
response.role           # str — "initial", "reflection", or "synthesis"
response.content        # str — response text
response.timestamp      # datetime (UTC)
response.token_count    # int | None
response.input_tokens   # int | None
response.output_tokens  # int | None
response.latency_ms     # int | None
response.error          # str | None — set on failure, None on success
response.routing        # dict | None — RoutingDecision serialized
response.analysis       # dict — scoring metadata
```

## ExperimentMetadata

Links a debate to a research experiment. Attached to `transcript.metadata["experiment"]`.

```python theme={null}
from mutual_dissent.models import ExperimentMetadata

meta = ExperimentMetadata(
    experiment_id="study-2-run-001",
    source_tool="countersignal",       # "countersignal", "counteragent", or "manual"
    campaign_id="cs-campaign-abc",     # optional
    condition="unicode tag injection",
    variables={"technique": "unicode_tag", "target_model": "claude"},
    finding_ref="MD-003",              # optional
)
```

## RoutingDecision

Records how a request was routed. Serialized into `ModelResponse.routing`.

```python theme={null}
from mutual_dissent.types import RoutingDecision, Vendor

decision.vendor           # Vendor enum — e.g. Vendor.ANTHROPIC
decision.mode             # str — "auto", "direct", or "openrouter"
decision.via_openrouter   # bool
```

## Vendor

```python theme={null}
from mutual_dissent.types import Vendor

Vendor.ANTHROPIC    # "anthropic"
Vendor.OPENAI       # "openai"
Vendor.GOOGLE       # "google"
Vendor.XAI          # "xai"
Vendor.NVIDIA       # "nvidia"
Vendor.GROQ         # "groq"
Vendor.OPENROUTER   # "openrouter"
Vendor.OLLAMA       # "ollama"
```
